Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Ève

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 1323: TCP Extensions for High Performance

Date de publication du RFC : Mai 1992
Auteur(s) du RFC : Van Jacobson (University of California Berkeley, Lawrence Berkeley Laboratory), Bob Braden (University of Southern California, Information Sciences Institute), Dave Borman (Cray Research)
Chemin des normes
Première rédaction de cet article le 20 décembre 2013


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, ce 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. Ce RFC est ancien et a été remplacé depuis par le RFC 7323. Mais certaines discussions n'ont pas été reprises dans le nouveau RFC et ce RFC 1323 représente donc toujours une lecture indispensable pour les fans de TCP ou tout simplement pour ceux qui veulent comprendre en détail ce protocole.

Avant ce 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 plutôt élargie depuis. La transmission par fibre optique venait juste d'apparaître, poussant à explorer le comportement de TCP à de plus grands débits. 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 de notre RFC, 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 notre RFC 1323 avec l'introduction du window scaling.
  • TCP n'avait pas une connaissance assez précise du RTT, valeur pourtant essentielle au calcul du délai d'attente maximum avant la réémission d'un segment pour lequel il n'y a pas eu d'accusé de réception. Notre RFC 1323 s'attaque au problème avec une nouvelle option TCP permettant d'estampiller temporellement un segment.
  • 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). Contrairement aux deux points précédents, celui-ci n'a pas été traité dans ce RFC 1323 mais dans un RFC ultérieur, 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 or, à 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 1323 de la nouvelle 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.

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. TCP semble mieux placé de ce point de vue (il est mentionné à la fin de mon article sur les options IP).

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).

La nouvelle (à l'époque de ce RFC) 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. 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).

La section 4 présente le mécanisme PAWS (Protect 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.

L'annexe C résume les changements depuis les prédécesseurs, les RFC 1072 et RFC 1185 et ils sont assez profonds. Notamment :

  • L'option SACK (Selective ACKnowledgment), trop contestée à cette époque, a été migrée vers un futur RFC (ce fut le RFC 2018).
  • Les règles précises d'envoi des estampilles temporelles ont été sérieusement refondues.
  • L'ancêtre de l'option Timestamps, les options Echo et Echo reply du RFC 1072 ont été supprimées.

Téléchargez le RFC 1323


L'article seul

RFC 7091: GOST R 34.10-2012: Digital Signature Algorithm

Date de publication du RFC : Décembre 2013
Auteur(s) du RFC : V. Dolmatov (Cryptocom), A. Degtyarev (Cryptocom)
Pour information
Première rédaction de cet article le 17 décembre 2013


L'algorithme de signature GOST est une norme russe de cryptographie. Son utilisation est obligatoire en Russie pour les services publics. L'ancienne version de cet algorithme de signature, GOST R 34.10-2001, était dans le RFC 5832, que ce nouveau RFC met à jour.

Le caractère très étatique de GOST est rappelé dès la section 1.1 du RFC qui note que l'algorithme a été développé par la FAGCI (ou FAPSI), la NSA russe. Il remplace l'ancien GOST R 34.10-2001 (mais ce RFC ne contient malheureusement pas de description des changements entre les deux versions). GOST est obligatoire en Russie pour les services nationaux (section 2 du RFC).

GOST R 34.10-2012, décrit dans ce RFC, est donc un algorithme de pure signature, ne pouvant pas servir au chiffrement. Reposant sur la cryptographie asymétrique, il est donc sur le même créneau que DSA. Mais, contrairement à lui, il repose sur les courbes elliptiques.

Je vous laisse découvrir ledit algorithme dans le RFC, personnellement, mes compétences en cryptographie sont bien trop faibles pour y comprendre quelque chose. Et le code source ? Il ne semble pas être dans OpenSSL qui a apparemment toujours (version 1.0.1e) l'ancienne version de GOST R 34.10. Pour DNSSEC, le numéro d'algorithme 12 est explicitement marqué pour l'ancienne version donc il faudra sans doute un nouveau RFC, succédant au RFC 5933, pour passer à GOST R 34.10-2012.


Téléchargez le RFC 7091


L'article seul

Les places de marché Bitcoin, ça sert à quoi et ça marche comment ?

Première rédaction de cet article le 15 décembre 2013


Il y a plein d'aspects rigolos dans le système Bitcoin et je ne vais pas répéter sur ce blog les très bonnes choses qu'on trouve partout. Cet article se focalise sur un seul aspect, les places de marché. Quel est leur rôle dans le système ? Que font-elles exactement ?

La présentation dans les médias de ces places de marché (bitcoin exchanges dans la langue de Warren Buffett) est souvent trompeuse : elles sont souvent décrites comme un acteur indispensable, nécessaire au fonctionnement du système et, dans ce cas, on en vient forcément à les comparer aux banques traditionnelles, et à se demander si elles sont meilleures ou pires que ces banques et si on a vraiment gagné au change (ah, ah) à remplacer sa banque par une place de marché Bitcoin.

La vérité est que ces places ne sont nullement indispensables. C'est une des beautés de Bitcoin : les intermédiaires ne sont pas indispensables. Vous pouvez parfaitement avoir vos bitcoins dans un ou plusieurs portefeuilles installés sur votre ordinateur et envoyer ou recevoir des bitcoins avec d'autres volontaires, sans passer par une place de marché. Échanger des bitcoins, c'est simplement publier une nouvelle transaction dans la chaîne de transactions publique et cela ne nécessite pas d'intermédiaire entre votre logiciel (comme Electrum ou Multibit) et la chaîne. Les intermédiaires peuvent jouer un rôle utile (j'ai personnellement un compte sur deux de ces places de marché) mais ne sont pas nécessaires. Le rôle d'une de ces places de marché est double : stocker votre argent, qu'il soit en euros ou en bitcoins, et le changer d'euros en bitcoins ou réciproquement.

Le premier rôle est proche de celui d'une banque classique : votre argent n'est pas chez vous, il est dans le cloud. À vous de voir si vous trouvez cela plus sûr ou pas. Des places de marché ont déjà été piratées et les bitcoins volés (les voleurs vont là où est l'argent...) Mais des PC individuels à la maison ont déjà été victimes de logiciels malveillants qui ont volé les bitcoins. Ou de panne ou de destruction.

Si on peut se passer de la première fonction, en gardant les bitcoins chez soi, pour la seconde, c'est plus difficile. Bien sûr, rien n'empêche d'échanger des bitcoins contre des euros avec des copains, ou avec des inconnus rencontrés sur BitcoinMeet ou LocalBitcoins. Pour des petites sommes « pour voir », je ne pense pas que cela cause un problème. Au delà, je ne me prononcerai pas sur la légalité de l'opération. En effet, le bitcoin lui-même n'est pas légal ou illégal. Il est « a-légal » dans la mesure où il n'est pas traité par une loi. Son échange entre acteurs économiques ne me semble pas poser de problème (je ne suis pas juriste, attention, prenez mes appréciations avec des pincettes). En revanche, sa conversion en euros (ou le contraire) fait intervenir la monnaie officielle et c'est là que s'exerce le pouvoir de l'État, à des fins d'imposition ou de lutte contre certains trafics. Donc, l'achat ou la vente de bitcoins avec des euros ne peut probablement pas se faire simplement, d'un commun accord. Vous devez passer par une place de marché (ou par un distributeur automatique), et celles-ci sont fortement régulées. (À noter qu'aussi bien les partisans du Bitcoin, pour s'en féliciter, que ses adversaires, pour le déplorer, affirment souvent que le Bitcoin échappe à toute loi et toute régulation. C'est tout à fait faux, au moins quand on l'échange avec la monnaie officielle.)

Donc, quelles sont les places de marché disponibles, et leurs caractéristiques ? Les médias, qui ne font en général rien d'autre que de se recopier les uns les autres, n'en citent quasiment qu'une seule, Mt.Gox. Enregistrée au Japon, ce n'est pourtant pas forcément la solution la plus naturelle pour quelqu'un qui vit en France, comme moi. Il existe pourtant de nombreuses autres places de marché, et je vais citer les deux où j'ai un compte, Bitcoin Central et Kraken. Elles sont entièrement en ligne (pas de guichets physiques). Dans les deux cas, on se crée un compte en ligne mais, au contraire de tant de services sur le Web, on ne peut pas s'en servir tout de suite, un certain nombre de vérifications sont faites. Ces vérifications dépendent de la politique de la place de marché mais aussi des lois et réglements qui s'appliquent à elles. Si le Bitcoin lui-même peut être décrit comme planant dans un espace virtuel, ces places de marché sont, elles, fermement ancrées dans un espace légal national.

Du point de vue de cet ancrage national, Bitcoin Central est français (et doit donc appliquer la loi française), et Kraken états-unien (avec une adresse d'une banque allemande en Grande-Bretagne pour les virements... On peut noter que leur site Web n'est pas excessivement bavard en informations). Les vérifications demandées sont bien plus détaillées pour Bitcoin Central (il faut donner des détails personnels et envoyer un fichier numérisé d'un certain nombre de papiers officiels) et plus longues (il m'a fallu seize jours pour être validé). Il est difficile de comparer avec les conditions de Kraken, car, alors que Bitcoin Central est binaire (on est validé ou on ne l'est pas), Kraken a un système de niveaux (tiers), cinq au total. Pour passer au niveau supérieur, il faut fournir plus d'informations et se prêter à plus de vérifications. Et les actions qu'on peut faire sont limitées en fonction du niveau. Pour ma part, je suis actuellement au niveau Deux (le troisième, puisque cela part de zéro), ce qui me permet de déposer ou retirer 2 000 $ par jour (avec une limite de 10 000 par mois). La validation à ce niveau a pris deux jours mais il est difficile de dire ce qui a été exactement vérifié (je ne pense pas que quelqu'un soit venu voir en bas de l'immeuble si mon nom était bien sur une des boîtes aux lettres).

Une fois qu'on est validé, que peut-on faire ? L'interface de Bitcoin Central est très simple, n'offrant que peu de possibilités, ce qui est certainement un avantage pour les débutants :

Sans vérifier la documentation, on trouve tout de suite comment déposer des euros ou des bitcoins, changer de l'argent, ou retirer des euros ou des bitcoins. Dans mon cas, j'ai alimenté mon compte Bitcoin Central avec des euros par un simple virement bancaire SEPA vers l'IBAN indiqué. Ensuite, j'ai pu changer ces euros en bitcoins et retirer ensuite des bitcoins, en les envoyant à l'adresse Bitcoin indiquée. On voit donc qu'on peut utiliser une place de marché juste pour le change et ne pas laisser son argent ensuite. (Mais attention, avant de retirer des bitcoins, assurez-vous que le portefeuille de destination est sécurisé, à la fois contre le piratage, et contre la perte accidentelle. Vérifiez la sécurité de la machine qui l'héberge, et les sauvegardes. N'oubliez pas que Bitcoin a une sémantique proche de l'argent liquide : si vous envoyez à une mauvaise adresse, l'argent est perdu. Si votre disque dur vous lâche, même chose.) Un autre piège avec Bitcoin Central (documenté mais, comme je l'ai écrit, je n'avais pas lu la documentation) : pour des raisons de sécurité, des tas de choses sont stockées hors-ligne et ne sont extraites du coffre-fort qu'à certains moments. Vous n'aurez donc pas vos bitcoins tout de suite.

L'interface de Kraken est très différente. Par défaut, pour passer un ordre, vous avez la version simple :

Et il y a une version plus riche :

Beaucoup plus riche qu'avec Bitcoin Central, l'interface est même franchement effrayante pour des débutants qui ne connaissent pas le monde de la finance. On vous y propose de faire plein de choses. Suivez un conseil de bon sens : si vous ne connaissez pas ces instruments financiers, tenez-vous à l'écart et contentez-vous, comme dans le paragraphe précédent, d'échanger des bitcoins contre des euros (toujours avec un virement bancaire pour alimenter le compte originalement). L'interface de Kraken étant riche, consulter la documentation, même pour des tâches simples, est recommandée.

Je ne suis pour l'instant qu'un tout petit utilisateur, expérimentant avec des petites sommes. Je ne peux donc pas encore donner d'affirmation solide sur la meilleure place de marché. Je ne peux notamment rien dire sur la qualité du support utilisateurs chez Kraken, je n'ai pas encore eu à l'utiliser. Mais je note que, pendant la grande panne de Kraken du 12 décembre 2013 (apparemment due à une attaque par déni de service), le community manager n'a donné aucune information sur Twitter. En revanche, chez Bitcoin Central, je peux dire que le support est aimable, assez rapide, et répond en général de manière pertinente. Je le sais car j'ai eu souvent besoin de faire appel à eux, chaque opération nécessitant au moins un appel au support, en raison du nombre de choses qui ne fonctionnaient pas encore (virements qui n'arrivent pas, courrier de demande de confirmation qui ne part pas, etc). Leur logiciel semble encore très jeune. Mais, à chaque fois, ça a fini par marcher donc, si vous devenez client de Bitcoin Central, vous profiterez du déboguage fait grâce aux premiers utilisateurs :-)

Sur Kraken, un chose est à noter : on peut enregistrer sa clé publique PGP et les messages de Kraken vers vous sont alors en PGP. Excellente idée et j'aimerai bien que les autres banques suivent ! Deux petits bémols toutefois, le sujet du message est en clair et Kraken le fait très informatif, donc cela diminue l'intérêt de chiffrer. Et Kraken met le texte chiffré directement dans le corps du message au lieu d'utiliser le RFC 3156.

Kraken et Bitcoin Central disposent d'autres mécanismes de sécurité rigolos. Par exemple, l'authentification de base est faite par un mot de passe mais on peut demander des mécanismes plus sûrs (mais aussi plus complexes). Pour l'instant, comme je ne manipule que de petites sommes, j'ai juste activé une option astucieuse de Kraken : celle qui bloque toute modification du compte pendant une période qu'on choisit. Ainsi, même si je me fais piquer mon mot de passe, l'attaquant devra attendre quelques jours avant de changer les paramètres d'authentification, ce qui me permettra de détecter le problème et de donner l'alarme.

Ah, et si vous vous demandez ce que veulent dire les termes financiers mystérieux de l'interface de Kraken, Vincent Archer a fait un excellent travail d'explication, que je copie/colle ici avec mes remerciements. Leverage, en économie, c'est le taux d'endettement. Par extension, c'est l'emprunt pour investissement, lorsqu'on emprunte pour investir dans quelque chose qui rapportera plus que le taux d'intérêt à payer, par opposition à l'emprunt de financement (borrowing), pour financer un achat. Utilisé aussi pour indiquer le taux d'endettement ; quand on te demande le niveau de leverage, c'est que tu veux emprunter une partie du montant pour acheter tes bitcoins. Ce n'est pas une distinction absolue, mais plutôt un usage. On utilise beaucoup en adjectif l'expression leveraged buyout qu'on voit dans le rachat d'entreprise. Elle signifie qu'une partie du rachat de la boite est fait avec un emprunt (et pas en trésorerie ou en échange d'actions).

Margin, c'est la partie de ton achat qui est financée par le prêt.

Et la position, dans la bourse, c'est quand tu dois forcément vendre ou acheter quelque chose, en général parce que tu as acheté ou vendu à découvert (ou en margin, comme on vient de dire). Si tu as choisi un pourcentage d'emprunt, tu te places dans une position d'obligation où tu devras revendre la partie que tu as financée via le prêt. Sinon, c'est juste que tu as fait une opération de change et tu peux tout garder.

Et bien sur, closed signifie dérouler l'obligation de revente... Et réaliser (matérialiser en vrai) le bénéfice ou la perte. Fin des explications financières de Vincent.

Les idées sur le caractère a-légal du bitcoin et sur le fait que c'est l'échange en euros qui l'amène sous les projecteurs de la régulation viennent d'une publication de la Banque de France, Focus n° 10, disponible en ligne.

Merci à Vincent Archer et Laurent Penou pour la relecture, mais je garde le copyright sur toutes les fautes et erreurs de cet article.


L'article seul

Article et exposé JRES sur les attaques par déni de service utilisant le DNS

Première rédaction de cet article le 12 décembre 2013


Le 11 décembre, à Montpellier, lors des Journées RÉSeaux (JRES, le plus important rassemblement francophone d'administrateurs système et réseaux), j'ai parlé des attaques par déni de service utilisant le DNS.

Voici l'article complet, son source. Et puis les diapos et leur source.

La page JRES sur cet exposé est https://conf-ng.jres.org/2013/planning.html#article_37. Avec le lien « Voir la présentation en VOD », vous pouvez accéder à la vidéo. Ceci dit, j'ai eu beaucoup de problèmes techniques en streaming. L'URL comprend un nom (video.renater.fr) qui a une adresse IPv6 mais qui ne répond pas en IPv6. vlcne bascule pas tout de suite en IPv4. Quand il le fait, la liaison est mauvaise, on voit des écrans noirs, etc. Peut-être est-ce mieux en téléchargeant.


L'article seul

Mes opinions sur le bitcoin

Première rédaction de cet article le 9 décembre 2013


Comme j'ai écrit un article sur le bitcoin (et que ce n'est pas terminé), des gens m'ont demandé ce que j'en pensais. Des questions faciles du genre « ça va monter ? », « c'est légal ? », « c'est de gauche ? » ou encore « je peux m'enrichir avec ? » (C'est bien la première fois qu'on me demande un avis sur une question financière : merci, le bitcoin.)

Alors, quelques paragraphes sur mes opinions sur le bitcoin. D'abord, ne me demandez surtout pas de conseil d'investissement, je n'en ai aucune idée. J'ai pour l'instant peu de bitcoins, mais je vais peut-être en acheter plus car je pense que c'est rigolo mais je ne suis pas un gourou des finances qui peut vous aider à vous enrichir (attention : les gourous professionnels n'en savent pas forcément plus que moi). Je note quand même un avantage du bitcoin : sa volatilité est bien connue. Elle est typiquement affichée dès la page d'accueil de la plupart des places de marché (voir par exemple les statistiques sur Bitcoin Central). On aimerait pouvoir en dire autant des mirifiques placements en actions que le commercial de votre banque essaie de vous fourguer à chaque occasion. (Le bitcoin a certes des tas d'inconvénients mais une grande partie de l'intérêt que les gens lui portent est due à la frustration éprouvée avec les banques. Si les banques veulent diminuer l'intérêt pour le bitcoin, elles peuvent déjà commencer par améliorer l'information aux clients. Par exemple, la page d'accueil de l'excellent site http://www.bitcoin.fr/ dit « n'y investissez que le temps et l'argent que vous pouvez vous permettre de perdre ». Quelle banque a des avertissements aussi francs ?)

Deuxième chose, je ne sais pas non plus si le bitcoin est l'avenir de la monnaie et va remplacer les vieux systèmes. Et je m'en fiche, je ne suis pas un commercial cherchant à promouvoir le bitcoin. Ce qui m'intéresse dans ce projet, c'est la réouverture des questions fondamentales, qui avaient été bien verrouillées par les banques et les gouvernements. C'est quoi, la monnaie ? Quelles doivent être ses propriétés essentielles ? Qui doit la contrôler ? En suivant quels principes ? Il n'est donc pas exagéré de dire que le bitcoin est à la finance ce que l'Internet est aux télécommunications : la preuve vivante qu'on peut faire autrement que la « seule méthode », que la pensée unique promue par les experts et les gens sérieux. Qu'un expert dise que le bitcoin ne peut pas marcher, pour telle ou telle raison, cela me laisse froid. Les experts en télécommunications de toutes catégories disaient aussi que l'Internet ne pouvait pas marcher.

Est-ce que la future monnaie générale sera le bitcoin ? Peut-être. Et peut-être pas. Peut-être les forces conservatrices l'emporteront. Peut-être aussi que le bitcoin prouvera, à l'usage, des inconvénients vraiment insupportables et qu'une autre monnaie nouvelle lui succédera (il existe déjà des tas de candidats comme le litecoin). Je l'ai dit, c'est pour l'instant l'exploration de nouvelles possibilités qui m'intéresse.

Enfin, il y a des appréciations sur le bitcoin qui ont l'air techniques mais qui sont en fait morales, voire moralisatrices. Par exemple de dire qu'il est une monnaie virtuelle. Il y a très longtemps que c'est le cas de toutes les monnaies. Pas seulement depuis que les milliards s'échangent de manière dématérialisée avec le HFT et entre paradis fiscaux. Pas seulement depuis l'abandon de l'étalon-or par les États-Unis en 1971. Mais au moins depuis Philippe le Bel qui rognait les pièces d'or en décrétant que la valeur d'une pièce ne provenait pas de son ancrage dans le monde physique, mais uniquement du décret royal.

De la même façon, reprocher aux gens qui achètent du bitcoin et qui le revendent plus cher (sans avoir travaillé pour justifier ce gain) de faire de la spéculation est risible : la majorité des échanges monétaires n'a aucun lien avec une vraie création de richesses. Qu'on critique la finance, OK. Mais qu'on n'oppose pas une vraie économie au méchant bitcoin. La vraie économie (les gens qui, en travaillant, produisent des richesses) est minoritaire en dollars ou en euros depuis bien longtemps.

En conclusion, je ne sais pas encore ce que je vais faire dans l'avenir, question bitcoins. Mais je trouve réjouissantes les critiques qui lui pleuvent dessus : c'est peut-être que le bitcoin pose les bonnes questions.

Cet article a été repris sur l'excellent site d'information sur le Bitcoin http://www.bitcoin.fr/ et a suscité pas mal de commentaires (dont plusieurs négatifs). Même chose sur ContrePoints (site d'information de droite, tendance libertarien).


L'article seul

Sécurité de DANE

Première rédaction de cet article le 9 décembre 2013


Le système DANE (DNS-Based Authentication of Named Entities) permet d'augmenter la sécurité des échanges chiffrés avec TLS en permettant au gérant du serveur de publier lui-même le certificat qu'il utilise, et en permettant au client de vérifier, par une deuxième voie, le DNS, que le certificat est le bon. L'expérience d'autres technologies de sécurité est que DANE, s'il est effectivement déployé dans le futur, sera attaqué par des méchants compétents et que ses faiblesses seront exploitées. C'est donc une bonne idée, avant ce déploiement massif, de se demander quelle est la sécurité de DANE et quelles attaques sont possibles. Plaçons-nous donc dans la peau de l'attaquant. Alice se connecte au serveur de Bob en TLS (par exemple en HTTPS), et Bob utilise DANE. Que peut faire Mallory pour se faire passer pour Bob sans qu'Alice s'en aperçoive ?

Si vous ne connaissez pas DANE, vous pouvez l'apprendre dans l'excellent dossier thématique de l'AFNIC ou (plus anciens) dans mon article à JRES ou encore dans mon article sur le RFC 6698, qui normalise DANE. Avant DANE, les communications en TLS (RFC 5246) étaient sécurisées par X.509 uniquement. Une grosse faiblesse de X.509 est que n'importe quelle autorité de certification peut émettre un certificat pour n'importe quel nom, même s'il n'est pas son client. On voit ainsi régulièrement des faux certificats émis par des AC malhonnêtes, maladroites ou piratées, par exemple pour intercepter le trafic des services de Google.

Donc, plaçons-nous quelques années dans le futur. DANE est largement déployé, des sites Web accessibles en HTTPS publient les enregistrements DANE (nommés TLSA) dans leurs zones DNS signées avec DNSSEC, Alice veut se connecter au serveur de Bob et Mallory, qui peut détourner le trafic, veut être Homme au Milieu sans que le navigateur Web d'Alice ne donne l'alarme.

D'abord, Mallory, en vrai professionnel, étudie les mises en œuvre de DANE dans les navigateurs. Il y a deux façons très différentes d'utiliser DANE, les utilisations 0 et 1 d'un côté, et les 2 et 3 de l'autre. Lorsque l'enregistrement TLSA contient 0 ou 1 dans le champ « Utilisation du certificat » (Certificate usage), l'authentification DANE se fait en plus de l'authentification X.509 classique (plus exactement PKIX, un profil de X.509 décrit dans le RFC 5280). Avec ces utilisations 0 et 1, Mallory doit casser DNSSSEC et X.509. Lorsque l'enregistrement TLSA contient 2 ou 3, l'authentification DNSSEC se fait à la place de l'authentification X.509 classique.

Quelles utilisations seront adoptées ? Les plus prudents, soucieux de ne pas lâcher la proie pour l'ombre, adopteront sans doute 0 et 1, renforçant la sécurité X.509 par celle de DNSSEC (stratégie « ceinture et bretelles »). Les autres, ou simplement ceux qui ne veulent pas passer par les procédures et coûts des AC X.509, adopteront les utilisations 2 et 3 (stratégie « remplacer les bretelles par des ceintures »). Mais il ne faut pas oublier que les choix de sécurité, dans le cas de HTTPS, sont faits essentiellement par les auteurs de navigateurs, pas par les utilisateurs (que ce soit Alice ou Bob). Il est donc possible que certains navigateurs ne mettent en œuvre DANE que pour les usages 0 et 1, jugeant 2 et 3 trop dangereux.

Donc, Mallory regarde l'enregistrement TLSA de Bob (ici, avec le site Web https://dane.rd.nic.fr/) :


% dig TLSA _443._tcp.dane.rd.nic.fr

; <<>> DiG 9.9.3-rpz2+rl.13214.22-P2-Ubuntu-1:9.9.3.dfsg.P2-4ubuntu1 <<>> TLSA _443._tcp.dane.rd.nic.fr
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40804
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;_443._tcp.dane.rd.nic.fr. IN TLSA

;; ANSWER SECTION:
_443._tcp.dane.rd.nic.fr. 1 IN TLSA 3 0 1 (
				C68EBCC998FDA83222CABF2C0228ECC413566E709E5D
				C5CF25396A8BF4342DD3 )
...
;; Query time: 117 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 09 10:39:48 CET 2013
;; MSG SIZE  rcvd: 876

OK, il est bien signé (le bit AD pour Authentic Data). Rappelons en effet que DANE dépend de DNSSEC. Le RFC 6698 est très clair là-dessus (après de longs débats à l'IETF) : les enregistrements TLSA non signés sont ignorés. Une conséquence est que la sécurité de DANE dépend d'une bonne politique DNSSEC. Par exemple, pour être vraiment sûre, la validation DNSSEC devrait se faire sur le poste local d'Alice.

Ici, l'utilisation est 3 (les données dans l'enregistrement TLSA sont un certificat auto-signé). Quelles sont les attaques possibles pour Mallory ? Sauf si Mallory connait un moyen de casser cryptographiquement DNSSEC, la seule solution est de s'attaquer à un des intermédiaires dans la chaîne DNSSEC, afin de supprimer ou de remplacer l'enregistrement TLSA. En effet, comme le DNS, DNSSEC fonctionne selon une logique arborescente : la validation de www.example.nl dépend de la racine du DNS et du registre de .nl. On a déjà vu des registres ou des bureaux d'enregistrement être piratés, donc cela n'a rien d'impossible (même si DNSSEC complique sérieusement la tâche de Mallory). Avec l'utilisation 3, pas besoin d'attaquer une AC ou de trouver une faille dans le système X.509. Mais est-ce à dire qu'on a simplement remplacé la confiance dans son AC par la confiance dans son registre de noms de domaine ? Si c'était le cas, DANE ne changerait pas grand'chose. Mais il y a une grosse différence : avec X.509, vous devez faire confiance à toutes les AC, pas seulement celle que vous avez choisi et donc vous êtes clients, car toutes peuvent émettre un certificat pour le site Web de Bob. Avec DNS et DNSSEC, vous choisissez à qui vous faites confiance.

Et si l'enregistrement TLSA avait l'utilisation 2 ? Dans ce cas non plus, il n'y a pas de validation X.509 depuis le magasin de certificats du navigateur Web, et donc pas la peine de détourner une des AC reconnues des auteurs de navigateurs. Avec un enregistrement TLSA d'utilisation 2, le contenu de l'enregistrement TLSA est le certificat d'une AC (qui n'a pas besoin d'être dans le magasin des navigateurs). On a donc deux possibilités d'attaque : contre le système d'enregistrement de noms de domaine, comme dans le cas de l'utilisation 3 précédemment cité, ou bien une attaque contre cette AC particulière, par exemple en la piratant. Notons encore une fois que, contrairement au X.509 classique, Mallory n'a pas le choix de la cible, elle doit réussir à pirater une AC particulière. Conclusion : si l'AC désignée par l'enregistrement TLSA d'utilisation 2 est gérée par une organisation différente de celle de Bob, on a élargi les possibilités de Mallory.

Et si on a le navigateur paranoïaque hypothétique que je citais, celui qui refuse les utilisations 2 et 3 ? Ce cas n'est pas prévu par le RFC. Le plus logique serait qu'il ignore ces enregistrements (les faire correspondre d'autorité aux utilisations 0 et 1 serait une violation de la norme DANE, avec plein de résultats surprenants). On se trouverait donc ramené au cas d'un navigateur qui n'a pas DANE du tout, ce qui est le cas de la totalité de ceux d'aujourd'hui.

Et avec l'utilisation 1 ? Cette fois, les habitué(es) du X.509 classique se retrouveront en terrain connu. Une valeur 1 dans la champ « Utilisation du certificat » de l'enregistrement TLSA signifie que les données de l'enregistrement contiennent le certificat effectivement utilisé par le site et qu'il faut le valider par les mécanismes X.509 habituels. C'est la sécurité maximale : DNSSEC plus X.509. Mallory doit cette fois pirater une AC (pour faire un autre certificat) et modifier l'enregistrement TLSA. Pirater une AC, même celle utilisée par Bob, ne suffirait plus car le certificat est épinglé par Bob : celui-là et pas un autre.

Reste l'utilisation 0, nombre dont la présence dans le champ Utilisation signifie que l'enregistrement TLSA désigne une AC, celle de Bob. Mallory doit donc pirater le DNS pour le changer ou bien pirater cette AC particulière. Notez que, pour les utilisations 0 et 1, cette analyse dépend du fait que le piratage de l'AC et celui du DNS sont des opérations indépendantes. Si, en piratant l'un, Mallory peut pirater l'autre, la double sécurité ne sera en fait qu'une illusion. Or, certaines AC signent des certificats après juste un échange de courrier électronique, qui peut être détourné si on détourne le DNS.

En conclusion, DANE, comme toute technique de sécurité, n'est pas invulnérable. Un attaquant déterminé, patient et compétent peut en venir à bout. Il est donc nécessaire de faire une analyse de la sécurité et de voir ce qu'on risque.

Un autre article en français avec une analyse détaillée de la sécurité de DANE (avec notamment les risques des attaques par rejeu) est celui de Florian Maury. En anglais, curieusement, je n'ai pas encore trouvé grand'chose, à part bien sûr la section 8 du RFC 6698.


L'article seul

RFC 7045: Transmission and Processing of IPv6 Extension Headers

Date de publication du RFC : Décembre 2013
Auteur(s) du RFC : B. Carpenter (Univ. of Auckland), Huawei Technologies
Chemin des normes
Première rédaction de cet article le 6 décembre 2013


Encore un RFC de clarification sur IPv6. Le déploiement effectif de ce protocole a en effet suscité des questions qui n'étaient pas évidentes avant. Ce RFC s'occupe des en-têtes d'extension que peut contenir un datagramme IPv6. Les règles de traitement de ces en-têtes dans la section 4 du RFC 2460 n'étaient en effet pas d'une clarté limpide. Ce RFC précise aussi les règles d'enregistrement de nouveaux en-têtes à l'IANA, puisqu'il n'existait malheureusement pas de liste faisant autorité.

Petit rappel, d'abord (section 1 du RFC) : l'en-tête normal d'un datagramme IPv6 est de taille fixe (40 octets) contrairement à ce qui se passe en IPv4. Mais entre cet en-tête et le contenu du paquet (qui peut être du TCP, de l'ICMP, de l'UDP ou même être vide), peuvent se glisser plusieurs en-têtes d'extension. Il y a donc une chaîne d'en-têtes, reliés par le champ Next header qui identifie le type de l'en-tête d'extension ou du contenu qui suit. Par exemple, un Next header à 60 signifie que cet en-tête est suivi par un en-tête Destination options alors qu'un Next header à 6 indique que l'en-tête est suivi par du contenu TCP.

La norme IPv6, le RFC 2460, spécifiait dans sa section 4 un jeu initial d'en-têtes d'extension, ainsi que la façon de les traiter. À l'exception de l'en-tête Hop-by-Hop Options, les en-têtes d'extension devaient être ignorés par les routeurs intermédiaires, et traités uniquement dans la machine de destination finale. Ainsi, de nouveaux en-têtes pouvaient être introduits sans affecter les routeurs et sans que ceux-ci aient besoin d'être mis à jour.

Ce schéma correspondait à l'architecture originale de l'Internet : le moins de traitements possible dans les nœuds intermédiaires, et toute l'intelligence aux extrémités. Mais ce modèle est désormais menacé par l'invasion de middleboxes plus ou moins invasives. Par exemple, pare-feux et répartiteurs de charge inspectent le paquet et prennent des décisions en fonction d'autres informations que l'en-tête initial (en général, elles regardent au moins l'en-tête TCP). Résultat, on ne peut plus prétendre que le réseau est transparent pour les en-têtes d'extension. Ces middleboxes doivent suivre toute la chaîne des en-têtes et ce travail est plutôt compliqué, car il n'existait pas (jusqu'au RFC 6564) de format uniforme pour les en-têtes. Il est donc difficile de l'accomplir à la vitesse du réseau, lorsque celui-ci est du 100 Gb/s ! Ce problème n'a pas de solution simple (il découle d'un mauvais choix lors de la création d'IPv6) mais on peut au moins spécifier rigoureusement ce qu'on attend de ces middleboxes.

En effet, certaines middleboxes, notamment les pare-feux, ont un comportement anormal. Un pare-feu est, par profession, paranoïaque : il rejette tout ce qu'il ne connait pas. Un en-tête inconnu et, hop, tout le paquet est jeté. Les en-têtes nouveaux ont donc peu de chances de réussir à se frayer un chemin dans l'Internet. Mais il y a pire : bien des pare-feux programmés avec les pieds par des gens qui n'ont jamais lu le RFC 2460 ne reconnaissent même pas la totalité des en-têtes d'extension originels. Ainsi, certaines fonctions d'IPv6, pourtant normalisées dès le début, comme la fragmentation, ont du mal à fonctionner.

Même si le programmeur de la middlebox a lu le RFC 2460, il risque de s'être simplifié la vie en ignorant la possibilité que de nouveaux en-têtes soient définis. L'IETF ne leur facilitait pas la tâche en ne fournissant pas de liste faisant autorité de tous les en-têtes déclarés. En effet, les numéros d'en-tête sont issus du même espace que les protocoles de transport (voir le registre). Et il n'y avait pas de moyen simple de savoir si le numéro N dans cet espace désigne un protocole de transport ou un en-tête d'extension, si l'application ne connait pas ce qui est désigné par ce N. Résultat, les nouveaux en-têtes ont peu de chance d'être déployés (ils se heurteront à toutes les middleboxes). On voit donc peu d'applications qui tentent d'utiliser des nouveaux en-têtes... ce qui ne motive pas les développeurs de middleboxes à réparer leurs engins. Le format uniforme des en-têtes, décrit dans le RFC 6564, arrangera un peu les choses, en permettant de passer un en-tête, même inconnu.

Après ces préliminaires, les exigences (section 2 de notre RFC). D'abord, un rappel, le traitement des en-têtes d'extension n'est pas une cerise sur le gâteau, c'est un composant indispensable d'IPv6 et toute machine qui prétend traiter l'IPv6 doit traiter ces en-têtes et, si elle veut accéder au contenu du paquet, doit être capable de traiter la chaîne complète des en-têtes. Un simple routeur (qui ne regarde pas le contenu des paquets) doit transmettre les paquets qu'ils aient des en-têtes d'extension ou pas (ce routeur n'a que l'en-tête fixe à regarder). Un engin qui a des fonctions supplémentaires (comme un pare-feu) doit examiner toute la chaîne si elle ne comprend que des en-têtes normalisés et notre RFC recommande que cela soit possible même s'il existe des en-têtes inconnus dans la chaîne. Maintenant qu'une liste des en-têtes normalisés est publiée, les programmeurs n'ont plus d'excuse.

Le RFC 2460 demandait que les machines de destination jettent les paquets contenant des en-têtes inconnus. Mais cela ne s'applique qu'aux machines de destination. Les machines intermédiaires, comme les pare-feux, ne doivent pas en faire autant, sinon il ne sera jamais possible de déployer de nouveaux en-têtes (je crains que cette excellente recommandation ne soit largement ignorée, dans un Internet de plus en plus ossifié).

Une machine intermédiaire peut avoir une option configurable pour jeter les paquets contenant des en-têtes normalisés mais cela doit être une option, non activée par défaut. (Pour les en-têtes inconnus, le choix par défaut peut être de les jeter.)

Une mention spéciale pour l'en-tête de routage (section 4.4 du RFC 2460). Il existe en plusieurs variantes, identifiées par un numéro de type. Si les types 0 et 1 ont été officiellement abandonnés pour des raisons de sécurité (RFC 5095), il n'y a aucune bonne raison de jeter les paquets contenant d'autres types, comme le type 2 (RFC 6275) ou le type 3 (RFC 6554).

Une autre mention concerne l'en-tête hop by hop, le seul que tous les routeurs sur le trajet sont censés examiner (c'est pour cela qu'il est obligatoirement en premier). Comme c'est très difficile à faire à pleine vitesse, notre RFC adopte une position réaliste en notant qu'il ne faut pas s'attendre à ce que tous les routeurs le fassent effectivement, et que ceux qui le feront utiliseront sans doute un chemin plus lent à l'intérieur du routeur.

La section 3 revient sur des questions de sécurité générales. Par exemple, elle rappelle que des en-têtes utilisant les valeurs marquées comme expérimentales (253 et 254) auront encore plus de problèmes que les autres à passer (RFC 4727).

Quant à la section 4, elle spécifie les changements à l'IANA visant à faciliter la tâche des programmeurs de code IPv6. D'abord, dans le registre des numéros de protocole, ajouter une colonne pour indiquer s'il s'agit d'un en-tête d'extension IPv6 (la nouvelle colonne « IPv6 Extension Header »). Ensuite, créer un nouveau registre ne contenant que ces numéros. L'enregistrement de nouveaux en-têtes continue à suivre les règles du RFC 2780.


Téléchargez le RFC 7045


L'article seul

RFC 7100: Retirement of the "Internet Official Protocol Standards" Summary Document

Date de publication du RFC : Décembre 2013
Auteur(s) du RFC : P. Resnick (Qualcomm Technologies)
Première rédaction de cet article le 6 décembre 2013


Un peu de rangement dans la bibliothèque des RFC. La section 2.1 du RFC 2026 indiquait qu'un RFC spécial (nommé « STD 1 ») contenait une liste de tous les RFC ayant le statut de norme. Maintenir un tel document était devenu trop coûteux et cette règle est désormais abandonnée. Le dernier de la série aura été le RFC 5000, qui n'aura donc pas de successeur (RFC 7101). Désormais, il ne reste plus que la liste publiée en ligne, maintenant la seule à faire foi. Si vous voulez connaître le statut d'un RFC, c'est là qu'il faut aller.


Téléchargez le RFC 7100


L'article seul

RFC 7101: List of Internet Official Protocol Standards: Replaced by an Online Database

Date de publication du RFC : Décembre 2013
Auteur(s) du RFC : S. Ginoza (AMS)
Pour information
Première rédaction de cet article le 6 décembre 2013


Il fut une époque où le RFC Editor publiait une liste des normes techniques Internet, sous forme d'un RFC. Connue sous le nom de « xx00 », cette liste n'a plus été publiée depuis 2008 et il était donc temps de documenter sa disparition. Elle est désormais remplacée par une page Web.

Le premier RFC à jouer ce rôle était le RFC 1083. À partir du RFC 2200, cette liste était publiée dans des RFC dont le numéro se terminait par 00, ce qui a mené au surnom « xx00 » pour désigner la série. Le dernier a été le RFC 5000. La série étant terminée, des futurs RFC au numéro se terminant par 00 pourront apparaître, sans qu'ils aient de lien avec cette liste de normes.

De nos jours, une liste en ligne, mise à jour en permanence, est évidemment plus logique. Elle existe depuis maintenant dix ans, et, comme noté par le RFC 7100, en raison de cette existence, les RFC « xx00 » (également désignés par l'abréviation « STD 1 ») n'ont plus de sens.


Téléchargez le RFC 7101


L'article seul

Utilité de DNSSEC contre un attaquant qui contrôle la clé privée de la racine

Première rédaction de cet article le 5 décembre 2013


Aujourd'hui, petit exercice intellectuel avec du DNS, de la cryptographie et de la sécurité. Si un attaquant peut injecter des fausses réponses DNS et le faire accepter par un résolveur, il peut empoisonner ce résolveur. DNSSEC protège contre cette attaque. Mais DNSSEC, comme le DNS, est arborescent. Si l'attaquant contrôle d'une façon ou d'une autre la racine, tout DNSSEC s'écroule-t-il ?

Cet exercice provident d'un article de Bruce Schneier où il décrit un des programmes d'espionnage de la NSA, QUANTUM. L'attention du public, suite aux révélations d'Edward Snowden, s'est surtout focalisée sur les attaques passives de la NSA, comme la copie des données stockées dans les grands silos états-uniens (programme PRISM). Mais QUANTUM est, lui, un programme d'attaque active. La NSA peut aussi injecter des paquets dans le réseau, afin de faciliter un espionnage passif ultérieur. Schneier ne parle pas du tout du DNS dans son article. Mais on peut néanmoins supposer que, parmi ces attaques actives de la NSA (ou d'autres attaquants), certaines vont consister à utiliser le DNS pour empoisonner les résolveurs, détournant les utilisateurs vers des copies des sites à visiter. Ce mécanisme (sur lequel, rappelez-vous, nous n'avons pas de preuve dans les documents Snowden), a été décrit dans un excellent article d'un expert DNS, Nicholas Weaver. Weaver dit « Since every communication starts with a DNS request, and it is only a rare DNS resolver that cryptographically validates the reply with DNSSEC, a packet injector can simply see the DNS request and inject its own reply. This represents a capability upgrade, turning a man-on-the-side into a man-in-the-middle. ».

Weaver mentionne DNSSEC comme une solution possible contre cette attaque. (Si vous ne connaissez pas DNSSEC, vous pouvez commencer par mon article à JRES.) Seulement, si l'attaquant est la NSA, il faut supposer qu'il peut signer des données quelconques avec la clé privée de la racine, cette racine étant sous le contrôle exclusif des États-Unis. Notez que je dis « l'attaquant peut signer des données », pas « l'attaquant peut mettre la main sur la clé privée ». En effet, cette clé est dans un HSM dont elle ne peut jamais, sauf bogue ou porte dérobée dans le HSM, sortir. Mais peu importe : la NSA peut certainement accéder au système de signature et faire signer ce qu'elle veut, pour injection ultérieure. La question est « est-ce réaliste techniquement ? » Accrochez-vous, la réponse peut être compliquée.

En théorie, oui, cette attaque va marcher et DNSSEC ne serait donc pas utile contre la NSA. En pratique, Nicholas Weaver est sceptique. Il fait remarquer qu'il faudrait que l'attaquant fabrique une chaîne complète. S'il veut faire une fausse signature pour www.slate.com (en supposant que ce domaine soit signé avec DNSSEC, ce qui n'est pas le cas aujourd'hui), il doit fabriquer un faux ensemble d'enregistrements NS pour .com, et que les machines ainsi désignées répondent aux autres requêtes pour .com, sinon l'attaque sera vite détectée. Ou alors faire un faux enregistrement NSEC pour convaincre le résolveur que .com n'est pas signé. Car le vrai .com l'est et cette information se retrouve très vite dans les caches de n'importe quel résolveur de la planète, rendant difficile l'empoisonnement. Pour empoisonner, il faut être rapide, avant que le résolveur ait pu apprendre qu'il y a un zone cut entre la racine et .com, et qu'il y a un DS pour .com.

Bien sûr, pour .com, il y a une autre solution, signer des données avec la clé privée de .com puisque son registre est également situé aux États-Unis et donc vulnérable aux demandes officielles. Mais si la NSA veut détourner www.petrobras.com.br, là, l'attaquant n'a pas cette possibilité et il doit donc bien fabriquer une chaîne entière, ou alors un faux NSEC.

Bref, on se retrouve dans un cas classique en sécurité : il y a bien une faiblesse, mais son exploitation effective n'est pas forcément de la tarte. Bien sûr, ce qui précède n'est qu'un raisonnement théorique. Si vous êtes un programmeur courageux, il serait intéressant d'essayer de réaliser cette attaque en laboratoire et de documenter le résultat.

D'autres points à garder en tête :

  • En pratique, il y a aujourd'hui trop peu de résolveurs validant avec DNSSEC. Donc, si j'étais la NSA, je ne m'embêterais pas immédiatement.
  • Les empoisonnements de résolveurs peuvent se détecter. Certes, les gérants des résolveurs sont parfois incompétents, négligents ou débordés de travail. Mais il suffirait d'un gérant de résolveur qui, au bout moment, fasse un dig pour examiner son propre cache, découvre les données mensongères mais signées et les publie. N'importe qui pourrait vérifier que la clé privée de la racine n'est plus digne de confiance et tout DNSSEC, pour lequel le gouvernement des États-Unis a beaucoup investi, s'écroulerait.
  • Si on n'a pas confiance dans la racine, une possibilité est de configurer son résolveur DNSSEC avec d'autres clés de confiance pour les zones situées plus bas. Par exemple, celles de .fr sont publiées. Mais attention : les conséquences en terme d'administration du résolveur sont sérieuses car il faut modifier ces clés de confiance lorsque le gérant de la zone ainsi protégée les change.
  • Si on a confiance dans les clés de zones gérées en dehors des États-Unis, il faut aussi se demander si ces clés sont correctement protégées contre des attaques techniques ou légales.

L'article seul

RFC 7085: Top-Level Domains that Are Already Dotless

Date de publication du RFC : Décembre 2013
Auteur(s) du RFC : J. Levine (Taughannock Networks), P. Hoffman (Cybersecurity Association)
Pour information
Première rédaction de cet article le 5 décembre 2013


La question du bon ou mauvais fonctionnement d'un nom de domaine fait d'un seul composant (par exemple com ou dk) a déjà fait l'objet de pas mal d'articles. (Le premier était apparemment le mien, en 2009.) Elle a pris plus d'importance avec la création massive de nouveaux TLD par l'ICANN, les premiers ayant été introduits dans la racine du DNS en 2013. Ce RFC a une approche documentaire : il n'étudie pas le fonctionnement de ces domaines d'un seul composant (dotless domains) mais il regarde quels TLD, aujourd'hui, sont dans ce cas.

Le choix a été fait de considérer comme « permettant de faire des noms d'un seul composant » tout TLD ayant un enregistrement A (adresse IPv4), un AAAA (adresse IPv6) ou un MX (relais de courrier). C'est assez arbitraire (les différents documents sur les dotless domains ne sont pas d'accord sur la définition). Avec cette définition, des domaines d'un seul composant (dotless domains) existent (rappelons que l'ICANN ne régule pas le DNS ; ses règles ne s'appliquent pas à tous les TLD).

Donc, test fait en septembre 2013 : 5 % des TLD avaient un des enregistrements DNS qui les rendent « capables de faire des noms d'un seul composant » et tous étaient des ccTLD. 18 TLD ont un enregistrement MX (dont deux français, .mq et .gp). 17 (pas forcément les mêmes) ont un enregistrement A. Un seul, .dk, a un enregistrement AAAA.

Ce RFC ne formule pas de recommandations. Il ne dit pas si les domaines d'un seul composant sont Bien ou Mal (personnellement, je ne vois pas quels problèmes ils pourraient sérieusement poser).

Pour les informaticiens, le script qui a servi à compter ces résultats est inclus dans le RFC :


#! /bin/sh

# Get the current list of TLDs from IANA
wget -O orig.txt http://data.iana.org/TLD/tlds-alpha-by-domain.txt
# Remove the comment at the top of the file
grep -v '^#' orig.txt > TLDs.txt
# Get all the nameservers
while read tld; do host -t NS $tld; done < TLDs.txt > TLD-servers.txt
# Do queries for each record type, and do them on each nameserver
for rec in A AAAA MX; do
     while read tld ignorea ignoreb ns; do
       host -t $rec $tld. $ns;
     done < TLD-servers.txt;
done > all-out.txt
# Print the results
grep "has address" all-out.txt | sort -uf
grep "has IPv6" all-out.txt | sort -uf
grep "mail is handled" all-out.txt | sort -uf

Notez que ce script a peu de traitement d'erreurs. Comme la racine, dont l'ICANN ne vérifie pas vraiment la qualité, a plusieurs erreurs, vous aurez quelques messages amusants si vous le faites tourner.

Voici une liste non exhaustive des articles et études sur la question des domaines d'un seul composant :


Téléchargez le RFC 7085


L'article seul

Avoir son propre résolveur DNS ?

Première rédaction de cet article le 4 décembre 2013


Faut-il avoir son propre résolveur DNS, sur sa machine (ou, au moins, sur son réseau local à soi) ? Question compliquée à laquelle je réponds désormais oui, en raison de l'intensification de la censure utilisant le DNS.

D'abord, un petit rappel : la quasi-totalité des activités sur l'Internet commencent par une requête DNS, une demande faite au résolveur DNS par les applications  « quelle est l'adresse IP de www.slate.fr ? » Le résolveur, après interrogation des serveurs DNS faisant autorité (gérés, dans le cas de ce nom de domaine, par la racine, par l'AFNIC et par Slate), va répondre aux applications et le reste de l'activité Internet pourra continuer. Comme tout commence par le DNS, ce service est particulièrement tentant pour tous ceux qui veulent censurer / dévier / détourner les activités de l'utilisateur. Il y a donc une histoire déjà ancienne de tentatives de filtrage via le DNS et une histoire tout aussi ancienne de textes expliquant pourquoi c'est une très mauvaise idée. Le filtrage via le DNS peut se faire dans le réseau, comme en Chine. Mais le plus courant est de le faire dans le résolveur. Cette machine est typiquement gérée, pour un accès Internet par un particulier, par son FAI. En raison de la concentration du marché, en contraignant les quatre ou cinq plus gros FAI à effectuer ce filtrage, on pourrait frapper un bon nombre des MM. Michu. Techniquement; c'est simple à faire, avec des systèmes comme RPZ. Et cette voie a déjà été suivie, en France par l'ARJEL.

Une solution évidente à ce filtrage est d'avoir son propre résolveur DNS, de ne plus compter sur celui du FAI. Cette solution a deux défauts, le premier est temporaire : sa mise en œuvre est encore trop complexe, comme déjà expliqué dans un de mes articles. La deuxième est moins visible : si chaque utilisateur de l'Internet a son propre résolveur DNS, ils ne partageront plus leur mémoire (leur « cache ») et la charge sur les serveurs faisant autorité s'aggravera. Pour cette raison, je prônais plutôt des systèmes comme dnssec-trigger qui installaient un résolveur local mais faisaient suivre les requêtes non résolues aux résolveurs (et donc aux caches) des FAI. C'est une solution simple et élégante (et qui permettait aussi de faire de la validation DNSSEC proprement).

Mais dnssec-trigger a une limite. Certes, avant d'utiliser les résolveurs du réseau local comme relais, il les teste pour s'assurer qu'ils transmettent les données DNSSEC correctement. Mais il ne teste pas s'ils mentent ou pas. Si le résolveur officiel du réseau local applique la censure, dnssec-trigger ne pourra plus accéder aux données (si DNSSEC est utilisé, on aura un code d'erreur, SERVFAIL, plutôt qu'une réponse mensongère comme l'adresse IP 127.0.0.1 dans l'exemple ci-dessous, mais cela ne change pas grand'chose ; DNSSEC protège contre le détournement, pas contre le déni de service qu'est la censure).

Or, l'usage du DNS pour la censure se répand. Ainsi, le 28 novembre 2013, un tribunal français a ordonné la censure par le DNS de sites Web de diffusion de films. Et cette censure semble effectivement appliquée. En testant depuis un très gros FAI français, avec dig :

% dig +short @192.168.2.254 A alloshare.com          
127.0.0.1

Or, cette adresse IP bidon (127.0.0.1 désigne la machine locale, donc ce mensonge renvoie votre navigateur Web vers votre machine) n'est pas la vraie. Avec mon résolveur personnel :

% dig +short A alloshare.com 
204.236.239.5

Cela vous semble exagéré de parler de censure, pour une affaire essentiellement commerciale (les intérêts des ayant-trop-de-droits) ? Sauf que cela commence comme ça puis, une fois que l'outil est au point, on pourra de la même façon demander la censure de n'importe quel nom qui déplait aux autorités. Il est donc normal que les citoyens se détournent des résolveurs DNS menteurs et veuillent configurer leur propre résolveur.

La situation technique n'est pas aujourd'hui tellement meilleure qu'à l'époque de mon précédent article sur le changement de résolveur. Mais le problème devenant plus crucial, il faut quand même se lancer.

Donc, d'abord, pour les systèmes que je connais le mieux, les Unix. Il faut 1) installer le logiciel résolveur 2) configurer la machine pour l'utiliser et surtout 3) faire en sorte que DHCP ne vienne pas écraser ce réglage. Pour le logiciel résolveur, on a plusieurs choix, notamment BIND et Unbound, disponibles sous forme de paquetage dans n'importe quel Unix. Un exemple de configuration BIND pour un résolveur, validant avec DNSSEC pendant qu'on y est :

options {
	// N'écouter que sur l'interface locale. Autrement, faites
	// attention à interdire l'accès aux machines non-locales, pour
	// ne pas faire un résolveur ouvert.
        listen-on {127.0.0.1;};
        dnssec-enable yes;
        dnssec-validation yes;
};
trusted-keys {
           "." LA CLÉ DNSSEC DE LA RACINE EST EN GÉNÉRAL DISTRIBUÉE AVEC BIND (fichier bind.keys)
};

Et pour Unbound :

server:
    interface: 127.0.0.1
    auto-trust-anchor-file: "/var/lib/unbound/root.key"

Pour récupérer de manière sûre la clé de la racine avec Unbound, le plus simple est un unbound-anchor -a "/var/lib/unbound/root.key". Une fois le résolveur démarré, testez avec dig qu'il peut résoudre les noms :

% dig @127.0.0.1 A www.techn0polis.net 
...
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
www.techn0polis.net.	2917 IN	CNAME gpaas6.dc0.gandi.net.
gpaas6.dc0.gandi.net.	1156 IN	A 217.70.180.136
...
;; SERVER: 127.0.0.1#53(127.0.0.1)
...

Testez aussi depuis des machines extérieures que votre résolveur ne répond pas aux machines extérieures. Autrement, c'est un résolveur ouvert, ce qui est très dangereux. Si vous voulez rendre accessible votre joli résolveur depuis tout votre réseau local, vous devez également écouter sur les adresses IP du réseau local (et bien utiiser le contrôle d'accès de votre serveur - acl dans BIND et access-control: dans Unbound - pour ne pas devenir un résolveur ouvert).

Une fois que c'est fait, configurez votre machine pour interroger le serveur/résolveur en question. Mais attention, le problème est que DHCP vient souvent dans votre dos changer ce réglage. Donc, simplement éditer /etc/resolv.conf, comme on le lit parfois sur des forums de neuneus, n'est pas suffisant. Il faut modifier la configuration du client DHCP. Cela dépend du client mais, par exemple, sur une Debian, éditer /etc/resolvconf/resolv.conf.d/head pour y mettre :

nameserver 127.0.0.1

suffit. Une fois que c'est fait, vous pouvez tester avec dig sans indiquer @127.0.0.1 et la ligne SERVER dans la sortie doit vous indiquer quel serveur vous utilisez.

Pour Mac OS X, je n'ai pas d'expérience de ce système mais je suggère l'article de hukl. Sinon, Ludovic Hirlimann propose « installer MacPorts puis sudo port install unbound et c'est tout ». Experts OS X, si vous avez d'autres idées ?

Et pour Windows ? Apparemment, Unbound tourne sur Windows (si quelqu'un a une expérience d'utilisation à raconter...) Je ne connais pas assez Windows pour le reste mais je vous suggère une solution pour la partie « configurer sa machine pour accéder au résolveur local ». Un certain nombre de services commerciaux vous fournissent des résolveurs alternatifs, pour accéder plus rapidement à certains services bridés comme YouTube. Je ne vous dis pas d'utiliser ces résolveurs, qui sont aussi menteurs (même si c'est pour la bonne cause) mais tous viennent avec une documentation, conçue pour un large public, indiquant comment changer de résolveur. Par exemple, c'est le cas de la documentation de Unlocator.

Quelle sera la prochaine étape de la course aux armements entre les censeurs et les utilisateurs de l'Internet ? Peut-être d'essayer de faire filtrer le port 53. En attendant, voici d'autres documents sur le thème de cet article :


L'article seul

Atelier « anycast DNS » à AfriNIC

Première rédaction de cet article le 27 novembre 2013


AfriNIC organisait une réunion à Abidjan cette semaine. J'ai eu le plaisir d'y faire un atelier pratique consacré à l'anycast pour les serveurs DNS.

Il y avait environ 25 personnes, administrateurs système de divers sites en Afrique francophone. Les diapos de cet atelier sont disponibles ici au format PDF.


L'article seul

RFC 7069: DECoupled Application Data Enroute (DECADE)

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : R. Alimi (Google), A. Rahman (InterDigital Communications), D. Kutscher (NEC), Y. Yang (Yale University), H. Song (Huawei Technologies), K. Pentikousis (EICT)
Pour information
Première rédaction de cet article le 27 novembre 2013


L'architecture traditionnelle de l'Internet est celle d'un réseau « bête », transportant des paquets sans en comprendre le contenu, avec toute l'« intelligence » concentrée aux extrémités, dans les machines terminales. Un travail avait été commencé à l'IETF, dans le défunt groupe DECADE, pour voir s'il était possible de changer légèrement ce modèle pour certaines catégories d'applications (notamment pair-à-pair), en dotant le réseau de capacité de stockage des données (un peu comme le font, de manière non-standard, les CDN). Le projet a finalement échoué mais a publié quelques RFC, dont ce dernier document, qui décrit l'architecture d'un tel système.

Les deux autres RFC importants de DECADE étaient le RFC 6646, exposé détaillé du problème, et le RFC 6392, qui fait le tour des mécanismes disponibles. (Il est très recommandé de lire au moins le RFC 6646 avant ce RFC 7069.) Finalement, le projet a été abandonné et le groupe DECADE dissous, mais, pour ne pas perdre le travail effectué, il est publié dans ce nouveau RFC, qui décrit, en termes assez généraux, l'architeecture de DECADE. Comme exemple d'usage, prenons une machine connectée en ADSL. Elle a typiquement une capacité réseau « montante » très limitée. Mettre à jour le réseau pour augmenter cette capacité (par exemple pour passer en FTTH) risque d'être coûteux. Disposer dans le réseau des dispositifs de stockage permettant à cette machine de distribuer du contenu sur l'Internet sans tuer sa capacité ADSL limitée serait peut-être plus économique. (Notez aussi que cela soulève d'intéressants problèmes politiques de contrôle sur les données servies.)

Donc, l'idée est d'avoir des serveurs DECADE dans le réseau, qui stockent les données des clients DECADE. Les données pourront être copiées entre serveurs, et récupérées par d'autres clients que ceux qui les ont déposées. Pour cela, il faudra un protocole de gestion des ressources déposées, le DRP (DECADE Resource Protocol) et un protocole d'accès aux ressources, le SDT (Standard Data Transfer protocol). Pour ce dernier, il était prévu dès le début d'utiliser un protocole standard existant comme HTTP.

Les serveurs DECADE seront fournis par des fournisseurs de stockage, qui pourront être les FAI ou bien d'autres acteurs. Ces fournisseurs décideront de l'allocation de ressources (espace de stockage, capacité réseau).

Il n'était pas prévu que les utilisateurs accèdent aux serveurs DECADE directement mais que ceux-ci fournissent un service aux applications, service masqué aux utilisateurs. La section 3 de notre RFC contient un schéma qui illustre ce principe : une application veut envoyer des données à une autre application (les deux applications parlent entre elles avec un protocole pair-à-pair quelconque). Pour cela, elle envoie les données au serveur avec le SDT (rappelez-vous que c'est un protocole standard comme HTTP) et utilise le DRP pour indiquer au serveur les conditions d'accès aux données. L'autre application utilisera SDT pour récupérer les données. Selon le niveau de confidentialité des données, il y aura aussi peut-être une étape de récupération d'un jeton que l'envoyeur transmettra au destinataire (toujours avec leur protocole pair-à-pair à eux, qui ne regarde pas DECADE), et avec lequel le destinataire pourra prouver ses droits au serveur DECADE. Un peu comme les applications « passe-plat » existants comme http://dl.free.fr/ mais masqué à l'utilisateur. Entre parenthèses, ce scénario d'usage avait été réclamé dans un excellent dessin de xkcd.

La section 4 décrit l'architecture du service DECADE (s'il avait été construit ; rappelez-vous que le projet a été abandonné). En gros, DECADE fournira les données (data plane), l'application pair-à-pair la signalisation (control plane). DECADE se voulait indépendant de l'application, fournissant un service général de données. Les applications auraient géré les services comme l'indexation, le moteur de recherche dans les données, etc. Des systèmes de stockage des données séparant données et signalisation existent déjà. Le RFC mentionne Google File System, ou l'extension pNFS de NFS, décrite dans la section 12 du RFC 5661.

Une chose importante avec DECADE est que ce système ne prévoit pas de modifier le contenu déposé dans le stockage en réseau. Les objets écrits sont immuables (section 4.2). Ce principe permet de simplifier considérablement le système, puisqu'il n'y a plus de problème de synchronisation entre les différents serveurs de stockage. Si on veut vraiment modifier une ressource mise en ligne, il faut détruire l'ancienne et en mettre une nouvelle. Ce sera à l'application, pas à DECADE, de changer la correspondance entre le nom de la ressource et le nouvel objet qui, pour DECADE, sera un objet différent, sans lien avec le premier. Chaque application aura en effet son propre système de nommage. On peut comparer cela avec le nommage dans un système de fichiers (comme /home/stephane/Downloads/galaxy.avi) contre celui de plus bas niveau utilisé par le système de fichiers pour parler aux contrôleurs de disque.

Puisqu'on a commencé à parler d'identité (« le même objet ») et donc d'identificateurs, quels sont les identificateurs dans DECADE ? Chaque objet a un identificateur unique. Si un objet est répliqué sur plusieurs serveurs, toutes ces copies sont toujours désignées par le même identificateur. DECADE n'envisageait pas d'imposer un mécanisme unique de nommage mais le RFC suggère d'utiliser des condensats du contenu, comme dans le RFC 6920 (voir aussi la section 6.1). Là encore, l'immuabilité des objets stockés est essentielle pour que ce nommage par le contenu fonctionne.

La section 5 est plus concrète, décrivant certains des composants du système. Par exemple, elle couvre les jetons d'authentification, dont l'utilisation était prévue pour que le déposant d'un fichier puisse distribuer des droits d'accès à des lecteurs (voir aussi la section 6.2.1). Elle parle aussi de l'importance d'avoir un mécanisme de découverte (non spécifié : rappelez-vous que le travail sur DECADE avait été interrompu en route) pour localiser le serveur DECADE approprié.

La section 6, elle, est consacrée aux protocoles DRP (protocole de contrôle) et SDT (protocole de transport des données). Elle est également assez abstraite : l'idée originale est que des protocoles concrets seraient choisis ultérieurement. Ces protocoles ne sont pas utilisés seulement entre un client DECADE et un serveur DECADE mais aussi entre serveurs, notamment pour la réplication. Les données stockées dans DECADE peuvent en effet être automatiquement copiées de serveur à serveur pour augmenter les performances lors de la récupération (section 6.4). Une évaluation des protocoles possibles pour remplir ces rôles figure dans l'annexe A.

HTTP (RFC 7230) est évidemment le premier protocole considéré. C'est un candidat presque idéal pour le rôle de SDT mais il peut aussi servir de DRP. HTTPS fournit des mécanismes de sécurité bien compris et largement déployés. HTTP permet d'assurer les deux fonctions du SDT, en lecture mais aussi en écriture (avec les méthodes PUT et POST). Par contre, il lui manque quelques fonctions, comme des ACL ou comme des mécanismes de transmission de politique d'accès au serveur. Ceci dit, ces manques pourraient être comblés en ajoutant quelques en-têtes dans les requêtes et réponses HTTP. C'est ce que fait Google Storage. Ce dernier utilise OAuth (RFC 6749) pour les délégations d'accès.

Un autre candidat est CDMI. Il est basé sur HTTP mais avec de nombreux enrichissements. Lui dispose d'ACL aussi riches qu'on le veut. Et, question contrôle des données, il permet de spécifier des choses comme le nombre de copies à générer, leur placement géographique, la durée de conservation, etc. CDMI parait donc plus proche des besoins de DECADE.

Et la sécurité d'un système comme DECADE ? La section 8 la décrit en détail, en s'appuyant sur la section 5 du RFC 6646. Il y a évidemment le risque d'attaques par déni de service, par exemple si un client méchant envoie une quantité astronomique de données à stocker.

Pour l'accès aux données, DECADE comptait sur un mécanisme de délégation : on n'autorise pas le client, mais on distribue des jetons dont la possession suffit pour l'accès. Les problèmes de sécurité liés à ces mécanismes de délégation sont traités dans la section 10 du RFC 6749.

Un autre type d'attaque est dirigé contre le client : arriver à lui faire télécharger des données qui ne sont pas celles qu'il espérait. Ce genre d'attaques est courant dans le monde du téléchargement pair-à-pair où un fichier nommé hot-naked-women-at-the-beach.avi peut en fait contenir un discours d'un télévangéliste. S'il est difficile de se prémunir contre un nom trompeur, en revanche, DECADE peut sécuriser la liaison entre un nom et un objet. Ainsi, des adresses basées sur un condensat du contenu sont auto-validantes : après le téléchargement, on recalcule le condensat et on vérifie que le contenu est bien celui demandé. Cela ne règle qu'une partie du problème : la publicité mensongère, par exemple pour tromper un moteur de recherche, reste possible.


Téléchargez le RFC 7069


L'article seul

RFC 7059: A Comparison of IPv6 over IPv4 Tunnel Mechanisms

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : S. Steffann (S.J.M. Steffann Consultancy), I. van Beijnum (Institute IMDEA Networks), R. van Rein (OpenFortress)
Pour information
Première rédaction de cet article le 27 novembre 2013


Il existe d'innombrables techniques pour faire coexister IPv4 et IPv6 sur l'Internet. Tellement qu'on s'y perd facilement. Ce nouveau RFC se concentre sur une catégorie particulière, les tunnels « IPv6 sur IPv4 » et fait la liste de tous les mécanismes de cette catégorie (des plus répandus aux plus exotiques), avec leurs forces et leurs faiblesses.

Ces tunnels sont dictés par la nécessité. La bonne méthode pour se connecter en IPv6 est clairement d'utiliser une connexion native. Mais on n'a pas toujours le choix. Aujourd'hui, depuis de nombreuses années, et sans doute encore pour un certain temps, il existe de nombreuses îles IPv6, séparées les unes des autres par des réseaux purement IPv4. Par exemple, vous avez loué une machine virtuelle chez un fournisseur qui est resté à l'ancien protocole (comme Numergy) mais vous voulez accéder à l'Internet IPv6. Ou bien vous avez déployé IPv6 sur votre campus mais votre opérateur réseau n'est toujours pas capable de fournir de l'IPv6 ce qui vous désespère. Dans ces deux cas, et dans plusieurs autres, vous serez sans doute obligé d'utiliser un tunnel. Un tunnel fonctionne en encapsulant les paquets d'un protocole dans ceux d'un autre protocole. Ainsi, pour transporter de l'IPv6 sur l'IPv4, le routeur d'entrée de tunnel met le paquet IPv6 à l'intérieur d'un paquet IPv4, celui-ci voyage ensuite par les mécanismes IPv4 habituels, sur un réseau qui ne connait qu'IPv4 et, à l'arrivée sur le routeur de sortie de tunnel, le paquet IPv6 est décapsulé (extrait du paquet IPv4) puis continue son chemin dans le réseau IPv6.

Ce principe est le même pour toutes les techniques de tunnels. Mais les nombreuses techniques existent diffèrent par bien d'autres points, ce qui sème souvent la confusion chez les administrateurs réseau. D'autant plus que ces techniques ne se valent pas : certaines posent des gros problèmes de sécurité ou de fiabilité.

Ce RFC fait le tour de ces techniques. Attention : il ne couvre que le cas « IPv6 tunnelé dans IPv4 ». Il existe plein d'autres techniques de tunnels, pour faire des VPN par exemple. De même, ce RFC 7059 ne parle pas de DS-Lite, qui n'est pas une technologie de IPv6 sur IPv4 mais, au contraire, un moyen de transporter l'IPv4 sur des réseaux purement IPv6.

La section 3 est le gros morceau du RFC, contenant la liste de tous les mécanismes de tunnels étudiés (je ne les ai pas tous repris dans cet article). La plupart des tunnels font une encapsulation directe : pas d'intermédiaire entre l'en-tête IPv4 et le paquet IPv6. L'en-tête IPv4 a un champ « Protocole » qui contient la valeur 41, identifiant IPv6 (cf. section 5.1). L'adresse IPv6 des extrémités du tunnel est parfois automatiquement créée en fonction de l'adresse IPv4 (tunnels automatiques), pour trouver facilement l'extrémité du tunnel (ce point est détaillé en section 5.4). Au contraire, dans les tunnels manuels, il a fallu configurer explicitement les paramètres du tunnel (notamment l'adresse IPv4 de sortie). Un cas intermédiaire est celui où le tunnel est manuel mais la configuration se fait via un protocole auxiliaire de gestion du tunnel, qui dispense l'utilisateur de cette tâche.

D'autres tunnels ne font pas une encapsulation directe : ils mettent l'IPv6 dans de l'UDP qui est ensuite transporté sur IPv4. Cela permet la traversée des NAT et résout le problème de l'ossification de l'Internet v4, où seuls UDP et TCP arrivent à passer, les autres protocoles de couche 4 (comme le 41) étant de facto interdits en beaucoup d'endroits.

Commençons par les tunnels manuels, les plus anciens (ils étaient déjà dans le RFC 1933 en 1996). Leur norme actuelle est le RFC 4213. On les nomme aussi tunnels statiques ou bien 6in4. Le principe est de désigner explicitement, sur chaque point d'entrée, quel est le point de sortie du tunnel. Pour des exemples de configuration de tels tunnels, voir mes articles « Connecter un serveur dédié à IPv6 avec un tunnel manuel » et, plus compliqué « Un tunnel IPv6-in-v4 sur un tunnel GRE... ». Cette configuration manuelle rend cette solution « Michu-hostile » mais elle a des avantages : le réseau est prévisible (on sait exactement où les paquets vont passer) et facile à déboguer. À noter que la configuration peut être simplifiée par l'utilisation d'un courtier (broker). Les performances vont dépendre du choix de l'autre extrémité du tunnel (dans mon exemple au Cameroun, elle était à Londres, nous n'avions rien trouvé de plus proche). Autrefois, il était courant que le tunnel s'étende sur deux continents différents, allongeant sérieusement le RTT. Ces mauvais choix (tunnel trop long) ont souvent donné une mauvaise réputation aux tunnels. À tort : à titre personnel, je trouve qu'un tunnel manuel est une solution simple, fiable et efficace pour se connecter en IPv6 si on n'a pas de fournisseur IPv6 sous la main. Le seul piège est qu'il faut bien choisir son fournisseur de tunnel.

On peut aussi utiliser GRE (RFC 2784), qui est très répandu dans les routeurs (mais pas dans les machines terminales typiques). C'est un protocole d'encapsulation très généraliste (IPv4 sur IPv4, IPv6 sur IPv4, etc).

GRE est ultra-simple, avec son RFC de moins de neuf pages. Trop dans certains cas, alors on peut lui préférer SEAL (dont le RFC n'a pas encore été publié) qui prévoit quelques services supplémentaires dont un protocole de contrôle permettant aux deux extrémités du tunnel de dialoguer. Un autre exemple de « GRE++ » est AYIYA (pas encore de RFC non plus). Notez que SEAL, contrairement à GRE, n'a pas encore connu beaucoup d'utilisations.

Comme la nécessité d'une configuration manuelle refroidit beaucoup de gens et peut sembler un frein au déploiement d'IPv6, il existe des solutions de tunnels automatiques. Par exemple, le RFC 2893 décrivait une solution (supprimée depuis) où les adresses IPv6 étaient des adresses « compatibles IPv4 » (par exemple ::192.0.2.1, alias ::c000:201, équivalent IPv6 de 192.0.2.1). Le gros inconvénient de cette solution est qu'elle ne marchait qu'entre machines ayant cette technologie, et pas avec l'Internet IPv6. Elle n'a donc plus de rôle aujourd'hui.

Au contraire, 6to4 (RFC 3056) est très répandu (on le trouve dans plusieurs routeurs CPE). Il fonctionne automatiquement, en mettant l'adresse IPv4 du tunnel dans une adresse IPv6 préfixée par 2002::/16, et suivie de l'adresse IPv4. 6to4 dépend de relais (en général gérés bénévolement) capables de servir de point d'entrée et de sortie du tunnel. Grâce à l'anycast (RFC 3068) dont 6to4 avait été un des premiers utilisateurs, plusieurs relais sont accessibles pour un préfixe donné. Ils ont tous l'adresse IPv4 publique 192.88.99.1 (2002:c058:6301:: en IPv6). La route vers 2002::/16 est annoncée vers l'Internet IPv6 par tous les relais et le plus « proche » est sélectionné, répartissant ainsi automatiquement le travail. Sans configuration manuelle, 6to4 est bien adapté au petit réseau qui veut se connecter rapidement. Malheureusement, 6to4 est très imprévisible : les relais sont variés dans leur sérieux et la qualité de leur connexion, et on ne sait pas lequel on va utiliser. Le routage est en général asymétrique (on utilise un relais différent à l'aller et au retour) ce qui rend le déboguage des problèmes de connectivité difficile. Le RFC 6343 liste les problèmes de 6to4 et ne recommande pas son usage. Le RFC 7526 est allé plus loin en abandonnant officiellement 6to4.

Pour résoudre ces problèmes sérieux de 6to4, certains FAI (comme Free en France) ont déployé 6rd (RFC 5969). 6rd leur permet de déployer IPv6 pour leurs clients, en ne changeant qu'une partie du réseau, sans qu'il soit nécessaire qu'il fonctionne intégralement en IPv6. 6rd ressemble beaucoup à 6to4 mais n'utilise pas le préfixe commun 2002::/16, mais un préfixe spécifique au FAI (ce qui veut dire que, dans le journal d'un serveur, on ne repère pas les clients 6rd, contrairement aux clients 6to4). Ce préfixe doit être envoyé au client, par exemple en DHCP. À noter que, comme les clients 6rd d'un même FAI partagent en général un préfixe IPv4 commun, il n'est pas nécessaire d'encoder tous les 32 bits de l'adresse IPv4 dans l'adresse IPv6, ce qui libère quelques bits (section 4 du RFC 5969). Si, contrairement à 6to4, 6rd ne peut pas être déployé par l'utilisateur seul, il a par contre l'avantage d'être bien plus prévisible et facile à déboguer. La responsabilité de la connectivité est bien plus claire, elle est entièrement chez le FAI, sans avoir besoin d'impliquer des relais extérieurs.

Comme 6to4, 6rd est sans état et les routeurs relais peuvent donc utiliser l'anycast.

6to4 et 6rd utilisent l'encapsulation directe, où le paquet IPv6 est mis directement dans IPv4, ce dernier l'indiquant par le numéro de protocole 41. L'un des inconvénients que cela présente est que cela empêche la traversée des NAT. Un autre protocole de tunnel, Teredo (RFC 4380), résoud le problème en ajoutant UDP. On a donc IPv6-dans-UDP-dans-IPv4. Cela permet aussi d'avoir plusieurs clients derrière le même routeur NAT. Teredo étant activé par défaut dans certaines versions de Windows, son usage est répandu. Teredo inclut le port UDP, avec les adresses IPv4 du tunnel, dans l'adresse IPv6, qui est préfixée par 2001:0::/32.

Du point de vue de la fiabilité et des performances, Teredo est pire que 6to4, comme l'illustre l'article « Testing Teredo ».

Une solution de tunnel bien plus exotique et rare est LISP (RFC 6830). LISP n'a pas été spécialement conçu pour mettre de l'IPv6 dans l'IPv4, il est une solution générale de séparation de l'identificateur et du localisateur. Les identificateurs sont nommés EID dans LISP et les localisateurs RLOC. Tous les deux ont la forme d'une adresse IP. On peut avoir un EID IPv6 et un RLOC IPv4, réalisant ainsi un tunnel IPv6-sur-IPv4. Donc, LISP permet de faire nos tunnels mais c'est un protocole riche et complexe et l'utiliser uniquement pour cela semble exagéré.

Parmi les autres tunnels possibles, c'est dans ce RFC que j'ai appris l'existence de 6bed4. Son originalité est de fournir un mécanisme pour débrayer automatiquement le tunnel si le correspondant est joignable en IPv6 natif, par exemple s'il est sur le même réseau local. Cela lui permet d'atteindre des performances plus proches de celles de l'IPv4. Comme Teredo, 6bed4 met dans ses adresses IPv6 les adresses IPv4 et les numéros de ports UDP des routeurs du tunnel.

Les mécanismes de tunnel utilisent souvent des mécanismes auxiliaires, qui ne sont pas des tunnels mais qui aident à leur établissement et à leur gestion. La section 4 fait le tour des principaux. On y trouve par exemple le TSP du RFC 5572, qui permet de configurer automatiquement un tunnel, évitant l'étape « lecture de la doc' et tentative de la recopier ». Ce mécanisme est par exemple utilisé par Freenet6 et des exemples figurent dans mon article sur les serveurs de tunnel.

Un inconvénient des serveurs de tunnel se présente lorsque le client change d'adresse IPv4 (cas d'une adresse dynamique dans certains abonnements). Avant, il fallait arrêter le tunnel et en créer un nouveau. Le protocole SixXS Heartbeat permet d'éviter cela : le client envoie régulièrement des paquets au serveur de tunnel, qui peut ainsi apprendre un changement d'adresses et se reconfigurer. Le serveur de SixXS fait cela, et les clients typiques aussi. À noter qu'AYIYA inclut cette fonction de « battement de cœur ».

Enfin, après TSP, un autre protocole de négociation de paramètres et de création de tunnel est TIC, également utilisé à SixXS. Il a notamment été mis en œuvre dans un petit routeur CPE très populaire en Allemagne et aux Pays-Bas, le Fritz!Box AVM.

La section 5 de notre RFC discute les aspects communs à tous (ou en tout cas à une bonne partie) de ces mécanismes de tunnel. Par exemple, les routeurs NAT (plus exactement NAPT car ils changent le port, pas seulement l'adresse IP, et doivent donc connaître le protocole de couche 4 utilisé) et les pare-feux sont une cause fréquente de problème pour les tunnels, comme ils gênent d'ailleurs bien d'autres services. Ainsi, le protocole de « transport » 41 (encapsulation directe d'IPv6 dans IPv4) est souvent bloqué, ce qui a mené à l'utilisation d'UDP (par exemple par Teredo), pour contourner ce blocage. Puisqu'il n'a pas de port, le protocole 41 ne peut pas passer à travers un routeur NAPT. Il pourrait passer à travers un routeur NAT (rappelez-vous que la plupart des équipements NAT sont en fait du NAPT) dans certaines conditions. Mais, si l'adresse IPv6 est dérivée de l'IPv4, la traduction d'adresses va certainement casser le tunnel. C'est le cas de 6to4 et 6rd (6rd fonctionne en général car il ne traverse pas le routeur NAPT : il démarre sur ce routeur, qui est le point d'entrée du tunnel).

Par contre, GRE et les tunnels manuels peuvent fonctionner à travers un NAT. Il y a parfois des surprises et il peut être préférable d'utiliser un mécanisme prévu dès le début pour traverser le NAT, comme Teredo, AYIYA, ou 6bed4.

Et puis, bien sûr, une plaie récurrente de tous les tunnels est la question de la MTU (section 5.3). En raison de l'encapsulation, tout mécanisme de tunnel diminue la MTU effective de quelques octets. Normalement, la fragmentation et la découverte de la MTU du chemin devraient gérer cela et permettre au trafic de passer à travers le tunnel. En pratique, le nombre de pare-feux mal configurés qui bloquent les paquets ICMP nécessaires à la découverte de la MTU (message ICMP « Packet Too Big ») est tel que les problèmes sont fréquents. Si l'extrémité du tunnel est sur la machine terminale, celle-ci peut encore réussir à communiquer avec TCP, la MSS de ce dernier s'ajustera. Sinon, on aura des problèmes à première vue mystérieux comme le fait qu'un ping ordinaire passe mais pas un ping avec une taille différente. Ou bien on verra les connexions TCP s'établir, le client HTTP envoyer sa requête mais la réponse, plus grande et ne tenant pas dans la MTU, n'arrivera jamais. Ces problèmes liés à la MTU sont une des plaies de l'Internet et l'utilisation des tunnels les rend encore plus fréquents.

On le voit, la liste des solutions techniques pour tunneler IPv6 dans IPv4 est longue (et encore, je n'ai pas cité dans cet article tous ceux que mentionne le RFC). Comment choisir ? La section 6 du RFC est consacrée à l'évaluation de ces solutions (l'annexe A donne la iste des critères utilisés). D'abord, l'usage qu'ils font des adresses IPv4, celles-ci étant désormais très rares. Les tunnels manuels, qui dépendent d'une adresse IPv4 fixe et unique, ainsi que 6to4, ne peuvent pas marcher à travers un CGN, lorsque plusieurs clients se partagent une adresse IPv4. Teredo ou AYIYA, au contraire, ont été explicitement conçus pour bien marcher même à travers les pires NAT.

Deuxième critère d'évaluation, la topologie réseau permise. Certains tunnels (par exemple les tunnels manuels) sont point à point, entre deux machines fixes, les routeurs d'entrée et de sortie du tunnel. Cela facilite le déboguage car le cheminement du trafic est parfaitement prévisible. D'autres (comme 6to4) sont plutôt un vaste réseau où plusieurs relais peuvent être utilisés pour fournir un lien virtuel qui est NBMA plutôt que point à point. Cela offre plus de souplesse et ne fait pas des deux routeurs d'extrémité du tunnel des SPOF.

En pratique, la section 6.2 du RFC penche nettement vers la première solution, une liaison point à point, qui colle bien au modèle traditionnel suivi par les liens physiques, et qui établit clairement les responsabilités de chaque acteur. Bien que l'autre topologie soit séduisante sur le papier, elle a en pratique entraîné beaucoup de problèmes de performance et de déboguage.

Et à propos de SPOF, quelle est la fiabilité de ces techniques de tunnels lors d'une utilisation quotidienne ? L'expérience montre que les tunnels manuels sont plutôt fiables (une fois configuré, il n'y a guère de raison qu'ils arrêtent de marcher) et, surtout, ils sont simples dans leurs problèmes : soit le tunnel marche, soit rien ne passe. Pinguer l'extrémité du tunnel suffit en général à les superviser. D'où le tableau de la section 6.3, qui classe les techniques de tunnel par ordre de fiabilité décroissante, et qui met les tunnels configurés manuellement en haut, et Teredo et 6to4 tout en bas... (LISP est indiqué comme le plus fiable, à cause de ses mécanismes de réparation automatiques mais, contrairement à 6to4 ou aux tunnels, il n'a pas encore beaucoup été testé en vrai.)

Les problèmes de 6to4 ont été aggravés par le fait que certaines mises en œuvre de ce protocole ne testaient même pas que la machine avait une connectivité avec au moins un relais (RFC 6343 et RFC 7526).

Et les performances ? En raison de l'encapsulation, il y a forcément quelques octets perdus par le tunnel. Dans le cas d'une encapsulation directe, la moins coûteuse, cette perte représente 1,3 % d'un paquet de la taille maximale (1 500 octets). À part cette diminution de la charge utile, la performance dépend surtout des routeurs d'entrée et de sortie du tunnel. S'ils traitent les paquets « normaux » dans leur ASIC, mais l'encapsulation et la décapsulation en logiciel, dans leur relativement lent processeur, alors, oui, le tunnel sera lent. Mais ce n'est pas obligatoire. En fait, historiquement, le principal problème de performance des tunnels avait été le fait que les tunnels étaient souvent établis avec des machines relativement lointaines et c'est cet allongement du trajet qui ralentissait le service. Autrement, les tunnels ne sont pas synonymes de lenteur.

Bon, et la sécurité (section 7) ? Les tunnels (pas seulement ceux de IPv6 sur IPv4) sont souvent mauvais sur ce point. Par exemple, si l'entrée du tunnel ne fait rien pour vérifier les adresses IPv6 source des paquets qu'elle encapsule, le tunnel permettra peut-être de contourner les mécanismes anti-usurpation d'adresses (le cas de l'usurpation d'adresses avec 6to4 est couvert dans le RFC 3964). Il est donc important que le routeur d'entrée du tunnel prenne des précautions pour n'accepter que des paquets de ses clients légitimes. Autre faille possible : le tunnel permet d'établir une connectivité qui ne devrait pas « normalement » exister (dans le cas d'IPv6 sur IPv4, c'est son but explicite) et cela peut permettre de contourner les règles de sécurité qui sont en place (RFC 6169).


Téléchargez le RFC 7059


L'article seul

RFC 7064: URI Scheme for Session Traversal Utilities for NAT (STUN) Protocol

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : S. Nandakumar, G. Salgueiro, P. Jones (Cisco Systems), M. Petit-Huguenin (Impedance Mismatch)
Chemin des normes
Première rédaction de cet article le 23 novembre 2013


Ce court RFC normalise un nouveau plan d'URI, stun:, qui sera utilisé pour la configuration des clients STUN, un protocole de traversée des obstacles comme les routeurs NAT.

C'est le travail sur WebRTC qui a ravivé l'intérêt pour ce nouveau modèle d'URI (envisagé depuis longtemps mais jamais normalisé). WebRTC est un mécanisme de communication directe entre navigateurs Web. Souvent, les logiciels WebRTC vont devoir passer à travers des environnements hostiles comme des routeurs NAT. Une des techniques fréquemment utilisées pour aider ce passage est STUN, normalisé dans le RFC 5389, qui permet à un client STUN, en se connectant à un serveur STUN (en général installé par un fournisseur de services, par exemple SIP), d'apprendre son adresse IP extérieure et aussi d'autres caractéristiques utiles du NAT traversé.

Mais, pour cela, il faut que le client soit configuré avec les coordonnées d'un serveur STUN. Actuellement, cela se fait d'une manière spécifique à chaque client. D'où l'idée d'avoir un mécanisme simple de désignation du serveur STUN, un URI comme stun:example.net. Il n'y aura plus qu'à le copier/coller à l'endroit indiqué. Cela simplifiera la configuration et la documentation.

La section 3 fournit la syntaxe exacte. Il y a deux plans d'URI, stun: et stuns:, le second servant aux connexions sécurisées avec TLS. Ils sont notés dans le registre IANA des plans (après une discussion sur la liste d'examen des nouveaux plans). Un numéro de port est possible comme par exemple stuns:provider.example:8888. S'il est absent, le port par défaut est 3478 pour stun: et 5349 pour stuns:. Rappelez-vous que le nom du serveur, lui, sera déduit du nom de domaine indiqué dans l'URI par une recherche SRV (section 9 du RFC 5389).

Aujourd'hui, ces URI stun: sont utilisés dans des normes W3C comme celle de WebRTC. Ils sont acceptés par :


Téléchargez le RFC 7064


L'article seul

RFC 7084: Basic Requirements for IPv6 Customer Edge Routers

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : H. Singh, W. Beebee (Cisco Systems), C. Donley (CableLabs), B. Stark (AT&T)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 23 novembre 2013


Ce RFC du groupe de travail v6ops, qui se consacre aux problèmes pratiques du fonctionnement d'IPv6 (sans modification des protocoles, donc), porte sur les CPE (Customer Premises Equipment), alias CER (Customer Edge Routers), alias home gateway, qui sont les boîtiers installés chez l'utilisateur domestique ou dans la petite entreprise. Par exemple, en France, la Freebox ou la DartyBox sont des CPE. Certains d'entre eux gèrent le protocole IPv6 et ce RFC résume tout ce que doivent savoir les concepteurs de ces « boxes » pour faire de l'IPv6 proprement. Il succède, avec quelques changements, au RFC 6204, qui était le premier de cette série.

Ce RFC se focalise (section 1) sur le cas où IPv6 est natif (pas de traduction d'adresses entre v4 et v6), et sur le cas simple où il n'y a qu'un seul CPE, qui récupère sa configuration sur le WAN, puis la distribue aux machines IPv6 locales, puis route leurs paquets. Le déploiement de l'IPv6 dans le réseau de l'opérateur n'est pas discuté (cf. RFC 4779). Ce RFC concerne uniquement le « foyer, doux foyer ».

Ce RFC utilise un vocabulaire normatif, celui du RFC 2119, mais pas pour spécifier un protocole mais pour indiquer quel est le minimum qu'on peut attendre d'un CPE IPv6 aujourd'hui.

D'abord (section 3), un rappel du fonctionnement d'un CPE IPv4 aujourd'hui. Ce fonctionnement n'est spécifié nulle part, il résulte d'une accumulation de choix par les auteurs anonymes des CPE existants. Ces choix sont souvent erronés. En l'absence de norme formelle, la section 3.1 décrit le CPE « typique » de 2012. Ce CPE typique a une (et une seule) connexion avec l'Internet, une seule adresse IP publique (et encore, parfois, il y a même du NAT dans le réseau de l'opérateur) et il sert de routeur NAT aux machines IPv4 situées sur le réseau local. Par défaut, en raison du NAT, il bloque toutes les connexions entrantes (c'est la seule allusion à cette question qui soit restée dans la version finale du RFC). Ouvrir des ports entrants (port forwarding) se fait par une configuration manuelle du CPE, via une interface Web (cas de la Freebox) ou bien par UPnP. C'est donc un vrai Minitel 2.0. Un avantage de ces adresses privées est toutefois d'assurer la stabilité des adresses internes : elles ne changent pas si on quitte son FAI.

L'architecture ci-dessus est largement déployée et correspond au cas de la plupart des abonnés à l'Internet à la maison. À quoi ressemblera t-elle en IPv6 ? On ne peut évidemment pas encore être sûr, mais la section 3.2, qui la décrit en termes très généraux, suppose qu'elle ne sera pas très différente, à part que la présence de plusieurs réseaux (et donc plusieurs préfixes IP) sera peut-être un cas plus fréquent qu'aujourd'hui. Quelles adresses IP seront utilisées à l'intérieur ? On pense immédiatement au RFC 5902, qui n'est toutefois pas cité. Le RFC 7084 présente la possibilité que des adresse locales, les ULA (RFC 4193) soient utilisées pour le réseau local. Le CPE devra bien alors fournir un mécanisme de traduction. Pour les communications entre machines du réseau interne, il faudra utiliser les mécanismes du RFC 4191.

Alors, maintenant, quelles sont les exigences auxquelles devront se plier les futurs CPE IPv6 ? La section 4 est la liste de ces demandes. Elles sont nombreuses et, pour s'y retrouver, elles portent chacune un identificateur formel, indiquant la catégorie et un numéro. Par exemple, la première, G-1, rappelle qu'un routeur est aussi un nœud du réseau et doit donc suivre le protocole IPv6, tel qu'il s'applique à tous les nœuds IPv6, routeur ou machine terminale (RFC 6434). Parmi les autres exigences (je vous rassure, je ne vais pas les citer toutes), G-4 et G-5 précisent que, si le CPE n'a pas pu obtenir une connectivité IPv6 avec l'extérieur, il ne doit pas publier d'adresses IPv6 sur le réseau local (car beaucoup d'applications réagissent mal lorsque la machine a une adresse IPv6 mais pas de connectivité, cf. RFC 6555). Si le CPE n'a pas de connectivité globale, il doit émettre des annonces RA (Router Advertisement, RFC 4861) avec une durée de vie nulle.

Le CPE se connecte avec le reste de l'Internet en suivant les protocoles standard d'encapsulation pour IPv6 par exemple le RFC 2464 pour Ethernet et le RFC 5072 pour PPP (exigences WLL-1 et WLL-2).

Le CPE doit donc obtenir une adresse et une connectivité depuis l'amont, depuis le FAI. Cela peut se faire avec NDP ou avec DHCP (tous les deux fonctionnent sur tout type de lien, pas seulement sur Ethernet). C'est pour cela que, sur PPP, il n'y a pas de mécanisme en IPv6 pour allouer des adresses globales (RFC 5072). Donc, exigence W-1, le CPE doit utiliser NDP (RFC 4862) ou DHCP (RFC 3315) pour récupérer une adressse IPv6 globale. Avoir une adresse pour le CPE, c'est très joli, mais il faut aussi qu'il ait un préfixe à déléguer aux clients du réseau local, et il doit l'obtenir avec la technique DHCP du RFC 3633 (exigences W-4 et WPD-1).

Nouveauté de ce RFC par rapport au RFC 6204, W-6, le CPE doit aussi inclure un client PCP (Port Control Protocol, RFC 6887) pour son propre usage (il n'est pas obligé de fournir ce service à ces clients du LAN).

À côté d'autre exigences évidentes, portant sur des fonctions de base d'IPv6, le RFC demande aussi que le client DHCP dans le CPE utilise les options du RFC 3646 permettant de récupérer la liste des serveurs de noms (exigences WAA-3 et WAA-4).

Il devrait aussi avoir un serveur NTP (RFC 5905), mais pour son usage, pas forcément pour distribuer l'heure sur le réseau local (exigence WAA-5). La liste des serveurs NTP devrait également être récupérée dynamiquement et de manière standard avec les options DHCP du RFC 5908.

Justement, côté LAN, maintenant, que doit faire le bon CPE IPv6 ? Là encore, on trouve beaucoup d'exigences qui sont juste un rappel des fonctions de base d'IPv6. Mais d'autres sont moins évidentes comme la capacité à gérer des ULA (exigence ULA-1 et RFC 4193) ou le serveur DHCP pour les clients du réseau local (exigence L-8, en pratique, très rare sur les CPE d'aujourd'hui). Ce serveur DHCP peut servir à l'affectation des adresses IP (RFC 3315) ou bien uniquement à distribuer des paramètres statiques, comme le permet le RFC 3736. Aussi bien en DHCP (RFC 3646) qu'en RA (RFC 8106), le CPE doit fournir aux machines du réseau local les adresses des serveurs de noms, ainsi que quelques paramètres DNS.

Également côté LAN, le CPE devra fournir des adresses globales ou des ULA (les adresses locales au lien ne suffisent pas et, de toute façon, pas besoin d'un routeur pour en acquérir). La gestion des ULA (RFC 4193) est désormais obligatoire, et le CPE doit pouvoir mémoriser le préfixe ULA, même en cas de redémarrage, de façon à fournir un préfixe stable (et, idéalement, configurable) au réseau dont il a la charge (exigences ULA-1, ULA-2 et ULA-3).

Une autre nouveauté de ce RFC 7084 par rapport à son prédécesseur, le RFC 6204, est l'exigence que le CPE IPv6 gère certaines des techniques de coexistence et de transition IPv4-IPv6. Ainsi, le RFC recommande fortement 6rd (RFC 5969) et DS-Lite (RFC 6333).

La securité est la dernière sous-section de cette section 4. C'est un sujet très délicat, car il opposait, à l'IETF, ceux qui voulaient interdire par défaut les connexions entrantes, au nom de la sécurité (« Minitel 2.0 ») à ceux qui voulaient profiter du fait qu'IPv6, avec son abondance d'adresses globalement uniques, permettait de rétablit le modèle de bout en bout de l'Internet, qui permet à deux machines consentantes d'échanger les paquets qu'elles veulent. Le compromis entre les deux camps a finalement été que le CPE devait mettre en œuvre, dans son logiciel, cette capacité de bloquage, mais pas forcément l'activer par défaut. Un autre RFC, le RFC 6092, discute plus en détail des fonctions de pare-feu d'un CPE. Dans notre RFC 7084, on a juste la recommandation que, par défaut, le CPE filtre les adresses IP usurpées (RFC 2827) et les paquets clairement invalides (bogons, par exemple).

Quels sont les changements depuis le RFC 6204, qui avait été le premier à s'attaquer à cette difficile question de la spécification d'un CPE idéal ? Ils sont assez importants (surtout que le RFC 6204 est assez récent, vieux de seulement deux ans et demi), et décrits en annexe A. Les principaux :

  • L'ajout des techniques de transition comme 6rd et DS-Lite.
  • La normalisation de PCP dans le RFC 6887, qui permet désormais de l'indiquer comme obligatoire (mais seulement pour le CPE lui-même, pas forcément pour les machines du réseau local).
  • Des obligations en plus, comme les paramètres DNS, qui passent de SHOULD à MUST.
  • Plus de précision dans certaines demandes, par exemple sur le fait que le CPE doive cesser d'annoncer des routes IPv6 si lui-même n'a plus de connectivité vers le FAI.

Les CPE d'aujourd'hui mettent-ils en œuvre ces recommandations ? Difficile à dire, je ne connais pas d'étude systématique ayant été faite sur les capacités de ces engins (un projet est en cours), mais ce serait certainement très instructif.


Téléchargez le RFC 7084


L'article seul

RFC 7083: Modification to Default Values of SOL_MAX_RT and INF_MAX_RT

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : R. Droms (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dhc
Première rédaction de cet article le 23 novembre 2013


Choisir les valeurs numériques par défaut des paramètres réseaux est un art difficile. Et, parfois, on se trompe et il faut corriger. Depuis qu'il y a des réseaux IPv6 utilisant DHCP pour leur configuration, suivant la spécification du RFC 3315, on observe parfois des pics de trafic importants qui ont été attribués à la valeur maximale trop basse de deux paramètres, SOL_MAX_RT et INF_MAX_RT. Ce RFC remonte donc ces valeurs.

Ces paramètres sont définis dans le RFC 3315. Un client DHCP, en l'absence de réponse, doit réessayer mais en augmentant progressivement son délai d'attente jusqu'à une valeur maximale, à partir de laquelle il réessaiera périodiquement. SOL_MAX_RT est la durée maximale qu'un client DHCP attendra s'il ne reçoit pas de réponses à ses messages de sollicitation (section 17.1.2 du RFC 3315). Et INF_MAX_RT est la durée maximale entre deux demandes d'informations. Si le serveur DHCP choisit de ne pas répondre aux demandes de sollicitation des clients, chaque client retransmettra toutes les deux minutes, la valeur qui était indiquée par le RFC 3315. S'il y a des dizaines de milliers de clients DHCP, c'est trop, le serveur supportera une charge excessive.

La section 3 de notre RFC contient les nouvelles valeurs par défaut : SOL_MAX_RT et INF_MAX_RT passent de 120 secondes à 3 600. La charge d'un serveur, dans le pire des cas, devrait donc être divisée par trente. À noter que rien n'a été observé dans le monde réel pour INF_MAX_RT mais il est également remonté par souci de cohérence avec SOL_MAX_RT.

Attention : les valeurs spécifiées dans la section 3 sont des valeurs par défaut. Un serveur DHCP peut les changer en utilisant les nouvelles options du même nom (SOL_MAX_RT, numéro 82 et INF_MAX_RT, numéro 83) décrites dans les sections 4 et 5 et désormais enregistrées à l'IANA. Ces deux options dans la réponse DHCP permettent de spécifier une autre valeur (entre 60 et 86 400 secondes) pour les paramètres SOL_MAX_RT et INF_MAX_RT.

À noter qu'il n'existe pas encore de mise en œuvre de ces nouvelles options. Un client mis à jour devra obéir à ces options et un serveur mis à jour permettra de les fixer.


Téléchargez le RFC 7083


L'article seul

RFC 7065: Traversal Using Relays around NAT (TURN) Uniform Resource Identifiers

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : M. Petit-Huguenin (Impedance Mismatch), S. Nandakumar, G. Salgueiro, P. Jones (Cisco Systems)
Chemin des normes
Première rédaction de cet article le 23 novembre 2013


Ce court RFC normalise un nouveau plan d'URI, turn:, qui sera utilisé pour la configuration des clients TURN, un protocole de traversée des obstacles comme les routeurs NAT.

C'est le travail sur WebRTC qui a ravivé l'intérêt pour ce nouveau modèle d'URI (envisagé depuis longtemps mais jamais normalisé). WebRTC est un mécanisme de communication directe entre navigateurs Web. Souvent, les logiciels WebRTC vont devoir passer à travers des environnements hostiles comme des routeurs NAT. Une des techniques fréquemment utilisées pour aider ce passage est TURN, normalisé dans le RFC 5766, qui permet à un client TURN, en se connectant à un serveur TURN (en général installé par un fournisseur de services, par exemple SIP), de faire relayer ses paquets par le serveur TURN. TURN est une extension de STUN et s'utilise pour les cas désespérés, lorsque la seule solution pour communiquer est de faire relayer tout le trafic.

Mais, pour cela, il faut que le client soit configuré avec les coordonnées d'un serveur TURN. Actuellement, cela se fait d'une manière spécifique à chaque client. D'où l'idée d'avoir un mécanisme simple de désignation du serveur TURN, un URI comme turn:example.net. Il n'y aura plus qu'à le copier/coller à l'endroit indiqué. Cela simplifiera la configuration et la documentation. Combiné avec le mécanisme de résolution du RFC 5928, il n'y aura désormais presque rien à faire pour configurer TURN.

La section 3 fournit la syntaxe exacte. Il y a deux plans d'URI, turn: et turns:, le second servant aux connexions sécurisées avec TLS. Ils sont notés dans le registre IANA des plans. Un numéro de port est possible comme par exemple turns:provider.example:8888. S'il est absent, le port par défaut est 3478 pour turn: et 5349 pour turns:. Rappelez-vous que le nom du serveur, lui, sera déduit du nom de domaine indiqué dans l'URI par une recherche SRV, après passage par le mécanisme de résolution du RFC 5928.

Et les mises en œuvre ? Le logiciel turnuri (distribué en http://debian.implementers.org/stable/source/turnuri.tar.gz) met en œuvre les URI turn: ainsi que le mécanisme de résolution du RFC 5928. C'est également le cas de la bibliothèque libjingle, qu'utilise Chrome pour WebRTC (Firefox a sa propre implémenation).

Ce RFC a eu une histoire très longue et compliquée, remontant à plusieurs années. Ceux qui s'intéressent aux choix effectués (par exemple d'un plan turns: plutôt que d'un paramètre ;proto=tls dans l'URI) peuvent consulter un article de l'auteur sur son blog et la discussion à l'IETF. Parmi les nombreux messages échangés à l'IETF sur ces URI, je vous suggère la soumission originale et la discussion qui a suivi.


Téléchargez le RFC 7065


L'article seul

Panne du service DNS chez Microsoft

Première rédaction de cet article le 22 novembre 2013


Une grande panne DNS a planté hier soir tous les services de Microsoft, comme Hotmail. Comme d'habitude, l'information diffusée dans les médias et les forums ne vaut pas grand'chose, donc, revenons aux faits.

Les cris ont commencé le 21 novembre vers 2250 UTC sur Twitter. Plein de services ne répondaient plus. Une rapide analyse montrait un problème DNS. Ainsi, en demandant à DNSyo vers 2301 UTC, on avait « I asked 500 servers for NS records related to microsoft.com, 199 responded with records and 301 gave errors » (les résolveurs ouverts interrogés par DNSyo et qui avaient réussi ont en fait utilisé leur cache). Vers 2330 UTC, le problème a disparu.

Le DNS est un service crucial pour toute présence en ligne, puisque quasiment toute opération sur l'Internet commence par des requêtes DNS. Celui-ci doit donc être proprement configuré et géré. Malgré cela, il est régulièrement oublié lors des investissements.

Mais plus précisement, pourquoi est-ce que les résolveurs interrogés par DNSyo n'ont pas pu résoudre microsoft.com (ou xbox.com ou outlook.com, tous hébergés sur les mêmes serveurs et victimes du même problème) ? Regardons vers 2300 UTC :

% check-soa -i microsoft.com
ns1.msft.net.
	2a01:111:2005::1:1: OK: 2013112102 (146 ms)
	65.55.37.62: ERROR: Timeout
ns2.msft.net.
	2a01:111:2006:6::1:1: OK: 2013112102 (97 ms)
	64.4.59.173: ERROR: Timeout
ns3.msft.net.
	2a01:111:2020::1:1: OK: 2013112102 (15 ms)
	213.199.180.53: ERROR: Timeout
ns4.msft.net.
	2404:f800:2003::1:1: OK: 2013112102 (287 ms)
	207.46.75.254: ERROR: Timeout
ns5.msft.net.
	2a01:111:200f:1::1:1: OK: 2013112102 (100 ms)
	65.55.226.140: ERROR: Timeout

C'est le point le plus amusant de la panne, et aucun média ou forum ne l'a noté : le problème ne frappait qu'IPv4. Tous les serveurs répondaient normalement en IPv6. Un résolveur qui pouvait utiliser IPv6 n'avait donc aucun problème et les services de Microsoft marchaient comme avant. (Vous pouvez tester avec la requête dig SOA droneaud.org. Si vous récupérez un SERVFAIL, c'est que votre résolveur n'a pas été mis à jour depuis le siècle dernier et ne parle toujours qu'IPv4.)

Bien, cela montre qu'il faut avoir des résolveurs modernes, connectés en IPv6. Mais pourquoi cette curieuse panne ? Qu'est-ce qui a pu rendre tous ces serveurs, situés dans des réseaux très différents, inaccessibles en IPv4 tout en étant joignables en IPv6 ?

J'avoue que je ne sais pas. La liste des serveurs de noms est stable (vu avec DNSDB) depuis longtemps. RIPEstat, pas assez réactif, n'a pas encore de données sur cette panne. Une attaque par déni de service sur les machines n'épargnerait pas IPv6 (quoi que, attention, les services IPv4 et IPv6 correspondant à un même nom ne sont pas forcément sur la même machine). C'est encore plus vrai pour une attaque sur le réseau. Une panne d'une machine ou d'un réseau n'allait pas affecter tous les serveurs de Microsoft. Donc, pas d'explication simple, on peut se laisser aller à la spéculation. (Microsoft n'a évidemment rien communiqué et ne communiquera rien.)


L'article seul

RFC 7072: A Reputation Query Protocol

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : N. Borenstein (Mimecast), M. Kucherawy
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF repute
Première rédaction de cet article le 22 novembre 2013


Comment obtenir de l'information sur la réputation d'une entité (un nom de domaine, une adresse IP, etc) sur l'Internet ? Il existe actuellement tout un tas de méthodes ad hoc et le but du groupe de travail IETF repute est de fournir une alternative standard. Le RFC 7070 décrit le fonctionnement général de ce système. Ce cadre général autorise plusieurs protocoles concrets de récupération de l'information et ce RFC décrit un de ces protocoles, fondé sur HTTP.

Le mécanisme est assez simple et le RFC très court. Le client qui veut se renseigner auprès d'un serveur de réputation travaille en deux temps :

  • Il récupère un gabarit auprès du serveur de réputation, et l'utilise pour fabriquer un URI,
  • Il récupère ensuite le reputon, exprimé en JSON (cf. RFC 7071), via cet URI.

Ce mécanisme en deux étapes permet de la souplesse : les reputons peuvent se trouver derrière des URI très différents, qui n'ont pas besoin d'être « en dur » dans le client.

Ainsi, le service de réputation d'OpenDKIM, accessible en repute.opendkim.org a le gabarit http://{service}/repute.php{?subject,application,assertion,service,reporter} ce qui s'expanse en http://repute.opendkim.org/repute.php?subject=nom-de-domaine&application=email-id&assertion=spam&service=repute.opendkim.org (reporter est optionnel). Rappel de syntaxe des gabarits : le point d'interrogation ne s'applique pas qu'à la variable suivante mais à toutes les variables entre crochets.

Il n'y a pas de mécanisme de découverte d'un serveur de réputation : typiquement, cela se fait manuellement. En pratique, beaucoup de ces services nécessiteront une inscription ou un abonnement, de toute façon. Notez que le RFC ne spécifie pas de mécanisme d'authentification du client : on se sert par exemple des solutions classiques de HTTP. De même, si on veut de la confidentialité, on doit utiliser les mécanismes de chiffrement habituels, donc HTTPS (voir section 5 de ce RFC).

Le client doit aussi connaître le nom de l'application et le nom de l'assertion à tester. Il récupére ensuite le gabarit, en utilisant un URI « bien connu » (RFC 5785), /.well-known/repute-template (désormais dans le registre IANA des URI bien connus). Ce gabarit suit la syntaxe du RFC 6570. Le client remplace alors les variables. Par exemple, pour le gabarit ci-dessus, la variable application va être remplacée par email-id (le serveur de réputation peut gérer plusieurs applications). Pour reprendre l'exemple du RFC, si le gabarit du service example.com avait été http://{service}/{application}/{subject}/{assertion}, et qu'on cherchait des informations sur la réputation de example.org dans le cadre de l'application email-id (normalisée dans le RFC 7073), sur l'assertion spam, l'expansion du gabarit donnerait http://example.com/email-id/example.org/spam. Quelles sont les variables possibles dans un gabarit ?

  • application est le nom de l'application, pris dans le registre IANA,
  • service est le nom (ou l'adresse IP) du service de réputation demandé (celui d'où on a obtenu le gabarit),
  • subject est l'entité dont on veut connaître la réputation,
  • assertion est l'assertion qui nous intéresse, les valeurs possibles dépendant de l'application,
  • Sans compter des variables spécifiques à l'application.

Si un paramètre est optionnel mais que la syntaxe du gabarit ne permet pas de l'omettre, le client met une chaîne de caractères vide. L'auteur du gabarit doit veiller à ce que cela ne mène pas à des URI incorrects. Ainsi, le gabarit http://{service}/{application}/{subject}/{assertion}/{a}/{b}, si a est facultatif, pourrrait mener à une expansion où on aurait deux barres obliques de suite, ce que bien des serveurs HTTP réduisent à une seule, faussant ainsi la lecture de l'URI. Une bonne solution serait d'utiliser le mécanisme des gabarits du RFC 6570 pour les paramètres optionnels et donc de réécrire le gabarit vers http://{service}/{application}/{subject}/{assertion}/{?a,b}.

La réponse générée par le serveur de réputation sera alors un reputon (RFC 7071), étiqueté application/reputon+json.

Il existe une implémentation (due à Murray S. Kucherawy, un des auteurs du RFC) dans OpenDKIM à partir de la 2.9 (actuellement en version beta), le serveur est écrit en PHP (le serveur produit du JSON avec printf...) et le client en C. Testons-là avec le service public repute.opendkim.org. On récupère le gabarit :

% curl http://repute.opendkim.org/.well-known/repute-template
http://{service}/repute.php{?subject,application,assertion,service,reporter,format}

On fabrique ensuite une requête curl à la main (un vrai client du service de réputation le ferait automatiquement à partir du gabarit) :

% curl 'http://repute.opendkim.org/repute.php?subject=gmail.com&assertion=spam&application=email-id&service=repute.opendkim.org'
Content-Type: application/reputon+json

{
  "application": "email-id",
  "reputons": [
    {
	"rater": "repute.opendkim.org",
	"assertion": "spam",
	"rated": "gmail.com",
	"rating": 0.0113348,
	"identity": "dkim",
	"rate": 1735,
	"sample-size": 181,
	"generated": 1383463475
    }
  ]
}

On voit que Gmail émet apparemment peu de spam (classement à 0,0113348). Ce service est mis en œuvre avec les messages reçus par le domaine opendkim.org et seulement s'ils sont signés par DKIM (donc, n'essayez pas avec un domaine non signé comme laposte.net, vous aurez un No data available).


Téléchargez le RFC 7072


L'article seul

RFC 7073: A Reputation Response Set for Email Identifiers

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : N. Borenstein (Mimecast), M. Kucherawy
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF repute
Première rédaction de cet article le 22 novembre 2013


Le cadre général du système de requête sur la réputation a été défini dans le RFC 7070. Il reste à le décliner en diverses applications. L'une des utilisations les plus importantes pour un système de réputation est évidemment la lutte contre le spam et c'est donc à cela qu'est consacré notre RFC : la réputation des identifiants de courrier électronique.

L'application se nomme donc email-id (et est enregistrée dans le registre des applications). Les assertions possibles sur un acteur du courrier sont :

  • abusive : envoie-t-il des messages abusifs, par exemple de harcèlement ou de menaces ?
  • fraud : envoie-t-il des messages frauduleux, par exemple de hameçonnage ? (Voir à ce sujet le RFC 5901.)
  • invalid-recipients : envoie-t-il des messages à des utilisateurs inexistants (ce qui est courant chez les spammeurs, soit parce que leurs listes sont de mauvaise qualité, soit parce qu'ils testent de nouvelles adresses).
  • malware : envoie-t-il du logiciel malveillant ?
  • spam : envoie-t-il du spam ?

Dans le cadre du RFC 7070, ces assertions ne sont pas binaires : une entité a, pour chaque assertion, un classement qui va de 0 (assertion tout à fait fausse) à 1 (assertion vraiment vraie). Ainsi, example.net pourrait avoir un classement de 0,01 à l'assertion malware (il n'envoie quasiment jamais de logiciels malveillants) mais de 0,8 à l'assertion spam (il envoie souvent du spam). Les classements sont linéaires donc une entité qui aurait un classement de 0,4 pour le spam pourrait être décrite par « est deux fois moins spammeur que example.net ».

On note que toutes ces assertions sont « négatives », décrivent un comportement qu'on désapprouve. L'annexe A du RFC rappelle que certains pensent qu'il serait plus intéressant de travailler sur des assertions positives (et donc des bonnes réputations), car on peut échapper à des mauvaises réputations (on achète un nouveau nom de domaine et hop, on repart de zéro). Cela se fera peut-être dans le futur.

En réponse à une requête d'application email-id et comportant une ou plusieurs de ces assertions (celles qui intéressent le client du service de réputation), le serveur de réputation renvoie un reputon, une information structurée en JSON comportant un certain nombre de membres obligatoires (cf. RFC 7071) et, dans le cadre de cette application email-id, deux autres :

  • email-id-identity qui indique comment a été identifié l'émetteur (la réputation ne vaut évidemment pas grand'chose sans authentification mais, parfois, on n'a pas le choix et on a des identités non authentifiées) : DKIM (l'identité doit alors être la valeur de l'étiquette d=), SPF, adresse IP, valeur du champ HELO dans la connexion SMTP, valeur du champ MAIL FROM dans la communication SMTP (ce qu'on nomme le « RFC 5321 from »), valeur de l'en-tête From: du message (ce qu'on nomme le « RFC 5322 from »),
  • sources qui indique le nombre de sources qui ont contribué à l'établissement de cette réputation (le membre standard sample-size est le total de rapports, mais ils peuvent tous provenir d'une seule source).

L'identité (email-id-identity) est cruciale car on dispose de plusieurs identités dans un message (le From: de l'en-tête n'est pas forcément le même que le MAIL FROM de l'enveloppe SMTP), et elles n'ont pas toujours la même force. Par exemple, le From: de l'en-tête n'a subi aucune validation et peut valoir n'importe quoi. Au contraire, une signature DKIM permet de rattacher un message à un domaine responsable. Si le client n'est intéressé que par un seul type d'identité (par exemple SPF), il peut le préciser dans la requête.

Un exemple de reputon ? OpenDKIM a un service de distribution de réputation DKIM (donc, seuls les domaines utilisant DKIM y sont présents) :


% wget -O - 'http://repute.opendkim.org/repute.php?subject=amazon.com&assertion=spam&application=email-id&service=repute.opendkim.org'
...
{
  "application": "email-id",
  "reputons": [
    {
	"rater": "repute.opendkim.org",
	"assertion": "spam",
	"rated": "amazon.com",
	"rating": 0.000229625,
	"identity": "dkim",
	"rate": 1013,
	"sample-size": 181,
	"generated": 1384331169
    }
  ]
}


Téléchargez le RFC 7073


L'article seul

RFC 7071: A Media Type for Reputation Interchange

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : N. Borenstein (Mimecast), M. Kucherawy
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF repute
Première rédaction de cet article le 22 novembre 2013


Le cadre général d'accès à l'information sur la réputation d'une entité (identifiée par son nom de domaine, son adresse IP ou d'autres identificateurs) a été défini dans le RFC 7070. Cet autre RFC est plus concret et définit le format d'un reputon, une information structurée (en JSON) sur la réputation d'une entité, ainsi que le type de media associé, le nouveau application/reputons+json. Il crée également des registres IANA pour les noms d'applications de réputation et les réponses possibles selon l'application.

Le cadre du RFC 7070 prévoit que l'accès aux informations de réputation peut se faire par plusieurs mécanismes comme par exemple HTTP (RFC 7072). Mais le format transporté est toujours le même, celui d'un reputon. Un reputon est un objet JSON comportant les informations de réputation : identificateur de l'entité jugée, assertions sur cette identité, classement de l'identité selon ces assertions. Une requête va donc renvoyer un ou plusieurs reputons.

La section 3 liste les attributs d'un reputon, notamment :

  • L'identité de l'entité (rater) qui a jugé de la réputation,
  • Celle de l'entité jugée (rated),
  • L'assertion,
  • Le classement (rating) de l'entitée jugée, selon cette assertion, de 0,0 (assertion complètement fausse) à 1,0 (assertion tout à fait vraie).

Les identités dépendent de l'application et peuvent être des noms de domaine, des adresses IP, etc. La section 4 décrit en détail la notion de classement. Il y a aussi des attributs facultatifs dans un reputon :

  • Degré de confiance du juge vis-à-vis de son classement, de 0,0 à 1,0,
  • Classement considéré comme normal, pour pouvoir estimer si l'entité jugée est « dans les clous » ou pas,
  • Taille de l'échantillon sur lequel s'est fondé le jugement,
  • Date et heure où le classement a été établi (generated),
  • Date et heure à partir desquelles le jugement cessera d'être valable (expires).

Ces deux derniers attributs sont représentés par un nombre de secondes depuis le 1er janvier 1970. L'attribut expires permet (mais n'oblige pas) de mettre en place des caches devant le serveur qu'on interroge (section 5). Le RFC recommande de mettre des durées de validité d'autant plus courtes qu'on n'est pas sûr du jugement, par exemple parce qu'on n'a pas encore récolté beaucoup de données.

La section 6 indique la syntaxe concrète des reputons, sous forme d'un objet JSON, dont les membres (couples {clé, valeur}) représentent les attributs présentés plus haut. Les reputons sont mis dans un tableau JSON, puisqu'on peut en avoir plusieurs (s'il existe plusieurs assertions). Les assertions présentes dans un reputon sont typiquement celles qui ont été demandées par le client. Si ce dernier ne précise rien, le serveur peut renvoyer toutes les assertions qu'il connait. Un reputon peut être vide, si le serveur n'a aucune information sur l'entité et l'assertion demandées.

Voici l'exemple de reputon donné par le RFC, emprunté au baseball :

{
       "application": "baseball",
       "reputons": [
         {
           "rater": "RatingsRUs.example.com",
           "assertion": "is-good",
           "rated": "Alex Rodriguez",
           "rating": 0.99,
           "sample-size": 50000
         }
       ]
}

On a un seul reputon, pour l'assertion « est un bon joueur ». Vu le classement (quasiment 1), on peut dire que RatingsRUs.example.com estime qu'Alex Rodriguez est un bon joueur.

L'assertion est ici très générale. Elle pourrait être plus précise, si les concepteurs de l'application baseball le voulaient :

{
       "application": "baseball",
       "reputons:" [
         {
           "rater": "baseball-reference.example.com",
           "assertion": "hits-for-power",
           "rated": "Alex Rodriguez",
           "rating": 0.99,
           "sample-size": 50000
         },
         {
           "rater": "baseball-reference.example.com",
           "assertion": "strong-hitter",
           "rated": "Alex Rodriguez",
           "rating": 0.4,
           "confidence": 0.2,
           "sample-size": 50000
         }
       ]
}

Si vous ne connaissez pas le baseball et que vous vous demandez ce que veut dire hits-for-power (ne frappe pas forcément beaucoup mais fort) ou strong-hitter (frappe souvent des coups sûrs), voyez Wikipédia. On voit que le même Alex Rodriguez a une nettement moins bonne réputation pour strong-hitter que pour hits-for-power. Notez aussi l'indication de la taille de l'échantillon (ici, 50 000 points de mesure), qui permet aux statisticiens de se faire une idée de la validité de ces classements.

Un exemple moins artificiel de service de réputation serait évidemment lié à la lutte contre le spam. Prenons donc cette fois une application réelle, enregistrée dans le registre IANA des applications de réputation, l'application email-id définie dans le RFC 7073. Ce tableau contient deux reputons :

     {
       "application": "email-id",
       "reputons": [
         {
           "rater": "rep.example.net",
           "assertion": "spam",
           "identity": "dkim",
           "rated": "example.com",
           "confidence": 0.95,
           "rating": 0.012,
           "sample-size": 16938213,
           "updated": 1317795852
         },
         {
           "rater": "rep.example.net",
           "assertion": "spam",
           "identity": "spf",
           "rated": "example.com",
           "confidence": 0.98,
           "rating": 0.023,
           "sample-size": 16938213,
           "updated": 1317795852
         }
       ]
     }

Il se lit ainsi : « example.com, authentifié par DKIM (regardez l'attribut identity, spécifique à cette application) envoit du spam 1,2 % du temps. L'échantillon compte près de 17 millions de messages ». À noter que le second reputon, basé sur SPF, indique presque deux fois plus de spam. Cela peut vouloir dire que la liste des serveurs SMTP autorisés par SPF comprend quelques moutons noirs.

Ces reputons seront étiquetés avec le nouveau type application/reputons+json désormais enregistré à l'IANA. Il utilise les suffixes (+json) du RFC 6839. Est également enregistrée à l'IANA la liste des applications. Les nouvelles applications qui voudraient être incluses dans ce registre doivent avoir un examen par l'IETF ou bien une spécification stable (le RFC 5226 contient la liste des règles d'enregistrement à l'IANA).

Vous voulez voir des vrais reputons ? Il n'y a pas encore beaucoup de services disponibles publiquement. Essayons avec celui d'OpenDKIM :


% curl 'http://repute.opendkim.org/repute.php?subject=ietf.org&assertion=spam&application=email-id&service=repute.opendkim.org'
Content-Type: application/reputon+json

{
  "application": "email-id",
  "reputons": [
    {
	"rater": "repute.opendkim.org",
	"assertion": "spam",
	"rated": "ietf.org",
	"rating": 0,
	"identity": "dkim",
	"rate": 4,
	"sample-size": 2,
	"generated": 1338014959
    }
  ]
}

Très bon score pour ietf.org, une spamicité nulle. Mais faites attention à la taille de l'échantillon, seuls deux messages ont été examinés...

Merci à Vincent Levigneron pour ses explications sur le baseball (les erreurs qui restent sont les miennes, je n'ai pas forcément tout compris).


Téléchargez le RFC 7071


L'article seul

RFC 7070: An Architecture for Reputation Reporting

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : N. Borenstein (Mimecast), M. Kucherawy, A. Sullivan (Dyn)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF repute
Première rédaction de cet article le 22 novembre 2013


Il y a des tas de fois dans l'Internet où on souhaite se renseigner automatiquement sur la réputation d'une entité (une adresse IP, un nom de domaine, etc). Aujourd'hui, chaque application qui souhaite le faire développe une technologie spécifique pour l'accès à cette réputation (comme les listes noires DNS du RFC 5782). L'idée du projet repute de l'IETF est de créer des mécanismes communs, utilisables par une variété d'applications. Ce premier RFC est la fondation du projet et décrit l'architecture générale du système de réputation. D'autres RFC vont décrire les détails.

Un des principes fondateurs de l'Internet est qu'on n'a pas besoin de montrer patte blanche avant d'accéder à un service. Par exemple, pour une des applications les plus répandues, le courrier électronique, n'importe qui peut écrire à n'importe qui sans introduction préalable. On entend souvent des gens qui n'ont pas réfléchi à la question dire que cela contribue aux problèmes de sécurité de l'Internet. Mais cela a surtout contribué à son succès ! Comme le note à juste titre le RFC 5218, un système plus rigide, avec mécanismes de sécurités dès le début, avec authentification obligatoire avant d'envoyer un message, plairait certes aux dirigeants chinois ou saoudiens, et permettrait certainement de mieux traiter certains problèmes comme le spam. Mais il aurait aussi certainement à coup sûr tué le courrier électronique avant même qu'il ne décolle (ce n'est pas un avis personnel : c'est une constatation fondée sur l'observation de systèmes concurrents, bien oubliés aujourd'hui).

Donc, la plupart des services de l'Internet n'authentifient pas (l'émetteur d'un courrier peut mettre ce qu'il veut dans le champ From:...) et, même lorsqu'ils le font (en cas d'utilisation de TCP, l'adresse IP est relativement authentifiée), l'authenticité d'un pair ne nous renseigne pas sur son honnêteté et sa sincérité. Cette confusion entre authentification et autorisation est très fréquente, elle a même mené certains spammeurs à être les premiers à déployer certaines techniques (comme DKIM), en espérant jouer sur cette confusion. Si certains administrateurs de serveurs de messagerie étaient assez bêtes pour retirer des points de « spamicité » uniquement parce qu'un message avait une signature DKIM valide, le spammeur pouvait espérer injecter quelques spams en plus.

Résultat, les services de l'Internet, comme le courrier électronique, sont un grand succès mais, suite logique de ce succès, sont affligés de nombreux problèmes de sécurité (« Any real ecosystem has parasites », dirait Cory Doctorow). Comment lutte-t-on contre ces problèmes ? Une méthode courante est d'utiliser la réputation, c'est-à-dire des affirmations par un tiers comme quoi telle ou telle entité est digne de confiance. Son utilisation est particulièrement courante dans le cadre de la lutte contre le spam : on demande à un service de réputation « cette adresse IP est-elle souvent émettrice de spam ? » Si oui, on peut décider de ne pas accepter son message. Cette fois, on ne se limite pas à l'authentification : on bâtit au-dessus d'elle.

Si le monde du courrier électronique fut le premier à utiliser à grande échelle ces systèmes de réputation, d'autres dans l'Internet pourraient y venir. C'est pour les aider qu'a été développé ce modèle, et les protocoles qui l'accompagnent. En effet, les mécanismes actuels (le plus connu étant les DNSBL décrites dans le RFC 5782 mais il y a aussi le système du RFC 5518 pour se porter garant) sont très simplistes, notamment par le fait que leur réponse est binaire. On aurait besoin de nuances, et de la capacité d'apporter des détails (le RFC cite comme exemple la différence entre « approuver un chèque » et une institution très typiquement états-unienne, « faire un credit report complet »). Autre exemple où les systèmes actuels sont insuffisants, le cas où un acteur a une réputation différente selon ses services. Par exemple, un site de commerce en ligne peut avoir une mauvaise réputation pour les délais de livraison, mais un bonne réputation pour la qualité de l'information qu'il donne en cas de problème.

Compte tenu de tous ces points, le groupe de travail a développé un modèle, qui est résumé en section 2 de ce RFC. La réputation se gère à trois. On a un acteur qu'on veut évaluer, désigné par un identificateur. Un client qui est intéressé par la réputation de cet acteur. Et un service de réputation qui va distribuer de l'information sur les acteurs. Le service de réputation peut être public ou accessible seulement à des abonnés. Le client devra être configuré pour accéder à ce service de réputation. Les identificateurs utilisés peuvent être variés : noms de domaine, adresses de courrier électronique, adresses IP, etc.

Descendons un peu plus dans les détails (sections 4 à 6). L'architecture du système est celle d'un simple protocole question/réponse, qui peut utiliser comme transport sous-jacent divers mécanismes comme par exemple HTTP, le DNS... La syntaxe exacte dépend de l'application (rappelez-vous que ce RFC ne décrit qu'un cadre général). Un format possible des informations de réputation est normalisé dans le RFC 7071, un des protocoles d'accès, fondé sur HTTP, est dans le RFC 7072, et les identificateurs utilisés dans le cas du courrier électronique sont dans le RFC 7073.

Prenons l'exemple d'une application, un logiciel qui reçoit le courrier électronique, et qui utilise DKIM (RFC 6376) pour authentifier le domaine expéditeur. Ce nom étant authentifié, elle pourra s'en servir comme base de l'évaluation du message : on authentifie l'envoyeur du courrier avec DKIM, on interroge un serveur de réputation sur la réputation de cet envoyeur, et on décide alors d'accepter le message ou de l'envoyer dans le dossier « Spam ». DKIM apporte l'authentification, le système de notre RFC ajoute la réputation, et les deux ensemble permettent l'autorisation.

Que retourne un serveur de réputation ? Trois choses importantes :

  • Le nom de l'entité qu'il vient d'évaluer (dans l'exemple précédent, ce pourrait être gmail.com, le domaine expéditeur qui signe avec DKIM).
  • Une (ou plusieurs) assertion(s). Une assertion est une affirmation, plus ou moins fausse, sur le comportement de l'entité. Pour un domaine expéditeur, cela pourrait être « envoie du spam ». Pour un site de commerce en ligne, « livre dans les temps ». Pour quelqu'un qui modifie Wikipédia, « vandalise des articles ».
  • Un classement. Contraitrement aux DNSBL, le système de réputation n'est pas binaire. Une assertion peut être plus ou moins fausse et c'est ce qu'exprime le classement. Un classement va de 0 (assertion complètement fausse) à 1 (assertion toujours vraie). Ainsi, un domaine qui envoie rarement du spam pourrait avoir un classement de 0,2 à l'assertion « envoie du spam » alors qu'un domaine plus spammeur aurait un classement de 0,6.

Rappelez-vous que les assertions pertinentes, ainsi que la signification des classements, dépendent de l'application. Chaque application (réception de courrier, jugement des commentaires sur un blog, etc) aura donc sa propre spécification, décrivant les réponses attendues. Les applications ainsi spécifiées sont stockées dans un registre IANA.

La réponse structurée est dans un objet nommé « reputon ». Les détails de sa syntaxe dépendent du transport utilisé et de l'application. Mais si vous voulez voir des exemples de reputons, regardez le RFC 7071.

Pour obtenir un reputon en réponse, le client aura dû envoyer le nom de l'entité qu'il veut évaluer, le nom de l'application (tiré du registre IANA cité plus tôt) et, éventuellement, les assertions qui l'intéressent (le serveur de réputation peut en stocker plusieurs pour une même entité).

Comme le note la section 8, tout ceci peut poser des problèmes de préservation de la vie privée. Les informations de réputation peuvent dans certains cas être considérées sensibles et pas distribuables publiquement. Et il n'y a pas que la réponse qui peut être sensible, la question l'est aussi parce qu'elle révèle un intérêt du client (« le MP3 tina-turner-total-eclipse-of-the-heart.mp3 de condensat SHA-256 5ba214e312254abd22e7aae38af865a92f93cbd01e180051ab5bd443ceeae594, que je m'apprête à télécharger, est-il de bonne qualité ? ») Le RFC insiste donc sur la nécessité de fournir de la confidentialité si les données le justifient. Par exemple, le DNS, qui ne fournit aucune confidentialité, ne doit en aucun cas être utilisé pour des services sensibles. Si on se sert de HTTP comme transport de données de réputation sensibles, il faut utiliser HTTPS et, si on se sert du courrier, PGP ou équivalent.

De même, un accès non autorisé à la base de données d'un serveur de réputation pourrait causer des dommages, si ces données sont privées.

Mais il y a aussi des problèmes de sécurité qui ne sont pas liées à la vie privée (section 9). Par exemple, que se passe t-il si le serveur de réputation ment, distribuant délibérement des informations trop ou pas assez favorables à certaines entités ? Si un client accède à des informations de réputation, c'est probablement pour s'en servir pour prendre des décisions et des informations fausses peuvent donc avoir des conséquences concrètes désagréables. Imaginez un serveur de courrier qui accepterait du spam (ou, au contraire, rejetterait des messages légitimes) parce que le serveur de réputation l'a trompé.

Il n'y a pas de solution miracle à ce problème. Utiliser un serveur de réputation, c'est sous-traiter, c'est faire confiance. Cela implique le risque d'être trompé. Au minimum, le RFC conseille de ne faire confiance qu'à des services de réputation qui publient leurs pratiques de classement, qu'on puisse les analyser (voir le RFC 6471 pour ce problème dans le cas des listes noires de spammeurs dans le DNS).

Les motivations pour le projet de réputation ont été décrites dans les supports de la première présentation à l'IETF.

Pour des exemples d'utilisation et des informations sur les mises en œuvre de ce système, voir mes articles sur le RFC 7071 et sur le RFC 7072. Merci à Murray S. Kucherawy pour son aide.


Téléchargez le RFC 7070


L'article seul

Un "shunt" BGP observé en vrai

Première rédaction de cet article le 21 novembre 2013
Dernière mise à jour le 26 novembre 2013


On sait depuis longtemps qu'il est trivial d'annoncer sur l'Internet des routes pour d'autres adresses IP que les siennes. On peut ainsi capter le trafic de sa victime pour la couper du réseau (attaque par déni de service) ou peut-être pour se faire passer pour sa victime et, par exemple, recevoir du courrier qui ne vous est normalement pas destiné. Mais cette attaque est vite détectée car la victime ne reçoit plus (ou plus beaucoup) de trafic. D'où l'idée, très ancienne, de réinjecter le trafic à sa victime, après espionnage ou modification, pour retarder cette détection. Cela se nomme un shunt BGP, en référence à un dispositif électrique. Une étude récente de Renesys semble être la première à avoir mis en évidence cette attaque dans le monde réel.

L'attaque observée par Renesys comprend deux parties : une annonce BGP usurpée (comme dans la classique attaque de Pakistan Telecom contre YouTube) et un mécanisme (apparemment pas décrit dans l'article de Renesys) pour s'assurer de l'existence d'un chemin de retour, un clean path qui ne voit pas l'annonce BGP usurpée, de manière à ce qu'il transmette le trafic à la victime. La première partie, l'annonce BGP usurpée, est quelque chose de relativement fréquent dans l'Internet, la deuxième a été vérifiée par Renesys en envoyant des paquets vers un réseau détourné et en testant qu'ils arrivaient bien à destination, juste via une route très longue et très anormale (voir les traceroute dans l'article de Renesys). L'un des détournements était fait vers la Biélorussie, l'autre vers l'Islande (attention, le vrai responsable n'est pas forcément dans ces deux pays, il peut être caché derrière un opérateur piraté).

Si la possibilité d'un shunt BGP était connue depuis longtemps, les détails pratiques (il n'est pas évident de détourner un préfixe IP depuis tout l'Internet, tout en maintenant le clean path pour le retour) n'ont été décrits qu'en 2008 dans un article fameux de Kapela et Pilosov. Pour maintenir le chemin de retour, Kapela et Pilosov utilisaient l'AS prepending, l'ajout des numéros d'AS des opérateurs du chemin de retour à l'annonce usurpée, afin que ces opérateurs n'acceptent pas cette annonce (cela n'a pas été fait ici, voir l'annonce plus loin). À noter que Kapela et Pilosov proposaient également des méthodes pour rendre la détection plus difficile, comme de modifier le TTL dans les paquets IP pour tromper traceroute (cette astuce ne semble pas avoir été utilisée ici). Le travail de Kapela et Pilosov était théorique, il semble bien que les deux attaques étudiées par Renesys marquent le passage de leur méthode dans le monde réel.

Et les solutions ? À court terme, il est important de se rappeler qu'il faut chiffrer son trafic. Même si on pense être en sécurité car la communication est à courte distance (« mon trafic va uniquement de Denver à Denver, il n'y a pas de méchants à Denver »), l'étude de Renesys montre bien qu'un trafic local peut devenir distant grâce à l'attaque BGP et le faire passer par des endroits non sûrs. Quels que soient ses inconvénients, la cryptographie est une technologie à utiliser.

À un peu plus long terme, il faut mettre en place des systèmes de détection. Utiliser traceroute ne va pas forcément marcher (l'attaquant peut vous tromper en bricolant les TTL). Votre opérateur ou vous-même ont donc tout intérêt à utiliser des systèmes d'alarme BGP. L'attaquant peut faire bien des choses mais, par construction, il ne peut pas empêcher ses manipulations de se voir dans la table de routage globale. Bien sûr, ces systèmes n'empêcheront pas l'attaque mais, au moins, vous serez prévenus.

L'attaquant ne peut pas non plus violer les lois de la physique : en une milli-seconde, la lumière ne peut parcourir plus de 300 km. Un trajet de Denver à Denver qui prend moins d'une milli-seconde n'a certainement pas été détourné par l'Islande. Il faut donc mesurer le RTT et sonner l'alarme s'il augmente brusquement. Pour ceux qui utilisent les scripts de test compatibles Nagios, c'est le rta, le premier chiffre dans les seuils d'alerte de check_ping (le second étant le taux de pertes). Dans le futur, les sondes RIPE Atlas disposeront d'un mécanisme de test équivalent.

À plus long terme, la solution sera peut-être le déploiement massif de la RPKI mais on en est très loin aujourd'hui.

Plusieurs articles dans les médias ont été consacrés à cette attaque mais la plupart du temps, sans valeur ajoutée par rapport à l'article de Renesys, à part l'addition d'erreurs plus ou moins drôles. L'article d'Arik Hesseldahl n'est pas sans reproche (une erreur sur la notion d'attaque de l'homme du milieu) mais au moins il a fait un effort de pédagogie pour expliquer l'attaque à un public plus large que celui des lecteurs du blog de Renesys. J'en profite pour rappeler un très bon article sur la façon de faire une attaque en détournant le trafic, et comment le détourner, l'article d'Andree Toonk.

Et enfin, cherchons la vraie annonce BGP, dont Renesys ne donne qu'un résumé. (Attention, cela sera un peu plus technique.) On va se servir des archives de RouteViews, librement accessibles en ligne et qui remontent à 1997. Renesys donne l'heure exacte d'une des attaques, 07:36:36 UTC le 31 juillet. Les URL des archives de RouteViews sont prévisibles donc on sait que l'annonce qui nous intéresse va être dans le fichier bgpdata/2013.07/UPDATES/updates.20130731.0730.bz2 (updates.ANNÉE MOIS JOUR . HEURE MINUTE). On regarde les archives récoltées au LINX, plus proche de l'Islande (en vrai, j'avais d'abord regardé les archives récoltées par l'ISC en Californie, qui contenaient moins de choses). Donc :

% wget ftp://archive.routeviews.org/route-views.linx/bgpdata/2013.07/UPDATES/updates.20130731.0730.bz2

%  bunzip2 updates.20130731.0730.bz2

Le fichier ainsi obtenu est binaire, au format MRT (RFC 6396). On le transforme en texte avec bgpdump :

% bgpdump updates.20130731.0730 > updates.20130731.0730.txt

Et on examine tranquillement le fichier texte. Connaissant l'heure de l'attaque et l'AS d'origine de l'annonce usurpée, on finit par trouver une des annonces mensongères :

TIME: 07/31/13 07:36:46
TYPE: BGP4MP/MESSAGE/Update
FROM: 195.66.236.35 AS6067
TO: 195.66.237.222 AS6447
ORIGIN: IGP
ASPATH: 6067 6677 48685
NEXT_HOP: 195.66.236.35
ANNOUNCE
  64.81.96.0/24
  64.81.97.0/24
...

Que voit-on dans cette annonce ? L'heure correspond à ce qu'indique Renesys (les collecteurs de RouteViews n'ont pas forcément des horloges exactes à la seconde près et, de toute façon, la propagation BGP n'est pas instantanée). Le message a un chemin d'AS qui commence en 48685 et continue en 6677, comme le notait Renesys, avant d'arriver à l'AS 6067, un opérateur anglais, fournisseur de RouteViews. C'est donc là qu'on voit que l'attaquant n'utilisait pas d'AS prepending pour se créer un chemin de retour. Enfin, on a les préfixes annoncés, appartenant à Megapath, un opérateur états-unien, qui n'a certainement pas de fournisseur en Islande. L'annonce est donc clairement anormale, même si, juridiquement parlant, on peut estimer qu'on n'a pas de preuve qu'elle soit malveillante. (Jolie analyse, mais j'ai triché, j'ai été guidé par un informateur qui veut rester anonyme.)


L'article seul

Peut-on usurper une adresse IP ?

Première rédaction de cet article le 14 novembre 2013
Dernière mise à jour le 15 novembre 2013


Question technique du jour : peut-on usurper une adresse IP source sur l'Internet, c'est-à-dire peut-on envoyer un paquet IP en utilisant une adresse IP source qui n'est pas la sienne et qu'on n'a normalement pas « le droit » d'utiliser ? Tous les gens qui connaissent un peu l'Internet vont répondre « oui, on peut, c'est même une faiblesse de sécurité connue ». Mais la réalité est plus complexe.

La possibilité d'envoyer un paquet IP avec une adresse source usurpée découle du mode « datagramme » de fonctionnement d'IP. Chaque paquet est indépendant, porte des adresses source et destination que l'émetteur met à la valeur qui lui chante et, le paquet n'étant routé que sur la destination, il devrait arriver sans problème. Un certain nombre d'attaques, comme les attaques par réflexion, fonctionnent sur cette base.

Sur une machine Unix, par exemple, l'envoi d'un tel paquet se fait facilement avec hping :

% sudo hping --syn --spoof 192.0.2.42 -p 80 www.example.com

Notez que cela nécessite d'être root. À l'époque des gros mainframes très chers sur lesquels on n'avait qu'un compte utilisateur, c'était une limite. Aujourd'hui que chacun est root sur son PC ou sur son Pi, cela n'est plus un obstacle.

En raison des possibilités d'attaque, cet envoi avec une fausse adresse est très mal vue. La position officielle de l'IETF est que les FAI et autres acteurs des réseaux doivent interdire cet envoi, et c'est documenté dans deux RFC connus collectivement sous le nom de « BCP 38 » (BCP pour Best Current Practices), les RFC 2827 et RFC 3704. BCP 38 est loin d'être déployé par tous les opérateurs, comme le montrent les statistiques du Spoofer Project et cela explique pourquoi les attaques par réflexion continuent, et ne semblent pas devoir disparaître de si tôt. Néanmoins, certains opérateurs bloquent les paquets usurpés. (Un projet plus récent, visant à aller plus loin que BCP 38, est SAVI, RFC 6959.)

J'ai fait quelques tests avec hping et avec un logiciel écrit spécialement, afin de tester aussi en IPv6 (hping ne parle toujours pas IPv6 et son concurrent nping très mal et j'avais la flemme d'installer hping6). Sur trois fournisseurs différents de VPS, trois échecs. Chez un FAI grand public, idem (la box de ce FAI peut être configurée de deux façons différentes et je n'en ai testé qu'une, l'autre est peut-être plus favorable à l'usurpation). En IPv4, le NAT gêne probablement beaucoup toute tentative de triche. (Mais il y a une astuce, chez ce FAI, pour réussir à faire sortir les paquets usurpés malgré le NAT.)

Donc, si vous voulez vous lancer dans l'usurpation d'adresses IP, attention, ne vous attendez pas à ce que cela marche partout (mes tests ont été faits à partir d'accès accessibles au grand public ; cela peut être différent si l'usurpateur contrôle un réseau entier, avec un fournisseur de transit qui ne vérifie rien). Mais il y a d'autres obstacles que ceux de la couche 3. En effet, bien des protocoles utilisés au dessus d'IP nécessitent une réponse or l'usurpateur ne recevra pas forcément les réponses à ses paquets, puisqu'il a mis une autre adresse que la sienne. Distinguons deux cas : dans le premier, l'usurpateur peut voir les réponses (par exemple parce qu'il est sur le même réseau local que la victime dont il a usurpé l'adresse, et que ce réseau local n'a pas de protection contre le sniffing ; ou bien parce qu'il pratique le détournement de préfixes entiers par une attaque contre les protocoles de routage, ce qui est possible mais bien plus sophistiqué). Alors, l'usurpateur, s'il n'est pas bloqué par BCP 38, pourra envoyer des paquets avec une adresse mensongère et, voyant les réponses, pourra entretenir le dialogue.

Mais le second cas est plus fréquent : l'usurpateur ne voit pas du tout les paquets de retour, il doit travailler en aveugle. C'est beaucoup plus embêtant pour lui, car les protocoles sont en général conçus pour rendre la vie difficile pour un attaquant aveugle. Ainsi, TCP a un numéro de séquence dans les paquets et ce numéro part d'un numéro initial, l'ISN (Initial Sequence Number) qui est désormais choisi de manière imprévisible (si tout le monde suit bien les RFC 6528 et RFC 5961). Ne sachant pas quel est l'ISN, l'usurpateur ne pourra pas tenir un dialogue avec son correspondant. C'est pour la même raison que l'IETF recommande des ports source imprévisibles dans le RFC 6056. Et c'est aussi pour cela que le DNS a ses Query ID, un nombre imprévisible mis dans la requête et qui doit être renvoyé dans la réponse, pour que celle-ci soit acceptée. Malheureusement, dans le cas du DNS, ce Query ID, avec ses 16 bits, est trop petit et un usurpateur a donc toujours une chance. Et la technique de TCP n'est pas imparable non plus.

En résumé, oui, IP permet de tricher sur l'adresse source mais si vous voulez utiliser cette possibilité pour l'amusement, la gloire ou le fric, étudiez bien la question : cela peut être plus difficile à exploiter que cela n'en a l'air.


L'article seul

Peut-on se passer des métadonnées dans les protocoles Internet ?

Première rédaction de cet article le 12 novembre 2013


Dans les discussions sur les risques d'espionnage des utilisateurs sur l'Internet, le terme de métadonnées revient souvent. Ce sont les données qui, sans faire partie du contenu de la communication, servent à son acheminement. On sait qu'un espion qui n'aurait accès qu'à ces métadonnées peut récolter plein d'informations intéressantes. Peut-on empêcher cela ?

Par exemple, dans un paquet IP, les métadonnées sont entre autres les adresses IP source et destination. Dans un message de courrier électronique, les adresses de l'expéditeur et du destinataire (MAIL FROM et RCPT TO dans le dialogue SMTP). Pourquoi parle-t-on souvent des métadonnées lors de discussions sur les risques de l'espionnage et la protection de la vie privée ? Parce qu'elles sont particulièrement difficiles à sécuriser et parce qu'elles donnent certes moins d'informations que le contenu des messages mais que c'est encore trop.

Elles sont difficiles à sécuriser car les équipements intermédiaires en ont besoin pour acheminer les informations. La protection la plus évidente (et, effectivement, souvent la plus efficace) contre l'espionnage est le chiffrement. Celui-ci rend les données inaccessibles à l'espion. Mais il laisse les métadonnées. Dans le cas d'IP, l'utilisation d'une technique comme IPsec (RFC 4301) masque le contenu du paquet mais laissent intactes les adresses de source et de destination. Les techniques comme SSH (RFC 4251) ou TLS (RFC 5246) laissent encore plus de métadonnées visibles (le protocole de couche 4, et les ports). Dans le cas du courrier électronique, chiffrer le message avec PGP (RFC 4880) laisse les métadonnées SMTP (MAIL FROM, l'adresse de l'expéditeur, RCPT TO, celle du destinataire) en clair (ainsi que celles de l'en-tête du message, cf. RFC 5322).

Bien sûr, c'est moins intéressant pour l'espion que d'avoir tout le contenu du message et le chiffrement reste donc une excellente idée. Mais l'accès aux métadonnées reste un puissant outil. Il permet l'analyse de trafic.

Alors, comment éviter cela ? Supprimer les métadonnées ? Certaines sont implicites et ne sont pas modifiables facilement. Par exemple, l'écart temporel entre les messages est une métadonnée et elle peut être une source utile d'informations. Si on voit trois connexions HTTPS vers trois serveurs donnés, dans un intervalle très court, on pourra se dire que c'est sans doute la même page Web et on pourra chercher quelle page a des ressources sur ces trois serveurs (un jeu d'enfant pour Google). Autre exemple d'une métadonnée utile à l'écoutant, la taille des messages transmis. On peut en déduire, par exemple lors d'une connexion HTTPS s'il y a eu lecture d'une page Web ou bien envoi d'un fichier. Mais changer la taille d'un message n'est pas trivial. Comme on ne peut pas la réduire à volonté, la seule méthode est de bourrer en ajoutant des données aux messages trop courts. Cela a un coût en matière d'occupation de la capacité réseau. On trouve là un cas classique en sécurité : la nécessité de faire des compromis, ici entre vie privée et développement durable.

D'autres métadonnées sont explicites comme les adresses d'expéditeur et de récepteur. Comment les supprimer ? Parfois, c'est relativement facile. Par exemple, si on chiffre son courrier avec PGP, l'objet du message (champ Subject:) reste en clair. Il n'y a aucune bonne raison pour que cela soit le cas, à part la compatibilité avec le courrier traditionnel. Les logiciels qui chiffrent avec PGP devraient chiffrer tout le message (type message/rfc822) et le mettre comme partie MIME d'un message dont l'objet serait banalisé (Subject: this is a message). Mais d'autres métadonnées explicites sont là pour de bonnes raisons et vont être plus dures à éradiquer.

Le problème avec l'adresse de récepteur, c'est qu'elle est indispensable au routage. Les équipements intermédiaires ont besoin de cette adresse pour acheminer le message. Pour ne pas avoir d'adresse de destinataire visible, la seule solution est, là encore, très coûteuse en ressources réseau : il faut diffuser à tout le monde, comme le fait BitMessage.

Et pour l'adresse de l'expéditeur ? Elle n'est pas indispensable à l'acheminement, non ? On pourrait la supprimer (proposition dite « sourceless protocols »). Par exemple, sans changer le format des paquets IP, on pourrait imaginer une adresse source standard qui indiquerait « ce paquet est anonyme, il ne dira pas d'où il vient ». Mais ce n'est pas toujours aisé. Par exemple, parfois, il faut pouvoir envoyer un avis de non-remise comme les messages ICMP Destination Unreachable, ou comme les messages de courrier du RFC 8098. Pour cela, il faut bien avoir une adresse à qui envoyer ces notifications. Autrement, l'expéditeur enverra dans le noir, en ne sachant jamais si son message est arrivé.

Et c'est encore plus vrai pour les protocoles qui exigent un dialogue alors que la couche basse ne fournit qu'un service de messages. Par exemple, le protocole de transport le plus utilisé dans l'Internet, TCP, nécessite que les messages puissent circuler dans les deux sens, ce qui impose que les adresses IP mises dans le paquet soient joignables.

Notez que les protocoles à connexion ne posent pas les mêmes problèmes car ils peuvent être « sans source ». Dans le vieux X.25 (ce n'est pas moi qui ai choisi l'exemple, c'est Rémi Després, lors d'une discussion/pizza), le serveur n'avait pas forcément l'adresse du client. Chaque routeur sur le trajet établissait une connexion avec le routeur suivant, ce qui fait qu'une machine ne connaissait que son prédécesseur. Il est amusant de noter que Tor fonctionne comme cela, mais avec bien des services en plus pour limiter encore davantage la fuite d'information (routeurs gérés par plusieurs organisations pour qu'ils ne puissent pas s'informer mutuellement, chiffrement systématique). Faudra-t-il donc remplacer IP par un protocole à connexion ?

Aujourd'hui, pour sécuriser le courrier électronique, il faudra combiner plusieurs techniques. Par exemple PGP pour du chiffrement de bout en bout (s'assurer que les serveurs intermédiaires ne pourront pas lire le message) et SMTP sur TLS (RFC 3207) pour chiffrer les métadonnées vis-à-vis d'un écoutant situé sur le trajet. Certes, SMTP sur TLS a des tas de limites, question sécurité (notamment, peu de MTA vérifient le certificat du pair) mais c'est mieux que de laisser les messages PGP circuler en clair, avec les métadonnées.

À noter qu'un écoutant peut quand même savoir qu'il y a un trafic SMTP. Si la communication est entre deux serveurs SMTP personnels, ayant peu de comptes ou même un seul, il pourra, même si tout est chiffré avec TLS, savoir qu'il y échange de courrier entre deux personnes identifiées. On est mieux protégé contre ce genre d'espionnage si on utilise un gros serveur. L'écoutant ne sera guère avancé en sachant juste qu'un utilisateur de Yahoo écrit à un utilisateur de Gmail. Dans le cas de ces gros silos, le danger est évidemment ailleurs, dans leur envoi d'informations à la NSA. Il faudrait donc des gros serveurs, mais gérés par des organismes honnêtes. Pas facile, la sécurité.

Un dernier mot sur une technique qui peut aider à résoudre notre problème : le chiffrement homomorphique. Comme il permet de faire des opérations sur des données chiffrées, il offre (théoriquement, car je ne crois pas que cet usage ait déjà été exploré) la possibilité de combiner routage et chiffrement des métadonnées.


L'article seul

L'IETF et l'espionnage, et maintenant ?

Première rédaction de cet article le 7 novembre 2013


J'ai déjà parlé ici de l'attitude de l'IETF face à l'espionnage massif (pervasive surveillance est le terme le plus répandu à l'IETF) auquel se livrent des organisations comme la NSA. Maintenant que la réunion IETF de Vancouver est bien avancée, quelles vont être les suites ?

Quelques informations sur la plénière technique du 6 novembre, qui a symboliquement marqué le passage de l'IETF en mode « on est vraiment fâchés ». Les documents, diapos, etc sont tous en ligne. La plénière a été filmée et le film est aussi en ligne (chez un fournisseur de PRISM, ce qui est amusant). La partie sur la surveillance commence après 23 minutes environ quand Alissa Cooper, auteure du RFC 6973, monte à la tribune.

La vedette était Bruce Schneier, qui a bien fixé les objectifs : empêcher toute surveillance n'est pas réaliste, ce contre quoi on peut lutter, c'est la surveillance de masse. Schneier a posé le problème en termes financiers : la surveillance est trop bon marché aujourd'hui et peut donc être faite massivement. Des réformes techniques pourraient contribuer à la rendre plus coûteuse, forçant les agences d'espionnage à revenir à de la surveillance ciblée, ce qui serait mieux que rien. Il a également insisté sur le « partenariat public/privé » : la NSA ne fait pas tout toute seule, elle est aidée par les géants du Web, qui lui fournissent des données (c'est un des points dont l'IETF, où des entreprises comme Google sont très présentes, n'aime pas discuter, et cela explique certains manques dans le RFC 6973).

Du point de vue pratique, Schneier a rappelé l'importance de l'ergonomie (ne pas fournir d'options dans les logiciels de sécurité, car elles seront mal utilisées), et de la sécurité par le nombre (si peu de gens utilisent le chiffrement, celui-ci est négatif, il attire l'attention sur eux ; il faut du chiffrement massif).

Brian Carpenter a fait l'historique des RFC parlant de vie privée, du RFC 1126 (le premier à parler de sécurité... pour dire qu'il ne s'en occuperait pas) puis au RFC 1543, qui a rendu obligatoire la fameuse section Security Considerations. Il a aussi rappelé le contexte notamment la lutte de certains pays (la France a été citée) contre la cryptographie dans les années 80 et 90.

Stephen Farrell est ensuite passé au concret : que peut faire l'IETF ? (Il a aussi illustré son exposé d'une jolie photo d'un parc mais il aurait pu choisir de l'herbe.) Le nouveau groupe IETF perpass (abréviation de pervasive passive monitoring) est chargé de trier les idées : le travail concret se fera ensuite dans des groupes de travail spécialisés. L'orateur a noté la menace particulière que faisait planer l'Internet des objets : « la NSA saura quand vous tirez la chasse ».

Enfin, les chercheurs en sécurité noteront l'annonce d'un atelier de l'IAB « Internet Hardening » à Londres le 28 février 2014. Préparez vos articles !

La plénière technique à l'IETF n'est pas composée que d'exposés formels mais contient aussi une discussion. Cooper a introduit cette discussion en appelant les membres de l'IETF à la responsabilité (« plein de gens vous écoutent », ce qui a fait éclater la salle de rire). De nombreux thèmes ont été abordés : vue la disproportion des moyens, pouvons-nous vraiment gêner la NSA (Schneier : « oui, ils ont des limites, ne serait-ce que les lois de la physique »), intérêt de disperser les services à surveiller (il est plus coûteux de surveiller 100 000 serveurs de messagerie qu'un seul Gmail), et même l'argument très traditionnel « mais on n'est pas des terroristes, on n'a rien à cacher » (Cooper : « on veut de la vie privée même pour des activités légales, songez à vos visites chez le docteur, par exemple »)

La proposition de « durcir l'Internet » pour rendre la surveillance moins facile a été largement adoptée, par la pittoresque procédure du « hum ». Sans surprise, le communiqué officiel prend acte de ce consensus et s'en félicite. Mais cela ne veut pas dire que tout se passera comme sur des roulettes après. Il y a eu des critiques (plus ou moins voilées) contre ce projet (personne n'ose s'y opposer frontalement mais cela n'empêche pas les attaques indirectes) et, surtout, voter des motions est facile, développer de nouvelles techniques et protocoles et les déployer est une autre histoire.

Ce sera justement le premier travail du groupe perpass. Il s'est réuni juste après la plénière et avait un agenda chargé ! (Les documents sont eux aussi en ligne). Dave Thaler a notamment fait un remarquable exposé sur l'état des menaces sur la vie privée. Cet exposé tordait le cou à la légende très répandue comme quoi les cybercriminels auraient la partie trop facile, l'Internet leur permettrait l'anonymat, etc. C'est tout le contraire : la vie privée est aujourd'hui extrêmement difficile à préserver dans les réseaux numériques.

Et les solutions envisagées ? L'IETF a plein d'idées :

  • Évidemment, généraliser le chiffrement. Les gens de XMPP se sont promis de le faire pour leur protocole de messagerie instantanée avant mai 2014.
  • Un terme souvent revenu dans les discussions est celui d'opportunistic encryption. Il n'est pas très rigoureusement défini. Des fois, il veut dire « chiffrement sans authentification préalable » (ce qui protège d'un attaquant passif mais pas d'un homme du milieu), des fois, il signifie « chiffrement sans configuration manuelle préalable » et, là, c'est très souhaitable si on veut avoir des chances de généraliser le chiffrement.
  • Minimisation des données envoyées. Le chiffrement ne protège pas si le destinataire transmet vos données à un tiers (cas de Facebook, par exemple). Il est donc également nécessaire de diminuer la quantité de données envoyées. Christian Huitema a ainsi lancé un appel à ce que les résolveurs DNS arrêtent d'envoyer la question complète aux serveurs faisant autorité.

Alissa Cooper a bien résumé la démarche perpass : « 1) envoyer le moins de données possibles 2) les chiffrer ». Il n'y a plus qu'à réaliser ce programme.

Y a-t-il consensus sur cette démarche ? Comme indiqué plus haut, les opposants se font très discrets. Mais certaines remarques négatives ont déjà été entendues, par exemple que la généralisation du chiffrement de bout en bout va empêcher les intermédiaires d'examiner ou de modifier les messages (ce qui me semble une bonne chose mais ce n'est pas l'opinion de tout le monde, d'autant plus qu'il y a des craintes que les attaquants s'adaptent et cherchent d'autres moyens) ou, autre exemple, que la gestion opérationnelle des réseaux va en souffrir (un ennui courant avec la cryptographie).

Et puis, même si tout le monde est d'accord, le principe de réalité ne manquera pas de frapper : certains des changements proposés auront un coût et certains, qui ont applaudi avec enthousiasme à la proposition de renforcer la sécurité de l'Internet, reculeront peut-être devant ce coût.

D'autres articles intéressants sur cette question :


L'article seul

RFC 7050: Discovery of the IPv6 Prefix Used for IPv6 Address Synthesis

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : T. Savolainen (Nokia), J. Korhonen (Nokia Siemens Networks), D. Wing (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 5 novembre 2013


Lorsqu'on utilise le mécanisme NAT64 du RFC 6146 pour donner accès à l'Internet historique IPv4 depuis des machines IPv6, seul le traducteur NAT64 connait le préfixe IPv6 utilisé pour la traduction. Les machines ordinaires du réseau local ne le savent pas. Ce nouveau RFC fournit un moyen standard de découvrir ce préfixe.

Un tout petit rappel sur NAT64 (RFC 6146) et son copain DNS64 (RFC 6147) : leur but est de fournir une connectivité IPv4 (par exemple pour accéder à des machines qui n'ont toujours pas IPv6) aux réseaux modernes qui seront entièrement en IPv6 (RFC 6144). Pour cela, le serveur DNS64 « ment » en répondant aux requêtes de type AAAA (demande d'une adresse IPv6) par une réponse synthétisée, lorsque le nom demandé n'a qu'un A (adresse IPv4). Cette réponse synthétique utilise un préfixe configuré à la fois dans le serveur DNS64 et dans le traducteur NAT64 qui, voyant une adresse portant ce préfixe dans le champ Destination, va traduire l'IPv6 en IPv4 (et réciproquement au retour).

La plupart du temps, les machines IPv6 situées sur le réseau local n'auront aucun besoin de savoir ce qui se passe. Pour elles, tous les services externes sont accessible en IPv6 et elles ne connaissent pas la magie sous-jacente. Bien sûr, en regardant les adresses IPv6 obtenues, elles pourront s'étonner de voir que tant d'entre elles commencent par le même préfixe, mais qu'elles le fassent ou pas ne change rien. NAT64 est prévu pour fonctionner entièrement dans le routeur d'accès, sans participation (et donc sans mise à jour du logiciel) des machines terminales.

Sauf qu'il y a des cas où il serait utile que ces machines terminales bossent un peu. Par exemple, DNS64 ne sert à rien si l'application n'utilise pas le DNS. Si on a un URL http://192.168.0.33/, qui est légal (quoique déconseillé) et devrait marcher, DNS64 ne sera jamais appelé et NAT64 échouera donc. Pourtant, cet URL pourrait fonctionner à travers NAT64 si seulement la machine terminale faisait le travail de DNS64 en synthétisant l'adresse IPv6 correspondant à 192.168.0.33. Un problème analogue avec DNS64 se pose si la machine terminale fait la validation DNSSEC elle-même (ce qui est souvent une bonne idée). Dans ce cas, les réponses « mensongères » du serveur DNS64 seront refusées. Dans ces deux cas, on souhaite que la machine terminale synthétise une adresse IPv6 elle-même et, pour cela, elle doit connaître le préfixe qui permettra au routeur NAT64 de savoir ce qu'il doit faire.

Ce préfixe « magique » (les adresses utilisant tout autre préfixe seront traitées par le routeur comme de l'IPv6 ordinaire) peut être de deux types :

  • Un préfixe bien connu, réservé à cet usage, le WKP (Well-Known Prefix) qui vaut 64:ff9b::/96. Il est décrit dans le RFC 6052.
  • Ou bien un préfixe décidé localement, un NSP (Network-Specific Prefix), 2001:db8:1:64::/96 dans les exemples suivants.

Dans les deux cas, ce préfixe doit être configuré à l'identique dans le routeur NAT64 et dans le serveur DNS64. Et, si on utilise la synthèse locale (locale à la machine terminale) des adresses IPv6, il ,doit aussi être connu des machines terminales, ce qui est le but de ce RFC. Attention, il peut y avoir non pas un, mais plusieurs préfixes utilisés simultanément.

La technique utilisée dépend entre autres d'un nom bien connu, ipv4only.arpa, qui n'aura jamais que des adresses IPv4, et d'adresses IPv4 bien connues, les WKA (Well-Known Addresses), 192.0.0.170 et 192.0.0.171.


% dig +short A ipv4only.arpa
192.0.0.170
192.0.0.171

% dig +short AAAA ipv4only.arpa

Le principe (section 3 de notre RFC) est de faire une requête DNS de type AAAA (adresse IPv6) pour ce nom ipv4only.arpa. Comme ce nom n'a que des enregistremments A (adresse IPv4), si on obtient des enregistrements AAAA, c'est qu'il y a du DNS64 sur le trajet, qui synthétise ces enregistrements. Sinon, il n'y a pas de service DNS64. (La requête doit se faire avec le bit CD - Checking Disabled - à 0, autrement le serveur DNS64 ne fait pas la synthèse.) À la place d'un serveur DNS64, il peut aussi y avoir un serveur menteur qui répond même en l'absence de données (cela est fréquent sur les portails captifs). Dans ce cas, le client doit aussi faire une requête pour un nom qui n'existe pas (il n'est pas si facile que cela d'en trouver un) et vérifier qu'il récupère bien NXDOMAIN.

Une fois reçue sa réponse, la machine doit examiner tous ces AAAA et en déduire le (ou les) préfixe(s) utilisé(s) pour la synthèse. Si le préfixe est le WKP, c'est facile. Si c'est un NSP, c'est un peu plus dur. C'est là que les WKA sont utilisées : comme la machine connait les adresses IPv4 originales, elle peut les retrouver dans les adresses IPv6. Avec les examples plus haut, la machine fait une requête AAAA pour ipv4only.arpa, obtient comme réponse 2001:db8:1:64::192.0.0.170 (qu'on peut également écrire 2001:db8:1:64::c000:aa) et en déduit que le préfixe utilisé est 2001:db8:1:64::/96. Par exemple, avec BIND, et ce fichier de configuration :

options {
        ...
        dns64 2001:db8:1:64::/96 { // Network-Specific Prefix
              clients { me; };
        };

On obtiendra :

% dig +nodnssec AAAA ipv4only.arpa
...
;; ANSWER SECTION:
ipv4only.arpa.		3485 IN	AAAA 2001:db8:1:64::c000:ab
ipv4only.arpa.		3485 IN	AAAA 2001:db8:1:64::c000:aa

Si cela ne marche pas (par exemple si on ne trouve pas les WKA comme 192.0.0.170 dans la réponse), alors la recherche du préfixe a échoué (format d'adresses inhabituel ou un truc comme ça) et on doit laisser tomber et donc ne pas faire de synthèse d'adresses IPv6 sur la machine cliente. La procédure de ce RFC ne prétend pas marcher dans tous les cas.

Au fait, pourquoi deux adresses WKA, 192.0.0.170 et 192.0.0.171 ? L'annexe B du RFC discute ce choix, dû au désir de limiter les faux positifs (par exemple si la chaîne de bits qui compose une des deux adresses apparait également dans le préfixe NAT64.)

Notons que, si le canal entre le client et le serveur DNS64 n'est pas protégé, un attaquant peut facilement informer le client avec un mauvais préfixe. On peut (sauf pour le WKP) valider l'information avec DNSSEC (je ne détaille pas ici, voir la section 3.1 du RFC).

C'est bien joli d'avoir appris le préfixe mais rappelez-vous que ce RFC propose essentiellement une heuristique : il ne donne pas de garanties. Il faut donc tester le préfixe qu'on vient d'obtenir. Après tout, des tas de choses peuvent déconner. La machine cliente peut faire les tests qu'elle veut (viser des amers publics). Mais le RFC suggère une procédure que le FAI qui a déployé NAT64 peut mettre en place. Le FAI doit configurer une machine de test (qui répond aux paquets ICMP Echo et n'a pas de limitation de trafic) et mettre deux informations dans le DNS. La machine finale fait une requête DNS de type PTR pour une adresse WKA (192.0.0.170 ou 192.0.0.171) représentée en IPv6 et traduite au format ip6.arpa. Puis elle fait une requête de type A sur le nom obtenu et cela donne l'adresse de la machine de test du FAI, si celui-ci a suivi les recommandations de notre RFC. Avec les exemples de préfixes plus haut, on utilisera l'adresse 2001:db8:1:64::192.0.0.170, la requête PTR portera sur a.a.0.0.0.0.0.c.0.0.0.0.0.0.0.0.4.6.0.0.1.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa et, si elle renvoie le nom ping.example.net, la requête A portera sur ce nom. Mettons qu'on obtienne 192.0.2.33, on synthétisera 2001:db8:1:64::192.0.2.33 et on verra bien si ça marche. (L'annexe A du RFC contient un exemple complet de fichier de zone DNS standard utilisant cette technique.)

Par contre, les clients ne doivent pas faire de tests de connectivité avec les adresses obtenues en interrogeant ipv4only.arpa. (Elles ne sont pas censées répondre.)

Notre RFC rappelle aussi que cette technique ne change rien au fait que NAT64 est fondamentalement un bricolage provisoire, que le résultat est « mieux que rien » mais que la bonne solution est évidemment le passage généralisé à IPv6.

Ah, et, pendant qu'on parle de ce que configure localement le FAI, le RFC n'interdit pas des déploiements de NAT64 où les clients utilisent un autre nom que ipv4only.arpa, par exemple si le FAI veut ne dépendre que de ses propres noms (ipv4only.example.net).

Les sections 4 et 5 donnent quelques conseils pratiques pour le déploiement de l'infrastructure nécessaire. Ainsi, le domaine ipv4only.arpa devra avoir un long TTL, au moins une heure, pour bénéficier des caches. Il doit être signé avec DNSSEC.

Comme pour toutes les techniques de transition (ici, d'IPv4 vers IPv6), l'IETF impose une description d'une stratégie de sortie. Comment fera t-on lorsque NAT64 et DNS64 ne seront plus nécessaires ? La section 6 demande que les machines terminales qui ont la possibilité de découvrir le préfixe NAT64, et de synthétiser elles-mêmes les adresses IPv6, aient un mécanisme pour couper cette possibilité, le jour où elle sera abandonnée.

Enfin, un peu de bureaucratie IANA en section 8. Le domaine « spécial » ipv4only.arpa a été enregistré selon les règles des RFC 3172, et RFC 6761 mais il ne nécessite pas de traitement spécifique par les logiciels. Il a été placé dans le registre des noms spéciaux. Les adresses WKA, elles, ont été enregistrées selon les règles des RFC 5736 (qui gère 192.0.0.0/24) et RFC 6890. Elles sont donc désormais dans le registre des adresses spéciales.

Il existe au moins une mise en œuvre de NAT64 qui inclus la technique de découverte de préfixe de ce RFC.


Téléchargez le RFC 7050


L'article seul

RFC 7066: IPv6 for 3GPP Cellular Hosts

Date de publication du RFC : Novembre 2013
Auteur(s) du RFC : J. Korhonen (Renesas Mobile), J. Arkko (Ericsson), T. Savolainen (Nokia), S. Krishnan (Ericsson)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 5 novembre 2013


Il y a désormais des tas d'engins mobiles connectés à l'Internet, par la 3G ou bientôt par la 4G (mon Dieu, je mets des termes marketroïdo-publicitaires sur mon blog...) Les spécifications de ces protocoles imposent normalement IPv6 mais, en pratique, on ne trouve quasiment jamais d'IPv6 sur ces réseaux mobiles (tiens, le RFC utilise le terme états-unien, cellular). D'ailleurs, ça veut dire quoi « gérer IPv6 » pour ces engins ? Quels sont, parmi les nombreux RFC sur IPv6, ceux qu'il faut absolument mettre en œuvre ? Les caractéristiques du monde mobile (capacité réseau très limitée, par exemple) ont-elles des conséquences particulières pour IPv6 ? Ce RFC fait le point sur « IPv6 sur réseaux mobiles ». Il succède au RFC 3316, qui avait été le premier, en 2003, à se lancer dans ce travail.

Ces technologies de réseaux mobiles permettent à un appareil comme le smartphone d'avoir, lui aussi, une connexion permanente à l'Internet, comme l'ADSL le permet aux machines fixes. Cela a commencé avec le GPRS, puis l'UMTS et quelques autres techniques. Résultat, des centaines de millions d'engins mobiles sont connectés et chacun a besoin d'une adresse IP. IPv4 n'y suffit plus depuis longtemps, et, aujourd'hui, avoir un accès Internet sur son mobile impose quasiment toujours d'être coincé avec une adresse privée (RFC 1918). D'où l'intérêt d'IPv6, qui permettra à chaque machine d'avoir son adresse publique. UMTS a apparemment été le premier réseau mobile où IPv6 était mentionné dans la spécification. Pour les réseaux EPS/LTE, voir le RFC 6459.

Normalement, « avoir IPv6 », pour une machine terminale, est facile à définir. Cela veut dire respecter les règles du RFC 6434, qui rassemble en un document la liste des exigences. D'ailleurs, notre RFC 7066 ne prétend pas remplacer ce RFC 6434 : il le complète, pour préciser les points spécifiques aux réseaux mobiles (« cellulaires », comme si on était en prison). Il vise surtout les programmeurs qui vont mettre ou maintenir IPv6 dans Android, iOS, etc. À noter que le RFC distingue trois types de machines terminales connectées aux réseaux mobiles :

  • Celles complètement fermées, où l'utilisateur ne peut rien changer (un téléphone classique),
  • Celles où l'utilisateur peut ajouter des applications (le smartphone typique),
  • Celles où l'accès 3G est extérieur à la machine, par exemple un ordinateur portable muni d'une clé 3G, où les applications (et même une bonne partie du système) ne savent pas qu'elles utilisent la 3G.

Ce RFC se focalise sur l'IPv6, pas sur les techniques de transition d'IPv4 vers IPv6 ou de coexistence temporaire entre les deux protocoles. Il rappelle que la meilleure technique est la « double-pile » du RFC 4213 : que chaque machine ait deux adresses, une v4 et une v6, le temps de la transition.

Le RFC commence par les exigences de base (Basic IP), celles qui s'appliquent dans tous les cas (section 2). La machine doit évidemment mettre en œuvre la norme IPv6 de base (RFC 2460), ainsi que les mécanismes de découverte du voisin du RFC 4861.

Toutefois, il faut nuancer. Dans les réseaux GPRS, UMTS et EPS, la liaison est point-à-point : une machine n'a qu'un seul voisin, déjà connu car il s'annonce comme routeur (ce routeur est appelé par des sigles pittoresques qui dépendent de la technologie utilisée, comme GGSN ou PGW). Et donc, logiquement, il n'y a pas d'adresse de niveau 2, donc pas besoin d'un protocole pour résoudre les adresses IP en adresses de niveau 2, comme le fait NDP. Même si le routeur répondait aux messages Neighbor Solicitation, sa réponse ne contiendrait pas d'adresses de niveau 2. Le mécanisme NUD (Neighor Unreachability Detection) du RFC 4861, section 7.3, reste nécessaire (des détails dans l'annexe A). Ces messages permettent de s'assurer que le voisin répond bien. Mais il ne faut pas en abuser : les engins connectés à un réseau mobile ont en général une batterie à capacité limitée. Notre RFC recommande donc, pour s'assurer que le voisin est toujours vivant, de compter avant tout sur des indications indirectes, comme le retour des paquets TCP, ou comme les réponses DNS lorsqu'on a utilisé UDP pour les questions. Avec les protocoles de téléphonie comme RTP (RFC 3550) ou SIP (RFC 3261), il faut se servir des mécanismes de rétroaction de ces protocoles, pour confirmer la joignabilité. On ne doit faire du NUD qu'en dernier recours.

Le mobile ainsi connecté doit configurer sa propre adresse IPv6 avec SLAAC (StateLess Address AutoConfiguration, RFC 4862), ce qui veut dire qu'il doit accepter les RA (Router Advertisment) envoyés d'en face. Aucun besoin de faire de la détection d'adresses dupliquées (RFC 4862, section 5.4) puisqu'on est seul sur le lien (avec le routeur). En revanche, DHCP (RFC 3315) n'est pas obligatoire, mais on peut l'utiliser, par exemple pour récupérer les adresses des serveurs SIP (RFC 3736 et RFC 3319) ou pour obtenir la délégation d'un préfixe à utiliser sur le réseau local (RFC 3633, au cas où le mobile serve lui-même de routeur pour un tel réseau, par exemple en WiFi).

Le mécanisme d'adressage est très différent de celui des réseaux fixes. Le préfixe de l'adresse est fourni par le routeur et est unique par connexion 3G. Le suffixe est également choisi par le routeur, en général au hasard, il n'y a pas d'adresse MAC en dur dans l'engin mobile. L'annexe A rappele les particularités de l'adressessage IPv6 en 3G.

Le mobile doit également savoir trouver les adresses des résolveurs DNS avec SLAAC, comme normalisé dans le RFC 8106. Certes, ces adresses sont normalement transmises au mobile en 3G, sans passer par un protocole IP, mais il peut y avoir sur le trajet des intermédiaires qui ont du mal à passer cette option.

À ce sujet, on a parfois du PPP (RFC 1661) entre le mobile et un autre équipement, notamment dans le cas d'ordinateurs avec clé 3G. Dans ce cas, il faut utiliser le protocole de contrôle PPP pour IPv6, IPv6CP, normalisé dans le RFC 5072.

Des problèmes de vie privée ? Forcément, oui. Un mobile étant mobile, pouvoir le suivre à la trace serait très intéressant pour certains, et néfaste pour la vie privée de son propriétaire. Il est donc recommandé de mettre en œuvre les adresses temporaires du RFC 4941 mais lisez plus loin, la question de l'adressage IPv6 sur les réseaux 3G est plus compliquée qu'elle n'en a l'air. Comme le rappelle la section 7, la partie spécifique à la machine (Interface Identifier) de l'adresse IPv6 est donnée par le réseau, elle n'est pas une propriété constante de la machine (comme l'est une adresse Ethernet) et le suivi à la trace via les adresses 3G est donc nettement moins possible. En fait, c'est plutôt le préfixe et pas le suffixe qui identifie une machine, car il reste constant pendant le déplacement.

Et une dernière chose à bien garder en tête : la MTU. Les réseaux mobiles utilisent beaucoup de tunnels et les paquets peuvent donc avoir une taille maximum plus faible que prévue. Il est donc impératif que les mobiles tiennent compte de l'option MTU dans les messages RA (section 4.6.4 du RFC 4861).

Une fois ces questions de base réglées et correctement mises en œuvre dans le mobile, le RFC a encore deux courtes sections. La section 3 concerne la sécurité. Elle rappelle qu'IPsec n'est pas obligatoire (bien que, évidemment, son usage sécuriserait tout le trafic du mobile, avant son envoi sur les ondes radio). Elle note aussi qu'un mobile peut s'attendre à recevoir des paquets fragmentés, que ceux-ci posent des problèmes de sécurité fréquents, et qu'il faut donc suivre les RFC 5722 et RFC 6980. La sécurité est également discutée en section 7.

La dernière section d'exigences, la section 4, concerne la mobilité. Dans le monde 3G, elle est gérée par les couches basses et il n'est donc pas du tout nécessaire de mettre en œuvre les techniques de mobilité IP (par exemple celles du RFC 5555).

L'annexe B résume les changements depuis le RFC 3316. Rien de révolutionnaire, essentiellement des clarifications, l'ajout de technologies récentes comme la découverte des résolveurs DNS par le RFC 6106, beaucoup de points liés à la sécurité, suite au RFC 6583, etc.

Je ne fournis dans cet article aucun exemple concret : c'est parce que les opérateurs qui font de l'IPv6 sur la 3G sont en nombre infime (aucun en France). Par exemple, regardez le dernier point fait par SFR, aucune date n'était annoncée.


Téléchargez le RFC 7066


L'article seul

Mes premiers bitcoins

Première rédaction de cet article le 4 novembre 2013


Je viens de payer, puis de dépenser, mes premiers bitcoins. Cette monnaie décentralisée, qui ne dépend pas d'un État n'est pas encore très répandue mais elle suscite l'intérêt de beaucoup, notamment par sa sémantique proche de l'argent liquide : les paiements sont « anonymes », comme on pouvait le faire avec de l'argent liquide, et la sécurité est celle des données qu'on garde sur son disque dur. Si celui-ci est en panne, l'argent disparait.

Comment obtient-on des bitcoins ? Il existe plusieurs méthodes. Profitant de la réunion IETF de Vancouver, j'ai décidé de tester le Robocoin, le premier distributeur de bitcoins du monde, installé il y a quelques jours, au café Waves, à deux blocs de l'hôtel où se tient la réunion IETF, et géré par la société Bitcoiniacs. L'appareil ressemble à un DAB :

On peut s'en servir pour retirer des bitcoins (en échange d'argent liquide) ou au contraire pour vendre ses bitcoins. On peut utiliser un portefeuille bitcoin existant ou bien en créer un. N'ayant pas encore installé les logiciels nécessaires, j'ai créé un portefeuille sur le distributeur. Celui-ci imprime alors un petit papier indiquant la clé privée du compte et un code QR. Une fois qu'on a son portefeuille, on revient à la machine, on numérise le code QR et on peut alors mettre un billet (en l'occurrence, de 20 dollars, ce qui m'a fait 0,077 bitcoins) et obtenir des bitcoins, matérialisés par un autre petit papier, contenant l'adresse du compte créé précédemment (ce dernier n'est pas indispensable sauf en cas de désaccord avec la société qui gère le Robocoin). À noter qu'il existe une sécurité supplémentaire, au cas où on oublie son papier près de l'appareil : la machine a enregistré vos empreintes digitales et les redemande à chaque utilisation.

Ensuite, on prend un café pour réfléchir, en contemplant ses deux papiers. On discute avec ses voisins. L'appareil suscite beaucoup de curiosité et les autres clients du café demandent ce que vous faites et on passe donc beaucoup de temps à expliquer. Puis on rentre chez soi chercher comment on transfère cet argent sur son ordinateur. Il existe plein de logiciels client. J'ai choisi le logiciel Electrum (oui, d'accord, sécurité modérée mais c'est pour une expérimentation). Il est très simple à utiliser. Si j'avais commencé par Electrum, je créais un portefeuille et l'indiquais au Robocoin. Mais j'ai déjà créé un portefeuille que je vois rentrer dans Electrum. N'ayant pas envie de chercher un logiciel de lecture de QR code, j'ai tapé la clé privée (menu Import -> Private keys). Electrum a ensuite automatiquement reçu la transaction et, oh, joie, mes 0,077 bitcoins sont arrivés. Si on garde le papier contenant la clé privée, par exemple pour pouvoir récupérer ses sous en cas de perte des fichiers sur l'ordinateur, il faut la ranger à l'abri des regards indiscrets !

Je n'ai plus eu ensuite qu'à les dépenser en donnant à l'EFF, qui accepte les bitcoins. Il suffit de rentrer dans Electrum (bouton Send) l'adresse Bitcoin qu'indique l'EFF .

Merci à John Levine pour avoir signalé ce distributeur de bitcoins aux participants à la réunion IETF (nous avons été quelques centaines à en profiter), et à Cryptomars pour son aide technique. Au lieu d'Electrum, j'aurais pu utiliser Multibit. Parmi les bons articles sur ce distributeur, je suggère celui de Vanessa Collette. L'appareil ayant eu une période de maintenance après mon passage, cela a permis de prendre des photos de l'intérieur. Un premier bilan après une semaine indiquait 100 000 $ échangés. À noter l'amusante façon dont un escroc a détourné ce distributeur.


L'article seul

L'IETF, l'espionnage et les protocoles Internet

Première rédaction de cet article le 2 novembre 2013


Du 4 au 8 novembre 2013 se tient à Vancouver la 88ème réunion de l'IETF. Elle verra notamment un grand nombre de discussions sur l'espionnage de masse auquel se livrent des organisations comme la NSA, et aux moyens d'adapter la sécurité de l'Internet à ce type de menaces.

Le terme important est de masse. La réalité de l'espionnage sur l'Internet est connue depuis longtemps, même si beaucoup préféraient faire l'autruche. Mais même les experts en sécurité dont tout le monde se moquait, en les traitant de « paranoïaques », n'osaient pas forcément envisager l'ampleur de l'espionnage mené par des organisations puissantes et placées en dehors de tout contrôle démocratique, comme la NSA. Grâce aux révélations d'Edward Snowden, on sait désormais que les paranoïaques ne l'étaient pas assez. Il ne s'agit pas de combattre un sniffer isolé qui écoute de temps en temps les communications (contre ce type d'attaques, l'IETF a déjà une large panoplie de techniques). Il s'agit de faire face à un attaquant très puissant, qui peut se permettre d'écouter beaucoup de gens, tout le temps. Ce type d'attaques, qui a déjà un nom en jargon IETF, le pervasive monitoring, nécessite de repenser la sécurité de l'Internet.

Bien sûr, le problème est surtout politique, et c'est sur le champ politique qu'il va essentiellement se jouer. La technique seule ne peut pas grand'chose contre un attaquant qui contrôle autant de leviers. Mais, à une réunion IETF, il est normal qu'on se pose la question « Que peut faire l'IETF ? » Il y a deux axes importants :

  • Défendre les normes IETF contre les attaques visant à affaiblir délibérement leur sécurité pour faciliter l'écoute. Parmi les révélations de Snowden, en effet, se trouvait la preuve que des processus de normalisation étaient subvertis par la NSA pour lui faciliter la tâche (notamment l'affaire du générateur aléatoire du NIST). Faut-il changer les processus IETF pour diminuer ce risque ?
  • Rendre l'Internet plus résistant à l'espionnage.

Le premier axe a déjà été évoqué, par exemple par Jari Arkko, président de l'IETF, dans un exposé au RIPE à Athènes expliquant qu'il n'y avait sans doute pas trop de risque de subversion d'un processus de normalisation IETF. Contrairement à des organismes gouvernementaux comme le NIST, qui ne peut rien refuser à la NSA, l'IETF a un travail complètement ouvert, les normes sont relues par des tas de gens, peu diplomates et qui n'hésitent pas à poser des questions lorsque quelque chose n'est pas clair, ou à râler lorsque la sécurité semble en danger. Il serait difficile, dans une telle maison de verre, de glisser des modifications affaiblissant la sécurité.

Le second axe est un gros travail, déjà baptisé d'un nom de code IETF, « Internet hardening ». Il s'agit de durcir l'Internet, de le rendre moins aisé à écouter (ce qui voudra sans doute dire aussi, moins aisé à utiliser). Le projet a été exposé dans un article d'Arkko. À Vancouver, il fera l'objet notamment de la réunion plénière technique. Celle-ci, qui se tiendra le mercredi 8 novembre et sera diffusée en ligne, verra les exposés suivants :

  • Bruce Schneier expliquera ce qu'on sait et ce qu'on ne sait pas sur la surveillance généralisée. Malgré les révélations de Snowden, nous n'avons pas encore tous les détails et nous devons définir des techniques contre des attaques que nous ne connaissons pas toutes.
  • Brian Carpenter rappellera que l'IETF a déjà travaillé sur des sujets liés à l'espionnage et à la vie privée, par exemple dans les RFC 1984 et RFC 2804 (où l'IETF dit clairement qu'il ne faut pas architecturer le réseau pour faciliter les écoutes, contrairement à ce que fait l'UIT avec son projet NGN qui inclut un volet LI - Legal Interception), le RFC 3365 (sur l'importance de prendre en compte la sécurité dans les protocoles Internet), et le RFC 6973, qui est le premier à décrire une politique globale de protection de la vie privée dans les protocoles IETF. Je ne sais pas si Carpenter en parlera mais les RFC ne sont pas tous aussi honorables et il faudrait peut-être aussi mentionner le RFC 3924...
  • Stephen Farrell résumera le travail du groupe informel PERPASS. Ce groupe n'est pas un groupe de travail officiel de l'IETF car ceux-ci ont toujours des tâches bien précises, avec un calendrier. PERPASS a une activité plutôt exploratoire, regarder ce qu'on peut faire pour améliorer la résistance de l'Internet à l'espionnage.

Le groupe PERPASS a déjà vu passer plusieurs documents. Ainsi, http://tools.ietf.org/id/draft-tschofenig-perpass-surveillance, de Hannes Tschofenig décrit les menaces. Il différencie les attaques exploitant une faille du protocole, celles exploitant une faiblesse de la cryptographie, celles exploitant une bogue dans une mise en œuvre, et celles enfin qui s'appuient sur des mauvais choix lors du déploiement. Les premières sont les seules à être complètement du ressort de l'IETF. Par exemple, la faille BEAST était une faille du protocole TLS et a été réparée par le RFC 4346. Dans ce cas, la correction était assez simple. C'est plus difficile lorsque des choix d'architecture ont été faits : on ne peut pas en général les remettre en cause. Ainsi, le fait que les serveurs DNS (même ceux de la racine) reçoivent le nom complet du site auquel on veut accéder est certainement une faiblesse, pour la protection de la vie privée, mais ne peut pas être modifié, sauf à remplacer le DNS par un protocole nouveau et incompatible. Le draft cite aussi d'autres responsabilités de l'IETF : par exemple, peu de fournisseurs de voix sur IP ont déployé des mécanismes de protection cryptographiques mais l'IETF ne leur a certainement pas facilité la tâche en ayant pas moins de trois mécanismes de sécurisation concurrents. Et puis, déployer la sécurité a posteriori sur un protocole qui ne l'avait pas au début, est toujours difficile. (D'un autre côté, les protocoles qui ont la sécurité dès le début ne sont en général pas déployés du tout, car ils sont trop pénibles à utiliser.)

Mais les failles menaçant la vie privée ne sont pas en général dans les protocoles et le problème dépasse donc les seuls moyens de l'IETF. Ainsi, les protocoles IETF sécurisés dépendent en général de la cryptographie mais l'IETF elle-même ne fait pas de cryptographie, elle s'appuie sur des normes extérieures existantes. Par exemple, l'IETF a souvent suivi les recommandations du NIST, alors qu'on sait maintenant que cet organisme sabotait ses propres normes sur ordre de la NSA. La plupart des protocoles IETF sont « crypto-agiles » ce qui signifie que le protocole n'est pas lié à un seul algorithme cryptographique mais peut en changer. Cela permet d'abandonner un algorithme dont on sait qu'il est cassé mais cela ne dit pas quels algorithmes sont dangereux, car affaiblis délibérement par la NSA.

Et, bien sûr, il y a la mise en œuvre du protocole. Il y a nettement plus de bogues dans les programmes que de failles dans les protocoles. Écrire ces programmes n'est pas le rôle de l'IETF mais celle-ci a quand même une responsabilité : offrir aux programmeurs des spécifications claires, sans ambiguité et lisibles. Outre les bogues accidentelles, les réalisations concrètes des protocoles IETF ont aussi des faiblesses dues à des mauvais choix de sécurité. Ainsi, livrer une machine avec un mot de passe par défaut, dont on sait bien que la plupart des utilisateurs ne le changeront pas, n'est pas formellement une bogue mais cela a un effet désastreux sur la sécurité de l'Internet. Le draft fait aussi remarquer qu'évidemment, les programmes dont le code source n'est pas publié sont bien plus dangereux, d'autant plus qu'ils peuvent contenir des portes dérobées (trois ont été découvertes dans des routeurs dans les deux semaines précédant la réunion IETF).

Enfin, le draft de Tschofenig fait remarquer que même avec des protocoles parfaits, de la cryptographie sans faille et des programmes sans bogues, le déploiement effectif peut introduire des vulnérabilités et il cite le cas d'architectures où plusieurs serveurs sont utilisés pour contribuer à rendre le service (multi-tier) et où les communications entre ces serveurs ne sont pas sécurisées (ce qui était le cas de Google il y a peu, et avait fait l'objet du programme MUSCULAR de la NSA).

Un autre document PERPASS, pas encore officiellement publié, est le draft-huitema-perpass-analthreat de Christian Huitema. Il fait le tour des menaces, analysant ce qu'il est possible de faire en exploitant les protocoles Internet, notamment les fameuses métadonnées. Par exemple, pour le traditionnel téléphone, la simple connaissance de qui parle à qui, même sans accéder au contenu des communications, permet déjà de connaître le graphe des relations. La quantité de trafic, elle, permet de savoir que quelque chose se prépare. Bref, la collecte des métadonnées est une vraie menace pour la vie privée (section 2 du draft). Dans le monde IP, des données comme celles récoltées par NetFlow (RFC 3954), adresses IP source et destination, quantité de données échangées, présentent les mêmes dangers.

Huitema analyse aussi la liaison entre une adresse IP et une personne. Traditionnellement, c'était fait en demandant au FAI de fournir les informations « lequel de vos abonnés avait l'adresse 192.0.2.49 hier à 20:13 ? » Mais il note bien (section 4) qu'il existe d'autres méthodes de lier l'adresse IP à une identité, par exemple l'examen des sites Web visités, qui, ensemble, forment une véritable signature d'un individu. Autre exemple, l'analyse des en-têtes Received: dans les courriers électroniques permet de récupérer ce lien entre une adresse IP (en général explicitement indiquée) et une adresse de courrier donc sans doute un individu.

Huitema envisage aussi les solutions (section 5). S'il n'y a guère d'espoir d'empêcher techniquement l'espionnage, on peut en tout cas le rendre plus pénible et plus coûteux. D'abord, il faut développer le chiffrement. L'analyse des en-têtes Received: mentionnée plus haut serait plus difficile si SMTP utilisait systématiquement TLS (RFC 3207). On pourrait aussi, même si cela rendra le déboguage plus difficile, rendre ces en-têtes moins bavards, par exemple en n'indiquant pas l'adresse IP de l'émetteur original. Peut-être aussi faudrait-il revenir de la tendance à avoir des adresses IP stables : si elles changeaient souvent, cela serait moins pratique pour l'utilisateur mais cela rendrait le traçage plus difficile. On pourrait aussi utiliser le multi-homing de manière plus créative, en envoyant une partie des paquets d'un flot par un lien et le reste par un autre lien, rendant la reconstitution du flot plus difficile. Il y a aussi des idées plus futuristes (et qui ne font pas l'objet pour l'instant d'une spécification rigoureuse) comme de modifier l'architecture de l'Internet pour le rendre « sans source ». L'en-tête des paquets IP ne porterait plus que l'adresse destination, pas la source, celle-ci serait contenue plus loin dans le paquet, chiffrée, pour les cas où on veut une réponse (la plupart des usages).

Parmi les documents PERPASS, le Internet draft draft-hardie-perpass-touchstone de Ted Hardie choisit une autre question : comment évaluer la sécurité des systèmes ? Un système peut être sûr pour protéger une information triviale d'un script-kiddie mais pas pour protéger des informations cruciales contre la NSA. Et, entre les deux, il y a plein d'intermédiaires. Hardie propose donc un test de Litmus pour discuter des futurs protocoles IETF : « est-ce qu'un homosexuel en Ouganda peut l'utiliser sans craindre pour sa sécurité ? » L'Ouganda a été choisi pour deux raisons : c'est un pays où il y a une répression active (y compris par la loi) de l'homosexualité, et c'est un pays pauvre, où on peut être tenté de sacrifier la sécurité aux performances. Et pourquoi l'homosexualité ? Parce que, comme le note l'auteur, la surveillance mène à l'auto-censure, au repli sur soi, et que les jeunes homosexuels qui n'arrivent pas à rejoindre une communauté qui les soutient courent énormément de risques (dont le suicide). Si la réponse au test est Oui, cela ne signifie pas que le système résistera à la NSA ou à un autre attaquant déterminé, mais qu'il sera suffisant pour une très large variété d'usages.

Autres lectures sur cette réunion et sur le rôle de l'IETF :


L'article seul

RFC 7039: Source Address Validation Improvement Framework

Date de publication du RFC : Octobre 2013
Auteur(s) du RFC : Jianping Wu, Jun Bi (Tsinghua University), Marcelo Bagnulo (UC3M), Fred Baker (Cisco), Christian Vogt (Ericsson)
Pour information
Réalisé dans le cadre du groupe de travail IETF savi
Première rédaction de cet article le 1 novembre 2013


Une des choses agaçantes sur l'Internet est qu'il est trivial de tricher sur son adresse IP source. Une machine qui a comme adresse 2001:db8:1:2::42 peut parfaitement émettre un paquet où l'adresse IP source est 2001:db8:9fe:43::1 et, là plupart du temps, ce paquet arrivera à destination (le routage ne se fait que sur la destination, pas sur la source), trompant le récepteur sur la vraie source de l'envoi. Cette faiblesse a donc des tas de conséquences pour la sécurité. Il existe des bonnes pratiques documentées pour empêcher l'émission de tels paquets (RFC 2827 et RFC 3704) mais elles sont peu déployées en pratique. Le projet SAVI (Source Address Validation Improvement) vise à propose des mécanismes pour rendre plus difficile l'utilisation d'adresses IP usurpées. Ce document est son cadre général, exposant les principes.

Les attaques possibles sont documentées dans le RFC 6959, qui explique la portée du projet SAVI. Les deux RFC cités plus haut, collectivement connus sous le nom de « BCP 38 » (RFC 2827 et RFC 3704), assurent, lorsqu'ils sont déployés, une validation de la source avec pour granularité celle d'un préfixe IP. Ainsi, un FAI dont les adresses IP sont en 2001:db8:1::/32 peut empêcher un de ses clients de sortir avec l'adresse 2001:db8:9fe:43::1 (qui n'est pas dans le même préfixe) mais BCP 38 ne traite pas le cas où le client 2001:db8:1:2::42 veut usurper 2001:db8:1:2:73:66:e5:68 (même préfixe). Il existe des mécanismes privés pour traiter ce cas (comme le Source Guard de Cisco) mais pas encore de norme. C'est le but de SAVI.

Son principe (section 2) est que tout est fait dans le réseau, pas dans les machines (puisque celles-ci peuvent être sous le contrôle d'un méchant). Il y a trois étapes dans une validation SAVI :

  • Déterminer les adresses IP légitimes pour une machine,
  • Attacher ces adresses IP à une propriété au niveau 2, propriété qui doit être difficile à usurper. Cela peut être par exemple le port physique du commutateur.
  • Tester que les paquets ayant cette adresse source obéissent bien à cette propriété.

C'est vague ? Parce que ce n'est qu'un modèle. D'autres RFC, par exemple le RFC 6620, spécifieront rigoureusement cet attachement entre une adresse IP et une propriété de la couche 2. Le RFC 6620 prévoit que le commutateur note les adresses IP source utilisées et refuse ensuite les paquets ayant cette adresse source (le principe est donc « premier arrivé, premier servi ») sauf si un test montre que l'adresse n'est plus joignable sur l'ancien port.

L'entité qui accomplit les trois étapes ci-dessus est appelée « instance SAVI ». Dans l'exemple donné, c'est le commutateur mais cela peut aussi être un routeur ou un autre équipement. C'est typiquement le commutateur qui est le mieux placé pour vérifier les adresses locales (le routeur a du mal à empêcher une machine d'usurper l'adresse d'une autre machine du même lien). Le principe de base est que SAVI est d'autant mieux mis en œuvre qu'on est proche de la source des paquets. Si on s'éloigne :

  • Il est plus difficile de déterminer les adresses légitimes,
  • On n'a plus de propriétés de niveau 2 à attacher à une adresse,
  • On protège moins puisque la machine menteuse pourra toujours parler aux machines proches.

Toutefois, SAVI prévoit le cas où on ne peut pas utiliser la solution idéale (par exemple parce que le commutateur où sont connectées les machines est pré-SAVI et ne gère pas ce RFC), et où on se contente d'une solution imparfaite. Notez qu'un certain nombre de commutateurs ont déjà des fonctions analogues à SAVI, mais de manière non-standard.

La section 3 couvre ces options de déploiement. Toute solution SAVI concrète va dépendre du mécanisme d'allocation d'adresses (le RFC 7513 couvre le cas de DHCP et le RFC 6620 celui des adresses auto-attribuées, par exemple via le RFC 4862) et des caractéristiques de la couche 2. Pour le mécanisme d'allocation d'adresse, il faut noter que plusieurs mécanismes peuvent coexister sur un même lien (section 6).

Pour l'attachement d'une adresse IP à une propriété de couche 2, on a le choix :

  • Adresse MAC (déconseillé par le RFC car trop facile à usurper),
  • Port physique du commutateur (attention, il peut y avoir plusieurs machines derrière un port),
  • Association de sécurité WPA entre une machine et sa base, pour un lien WiFi,
  • Identifiant d'une session PPP,
  • Identifiant du tunnel, si la machine est connectée via GRE, MPLS, etc.

Chacun de ces cas va nécessiter une incarnation concrète des principes de ce RFC 7039.

Comme souvent en sécurité, le déploiement de la sécurisation va créer de nouveaux problèmes et de nouveaux motifs de panne. La section 5 en expose certains. Par exemple, un commutateur qui mémorise une association adresse<->port et qui redémarre perd ces associations et va alors se mettre à refuser tous les paquets, avant de réapprendre les associations. Ou bien une machine change brusquement de port et, pendant un moment, ne peut plus communiquer. SAVI doit donc prévoir des mécanismes de rattrapage, par exemple, lorsque beaucoup de paquets sont refusés, tester si l'adresse IP est unique sur le lien et, si oui, en déduire que c'était bien la machine légitime qui émettait. (À noter que ces mécanismes sont mis en défaut si la machine légitime était éteinte à ce moment.)

Comme noté par la section 7, une machine SAVI a aussi intéret à connaître le préfixe IP légitime du lien, pour faire un test supplémentaire de validité. Elle peut le faire par configuration explicite, en écoutant les annonces RA (Router Advertisment) du routeur IPv6, en écoutant les messages DHCP de délégation de préfixe, … (RFC 7513)

N'espérez pas de miracle de SAVI. La section 10, qui résume l'analyse de sécurité, note bien que SAVI rend l'usurpation plus difficile mais ne « prouve » pas l'adresse IP source, au sens où une signature cryptographique prouve l'authenticité d'un document, par exemple. Si on veut faire mieux, il faut passer à des protocoles avec authentification cryptographique de la source (comme HIP).

Notez que SAVI a une longue histoire à l'IETF, chaude et contestée. Le projet se nommait auparavant SAVA (Source Address Validation Architecture, cf. RFC 5210) et avait des objectifs bien plus ambitieux, au point de faire peur à beaucoup, d'autant plus que les propositions venaient de Chine. L'ancien SAVA prévoyait un cadre englobant tout l'Internet, avec intégration de « BCP 38 » (RFC 2827 et RFC 3704) et communication entre opérateurs pour garantir la validation de bout en bout. À la réunion IETF de Prague en 2008, SAVA s'était fait chaudement allumer. Personne n'avait osé le dire tout haut pendant la réunion mais la salle bruissait de « on ne va pas changer l'architecture de l'Internet pour faire plaisir aux communistes ». Le seul orateur à mentionner ce problème l'avait fait diplomatiquement en disant que SAVA risquait d'amener dans Internet des préoccupations qui sont traditionnellement celles des telcos (comme la facturation à l'usage). SAVI est donc désormais la version light, plus focalisée du point de vue technique, et avec acceptation du fait que tout le monde n'a pas envie d'être fliqué (SAVI soulève quand même plein de problèmes pour la vie privée, qui ne sont pas traités dans ce RFC).


Téléchargez le RFC 7039


L'article seul

Un problème DNSSEC : pas assez de NSEC3

Première rédaction de cet article le 24 octobre 2013


C'est une banalité que de noter que DNSSEC est complexe. Heureusement, cette complexité est souvent cachée par les outils utilisés. Mais, parfois, elle resurgit lorsque quelque chose ne marche pas. C'est le cas à l'instant du tout nouveau TLD .онлайн, dont les enregistrements NSEC3 sont insuffisants.

.онлайн s'écrit en Punycode xn--80asehdb. Comme tous les nouveaux TLD, il est signé avec DNSSEC. Interrogeons un résolveur DNS qui valide avec DNSSEC, un du ODVR :


% dig @149.20.64.20   SOA xn--80asehdb

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @149.20.64.20 SOA xn--80asehdb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44970
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 5, ADDITIONAL: 9

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;xn--80asehdb.		IN SOA

;; ANSWER SECTION:
xn--80asehdb.		84319 IN SOA anycast10.irondns.net. secretariat.corenic.org. (
				1310231925 ; serial
				21600      ; refresh (6 hours)
				3600       ; retry (1 hour)
				604800     ; expire (1 week)
				86400      ; minimum (1 day)
				)
xn--80asehdb.		84319 IN RRSIG SOA 10 1 86400 20131106172547 (
				20131023172547 38327 xn--80asehdb.
				ZUg0BUeRcEyTuyUmhcUC95U/iSd8/6GQS1D7k8YnADJa
				QV1nBPJ+9EOW7ycMKtg0XokKl+i8SqlCLqOs2mUs6nFg
				p9jB/T1sUar/w1QAjtClM9JcIliXC7AdDi4bmg5G15yX
				rgkrdgXrm/8kyUEbMUlto6LNdBz/IYP5fS4hlvo= )
...
;; Query time: 215 msec
;; SERVER: 149.20.64.20#53(149.20.64.20)
;; WHEN: Thu Oct 24 16:20:02 2013
;; MSG SIZE  rcvd: 726

Bon, tout va bien, on obtient bien l'enregistrement SOA demandé, et la réponse inclut le bit AD (Authentic Data) montrant que la validation s'est bien faite. Des outils de tests plus sophistiqués comme Zonecheck ne montrent pas non plus de problèmes. Mais ils ne testent pas assez. Cherchons cette fois un nom qui n'existe pas, www.xn--80asehdb :


% dig @149.20.64.20   SOA www.xn--80asehdb

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @149.20.64.20 SOA www.xn--80asehdb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 38016
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;www.xn--80asehdb.	IN SOA

;; Query time: 744 msec
;; SERVER: 149.20.64.20#53(149.20.64.20)
;; WHEN: Thu Oct 24 16:20:20 2013
;; MSG SIZE  rcvd: 45

Aïe ! On n'a pas le NXDOMAIN qu'on attendait mais un SERVFAIL qui semble indiquer un problème DNSSEC. Pour être sûr, demandons au résolveur de tester sans validation, avec l'option CD (Checking Disabled) :


% dig +cd @149.20.64.20   SOA www.xn--80asehdb

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> +cd @149.20.64.20 SOA www.xn--80asehdb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 28571
;; flags: qr rd ra cd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;www.xn--80asehdb.	IN SOA

;; AUTHORITY SECTION:
xn--80asehdb.		0 IN SOA anycast10.irondns.net. secretariat.corenic.org. (
				1310231925 ; serial
				21600      ; refresh (6 hours)
				3600       ; retry (1 hour)
				604800     ; expire (1 week)
				86400      ; minimum (1 day)
				)
xn--80asehdb.		0 IN RRSIG SOA 10 1 86400 20131106172547 (
				20131023172547 38327 xn--80asehdb.
				ZUg0BUeRcEyTuyUmhcUC95U/iSd8/6GQS1D7k8YnADJa
				QV1nBPJ+9EOW7ycMKtg0XokKl+i8SqlCLqOs2mUs6nFg
				p9jB/T1sUar/w1QAjtClM9JcIliXC7AdDi4bmg5G15yX
				rgkrdgXrm/8kyUEbMUlto6LNdBz/IYP5fS4hlvo= )
1kj9h96b2lh023ss088d4sv4fldblii8.xn--80asehdb. 0 IN RRSIG NSEC3 10 2 43200 20131106172200 (
				20131023172200 38327 xn--80asehdb.
				ConuMwi7xtPhtcwzZxH9+hrjE1yGVwYp7ql8nWbiUDqh
				AjUyzisxCjGUwSjiFTESUFMVnVuhd38Ns89pWxOfevPo
				jFVCo9kyNhZJ/OlIFTPto/Fi2gTsWiug/RDOD4rQ+66T
				Jr0GNZQFQHN/TEb7OywBKXWw9DegLyFRdbBdlaA= )
1kj9h96b2lh023ss088d4sv4fldblii8.xn--80asehdb. 0 IN NSEC3 1 0 12 7740536091A63907 HFVHO12QAPRRRKQ16K4R241K2OE81BLP NS SOA RRSIG DNSKEY NSEC3PARAM

;; Query time: 280 msec
;; SERVER: 149.20.64.20#53(149.20.64.20)
;; WHEN: Thu Oct 24 16:20:31 2013
;; MSG SIZE  rcvd: 557

Là, tout a marché. Aucun doute, c'est un problème DNSSEC. Mais lequel ? (Je triche, Mark Andrews a donné l'explication sur la liste dns-operations, je n'ai pas trouvé tout seul.) C'est parce que l'enregistrement NSEC3 ci-dessus, 1kj9h96b2lh023ss088d4sv4fldblii8.xn--80asehdb, ne couvre pas tout, seulement l'apex. Il faut plusieurs enregistrements NSEC3 pour prouver une non-existence. Les enregistrements NSEC3, normalisés dans le RFC 5155 sont considérés, à juste titre, comme une des parties les plus terribles de DNSSEC, et ce RFC comme un des plus difficiles à lire. Essayons quand même de comprendre. D'abord, récupérons les paramètres réglables de NSEC3 pour ce TLD :

% dig +short NSEC3PARAM xn--80asehdb
1 0 12 7740536091A63907
...

Donc, le sel est 7740536091A63907, l'algorithme de condensation 1 et il faut faire 12 itérations. Calculons ce que ça donne pour l'apex de la zone :

% nsec3hash 7740536091A63907 1 12 xn--80asehdb 
1KJ9H96B2LH023SS088D4SV4FLDBLII8 (salt=7740536091A63907, hash=1, iterations=12)

(Cet outil est livré avec BIND.) Bon, c'est bien la partie gauche de l'enregistrement NSEC3. Sa partie droite était HFVHO12QAPRRRKQ16K4R241K2OE81BLP. Et quel était le NSEC3 du nom qu'on demandait ?

% nsec3hash 7740536091A63907 1 12 www.xn--80asehdb 
VFAQP7GOV8SECOUA5KL7QMUPU09ABPF3 (salt=7740536091A63907, hash=1, iterations=12)

Et voilà l'explication du problème. Le condensé VFAQP7GOV8SECOUA5KL7QMUPU09ABPF3 n'est pas entre 1KJ9H96B2LH023SS088D4SV4FLDBLII8 et HFVHO12QAPRRRKQ16K4R241K2OE81BLP, le résolveur validant ne peut donc pas valider. Il faudrait en fait plusieurs enregistrements NSEC3, pas seulement celui qui couvre l'apex. Regardez avec un autre TLD signé comme .fr :


% dig SOA nexistepasdutout.fr

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> SOA nexistepasdutout.fr
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 16892
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 1

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

;; AUTHORITY SECTION:
fr.			5400 IN	SOA nsmaster.nic.fr. hostmaster.nic.fr. (
				2222302497 ; serial
				3600       ; refresh (1 hour)
				1800       ; retry (30 minutes)
				3600000    ; expire (5 weeks 6 days 16 hours)
				5400       ; minimum (1 hour 30 minutes)
				)
fr.			5400 IN	RRSIG SOA 8 1 172800 20131223203009 (
				20131024193009 62646 fr.
				DaGlS0gg6ZdrpPAlrGgTLnX7YIpuNy+drz9PXug4OQop
				DFDNbn5RGCyHaAwGI2C97F/unRNfJWxfJbvahKXjSxUk
				h1TV/HuJNR7NQ7B7ZbQhrXM+WJJOG2HMfM0ZjbuV7EDj
				i65zhfM4y+a9gxEofMtFpxvG/GLtmkToq0XYT5s= )
gbncp12fmut57r0t7oncls9uqlmlodmk.fr. 5400 IN RRSIG NSEC3 8 2 5400 20131222134010 (
				20131023124010 62646 fr.
				YMskIKa5wXIfNeM7nFuS+t7CrkIBj8yDbViY/UFaJHyY
				Fi6DluzDmzMro1P9JGtjMfOyCoHzELF/ypyP1AbD6gl6
				Q+8M+pWFaVcAqw2YM8gj5tTs/EaeBHkRt5LN+ieP46em
				24eW00n3hYVbbPzH16675tHQc6AQhKHV8XPilrE= )
gbncp12fmut57r0t7oncls9uqlmlodmk.fr. 5400 IN NSEC3 1 1 1 BADFE11A GBO5LRV9JCF6S1Q2IULLHM3S2E0HFNKT NS DS RRSIG
meqimi6fje5ni47pjahv5qigu1lv3jlj.fr. 5400 IN RRSIG NSEC3 8 2 5400 20131217141424 (
				20131018141424 62646 fr.
				HSlFBLGerg9v8cVNw/QtYfw9gtCxqsx4EI9GcL9loqUg
				FzYrpbEp/1Du6h3me1zmxY1QvywljEUqnYBVFN9S3JC2
				jDqxY+/xoHauiiz7ZCIWKaMT7UIo5o4Q/i+II1QfGRj1
				YoSZfH/qjASnitYaRse2rDa8R2MmZ9Hn56nO9j0= )
meqimi6fje5ni47pjahv5qigu1lv3jlj.fr. 5400 IN NSEC3 1 1 1 BADFE11A MER9S1NKQCO41NBRBJLTPKQ93HEONLR8 NS SOA TXT NAPTR RRSIG DNSKEY NSEC3PARAM
s450cin37ia3u7s37vsnc0po8vj2igth.fr. 5400 IN RRSIG NSEC3 8 2 5400 20131217141424 (
				20131018141424 62646 fr.
				bU6ZhqlPC0h6hf8xLqAtzpgkqyrHL/OZNJOlzUutjreL
				mL34i00G9eWIUAsjvKC2PZviFkvwhAuapD7OAGcAJvMS
				o3R+KYqTSQ39AmYTX80uVSupkRHw5CGIX3g87LY7CbQ+
				TRZ+LUUoYQ8vng3Ogi2IKEJwr9FAB9SCjHNeVSk= )
s450cin37ia3u7s37vsnc0po8vj2igth.fr. 5400 IN NSEC3 1 1 1 BADFE11A S45UOSDK5KJKQABLBLSBP7B5UK3R1MSV NS DS RRSIG

;; Query time: 37 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Oct 24 22:40:14 2013
;; MSG SIZE  rcvd: 1006

On peut voir graphiquement ce problème avec DNSviz. Il faut activer l'option Denial of existence qui ne l'est pas par défaut (et peut donc rassurer à tort).

Pourquoi cette erreur ? NSEC3, on l'a dit, est très complexe. Mais on ne fabrique pas ses NSEC3 à la main ! La très grande majorité des administrateurs DNS qui utilisent DNSSEC n'auront jamais à analyser des problèmes comme celui-ci. On utilise un outil pour générer signatures et NSEC3, et aucun outil n'oublierait une partie de l'espace à protéger. Soit le registre a développé un outil à lui, ce qui serait une opération délicate et dangereuse, et c'est donc peu vraisemblable, soit quelque chose a cafouillé au moment de la publication des données.

Merci à Marco Davids pour le diagnostic initial.


L'article seul

RFC 7042: IANA Considerations and IETF Protocol and Documentation Usage for IEEE 802 Parameters

Date de publication du RFC : Octobre 2013
Auteur(s) du RFC : Donald Eastlake (Huawei), Joe Abley (ICANN)
Première rédaction de cet article le 24 octobre 2013


Les identificateurs IEEE 802 comme les adresses MAC d'Ethernet ne sont pas gérés par l'IETF et ne sont pas dans un registre IANA. C'est l'IEEE qui les distribue et en garde trace. Toutefois, certains protocoles IETF dépendent de ces identificateurs et ce RFC documente cet usage. Il décrit l'OUI (Organizationally Unique Identifier) attribué à l'IANA, le 00-00-5E, et indique à quoi il peut servir et comment. Ce nouveau RFC remplace l'ancien RFC 5342, avec quelques changements importants.

Parmi les exemples d'utilisation d'identificateurs IEEE 802, on peut citer les adresses d'IPv6 qui, en auto-configuration sans état, sont dérivées de l'adresse MAC. Ou bien les types de paquets Ethernet comme 0x0800 pour IPv4 et 0x86DD pour IPv6. Mais la plus grande partie de ce RFC est consacrée à l'OUI (Organizationally Unique Identifier) de l'IANA, et comment allouer des identificateurs commençant par cet OUI. Ce RFC en écrit certains, comme ceux réservés à la documentation. Fini de choisir des adresses Ethernet au hasard lorsqu'on rédige un cours ou un manuel sur ARP ! Normalement, depuis la publication de notre RFC, on utilise désormais des adresses prévues à cet effet, suivant les recommandations des RFC 2606 et RFC 5737.

On l'a dit, c'est l'IEEE qui tient le registre de ces identificateurs. L'IEEE est l'héritier de la société Xerox qui avait créé le registre. Tout le monde peut obtenir des valeurs dans ce registre mais l'IEEE, organisation très traditionnaliste, fait payer très cher (570 $ pour la norme Ethernet, certaines sont distribuées gratuitement), et ne publie pas la liste intégrale des enregistrements. Toutefois, les autres SDO peuvent obtenir gratuitement certaines valeurs.

Parmi ces paramètres, les OUI, identificateurs uniques d'une organisation (registre à l'IEEE). Ils sont surtout connus car ils servent à préfixer les adresses Ethernet. Dell ayant entre autres l'OUI 18-03-73 (l'IEEE publie une liste partielle, on trouve une liste dans le programme arpwatch, installée en /usr/share/arpwatch/ethercodes.dat et une autre est en ligne), une machine de ce constructeur peut avoir, par exemple, l'adresse 18-03-73-66-e5-68 sur sa carte Ethernet (notre RFC utilise le tiret comme séparateur - cf. section 1.1 - alors qu'on voit souvent le deux-points dans d'autres contextes). L'IANA, on l'a vu, a l'OUI 00-00-5E. L'IEEE ne fournit pas d'OUI pour les documentations, donc l'IANA a réservé des identificateurs sous son OUI à elle, pour cet usage.

Le gros morceau du RFC, la section 2, concerne les adresses MAC de type Ethernet, l'utilisation la plus connue du registre IEEE. Aujourd'hui, elles existent en deux formats, le classique, de 48 bits, nommé EUI-48, un format plus récent sur 64 bits, l'EUI-64, et l'IEEE est actuellement en train d'étudier la possibilité de créer un format EUI-128 sur 128 bits.

Les EUI-48, archi-connus en raison de leur rôle dans l'adressage Ethernet, Wi-Fi, etc, sont mondialement uniques. Si une machine a 38-59-f9-7d-b6-47, elle sera la seule au monde dans ce cas (sauf erreur dans les processus de fabrication des cartes réseaux). Les six octets de ces adresses se divisent en un OUI de trois octets (38-59-f9 dans l'exemple précédent, identifiant la société Foxconn alias Hon Hai) et trois octets attribués par le titulaire de l'OUI (l'IEEE n'enregistre donc pas les adresses individuelles mais seulement les OUI). À noter que, dans les trois octets initiaux, ceux de l'OUI, deux bits ont une signification spéciale. Le Group bit indique si l'adresse MAC est multicast (s'il est à 1) ou unicast. Le Local bit dit si l'adresse MAC est mondialement unique (s'il est à 0) ou si elle est gérée localement sans souci du reste du monde (si le bit est à 1). Dans les OUI attribués par l'IEEE, comme le 00-00-5E de l'IANA, le Local bit est à 0. Ainsi, avec un seul OUI, on peut fabriquer des identificateurs unicast ou multicast. De même, les identificateurs peuvent être globaux ou purement locaux (et, dans ce dernier cas, l'OUI n'a plus d'importance).

Il y a quelques plages d'adresses spéciales sous l'OUI IANA. Ainsi, en unicast, les plages de 00-00-5E-00-00-00 à 00-00-5E-00-00-FF et de 00-00-5E-00-52-00 à 00-00-5E-00-52-FF sont réservées pour de futures allocations par l'IANA, celles de 00-00-5E-00-01-00 à 00-00-5E-00-01-FF et de 00-00-5E-00-02-00 à 00-00-5E-00-02-FF pour le protocole VRRP, du RFC 5798, protocole qui nécessite que la machine change son adresse MAC. Et 00-00-5E-00-53-00 à 00-00-5E-00-53-FF est réservée pour la documentation. Vous pouvez trouver la liste complète dans le registre IANA. Si je regarde les adresses MAC des voisins de ma machine :

% ip -6 neighbor show                                
fe80::10:dbff:feff:4070 dev eth1 lladdr 00:10:db:ff:40:70 router REACHABLE

Je peux trouver le type de machine dans la liste locale des OUI :

% grep 0:10:db /usr/share/arpwatch/ethercodes.dat 
0:10:db	Juniper Networks, Inc.

Et si j'écris une documentation sur le protocole NDP, je vais mettre à la place des jolies adresses réservées pour la documentation :

% ip -6 neighbor show                                
fe80::5eff:feff:4070 dev eth1 lladdr 00:00:5e:ff:40:70 router REACHABLE

Les allocations IANA doivent correspondre à un travail de normalisation d'un protocole (décrit dans un RFC ou bien un Internet-Draft), et ne doivent pas être utilisées comme moyen d'échapper aux règles « normales » de l'IEEE. Dans la plage de 00-00-5E-00-52-00 à 00-00-5E-00-52-FF, la procédure est simplement celle d'un examen par un expert (section 4.1 du RFC 5226), et le RFC recommande un examen léger (l'espace d'adressage est large et il n'est pas nécessaire d'économiser). Dans celle de 00-00-5E-00-00-00 à 00-00-5E-00-00-FF, la procédure est un cas nouveau, non documenté dans le RFC 5226 et nommé « ratification par l'IESG ». Le concept de « ratification par l'IESG » est introduit dans ce RFC 7042 (section 5.1) pour dire « examen par un expert, puis, après son accord, passage devant l'IESG qui peut refuser ». L'annexe A de notre RFC contient les formulaires à remplir pour demander ces enregistrements.

Et pour les EUI-64 ? La section 2.2 rappelle leurs usages, comme la fabrication de la partie droite, l'« Interface Identifier », des adresses IPv6 (section 2.5.1 et annexe A du RFC 4291 et annexe A du RFC 5214), ou comme l'adressage FireWire. Attention, dans les adresses IPv6, le sens du Local bit a été inversé (0 veut dire que l'adresse est locale). En EUI-64 modifié (avec cette inversion du bit local), le préfixe IANA est 02-00-5E.

On y retrouve des plages analogues à celles des EUI-48 comme celle de 02-00-5E-10-00-00-00-00 à 02-00-5E-10-00-00-00-FF pour la documentation, avec des règles identiques.

Outre le préfixe IANA 00-00-5E, il existe deux autres préfixes utilisés dans la normalisation IETF (section 2.3), 33-33, pour du multicast IPv6 (RFC 2464), et CF pour PPP (RFC 2153). Le premier doit sa valeur à l'adresse du PARC, 3333 Coyote Hill Road, Palo Alto, Californie, où a été conçu Ethernet. Le second est officiellement fermé aux nouveaux enregistrements.

Après cette section 2 consacrée aux adresses MAC, la section 3 regroupe tous les autres paramètres IEEE utilisés par l'IETF. On y trouve notamment les types Ethernet qui, placés dans la trame Ethernet après les adresses, indique le type du protocole de niveau supérieur. Ils comportent deux octets, 0x0800 pour IPv4, 0x0806 pour ARP, 0x86DD pour IPv6, 0x22F3 pour TRILL, etc. Ils sont gérés par l'IEEE mais sont mentionnés ici (annexe B pour une liste partielle) pour compléter l'information. Un mécanisme d'extension est prévu pour utiliser des types plus longs que deux octets et c'est ainsi que 00-00-5E-00-42 est un numéro de protocole valable, réservé pour la documentation.

Les OUI sont aussi utilisés comme préfixes pour d'autres choses, par exemple les sélecteurs d'un algorithme de chiffrement dans IEEE 802.11. La section 4 décrit l'allocation de paramètres sous le préfixe IANA pour ces usages. Là encore, cela ne doit être fait que dans le cadre d'un processus de normalisation, avec spécification publiée.

Les changements depuis le RFC 5342 ne sont peut-être pas spectaculaires mais sont importants. Il y a l'ajout des adresses MAC de documentation. Mais il y a surtout la suppression de la règle (section 2.1.2 du RFC 5342) « allocation pour l'unicast et le multicast en même temps » qui devait simplifier le travail de l'IANA mais qui s'est avérée trop difficile à suivre. Désormais, on peut donc réserver séparement pour l'unicast et le multicast.

Autres changements, l'intégration des réflexions actuellement en cours sur la restructuration des registres IEEE, en raison des risques d'épuisement des identificateurs IEEE, et ajout des types d'enregistrement DNS EUI48 et EUI64 pour les adresses MAC (décrits en détail dans le RFC 7043).


Téléchargez le RFC 7042


L'article seul

RFC 7049: Concise Binary Object Representation (CBOR)

Date de publication du RFC : Octobre 2013
Auteur(s) du RFC : C. Bormann (Universitaet Bremen TZI), P. Hoffman (VPN Consortium)
Chemin des normes
Première rédaction de cet article le 24 octobre 2013


Il existait un zillion de formats binaires d'échange de données ? Et bien il y en a désormais un zillion plus un. CBOR (Concise Binary Object Representation) est un format qui utilise un modèle de données très proche de celui de JSON, mais est encodé en binaire, avec comme but principal d'être simple à encoder et décoder, même par des machines ayant peu de ressources matérielles.

Parmi les autres formats binaires courants, on connait ASN.1 (plus exactement BER ou DER, utilisés dans plusieurs protocoles IETF) ou MessagePack mais ils avaient des cahiers des charges assez différents (l'annexe E du RFC contient une comparaison). CBOR se distingue d'abord par sa référence à JSON (RFC 7159), dont le modèle de données sert de point de départ à CBOR, puis par le choix de faciliter le travail des logiciels qui devront créer ou lire du CBOR. CBOR doit pouvoir tourner sur des machines très limitées. Par contre, la taille des données encodées n'est qu'une considération secondaire (section 1.1 du RFC pour une liste prioritisée des objectifs de CBOR). Quant au lien avec JSON, l'idée est d'avoir des modèles de données suffisamment proches pour qu'écrire des convertisseurs CBOR->JSON et JSON->CBOR soit assez facile, et pour que les protocoles qui utilisent actuellement JSON puissent être adaptés à CBOR sans douleur excessive.

La spécification complète de CBOR est en section 2 de ce RFC. Chaque élément contenu dans le flot de données commence par un octet dans les trois premiers bits indiquent le type majeur. Les cinq suivants donnent des détails. Ce mécanisme permet de programmeur un décodeur CBOR avec une table de seulement 256 entrées (l'annexe B fournit cette table et l'annexe C un décodeur en pseudo-code très proche de C). Si la valeur que codent ces cinq bits suivants est inférieure à 24, elle est utilisée telle quelle. Sinon, cela veut dire que les détails sont sur plusieurs octets et qu'il faut lire les suivants (la valeur des cinq bits codant la longueur à lire). Selon le type majeur, les données qui suivent le premier octet sont une valeur (c'est le cas des entiers, par exemple) ou bien un doublet {longueur, valeur} (les chaînes de caractères, par exemple). L'annexe A de notre RFC contient de nombreux exemples de valeurs CBOR avec leur encodage.

Quels sont les types majeurs possibles ? Si les trois premiers bits sont à zéro, le type majeur est un entier non signé. Si les cinq bits suivants sont inférieurs à 24, c'est la valeur de cet entier. S'ils sont égaux à 24, c'est que l'entier se trouve dans l'octet suivant l'octet initiale, s'ils sont égaux à 25, que l'entier se trouve dans les deux octets suivants, et ainsi de suite (31 est réservé pour les tailles indéterminées, décrites plus loin). L'entier 10 se représentera donc 00001010, l'entier 42 sera 00011000 00101010, etc. Presque pareil pour un type majeur de 1, sauf que l'entier sera alors signé, et négatif. La valeur sera -1 moins la valeur encodée. Ainsi, -3 sera 00100010. Vous voulez vérifier ? L'excellent terrain de jeu http://cbor.me vous le permet, essayez par exemple http://cbor.me?diag=42.

Le type majeur 2 sera une chaîne d'octets. La longueur est codée d'abord, en suivant la même règle que pour les entiers. Puis viennent les données. Le type 3 indique une chaîne de caractères et non plus d'octets. Ce sont forcément des caractères Unicode, encodés en UTF-8 (RFC 3629). Le champ longueur (codé comme un entier) indique le nombre d'octets de l'encodage UTF-8, pas le nombre de caractères (pour connaître ce dernier, il faut un décodeur UTF-8). Vous voulez des exemples ? Connectez-vous à http://www.cbor.me/?diag=%22lait%22 et vous voyez que la chaîne « lait » est représentée par 646c616974 : 64 = 01100100, type majeur 3 puis une longueur de 4. Les codes ASCII suivent (rappelez-vous qu'ASCII est un sous-ensemble d'UTF-8). Avec des caractères non-ASCII comme http://www.cbor.me/?diag=%22caf%C3%A9%22, on aurait 65636166c3a9 (même type majeur, longueur 5 octets, puis les caractères, avec c3a9 qui code le é en UTF-8).

Le type majeur 4 indique un tableau. Rappelez-vous que CBOR utilise un modèle de données qui est très proche de celui de JSON. Les structures de données possibles sont donc les tableaux et les objets (que CBOR appelle les maps). Un tableau est encodé comme une chaîne d'octets, longueur (suivant les règles des entiers) puis les éléments du tableau, à la queue leu leu. La longueur est cette fois le nombre d'éléments, pas le nombre d'octets. Les éléments d'un tableau ne sont pas forcément tous du même type.

Le type majeur 5 indique une map (ce qu'on appelle objet en JSON et dictionnaire ou hash dans d'autres langages). Chaque élément d'une map est un doublet {clé, valeur}. L'encodage est le même que pour les tableaux, la longueur étant le nombre de doublets. Chaque doublet est encodé en mettant la clé, puis la valeur. Donc, le premier scalaire est la clé de la première entrée de la map, le deuxième la valeur de la première entrée, le troisième la clé de la deuxième entrée, etc.

Les clés doivent être uniques (une question problématique en JSON où les descriptions existantes de ce format ne sont ni claires ni cohérentes sur ce point).

Je passe sur le type majeur 6, voyez plus loin le paragraphe sur les étiquettes. Le type majeur 7 sert à coder les flottants (encodés ensuite en IEEE 754) et aussi d'autres types scalaires et le break code utilisé dans le paragraphe suivant. Les autres types scalaires, nommés « valeurs simples » (simple values) sont des valeurs spéciales comme 20 pour le booléen Faux, 21 pour le Vrai, et 22 pour le néant. Elles sont stockées dans un registre IANA.

Dans la description ci-dessus, les types vectoriels (tableaux, chaînes, maps) commencent par la longueur du vecteur. Pour un encodeur CBOR, cela veut dire qu'il faut connaître cette longueur avant même d'écrire le premier élément. Cela peut être contraignant, par exemple si on encode au fil de l'eau (streaming) des données en cours de production. CBOR permet donc d'avoir des longueurs indéterminées. Pour cela, on met 31 comme « longueur » et cette valeur spéciale indique que la longueur n'est pas encore connue. Le flot des éléments devra donc avoir une fin explicite cette fois, le break code. Celui-ci est représenté par un élément de type majeur 7 et de détails 31, donc tous les bits de l'octet à 1. Par exemple, http://cbor.me/?diag=%28_%20%22lait%22%29 nous montre que la chaîne « lait » ainsi codée (le _ indique qu'on veut un codage en longueur indéterminée) sera 7f646c616974ff. 7f est le type majeur 3, chaîne de caractères, avec la longueur 31, indiquant qu'elle est indéterminée. Puis suit la chaîne elle-même (les chaînes indéterminées en CBOR sont faites par concaténation de châines de longueur déterminée), puis le break code ff.

La même technique peut être utilisée pour les chaînes d'octets et de caractères, afin de ne pas avoir à spécifier leur longueur au début. À noter que cette possibilité de listes de longueur indéterminée n'existait pas dans les premières versions de CBOR. Elle a été ajoutée pour faciliter la vie du streaming.

Revenons au type majeur 6. Il indique une étiquette (tag), qui sert à préciser la sémantique de l'élément qui suit. Un exemple typique est pour indiquer qu'une chaîne de caractères est un fait une donnée structurée, par exemple une date ou un numéro de téléphone. Un décodeur n'a pas besoin de comprendre les étiquettes, il peut parfaitement les ignorer. Les valeurs possibles pour les étiquettes sont stockées dans un registre IANA.

Quelques valeurs d'étiquette intéressantes ? La valeur 0 indique une date au format du RFC 3339 (une chaîne de caractères). La valeur 1 étiquette au contraire un entier, et indique une date comme un nombre de secondes depuis le 1er janvier 1970. Les valeurs 2 et 3 étiquettent une chaîne d'octets et indiquent qu'on recommande de l'interpréter comme un grand entier (dont la valeur n'aurait pas tenu dans les types majeurs 0 ou 1). Les décodeurs qui ne gèrent pas les étiquettes se contenteront de passer à l'application cette chaîne d'octets, les autres passeront un grand entier.

Autre cas rigolos, les nombres décimaux non entiers. Certains ne peuvent pas être représentés de manière exacte sous forme d'un flottant. On peut alors les représenter par un couple [mantisse, exposant]. Par exemple, 273,15 est le couple [27315, -2] (l'exposant est en base 10). On peut donc l'encoder en CBOR sous forme d'un tableau de deux élements, et ajouter l'étiquette de valeur 4 pour préciser qu'on voulait un nombre unique.

D'autres étiquettes précisent le contenu d'une chaîne de caractères : l'étiquette 32 indique que la chaîne est un URI, la 34 que la chaîne est du Base64 (RFC 4648), la 35 dit qu'on va rencontrer une expression rationnelle et la 36 que cela va être un message MIME (RFC 2045). Comme l'interprétation des étiquettes est optionnelle, un décodeur CBOR qui n'a pas envie de s'embêter peut juste renvoyer à l'application cette chaîne.

Une astuce amusante pour finir les étiquettes, et la spécification du format : l'étiquette 55799 signifie juste que ce qui suit est du CBOR, sans modifier sa sémantique. Encodée, elle sera représentée par 0xd9d9f7 (type majeur 6 sur trois bits, puis détails 25 qui indiquent que le nombre est sur deux octets puis le nombre lui-même, d9d7 en hexa). Ce nombre 0xd9d9f7 peut donc servir de nombre magique. Si on le trouve au début d'un fichier, c'est probablement du CBOR (il ne peut jamais apparaître au début d'un fichier JSON, donc ce nombre est particulièrement utile quand on veut distinguer tout de suite si on a affaire à du CBOR ou à du JSON).

Maintenant que le format est défini rigoureusement, passons à son utilisation. CBOR est conçu pour des environnements où il ne sera souvent pas possible de négocier les détails du format entre les deux parties. Un décodeur CBOR générique peut décoder sans connaître le schéma utilisé en face. Mais, en pratique, lorsqu'un protocole utilise CBOR pour la communication, il est autorisé (section 3 du RFC) à mettre des restrictions, ou des informations supplémentaires, afin de faciliter la mise en œuvre de CBOR dans des environnements très contraints en ressources. Ainsi, on a parfaitement le droit de faire un décodeur CBOR qui ne gérera pas les nombres flottants, si un protocole donné n'en a pas besoin.

Un cas délicat est celui des maps (section 3.7). CBOR ne place guère de restrictions sur le type des clés et un protocole ou format qui utilise CBOR voudra souvent être plus restrictif. Par exemple, si on veut absolument être compatible avec JSON, restreindre les clés des chaînes en UTF-8 est souhaitable. Si on tient à utiliser d'autres types pour les clés (voire des types différents pour les clés d'une même map !), il faut se demander comment on les traduira lorsqu'on enverra ces maps à une application. Par exemple, en JavaScript, la clé formée de l'entier 1 est indistinguable de celle formée de la chaîne de caractères "1". Une application en JavaScript ne pourra donc pas se servir d'une map qui aurait de telles clés, de types variés.

On a vu que certains élements CBOR pouvaient être encodés de différentes manières, par exemple un tableau peut être représenté par {longueur, valeurs} ou bien par {valeurs, break code}. Cela facilite la tâche des encodeurs mais peut compliquer celle des décodeurs, et cela peut rendre certaines opérations, comme la comparaison de deux fichiers, délicates. Existe t-il une forme canonique de CBOR ? Non, pas en standard, et ce point a suscité de chaudes discussions à l'IETF. Néanmoins, un protocole ou format donné, qui utilise CBOR, peut définir une telle forme canonique. La section 3.9 donne quelques pistes à ce sujet et suggère les règles suivantes :

  • Mettre les entiers sous la forme la plus compacte possible. L'entier 2 peut être représenté par un octet (type majeur 0 puis détails égaux à 2) ou deux (type majeur 0, détails à 24 puis deux octets contenant la valeur 2), voire davantage. La forme canonique recommandée est la première (un seul octet). Même règle pour les longueurs (qui, en CBOR, sont encodées comme les entiers.)
  • Trier les clés d'une map de la plus petite à la plus grande. (Selon leur représentation en octets, pas selon l'ordre alphabétique.)
  • Mettre les tableaux et les chaînes sous la forme {longueur, valeurs}.

Tous les encodeurs CBOR qui suivent ces règles (qui seront peut-être un jour normalisées dans un nouveau RFC définissant le « CBOR canonique ») produiront, pour un même jeu de données, le même encodage.

Autre question pratique importante, le comportement en cas d'erreurs. Que doit faire un décodeur CBOR si deux clés sont identiques dans une map, ce qui est normalement interdit en CBOR ? Ou si un champ longueur indique qu'on va avoir un tableau de 5 éléments mais qu'on n'en rencontre que 4 avant la fin du fichier ? Ou si une chaîne de caractères, derrière son type majeur 3, n'est pas de l'UTF-8 bien formé ? Les sections 3.3, 3.4 et 3.10 décrivent la question. CBOR n'est pas pédant: un décodeur a le droit d'ignorer certaines erreurs, de remplacer les valeurs par ce qui lui semble approprié. CBOR penche nettement du côté « être indulgent avec les données reçues » ; il faut dire qu'une application qui utilise CBOR peut toujours le renforcer en ajoutant l'obligation de rejeter ces données erronées. Un décodeur strict peut donc s'arrêter à la première erreur. Ainsi, un pare-feu qui analyse du CBOR à la recherche de contenu malveillant a tout intérêt à rejeter les données CBOR incorrectes (puisqu'il ne sait pas trop comment elles seront interprétées par la vraie application, la section 7 revient sur ce point). Bref, la norme CBOR ne spécifie pas de traitement d'erreur unique.

Comme CBOR a un modèle de données proche de celui de JSON, on aura souvent envie d'utiliser CBOR comme encodage efficace de JSON. Comment convertir du CBOR en JSON et vice-versa sans trop de surprises ? La section 4 du RFC se penche sur ce problème. Depuis CBOR vers JSON, les traductions suivantes sont suggérées :

  • Les entiers deviennent évidemment des nombres JSON.
  • Les chaînes d'octets sont encodées en base64 et deviennent des chaînes de caractères JSON (JSON n'a pas d'autre moyen de transporter du binaire).
  • Les chaînes de caractères deviennent des chaînes de caractères JSON (ce qui nécessite d'en échapper certains, RFC 7159, section 7).
  • Les tableaux deviennent des tableaux JSON et les maps des objets JSON (ce qui impose de convertir les clés en chaînes UTF-8, si elles ne l'étaient pas déjà).
  • Etc.

En sens inverse, de JSON vers CBOR, c'est plus simple, puisque JSON n'a pas de constructions qui seraient absentes de CBOR.

Pour les amateurs de futurisme, la section 5 discute des éventuelles évolutions de CBOR. Pour les faciliter, CBOR a réservé de la place dans certains espaces. Ainsi, le type majeur 7 permettra d'encoder encore quelques valeurs simples (cela nécessitera un RFC sur le chemin des normes, cf. RFC 5226 et la section 7.1 de notre RFC). Et on peut ajouter d'autres valeurs d'étiquettes (selon des règles qui dépendent de la valeur numérique : les valeurs les plus faibles nécessiteront une procédure plus complexe, cf. section 7.2).

CBOR est un format binaire. Cela veut dire, entre autres, qu'il n'est pas évident de montrer des valeurs CBOR dans, mettons, une documentation, contrairement à JSON. La section 6 décrit donc un format texte (volontairement non spécifié en détail) qui permettra de mettre des valeurs CBOR dans du texte. Nulle grammaire formelle pour ce format : il est prévu pour l'utilisation par un humain, pas par un analyseur syntaxique. Ce format ressemble à JSON avec quelques extensions pour les nouveautés de CBOR. Par exemple, les étiquettes sont représentées par un nombre suivi d'une valeur entre parenthèses. Ainsi, la date (une chaîne de caractères étiquetée par la valeur 0) sera notée :

0("2013-10-12T11:34:00Z")

Une map de deux éléments sera notée comme en JSON :

{"Fun": true, "Amt": -2}  

Même chose pour les tableaux. Ici, avec étiquette sur deux chaînes de caractères :

[32("http://cbor.io/"), 34("SW5zw6lyZXogaWNpIHVuIMWTdWYgZGUgUMOicXVlcw==")]

Lors de l'envoi de données encodées en CBOR, le type MIME à utiliser sera application/cbor. Comme l'idée est d'avoir des formats définis en utilisant la syntaxe CBOR et des règles sémantiques spécifiques, on verra aussi sans doute des types MIME utilisant la notation plus du RFC 6839, par exemple application/monformat+cbor.

Un petit mot sur la sécurité (section 8) : il est bien connu qu'un analyseur mal écrit est un gros risque de sécurité et d'innombrables attaques ont déjà été réalisées en envoyant à la victime un fichier délibérement incorrect, conçu pour déclencher une faille de l'analyseur. Ainsi, en CBOR, un décodeur qui lirait une longueur, puis chercherait le nombre d'éléments indiqué, sans vérifier qu'il est arrivé au bout du fichier, pourrait déclencher un débordement de tampon. Les auteurs de décodeurs CBOR sont donc priés de programmer de manière défensive, voire paranoïaque : ne faites pas confiance au contenu venu de l'extérieur.

Autre problème de sécurité, le risque d'une attaque par déni de service. Un attaquant taquin peut envoyer un fichier CBOR où la longueur d'un tableau est un très grand nombre, dans l'espoir qu'un analyseur naïf va juste faire malloc(length) sans se demander si cela ne consommera pas toute la mémoire.

Enfin, comme indiqué plus haut à propos du traitement d'erreur, comme CBOR ne spécifie pas de règles standard pour la gestion des données erronées, un attaquant peut exploiter cette propriété pour faire passer des données « dangereuses » en les encodant de telle façon que l'IDS n'y voit que du feu. Prenons par exemple cette map :

{"CodeToExecute": "OK",
 "CodeToExecute": "DANGER"}

Imaginons qu'une application lise ensuite la donnée indexée par CodeToExecute. Si, en cas de clés dupliquées, elle lit la dernière valeur, elle exécutera le code dangereux. Si un IDS lit la première valeur, il ne se sera pas inquiété. Voilà une bonne raison de rejeter du CBOR invalide (les clés dupliquées sont interdites) : il peut être interprété de plusieurs façons.

Pour les amateurs d'alternatives, l'annexe E du RFC compare CBOR à des formats analogues. Attention, la comparaison se fait à la lumière du cahier des charges de CBOR, qui n'était pas forcément le cahier des charges de ces formats. Ainsi, ASN.1 (ou plutôt ses sérialisations comme BER ou DER, PER étant nettement moins courant puisqu'il nécessite de connaître le schéma des donnéees) est utilisé par plusieurs protocoles IETF (comme LDAP) mais le décoder est une entreprise compliquée.

MessagePack est beaucoup plus proche de CBOR, dans ses objectifs et ses résultats, et a même été le point de départ du projet CBOR. Mais il souffre de l'absence d'extensibilité propre. Plusieurs propositions d'extensions sont restées bloquées à cause de cela.

BSON (connu surtout via son utilisation dans MongoDB) a le même problème. En outre, il est conçu pour le stockage d'objets JSON dans une base de données, pas pour la transmission sur le réseau (ce qui explique certains de ses choix). UBJSON est un autre encodage binaire de JSON. Contrairement à CBOR, il se tient étroitement au modèle de données de JSON. Enfin, MSDTP, spécifié dans le RFC 713, n'a jamais été réellement utilisé.

Rappelez-vous que CBOR prioritise la simplicité de l'encodeur et du décodeur plutôt que la taille des données encodées. Néanmoins, un tableau en annexe E.6 compare les tailles d'un même objet encodé avec tous ces protocoles : BSON est de loin le plus bavard (BER est le second), MessagePack et CBOR les plus compacts.

Une liste des implémentations sera publiée en http://cbor.io/ (il est vide en ce moment). Au moins quatre existent, en Python, Ruby, JavaScript et Java.

Merci à Carsten Bormann pour sa relecture.


Téléchargez le RFC 7049


L'article seul

RFC 7043: Resource Records for EUI-48 and EUI-64 Addresses in the DNS

Date de publication du RFC : Octobre 2013
Auteur(s) du RFC : J. Abley (TekSavvy Solutions)
Pour information
Première rédaction de cet article le 24 octobre 2013


Tout le monde connait les identifiants EUI-48 et EUI-64 même si ce n'est pas sous ce nom là. Normalisés par l'IEEE, ils servent notamment d'adresses Ethernet. Désormais, on peut les mettre dans le DNS, en utilisant les nouveaux types créés par ce RFC. Attention : pour des raisons liées à la protection de la vie privée, il n'est pas prévu que ces enregistrements DNS EUI48 et EUI64 se retrouvent dans le DNS public, seulement dans des zones locales (un point qui a soulevé des controverses).

Donc, d'abord, le type EUI48 (section 3). Il a le numéro 108 dans le registre IANA. En binaire, c'est simplement un groupe de six octets. Sous la forme texte (par exemple dans un fichier de zone), c'est six groupes (séparés par des tirets) de chacun deux chiffres hexadécimaux, par exemple :

host.example.   86400   IN   EUI48 00-00-5e-00-53-2a

(Notez que l'adresse MAC utilise le préfixe IANA et les valeurs réservées pour les exemples par le RFC 7042.)

C'est quasiment pareil pour le type EUI64. Numéro 109, huit octets à la suite en binaire, huit groupes de chiffres hexa en mode texte :

host.example.   86400   IN   EUI64 00-00-5e-ef-10-00-00-2a

Mais à quoi cela sert, ces adresses Ethernet dans le DNS ? La section 5 répond à la question en décrivant le cas d'usage qui avait motivé ce RFC. Au Canada, les FAI utilisant le câble utilisent DHCP pour fournir des adresses IP aux abonnés. Souvent, cela passe par un revendeur qui ne contrôle pas tout le réseau. Le revendeur connait l'adresse EUI-48 de son client mais pas l'adresse IP allouée. La correspondance entre l'adresse IP et l'adresse MAC, a décidé le régulateur, doit être publiée dans le DNS (document « Implementation of IP Address Tracking in DOCSIS Networks (TIF18) » du CRTC Interconnection Steering Committee Network Working Group, voir leurs documents). Avant ce RFC, les méthodes utilisées étaient variables et pas forcément très jolies (des enregistrements TXT, par exemple).

Cela pose quelques problèmes de sécurité, notamment liés à la protection de la vie privée. Une adresse MAC est en effet (en théorie) unique au niveau mondial et peut donc permettre de suivre une machine. Elle change moins que l'adresse IP attribuée et fournit donc un meilleur moyen de traque, permettant de suivre un utilisateur donné. C'est pour cela que la section 8 du RFC dit clairement que les types EUI48 et EUI64 ne doivent apparaître que dans des zones privées, non accessibles au public. (Cela n'a pas suffit à certains participants à l'IETF qui réclamaient qu'on ne mette jamais ces adresses EUI48 et EUI64 dans le DNS, zones privées ou pas.)

Ces deux nouveaux types d'enregistrement DNS sont mis en œuvre dans NSD en expérimental (ticket #496, il faut compiler avec l'option --enable-draft-rrtypes) et dans Knot, apparemment depuis la version 1.3.0.


Téléchargez le RFC 7043


L'article seul

Fiche de lecture : CultureNum

Auteur(s) du livre : Ouvrage collectif coordonné par Hervé le Crosnier
Éditeur : C&F
978-2-915825-31-2
Publié en 2013
Première rédaction de cet article le 19 octobre 2013


Ce livre rassemble un certain nombre de textes de réflexions autour de la notion de « Culture numérique ». Le numérique (en pratique, le livre parle beaucoup, mais pas uniquement, de l'Internet) est souvent abordé sous l'angle technique (les routeurs, les serveurs, les câbles, les logiciels...) ou sous l'angle anecdotique, rarement sous celui des réelles pratiques de ses innombrables utilisateurs. Ce livre vise à aborder le numérique d'une autre façon : les utilisateurs ne se comportent pas comme le voudraient les marketeux, ils ne se limitent pas aux quelques excès ou délires pointés par le presse à sensation. Mais, alors, ils font quoi ?

Comme la plupart des ouvrages collectifs, celui-ci n'a guère d'unité, à part cette volonté de considérer que l'Internet est aussi défini par les choix de ses utilisateurs. « L'Internet est trop souvent vécu comme un réseau dominé par des acteurs industriels et des décisions institutionnelles [par exemple dans les débats sur la gouvernance], alors que ce sont les usagers qui forment l'élement majeur du succès du numérique » (p. 8).

Ainsi, si de nombreux penseurs ont glosé sur le numérique chez les adolescents, peu sont allés étudier ce que faisaient vraiment lesdits ados. Élisabeth Schneider est allé enquêter et raconte ses trouvailles (j'ai bien aimé la moyenne des 15 SMS envoyés par heure de cours, p. 22...) Karine Aillerie est partie voir ces mêmes ados pour regarder comment ils recherchent et s'informent sur l'Internet. Si leur usage de Google est souvent cité, celui de Wikipédia l'est moins, notamment sur le pourquoi de la confiance accordée (Wikipédia est vue par les ados comme une « marque », immédiatement reconnaissable, et cohérente dans toute ses pages, cf. p. 61). L'auteur note bien, comme l'ont déjà fait d'autres, que tous ces outils ne dispensent pas d'« apprendre à chercher », chose très rare aujourd'hui (p. 67).

Laurent Matos se demande dans ce livre comment les bibliothèques peuvent s'adapter au numérique, par exemple en prêtant des liseuses. Mais la complexité technique de l'offre, la variété des formats et bien sûr les DRM forment des obstacles colossaux à une implication plus grande des bibliothèques dans le numérique (p. 82-83). Guénaël Boutouillet, lui, a voulu renouveler les traditionnels ateliers d'écriture en les faisant via le Web (p. 87), notant le paradoxe que ces ateliers, la plupart du temps, n'utilisent pas les outils qui sont le quotidien de tous (écran et clavier).

Le livre, je l'ai signalé, est à plusieurs voix, et ces voix ne chantent pas tous en chœur. On trouve même un long texte corporatiste d'Alain Charriras de défense des ayant-droits (p. 108). Le problème est complexe mais bien expliqué par l'auteur, qui défend la taxe « copie privée » sans nuances. Mais il note aussi que la nullité de l'offre légale est une des principales explications de la copie illégale.

Le numérique envahit aussi la radio et Xavier de la Porte a un excellent article (p. 116) sur la mutation de « la radio la plus vieillotte » (France Culture). De l'époque des Nagra emportés en reportage, au montage d'interviews sur ordinateur et ses conséquences. Le fait que les interviews ne soient plus coupés par le changement de bande magnétique ne permet plus de s'arrêter pour réflechir... Le fait que les moteurs de recherche n'indexent pas le son limite la visibilité des émissions de radio sur l'Internet...

Un exemple typique où le contenu est créé par les utilisateurs et non pas consommé passivement par eux est le fansubbing (les passionnés d'une série télévisée étrangère qui en assurent eux-mêmes le sous-titrage pour leurs compatriotes moins polyglottes), couvert par Brigitte Chapelain avec plusieurs autres pratiques créatives du numérique (p. 142). J'en profite pour remercier « Honey Bunny » qui fait un travail très rapide (quoique pas toujours très rigoureux mais même ses coquilles sont amusantes comme « va sceller mon cheval ») de sous-titrage de Game of Thrones.

Alors, le numérique est-il bon ou mauvais ? Comme le note Hervé le Crosnier (p. 179), il est comme un médicament, soignant certains, en rendant d'autres malades, et le tout dépendant de la dose et de la façon dont elle est administrée et reçue. Il y a eu des promesses délirantes liées au numérique (Hervé le Crosnier démolit les plus ridicules, celles portant sur l'éducation, notamment au e-learning, p. 181 et 183) mais aussi des transformations radicales, souvent dans le sens d'une plus grande participation du peuple.

Avertissement : j'ai reçu un exemplaire gratuit de l'éditeur, mais cela n'a pas affecté mon jugement, je suis incorruptible, d'autant plus qu'il n'y avait pas de chocolats joints à l'envoi.


L'article seul

RIPEstat, plein de données sur l'Internet

Première rédaction de cet article le 17 octobre 2013


L'Internet est une ressource cruciale aujourd'hui, mais peu connue. Pour beaucoup de gens, y compris des administrateurs réseau, l'Internet est une boîte noire, un mystère. Lorsqu'il marche, tant mieux, s'il plante, on ne sait pas quoi faire. Pourtant, une des caractéristiques de l'Internet est que tout est accessible. Ainsi, l'outil RIPEstat du RIPE-NCC donne accès à plein d'informations techniques sur le fonctionnement de l'Internet. Démonstration, avec plein de chiffres et de faits.


L'article complet

Le routeur Wi-Fi ASUS WL 330 NUL

Première rédaction de cet article le 13 octobre 2013


La publicité d'ASUS le présente comme le plus petit routeur Wi-Fi du monde, ou à peu près. Que peut faire cet engin ?

Grand comme une clé USB, il sert à combler les trous de la connectivité lorsqu'on voyage. Si vous n'avez qu'une seule machine, et qu'elle a Ethernet et Wi-Fi, ce routeur ne vous servira pas à grand'chose. Il est utile si vous avez des engins qui manquent de la connectivité requise, ou si vous avez plusieurs machines. Le routeur a deux prises, une USB et une Ethernet. L'USB sert à l'alimentation électrique, mais aussi à la connectivité réseau si une de vos machines peut faire de l'Ethernet sur USB. On branche le routeur sur un PC via USB, on le configure via un navigateur Web (http://192.168.1.1/) et c'est parti. Ce routeur permet, entre autres :

  • De connecter une machine qui n'a que Wi-Fi lorsque la seule connectivité disponible est Ethernet, et réciproquement.
  • De connecter plusieurs machines, même si une seule est normalement autorisée (l'interface du routeur permet de facilement changer l'adresse MAC, fonction « Clone MAC »).

Le routeur peut à la fois être connecté à l'Internet en Wi-Fi et distribuer du Wi-Fi aux alentours (quelque chose que je n'ai jamais réussi à faire avec mon PC Ubuntu). En Wi-Fi, il peut gérer un réseau protégé par WPA2 (fonction « Réseau privé »), ou bien un réseau ouvert avec portail captif (fonction « Réseau invité »). Dans ce second cas, le portail peut authentifier par mot de passe ou bien envoyer un message à l'administrateur, qui autorise alors le client via l'interface Web.

Ce que j'apprécie dans cet engin : son faible prix, son faible encombrement, sa simplicité de configuration. Ce que je n'apprécie pas : pas d'IPv6, aucune statistique disponible via l'interface Web.

La fonction « Historique du système » permet de voir quels logiciels utilise ce routeur :

Jan  1 08:00:15 syslogd started: BusyBox v1.17.4
Jan  1 08:00:15 stop_nat_rules: apply the redirect_rules!
Jan  1 08:00:16 WAN Connection: Ethernet link down.
Jan  1 08:00:18 dnsmasq[366]: started, version 2.55 cachesize 1500
Jan  1 08:00:18 dnsmasq[366]: compile time options: IPv6 GNU-getopt no-RTC no-DBus no-I18N DHCP TFTP
Jan  1 08:00:18 dnsmasq[366]: asynchronous logging enabled, queue limit is 5 messages
Jan  1 08:00:18 dnsmasq-dhcp[366]: DHCP, IP range 192.168.1.2 -- 192.168.1.254, lease time 1d
Jan  1 08:00:18 dnsmasq[366]: read /etc/hosts - 3 addresses
Jan  1 08:00:18 dnsmasq[366]: failed to read /etc/resolv.conf: No such file or directory
Jan  1 08:00:19 WL-330NUL: start macreceiver
Jan  1 08:00:19 WL-330NUL: start httpd
...
Oct 13 22:37:04 dnsmasq-dhcp[366]: DHCPREQUEST(br0) 10.50.2.7 5c:b5:24:b4:ee:f3 
Oct 13 22:37:04 dnsmasq-dhcp[366]: DHCPNAK(br0) 10.50.2.7 5c:b5:24:b4:ee:f3 wrong network
Oct 13 22:37:08 dnsmasq-dhcp[366]: DHCPDISCOVER(br0) 5c:b5:24:b4:ee:f3 
Oct 13 22:37:08 dnsmasq-dhcp[366]: DHCPOFFER(br0) 192.168.1.254 5c:b5:24:b4:ee:f3 
Oct 13 22:37:08 dnsmasq-dhcp[366]: DHCPREQUEST(br0) 192.168.1.254 5c:b5:24:b4:ee:f3 
Oct 13 22:37:08 dnsmasq-dhcp[366]: DHCPACK(br0) 192.168.1.254 5c:b5:24:b4:ee:f3 android-c38952bf32157985
Oct 13 22:41:08 dnsmasq-dhcp[366]: DHCPREQUEST(br0) 192.168.1.254 5c:b5:24:b4:ee:f3 
Oct 13 22:41:08 dnsmasq-dhcp[366]: DHCPACK(br0) 192.168.1.254 5c:b5:24:b4:ee:f3 android-c38952bf32157985
Oct 13 22:45:39 dnsmasq-dhcp[366]: no address range available for DHCP request via wlan0-vxd

Quelques engins similaires, signalés par de fidèles lecteurs que je remercie :


L'article seul

Ma conférence à Paris-Web sur la sécurité des sites Web

Première rédaction de cet article le 11 octobre 2013


Hier, jeudi 10 octobre, j'ai eu le plaisir de faire un exposé général sur la sécurité des sites Web à http://www.paris-web.fr/. Cet exposé, intitulé « Deux ou trois choses que vous ne savez peut-être pas sur la sécurité de votre site Web », passait très rapidement sur des attaques que les programmeurs Web connaissent déjà (XSS, injections SQL, etc) et se focalisait sur trois grandes catégories d'attaques : celles par déni de service, celles utilisant les noms de domaines et celles sur HTTPS.

Les supports utilisés sont disponibles ici. C'est du reveal.js, un système que j'ai récemment choisi. Je débute dans toutes ces techniques Web donc la présentation n'est pas parfaite sur tous les navigateurs (ça semble marcher mieux avec Chromium). Bref, vous pouvez regarder, si vous ne connaissez pas reveal.js, c'est la touche F pour passer en plein écran (Esc pour en sortir), et N pour la page suivante.

La vidéo est disponible en ligne.

Merci à Ève Demazière pour son aide pour la rédaction de la proposition faite à Paris Web et pour la réalisation des supports.


L'article seul

RFC 6950: Architectural Considerations on Application Features in the DNS

Date de publication du RFC : Octobre 2013
Auteur(s) du RFC : J. Peterson (NeuStar), O. Kolkman (NLnet Labs), H. Tschofenig (Nokia Siemens Networks), B. Aboba (Microsoft Corporation)
Pour information
Première rédaction de cet article le 10 octobre 2013


Le DNS est un des plus grands succès de l'Internet : une base de données répartie, fiable, sur laquelle on peut compter, et qui est très souple dans ses usages, lui permettant d'être utilisée pour beaucoup de choses (seuls les journalistes écrivent encore que « le DNS sert à trouver une adresse IP à partir d'un nom de domaine » : la réalité est bien plus riche). Mais, justement, la disponibilité et l'efficacité du DNS font qu'il est utilisé par beaucoup d'applications dont les auteurs ne sont pas forcément conscients des forces et faiblesses du DNS. Ne faudrait-il pas les appeler à réfléchir deux secondes sur ces forces et ces faiblesses ?

Le DNS permet de récupérer des données (quelconques : ce ne sont pas forcément des adresses IP) à partir d'un nom de domaine. Il est même utilisé par des applications dont les identifiants ne sont pas des noms de domaine : une petite transformation pour convertir l'identifiant en nom de domaine et hop (ONS, ENUM, etc). Le premier RFC à avoir décrit l'usage du DNS pour autre chose qu'une correspondance nom->adresse est le RFC 974 en 1986. C'est dire que c'est ancien et cela explique mes critiques sévères des ignorants qui continuent à considérer le DNS comme un simple moyen de trouver des adresses. Depuis ce RFC 974, qui introduisait l'enregistrement MX, l'idée a suivi son chemin. Un mécanisme plus général, le SRV, a été introduit par le RFC 2052 (remplacé depuis par le RFC 2782). Et, pour faire des mécanismes de délégation aussi compliqués qu'on le souhaite, il y a le NAPTR créé par le RFC 2168, généralisé ensuite par le RFC 3401. Enfin, il y a des applications qui mettent simplement leurs données dans le très général et pas structuré enregistrement TXT, ce que fait par exemple DKIM (RFC 6376).

Mais ce succès, comme tous les succès, a aussi son revers : les applications demandent de plus en plus au DNS alors que son vaste déploiement est largement dû à sa focalisation sur un petit nombre de fonctions qu'il réalise très bien. La mentalité fréquente aujourd'hui de « on met tout dans le DNS » (illustrée par un gadget fameux) est parfois en conflit avec les principes du DNS. La confidentialité est un bon exemple : elle était délibérement exclue du cahier des charges du DNS (et à juste titre : lisez le RFC 3414 si vous voulez un exemple de la complexité que la confidentalité apporte à un protocole requête-réponse). Vouloir l'ajouter aujourd'hui risque fort de faire perdre au DNS ses propriétés intéressantes (il n'est pas cité par ce RFC, mais c'est l'une des raisons de l'échec de DNScurve, qui essayait de faire trop de choses). Bien des applications qui veulent utiliser le DNS ont réclamé une certaine dose de confidentialité, alors que le DNS doit une partie de son efficacité au fait que toutes les données sont publiques. Ainsi, un cache n'a pas à s'inquiéter si les données qu'il mémorise doivent être servies à tous ou pas.

Ce nouveau RFC de l'IAB vise donc à aider les concepteurs d'applications en exposant clairement ce que le DNS fait bien, ce qu'il peut faire, et ce qu'il ne sait pas faire. C'est un excellent document pour qui veut comprendre en détail le DNS et, malgré sa longueur, il mérite d'être lu attentivement. Il fournit les informations nécessaires pour que ledit concepteur puisse répondre intelligemment à la question « Dois-je mettre cette information dans le DNS ou bien ailleurs ? » Il complète le RFC 5507, qui restait plutôt sur les questions de syntaxe, alors que ce nouveau RFC 6950 adopte une vue plus générale, plus tournée vers l'architecture du système. Pour le résumer en deux mots : le DNS doit son succès à ce qu'il n'essaie pas de résoudre tous les problèmes mais un ensemble bien précis de problèmes, pour lesquels il est une bonne solution. Comme il existe d'autres protocoles que le DNS, une application ou un service qui envisage d'utiliser le DNS dit sérieusement étudier s'il est vraiment la solution la plus adaptée (parfois oui mais parfois non).

La section 2 de notre RFC présente un certain nombre d'usages du DNS par des applications. Il commence évidemment par le routage du courrier, avec les enregistrements MX. Le MX était la première utilisation du DNS pour faire autre chose que de la simple traduction de nom en adresse IP. En partie droite d'un MX, on trouve le nom du ou des serveurs qui gèrent la messagerie pour le domaine en partie gauche. Bien sûr, une convention de nommage (du genre « le serveur de messagerie de example.org se nomme mail.example.org ») aurait pu jouer un rôle similaire. Mais les MX sont plus souples (le serveur d'un domaine n'est pas obligé d'avoir un nom dans le domaine, cf. RFC 4367) et offrent des possibilités supplémentaires (plusieurs serveurs, avec des priorités différentes). Mais le MX est spécifique au courrier électronique. Les enregistrements SRV, créés par le RFC 2052 (aujourd'hui RFC 2782), ont étendu le principe à tous les protocoles qui voulaient en profiter (avec des choses en plus comme l'indication du numéro de port ou bien comme la répartition de charge). Tous les protocoles créés depuis utilisent ces enregistrements, à la triste exception de HTTP qui, stupidement (l'avis est le mien, il n'est pas dans le RFC), ne fournit pas de mécanisme pour trouver le serveur d'un domaine (obligeant à utiliser des conventions de nommage comme www.example.com ou, pire, à mettre une adresse IP sur le domaine lui-même, et empêchant d'utiliser le DNS pour la répartition de charge et la résilience, ce qu'auraient permis les SRV).

Autre service fourni aux applications par le DNS, les enregistrements NAPTR. L'idée au début était de pouvoir trouver n'importe quel identificateur, même distinct d'un nom de domaine, dans le DNS (RFC 2915). Les NAPTR permettent de spécifier des transformations complexes depuis une famille d'identificateurs, vers les noms de domaine. L'idée est ancienne. Sa première manifestation avait été le domaine in-addr dans le RFC 883 (c'était un TLD à l'époque, il est devenu in-addr.arpa dans le RFC 973). Son but était de permettre de traduire des adresses IP en noms, en convertissant d'abord l'adresse IP en un nom de domaine se terminant en in-addr. Ce genre de transformation textuelle sur un identificateur pour en faire un nom de domaine a ensuite été reprise par tpc.int (RFC 1530, un mécanisme pour router des appels téléphoniques via l'Internet, qui allait déboucher sur ENUM). Ces mécanismes ne changent pas le protocole DNS mais ils changent la manière dont on se sert du DNS, et apportent de nouveaux utilisateurs, ayant de nouvelles attentes.

Une des demandes de ces « nouvelles » applications est de stocker des données quelconques dans le DNS. On peut mettre ce qu'on veut dans un URI (et même directement des données, cf. RFC 2397). Donc, comme un NAPTR mène à un URI, il peut nous mener à n'importe quoi. Mais, avant même cette astuce, le DNS pouvait déjà stocker n'importe quoi. Il existe même un type d'enregistrement, TXT, spécialement prévu pour des données non structurées. La souplesse du TXT et son absence de contraintes ont attiré plein de gens, malgré les conseils de prudence du RFC 5507. Il y a même eu une proposition de structurer le contenu des TXT (RFC 1464).

Bon, mais qui y a-t-il de mal à ce que les gens se servent du DNS pour y mettre des informations ? En combinant les différentes techniques vues ci-dessus, on pourrait faire tenir n'importe quel protocole requête/réponse dans le DNS. Mais ce n'est pas complètement exact. La section 3 décrit les défis auxquels son succès confronte le DNS. Certes, le DNS est une base de données répartie, fiable, et rapide. Mais lorsqu'on dit « base de données », certains utilisateurs voudraient que le DNS fournisse des services classiques des bases de données, comme la confidentialité, le contrôle d'accès, l'introspection (utiliser le protocole d'accès pour découvrir le schéma) et la possibilité de requêtes structurées complexes, un peu comme ce que fournit SQL. Mais le DNS n'a pas été conçu pour cela et ce RFC argumente que, plutôt que de forcer le DNS à fournir ces services, on utiliserait mieux son temps à développer d'autres protocoles ou tout simplement à utiliser d'autres protocoles existants. Le succès du DNS et ses qualités viennent justement de ce qu'il n'essayait pas de tout faire.

Les exemples donnés par le RFC sont tous empruntés au monde ENUM (RFC 6116) mais les questions soulevées ne sont pas spécifiques à ENUM.

D'abord, les critères de recherche : dans le DNS, la clé d'accès est le triplet {nom de domaine, classe, type}, par exemple (en syntaxe dig) www.afnic.fr. IN AAAA, et la correspondance doit être exacte (pas de recherche floue). Or, certains souhaiteraient pouvoir exprimer des requêtes plus riches. Des tentatives ont été faites pour mettre des critères supplémentaires dans le nom de domaine lui-même (par exemple, pour ENUM, tg011.0.0.4.5.4.3.4.1.7.5.1.e164.arpa pour ajouter au nom normal, 0.0.4.5.4.3.4.1.7.5.1.e164.arpa, qui est dérivé du numéro de téléphone, le trunk group tg011) mais cela devient vite pénible lorsque le nombre de critères augmente.

Autre solution envisagée, EDNS (RFC 6891), en passant les critères supplémentaires comme options EDNS. Mais cela ne marche pas comme certains le prévoient car EDNS est de saut en saut et pas de bout en bout : un serveur DNS relais ne va pas transmettre les options EDNS.

Enfin, les requêtes complexes posent un problème pour les caches, si fréquents avec le DNS. Les caches actuels considèrent que la réponse ne varie qu'avec le triplet {nom de domaine, classe, type} et pourrait donc garder en cache à tort des réponses faites à des requêtes plus complexes.

Autre demande fréquente des nouveaux utilisateurs du DNS, avoir des réponses « à la tête du client », dépendant de l'émetteur de la question. Il est par exemple courant aujourd'hui de servir des réponses différentes selon l'adresse IP de la source (option view de BIND). Tant que cela ne sert qu'à présenter des versions adaptés d'un contenu (un portail Web différent selon le pays d'origine de la requête), sans problème de sécurité, ce n'est pas trop grave : une erreur n'aura pas de conséquences trop ennuyeuses. Pour des cas plus sensibles, cela peut être gênant. D'autant plus que l'adresse IP de la source n'est pas celle du vrai client, mais celle du résolveur qu'il utilise. Dans certains cas (Google Public DNS), la distance entre les deux peut être énorme. Une option EDNS a été proposée pour que le résolveur puisse indiquer au serveur faisant autorité la vraie adresse IP du client mais elle n'est pas encore adoptée (entre autres, elle pose des problèmes si le client a une adresse IP privée, genre RFC 1918).

Le DNS a d'autres limites lorsqu'on veut l'utiliser comme base de données générique, par exemple la taille des noms de domaine (limitée à 63 caractères par composant) et la taille des réponses. Quelle limite de taille ? L'ancienne limite de 512 octets n'est normalement plus qu'un souvenir (mais il existe encore des pare-feux bogués ou mal gérés qui imposent cette limite) mais il y a deux autres seuils derrière, la MTU (si la réponse est plus grosse, on risque de la fragmentation) et les 4 096 octets qui sont, en pratique, la limite de la plupart des serveurs. Si la réponse est un URI, notez que le RFC 2397 sur les URI data: indique que ceux-ci doivent être « courts » mais il ne définit pas cet adjectif. Le RFC note que, dans le contexte d'ENUM, stocker des sonneries de téléphone rigolotes sous forme de fichiers MP3 dans un URI data: n'est probablement pas raisonnable.

En outre, le DNS reposant sur UDP, qui ne garantit pas l'adresse IP source, des données de grande taille augmentent les risques d'attaque avec amplification (RFC 4732, section 3). Dans ces attaques, le méchant émet une requête DNS (de petite taille, donc) en usurpant l'adresse IP source de sa victime. Le serveur va alors répondre à celle qu'il croit être l'émetteur et la réponse est souvent bien plus grande que la question (le RFC cite l'exemple d'un certificat stocké dans le DNS, comme dans le RFC 4398). L'attaquant pourra donc obtenir ainsi un trafic plus important que ce qu'il peut lui-même générer. C'est d'ailleurs une des raisons pour lesquels les serveurs de .com, par exemple, limitent leurs réponses à 1 460 octets. Bref, malgré EDNS, on ne peut pas espérer faire passer dans le DNS des données de taille quelconque. Le DNS est prévu pour des informations courtes.

Autre limite du DNS lorsqu'on essaie de s'en servir comme d'une base de données générique, la non-correspondance des frontières administratives avec celles du DNS : les frontières des composants d'un nom de domaine ne sont pas forcément celles qu'on voudrait. Par exemple, pour la téléphonie, les anciennes numérotations étaient très hiérarchiques (et correspondaient donc bien au DNS) alors que, depuis la portabilité des numéros de téléphone, ce n'est plus le cas et il n'est donc pas évident de savoir où déléguer les noms ENUM. Ce n'est pas juste un problème esthétique : le bon fonctionnement du DNS dépend des délégations qui sont « cachées » (gardées en mémoire) dans les résolveurs, et qui épargnent à la racine la grande majorité des requêtes. Avec la portabilité des numéros téléphoniques, il faut interroger la racine ENUM pour tout numéro (puisqu'on ne peut pas savoir à l'avance quel opérateur téléphonique le gère). C'est d'autant plus ennuyeux pour la racine ENUM que les correspondances entre un numéro et un opérateur changent et qu'on souhaite souvent une portabilité rapide (de l'ordre de quinze minutes), peu compatible avec une racine simple et efficace.

Si vous pensez que ce n'est pas si grave, que .com est un espace plat avec de nombreux noms et des changements rapides, ce qui démontre que le DNS peut s'en tirer, pensez que dans les seuls États-Unis, il y a trois cents millions de numéros de téléphone attribués, trois fois la taille de .com.

Le problème n'est évidemment pas spécifique à ENUM : si on créait un mécanisme de portabilité pour les adresses IP, les domaines comme in-addr.arpa auraient les mêmes problèmes.

La section 4 est entièrement consacrée à un problème particulier qui a fait couler beaucoup d'encre, le désir d'avoir des réponses DNS « à la tête du client ». Officiellement, le DNS présent une vue unique à tous les utilisateurs (ce point est développé dans le RFC 2826) qui affirme que les noms doivent être uniques et donc donner un résultat unique. Mais il existe une forte demande pour avoir des noms qui ne fonctionnent que dans un espace privé (à l'intérieur d'une entreprise, par exemple), afin de limiter l'accès à certaines ressources. Il existe plusieurs solutions techniques pour avoir des réponses différentes en local et en public mais aucune n'est parfaitement satisfaisante. Par exemple, si on utilise des noms locaux avec un TLD bidon comme .prive ou .local, ces noms « fuiront » un jour ou l'autre, seront vus à l'extérieur, ce qui générera de la confusion (section 3.3 du RFC 5507).

Bien, après toutes ces critiques et toutes ces limites du DNS, quels conseils pratiques donner à ceux et celles qui voudraient quand même utiliser le DNS ? La section 5 est composée d'excellents conseils pour les développeurs d'applications ou de services utilisant le DNS. En gros, le DNS sera sans doute une bonne solution si le service qui veut l'utiliser a toutes ces propriétés :

  • Les données à publier peuvent être distribuées (et mémorisées dans les caches) en utilisant les mécanismes standards du DNS,
  • Les données sont accessibles par des clés qu'on peut convertir en noms de domaine sans violer leur sémantique,
  • Les clés en question (les noms de domaine) doivent être utilisées dans leur totalité (pas de recherche sur un nom partiel),
  • Les réponses ne dépendent pas du demandeur,
  • Une fois ses informations obtenues, l'application utilisera le DNS pour trouver le pair à contacter.

Si une seule de ces propriétés manque, le DNS n'est peut-être pas la bonne solution pour le problème. À l'inverse, de bons signaux d'alarme, indiquant qu'on utilise le DNS à tort, sont :

  • On a besoin de rajouter des données indiquant les frontières administratives (ce que les applications n'ont normalement pas besoin de connaître),
  • Les identificateurs utilisés ont une sémantique ou un modèle radicalement différent de celui du DNS (par exemple, ils sont dans un espace plat, alors que le DNS doit son efficacité à son modèle hiérarchique),
  • On veut distribuer des données à certaines personnes et pas à d'autres,
  • Les réponses sont de grande taille, poussant les limites du DNS trop loin.

Bon, mais si on n'utilise pas le DNS, alors quoi ? Le RFC suggère que, dans beaucoup de cas de protocole requête/réponse, HTTP convient parfaitement (par exemple, il a de l'authentification, il peut transporter des données de taille quelconque, il est largement déployé...)

Pendant l'élaboration de ce RFC, des commentaires intéressants ont été enregistrés dans le système de suivi des tâches.


Téléchargez le RFC 6950


L'article seul

La crypto n'a pas que des avantages

Première rédaction de cet article le 4 octobre 2013
Dernière mise à jour le 14 février 2015


Suite aux révélations du héros Edward Snowden, bien des gens ont pris conscience de ce que tous les experts en sécurité annonçaient depuis longtemps : les services d'espionnage espionnent et ne respectent aucune limite. Notamment, tout le trafic envoyé sur l'Internet peut être écouté, si on ne prend pas de précautions particulières. La solution technique la plus souvent citée est l'usage systématique de la cryptographie. Ce choix est tout à fait justifié. Mais il ne faut pas s'imaginer qu'il va être gratuit : tout chiffrer va faire perdre certaines possibilités, notamment en matière de déboguage.

Cet article a été motivé par une formation où on programmait des accès à un service réseau, via une API qui reposait sur HTTPS. Un moment, on avait un doute sur ce qu'on envoyait, quelqu'un a dit « on va utiliser Wireshark pour examiner ce qu'on envoie vraiment » et paf : à cause du S de HTTPS, la session était entièrement chiffrée par TLS et Wireshark ne pouvait pas aider. Une décision de sécurité parfaitement justifiée (ne permettre l'accès qu'en HTTPS) a fait perdre un remarquable outil de déboguage des applications HTTP.

Bien sûr, compte tenu des révélations de Snowden citées plus haut, il n'y a guère le choix. Même si on n'est pas sûr que la cryptographie protège bien contre un adversaire de la puissance de la NSA, ne pas se protéger serait une folie, puisque la NSA et tous les espions plus petits pourraient alors regarder le contenu du trafic sans problème. Donc, il faut chiffrer. Mais, personnellement, je regrette que les géniaux outils de déboguage réseau comme tcpdump et Wireshark soient de moins en moins utiles à cause du « tout chiffrement ».

Alors, certains et certaines vont me dire « mais il existe des outils qui savent déchiffrer le trafic chiffré, si on leur fournit la(les) clés privée(s), par exemple Wireshark ». Mais ce n'est plus vrai non plus. Voyons d'abord les outils disponibles :

  • tcpdump ne sait déchiffrer que l'IPsec, protocole peu utilisé.
  • ssldump sait déchiffrer le TLS (autrefois nommé SSL).
  • Wireshark sait déchiffrer le TLS.
  • Aucun ne sait déchiffrer le SSH.

Naturellement, ssldump et Wireshark vont avoir besoin de la clé privée du serveur pour cela (autrement, TLS ne servirait à rien). Si on utilise ssldump sans cette clé privée, on voit la négociation TLS :

% ssldump -d -r /tmp/tls.pcap
...
1 1  0.2319 (0.2319)  C>S  Handshake
      ClientHello
        Version 3.1 
        cipher suites
        TLS_DHE_RSA_WITH_AES_128_CBC_SHA
...
1 2  0.4557 (0.2238)  S>C  Handshake
      ServerHello
        Version 3.1 

Mais plus rien ensuite :

...
1 11 0.8215 (0.0110)  C>S  application_data
1 12 1.6280 (0.8065)  S>C  application_data
1 13 1.6845 (0.0564)  S>C  application_data
1 14 1.6993 (0.0148)  S>C  application_data
...

(Notez quand même que la négociation TLS se passe en clair, ce qui peut donner des informations à un espion.)

Si on copie la clé privée server.key sur le serveur TLS et qu'on permet à ssldump de s'en servir :

% ssldump -d -k server.key -r /tmp/tls.pcap

On ne récupère rien de plus ! C'est encore par la faute de la NSA. Celle-ci stocke apparemment les communications chiffrées sur ses disques durs, dans l'espoir de pouvoir les déchiffrer plus tard, soit par les progrès de la cryptanalyse, soit simplement en obtenant la clé privée (par espionnage, injonction d'un tribunal, etc). Les sessions TLS sont donc vulnérables à ces attaques du futur, ce qui a mené au concept de PFS (Perfect Forward Secrecy). La PFS est la propriété comme quoi un attaquant qui a copié la session et qui a obtenu la clé privée ne pourra quand même pas déchiffrer le message. Elle est mise en œuvre dans TLS via des algorithmes comme ceux dont le nom contient DHE (Diffie-Hellman éphémère), comme le TLS_DHE_RSA_WITH_AES_128_CBC_SHA de l'exemple plus haut. Avec cette procédure DHE, les deux parties (le client et le serveur TLS) se mettent d'accord sur des clés qui ne sont pas transmises et donc pas conservées dans les enregistrements de trafic. (Les autres algorithmes sont souvent nommés « RSA statique ». Avec eux, une clé de session est générée et envoyée, après chiffrement RSA, au pair. Elle sera donc accessible dans le trafic capturé.) Ainsi, ssldump et Wireshark ne peuvent rien faire (Wireshark affiche piteusement « Entire conversation (0 bytes) »). Les mises en œuvre modernes de TLS choisissent souvent ces algorithmes et, si vous avez du TLS récent et que vous n'avez pas changé la configuration, vous avez souvent du PFS par défaut... et donc pas de déboguage possible. Vous voyez en général qu'on a le PFS lorsque la négociation TLS comprend un ServerKeyExchange (section 7.4.3 du RFC 5246). Avec ssldump :

1 4  0.4582 (0.0025)  S>C  Handshake
      ServerKeyExchange

Au fait, pour comparaison, une session TLS où on n'a pas employé la PFS, le serveur ne la gérant pas :

...
1 8  0.7662 (0.1631)  S>C  ChangeCipherSpec
1 9  0.7664 (0.0002)  S>C  Handshake
      Finished
1 10 0.7762 (0.0097)  C>S  application_data
    ---------------------------------------------------------------
    GET / HTTP/1.0
    Host: www.example.net
    Accept: text/html, text/plain, text/css, text/sgml, */*;q=0.01
    Accept-Encoding: gzip, compress, bzip2
    Accept-Language: en
    User-Agent: Lynx/2.8.8dev.15 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/2.12.20
...

Cette fois, ssldump peut déchiffrer la communication en HTTP. Ne tentez pas cela avec le paquetage ssldump de Debian, il a une bogue énorme et jamais réparée, qui fait qu'on ne peut pas l'utiliser pour déchiffrer.

Donc, une nouvelle fois, la sécurité n'a pas été gratuite. La PFS est indispensable contre les attaquants modernes, mais elle fait perdre la possibilité d'utiliser les outils de déboguage avec déchiffrement. Le caractère très ouvert et très visible de l'Internet, qui m'avait tant facilité la vie lorsque j'avais appris TCP/IP avec un sniffer, en a pris un coup.

Des bonnes lectures :


L'article seul

RFC 7027: Elliptic Curve Cryptography (ECC) Brainpool Curves for Transport Layer Security (TLS)

Date de publication du RFC : Octobre 2013
Auteur(s) du RFC : J. Merkle (secunet Security Networks), M. Lochter (BSI)
Pour information
Première rédaction de cet article le 3 octobre 2013
Dernière mise à jour le 21 mai 2014


Rien d'extraordinaire dans ce très court RFC : juste l'enregistrement de trois nouvelles courbes elliptiques, collectivement nommées Brainpool, pour utilisation dans TLS.

Ces courbes Brainpool avaient été normalisées originellement dans le RFC 5639 (et leur description était dans « ECC Brainpool Standard Curves and Curve Generation - v. 1.0 »). Le protocole TLS permet d'utiliser des courbes elliptiques depuis le RFC 4492. Ces trois courbes Brainpool avaient déjà des OID mais TLS nécessitait en plus l'enregistrement de noms, ce qui est désormais fait.

Les trois courbes sont ainsi nommées, avec la syntaxe de TLS :

enum {
             brainpoolP256r1(26),
             brainpoolP384r1(27),
             brainpoolP512r1(28)
        } NamedCurve;

Et elles figurent désormais dans le registre IANA.

Au fait, pourquoi de nouvelles courbes elliptiques alors qu'il y en a déjà plein, dont certaines normalisées par le NIST ? C'est parce qu'il existe de sérieux soupçons que les courbes NIST aient été délibérement affaiblies sur ordre de la NSA (voir l'exposé « Crypto Won't Save You Either », p. 73).

Pour ceux qui lisent la langue de Konrad Zuse, il existe un site Web sur Brainpool en allemand.


Téléchargez le RFC 7027


L'article seul

Le principe de robustesse, une bonne ou une mauvaise idée ?

Première rédaction de cet article le 1 octobre 2013


On attribue souvent le succès de l'Internet, et notamment sa résilience, au principe de robustesse. Ce principe, attribué à Jon Postel, s'énonce « Be conservative in what you do, be liberal in what you accept from others. ». Que veut-il dire ? Était-ce un bon principe d'ingéniérie à l'époque ? Et l'est-il toujours aujourd'hui ?

On trouve ce principe formellement énoncé dans plusieurs RFC, parfois avec une formulation légèrement différente. Ainsi, le RFC 793 utilise le texte ci-dessus alors que le RFC 791 (également écrit par Postel) dit « In general, an implementation must be conservative in its sending behavior, and liberal in its receiving behavior. ». En se rappelant que liberal en anglais veut bien dire ce qu'il veut dire (contrairement au français où il désigne en général un partisan de laisser les forts écraser les faibles), ce principe veut dire qu'un programme qui met en œuvre un protocole réseau devrait être dur avec lui-même mais indulgent avec les autres. Par exemple, si la norme dit « un nombre entier est envoyé sous forme texte et peut comprendre des zéros au début si le nombre est inférieur à 1 000 », le programme qui suit Jon Postel ne va jamais envoyer ces zéros initiaux (afin d'être sympa avec des programmes qui n'ont pas fait attention à ce détail de la norme) mais, lorsqu'il reçoit des entiers, il acceptera des zéros initiaux. S'il est très « postelien », il les acceptera même si le nombre est supérieur à 1 000. Le « postelisme » est donc le contraire du pédantisme : le but est l'interopérabilité, que les programmes arrivent à se parler et à travailler ensemble. C'est plus important que de respecter rigoureusement la norme. (Merci à Anahi pour l'exemple, qui vient du proverbe espagnol, « como un cero a la izquierda », qui veut dire « inutile comme un zéro à gauche ».)

On comprend mieux le principe de robustesse de Postel lorsqu'on compare avec le projet qui était le principal concurrent des protocoles TCP/IP, le projet OSI de l'ISO. La culture dominante du monde OSI était au contraire d'extrême pédantisme et les programmeurs prenaient un malin plaisir à refuser les messages des autres programmes, en arguant du fait qu'ils n'étaient pas parfaitement conformes à la norme. Résultat, l'interopérabilité était très faible. C'est ainsi que, au début des années 90, un stagiaire et moi avons pu constater que deux mises en œuvre de FTAM (le concurrent OSI de FTP) développées par le même constructeur (Digital), ne pouvaient pas échanger un fichier... Et cela n'avait l'air de gêner personne dans le monde OSI.

Donc, oui, le choix de Postel s'expliquait et a en effet contribué au succès de l'Internet, OSI n'étant plus qu'un énorme gaspillage bien oublié.

Mais l'histoire ne s'arrête pas là. Car le principe de robustesse, comme n'importe quel bon principe, peut aussi, si on le pousse jusqu'au bout, donner des résultats ridicules. Car de savoir que les récepteurs seront indulgents peut pousser les envoyeurs à ne pas faire attention et à envoyer n'importe quoi, se disant que le récepteur se débrouillera. Le code du récepteur suit le principe de robustesse ? On va envoyer des entiers avec des zéros initiaux, puis on va envoyer des flottants, puis des chiffres suivis par des lettres en comptant que l'analyseur du récepteur s'arrêtera proprement. Et, rapidement, les programmes bien élevés et qui veulent interopérer seront de facto obligés de gérer ces horreurs, sous peine de ne pas pouvoir interopérer. Un exemple historique parfait est celui du langage HTML. Les premiers navigateurs acceptaient n'importe quoi, donc les webmestres ont pris l'habitude d'écrire du HTML sans faire attention à la syntaxe et, aujourd'hui, la plupart des pages Web sont incorrectes syntaxiquement (malgré d'excellents services comme le validateur du W3C) et les navigateurs sont obligés d'accepter cela : un navigateur qui rejetterait les pages mal formées ne pourrait regarder qu'une petite partie du Web. Et aucune autorité (et certainement pas le W3C, dans ce cas, où l'IETF pour les protocoles réseau) ne peut décider autrement, elles n'ont ni le pouvoir, ni l'envie. Résultat, le code est inutilement compliqué et fragile. Et HTML n'est certainement pas le seul exemple.

Le principe de robustesse est particulièrement délicat à appliquer lorsqu'il s'agit de sécurité. Une façon de résumer le principe de robustesse est de dire « ne soyez pas un fasciste pyscho-rigide, essayez de comprendre votre interlocuteur au lieu d'insister qu'il a tort ». Bref, il pousse à deviner ce que voulait dire le programme d'en face. En sécurité, c'est souvent une mauvaise idée car on peut deviner mal et ouvrir ainsi une faille de sécurité. Ainsi, le protocole DNSSEC vise à permettre d'authentifier, par des signatures cryptographiques, les enregistrements DNS envoyés. Pour éviter les attaques par rejeu, les signatures DNSSEC ont une durée de vie maximale. Bien des administrateurs DNS ont signé leurs zones sans prêter suffisemment attention à la nécessité de re-signer les enregistrements avant l'expiration. Résultat, les résolveurs DNS validants n'acceptaient plus ces enregistrements. Vu l'ampleur de ce problème, le résolveur DNS validant Unbound, par défaut, accepte des enregistrements expirés (jusqu'à 10 % de leur durée de vie totale, c'est réglable avec les paramètres val-sig-skew-min et val-sig-skew-max). C'est sympa. Mais on voit le paradoxe : un logiciel de sécurité qui décide d'accepter des enregistrements mal signés, pour ne pas être trop méchant... Si Unbound était le résolveur le plus utilisé, on verrait sans doute les administrateurs DNS ne pas trop s'inquiéter de l'expiration des signatures, disant « oui, c'est expiré mais ça va marcher encore quelque temps, grâce au principe de robustesse ».

On lit parfois que ce principe de robustesse n'avait de sens qu'autrefois, dans un Internet mythifié où de joyeux hackers hippies échangeaient des paquets librement et sans se soucier du lendemain. Mais je ne pense pas que cela soit la raison pour laquelle ce principe marchait à l'époque, et marche moins bien aujourd'hui. C'est plutôt que le principe était bon mais que les principes ne doivent pas être appliqués aveuglément, comme des règles religieuses. Ils sont un guide pour l'ingénieur, pas un moyen d'éviter de penser. C'est pour avoir oublié cela que tant de logiciels aujourd'hui doivent se battre avec des pairs mal écrits et qui les bombardent de messages bizarres.

Un débat au sujet de cet article a lieu sur SeenThis.


L'article seul

RFC 6988: Requirements for Energy Management

Date de publication du RFC : Septembre 2013
Auteur(s) du RFC : J. Quittek, M. Chandramouli (Cisco Systems), R. Winter (NEC Europe), T. Dietz (NEC Europe), B. Claise (Cisco Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF eman
Première rédaction de cet article le 1 octobre 2013


L'augmentation considérable des coûts de l'énergie, et la montée plus que justifiée des préoccupations écologiques, fait que la question de la consommation énergétique des équipements informatiques devient de plus en plus cruciale (certaines études estiment que la consommation d'énergie de l'Internet dépasse celle d'un pays comme la Russie). Les gros centres de données du nuage, usines à consommer du mégawatt, sont particulièrement visés. Cela a amené l'IETF à se lancer dans un domaine nouveau pour elle, et à créer un groupe de travail consacré à la gestion de l'énergie, EMAN, dont voici le premier vrai RFC, le cahier des charges du problème.

Le modèle envisagé est celui d'engins qui consomment ou fournissent de l'énergie, typiquement sous forme électrique, et qu'on veut pouvoir à la fois surveiller (monitoring function) et piloter (control function). Ces engins ont parfois une adresse IP, permettant de leur parler directement, et parfois pas, et il faut alors passer par un relais, qui va être la face visible de l'engin. Ce premier RFC du groupe EMAN définit les services indispensables dans les futures normes de gestion de l'énergie, suivant le modèle décrit dans le RFC 7326 (attention, ce RFC est un cahier des charges pour les normes, les futurs RFC d'EMAN, pas forcément pour les mises en œuvres qui suivront).

La gestion d'engins connectés au réseau n'est évidemment pas un problème nouveau et il existe déjà solutions et normes. Mais la gestion de l'énergie a trois particularités :

  • L'information intéressante n'est pas forcément obtenable auprès de l'engin géré. Ainsi, une machine peut être incapable d'indiquer sa consommation électrique, alors qu'on peut l'obtenir en interrogeant le dispositif qui l'alimente en électricité (par exemple un commutateur PoE) Ce genre de demandes indirectes sera fréquent dans le cadre de la gestion de l'énergie.
  • Même chose pour le contrôle (allumer ou éteindre l'engin), qui doit parfois se faire indirectement.
  • Et rappelez-vous qu'il sera fréquent que les engins connectés ne soient pas directement accessibles en IP et qu'il faille passer par un relais, ce qui est un cas bien plus rare en gestion de réseaux traditionnelle.

Avant d'aborder le cahier des charges proprement dit, la section 2 de notre RFC expose la terminologie, car tous les participants à l'IETF, bien versés dans le vocabulaire TCP/IP, ne connaissent pas forcément celui du monde de l'énergie (l'IEEE a un « Authoritative Dictionary of IEEE Standards Terms » d'où le RFC extrait plusieurs termes, mais je ne trouve pas ce dictionnaire en ligne). Donc, révisons un peu physique et ingéniérie :

  • Énergie (Energy) : dans le cadre de l'informatique et des réseaux, c'est typiquement de l'énergie électrique, mesurée en kWh (ne surtout pas écrire kW/h comme on le voit trop souvent).
  • Puissance (Power) : le taux d'usage, de production ou de transmission de l'énergie. En kW, parfois en joules par seconde.
  • Attributs (Power attributes) : les caractéristiques du courant électrique comme la tension, la phase ou la fréquence. Voir le « International Electrotechnical Vocabulary » de l'IEC.
  • Gestion de l'énergie (Energy management) : les fonctions qui permettent de mesurer, modéliser, planifier, optimiser, etc l'énergie.
  • Système de gestion de l'énergie (Energy management system) : le matériel et le logiciel qui assurent les fonctions ci-dessus.
  • Supervision de l'énergie (Energy monitoring) : le sous-ensemble de la gestion de l'énergie qui s'occupe de mesurer passivement.
  • Contrôle de l'énergie (Energy Control) : le sous-ensemble de la gestion de l'énergie qui s'occupe d'agir activement, par exemple en éteignant des machines inutiles.

La section 3 complète cette section 2 de terminologie en exposant quelques problématiques générales, qu'il faut avoir en tête lorsqu'on veut gérer l'énergie. D'abord, la notion d'état (Power state) : un engin peut être en état normal (il fonctionne, il répond et il consomme du courant), endormi (il consomme moins de courant, il ne répond pas aux requêtes normales mais il peut revenir en état normal rapidement) ou éteint (il ne consomme plus rien mais peut prendre un certain temps à se rallumer et à redevenir opérationnel). Les engins les plus simples n'ont que deux états, allumé et éteint. Les plus perfectionnés en ont plus que trois : par exemple, ils peuvent avoir des modes de basse consommation où l'engin reste complètement opérationnel mais avec des performances réduites. Sur des engins composés de plusieurs parties relativement indépendantes, il est parfois possible de couper le courant dans une partie de ces sous-ensembles et pas seulement dans l'engin entier.

Le but ultime de la gestion de l'énergie est d'économiser du courant. Comme rien n'est parfait en ce bas monde, cela se fera souvent au prix d'un service moins bon. Il sera donc en général nécessaire de faire des compromis.

La gestion de l'énergie peut être entièrement locale (à l'intérieur de l'engin lui-même) ou bien globale au réseau. Un exemple de gestion locale est une machine qui se met en sommeil automatiquement lorsqu'elle n'a pas eu d'activité depuis N minutes. Cela peut se faire sans réseau, sans collecter l'information et sans système central. Un exemple de gestion globale est un système qui voit que la consommation électrique du réseau devient trop importante (en coût ou, tout simplement, par rapport aux capacités du fournisseur d'énergie) et qui éteint alors autoritairement certains engins. Le système de gestion ayant plus d'informations que les machines locales, il peut prendre des décisions plus appropriées, et tenir compte de politiques globales (on éteint les machines dans le bureau la nuit). Les deux méthodes ont leurs avantages et leurs inconvénients et, en général, on combine les deux.

À noter (section 3.4) que la supervision de la consommation d'énergie, à elle seule, ne diminue pas la consommation. Elle va même l'augmenter, puisque le système de supervision consomme lui-même du courant. Pour que ce système mène à une diminution de la consommation, il faut aussi qu'il soit utilisé pour chercher les économies possibles, évaluer les mesures de réduction de consommation, assurer la comptabilité de chaque entité, etc.

Pour assurer une bonne supervision, avec une granularité permettant cette comptabilité, il va falloir des identificateurs pour désigner les différentes entités (section 4). Une entité peut être une machine ou bien seulement une partie d'une machine (un disque dur, par exemple, ou bien une line card). En effet, certaines mesures d'économie d'énergie peuvent être à ce niveau de détail (éteindre une seule line card). Il existe déjà de tels identificateurs, par exemple dans les MIB des RFC 4133 et RFC 3621. Il faudra donc lier les informations de gestion de l'énergie à ces identificateurs, traitant des problèmes comme la persistence en cas de redémarrage.

Ensuite, il faut connaître, pour chaque entité supervisée et/ou contrôlée, un certain nombre d'informations (section 5). Par exemple, il est préférable de connaître l'importance d'une entité, pour éviter d'éteindre une machine importante alors qu'on voulait économiser quelques watts. Une autre propriété utile est l'ensemble des caractéristiques statiques de son alimentation électrique : utilise-t-elle du courant continu ou alternatif, quelle est la tension normale, la fréquence normale (par exemple, 230 V à 50 Hz), etc. Il faut aussi connaître la liste des interfaces utilisées pour l'énergie, et s'il s'agit de production (power outlet, par où on envoie de l'énergie) ou de consommation (power inlet, par où on reçoit de l'énergie).

Et il y a des caractéristiques dynamiques :

  • Est-ce que le courant est disponible sur la prise ? Est-il utilisé ? Si oui, quelle est la puissance consommée ou produite en ce moment ? Attention, ce dernier point peut nécessiter des équipement de mesure coûteux. Certaines machines ne vont pas être capables de mesurer précisement leur propre consommation.
  • Et la consommation ou production d'énergie (rappel : l'énergie est la puissance multipliée par le temps) ? Que vaut-elle sur un intervalle de temps donné ?
  • Pour faciliter les alarmes, le RFC suggère aussi que la machine soit capable de signaler que la puissance tombe en dessous d'une certaine valeur, ou grimpe au-dessus d'un maximum.
  • Quelles sont la tension et l'intensité actuelles ?
  • Quel est l'état de la machine supervisée, allumée, éteinte, en basse consommation, en veille ? Et quels sont les états possibles (ils ne sont pas les mêmes pour toutes les machines) ? Là encore, pour les alarmes, un mécanisme de notification non sollicitée, permettant d'être informé des changements d'état, est demandé.
  • Il y a bien d'autres choses à superviser comme l'état des batteries (en train de se charger ? de se décharger ?), leur charge (pleine ? vide ? à moitié vide ?), mesurée en mAh avec évidemment des alarmes en dessous d'un certain seuil ou comme leur température.

Après la supervision, le contrôle (section 6). Contrairement à la supervision, il est actif. Il s'agit d'agir. Agir sur quoi ?

  • Couper ou allumer le courant (le RFC avertit que certains engins peuvent ne pas aimer une coupure brutale et que cette fonction doit donc se faire dans le cadre d'un système de gestion plus général, qui ne prend pas en compte que la consommation d'énergie).
  • Faire passer l'engin d'un état (basse consommation, veille, hibernation, etc) à un autre.

Une section 9 détaillée couvre les problèmes de sécurité. On a beaucoup parlé des risques de sécurité des SCADA, souvent connectés à l'Internet sans réflechir. Ces systèmes de contrôle, souvent anciens et n'ayant pas fait l'objet d'une analyse de sécurité sérieuse, sont parfois reliés à ce réseau mondial sans précautions. Contrôler l'état des machines et leur fourniture d'électricité est clairement une fonction très sensible. La sécurité doit donc être soigneusement pesée. Tout doit être authentifié et autorisé. Et les engins qui mettent en œuvre les services décrits dans ce RFC ne devraient pas être connectés à l'Internet public sans une très bonne raison (section 9.2).

Il n'y a pas que le contrôle qui pose des problèmes de sécurité. Par exemple, la supervision soulève des problèmes de vie privée, comme cela a été plusieurs fois évoqué dans le débat sur les compteurs intelligents.

Depuis ce cahier des charges, plusieurs RFC sur le sujet ont été publiés comme les RFC 7326 et le RFC 7603.


Téléchargez le RFC 6988


L'article seul

Le service d'hébergement de machines virtuelles de Numergy

Première rédaction de cet article le 30 septembre 2013


Profitant d'une offre d'essai gratuite (qui semble toujours d'actualité), j'ai testé le service de machines virtuelles (IaaS) de Numergy.

Ce service est un des survivants du défunt projet Andromède, qui visait à faire un « cloud français », en oubliant au passage que des fournisseurs de solution infonuagiques existaient déjà depuis des années en France. Andromède s'est cassé la figure et le relais a été pris par deux projets, Numergy et Cloudwatt. À ma connaissance, Cloudwatt n'a toujours pas d'offre opérationnelle mais Numergy en a une.

Pour l'utilisateur ordinaire, rien de nouveau : on se crée un compte sur une interface Web (qui accepte mon adresse, ce qui est rare), on demande la création d'une VM et quelque temps après (c'est assez long), on se connecte et on est root.

Curieusement, on n'a pas d'adresse IPv4 publique, mais une adresse du RFC 1918 :

% ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:50:56:95:42:e1  
          inet addr:10.200.0.73  Bcast:10.200.15.255  Mask:255.255.240.0
          inet6 addr: fe80::250:56ff:fe95:42e1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4846090 errors:0 dropped:409062 overruns:0 frame:0
          TX packets:161835 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:441749938 (441.7 MB)  TX bytes:46077749 (46.0 MB)

Ce n'est pas pour économiser des adresses IPv4 puisque chaque client peut rediriger à sa guise les ports d'une adresse publique vers son serveur. Numergy dit que cette architecture inhabituelle obéit à des raisons de sécurité. Peut-être aussi cette indirection (de l'adresse publique vers l'adresse privée) leur permet-elle davantage de souplesse dans la gestion du réseau. En tout cas, cela a été l'occasion de vérifier que le support répondait, et assez vite. Et par courrier électronique, pas besoin de passer par une exaspérante interface Web qui essaie de vous retarder le plus possible en posant plein de questions.

Comme vous pouvez le voir ci-dessus, Numergy ne fournit pas d'IPv6. C'est incroyable en 2013, et cela met Numergy très loin derrière les fournisseurs qui font du cloud en France depuis des années, qui ont tous IPv6 depuis longtemps.

On est routé par le réseau de SFR, comme le montre un traceroute :

...
 5  neuf-telecom.sfinx.tm.fr (194.68.129.178)  7.352 ms  7.458 ms  7.518 ms
 6  250.29.3.109.rev.sfr.net (109.3.29.250)  9.926 ms  9.230 ms  9.207 ms
 7  30.12.6.109.rev.sfr.net (109.6.12.30)  10.825 ms  9.792 ms  9.827 ms
 8  145.29.3.109.rev.sfr.net (109.3.29.145)  8.127 ms  8.015 ms  8.025 ms
 9  202.49.6.109.rev.sfr.net (109.6.49.202)  8.202 ms  8.050 ms  8.004 ms
10  cld2001rt.trp.sfr-sh.net (212.23.184.68)  17.466 ms  17.357 ms  17.537 ms
11  * * *
12  * * *

Le tout est fiable : supervisé par Icinga, ma machine n'a eu que trois heures de défaillance en deux mois (et le problème peut être du côté de mon système de supervision, je n'ai pas creusé plus loin).

Via l'interface Web, on peut configurer la redirection de ports entrants, les règles de filtrage (dans Administration -> Flux), etc. Il existe aussi une API REST mais que je n'ai pas testée (pour l'instant, c'est celle d'OpenStack). Globalement, rien de nouveau ou d'extraordinaire dans ce service. Juste un autre hébergeur de VPS.


L'article seul

On ne « tombe » pas dans le domaine public

Première rédaction de cet article le 30 septembre 2013


Le passage des œuvres de Guillaume Apollinaire dans le domaine public (94 ans après sa mort, ce qui donne une idée du niveau de délire atteint par le droit soi-disant d'auteur) est l'occasion de revenir sur un point de vocabulaire important : contrairement à ce qu'on écrit souvent, ses œuvres ne sont pas tombées dans le domaine public, elles y sont montées.

La nuance est d'importance car le terme le plus courant, « tombé dans le domaine public », est idéologiquement très chargé. Il vient des défenseurs de l'appropriation intellectuelle et sous-entend que le domaine public est une chute en dehors du monde (forcément plus élevé) du contrôle par les ayant-trop-de-droits.

Voilà pourquoi je reprends les gens qui utilisent ce terme erroné et que je dis que les œuvres d'Apollinaire sont montées dans le domaine public. Pour citer dwarfpower, « l'œuvre sort du patrimoine personnel pour entrer dans le patrimoine humain ».

D'autres termes seraient possibles. J'ai lu des suggestions de dire :

  • « élevé dans le domaine public » ce qui serait un meilleur contraire à « tombé » (« monté » serait plutôt le contraire de « descendu »). Pourquoi pas ?
  • « entré dans le domaine public », terme qui semble à ses défenseurs plus neutre, entre les extrêmes que sont « tombé dans le domaine public » et « monté dans le domaine public ». Mais je ne vois pas pourquoi il faudrait être neutre : je pense moi aussi qu'appartenir à tous est moralement et politiquement supérieur à n'appartenir qu'aux héritiers.
  • « libéré ». Là, par contre, cela me semble une erreur : un auteur peut parfaitement décider de publier sous une licence libre (c'est le cas de ce blog), son œuvre ne sera pas pour autant dans le domaine public (le droit moral s'y opposant).

Bref, je préfère « monté ».


L'article seul

RFC 7033: WebFinger

Date de publication du RFC : Septembre 2013
Auteur(s) du RFC : Paul E. Jones, Gonzalo Salgueiro (Cisco Systems), Michael B. Jones (Microsoft), Joseph Smarr (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 28 septembre 2013


Ce RFC décrit (même si elle n'est pas présentée ainsi) la deuxième version du protocole WebFinger. La première était informelle et permettait de récupérer de l'information sur une personne ou une organisation à partir de son adresse de courrier. La deuxième version, la première officiellement normalisée, généralise WebFinger : la clé d'entrée dans l'information est un URI, qui peut être une adresse de courrier (mailto:, RFC 6068) mais pas forcément.

WebFinger doit son nom à l'antique protocole Finger, normalisé dans le RFC 1288. Finger permettait de récupérer de l'information sur une personne, identifiée par login@nom-de-machine en se connectant sur le port 79 de la dite machine. On obtenait une réponse non structurée (du texte libre). Au contraire, WebFinger tourne sur le port 80, celui de HTTP, utilise REST, et envoie une réponse structurée, en JSON, qui est donc analysable par un programme. On nomme cette réponse le JRD, JSON Resource Descriptor.

Que contient ce JRD ? Ce qu'on veut. Pas grand'chose si on est soucieux de vie privée et, sinon, une adresse, un numéro de téléphone, une photo, etc. WebFinger peut être utilisé pour des entités non humaines (une imprimante, une machine à café, etc), pour obtenir de l'information sur leurs capacités. Par contre, WebFinger est prévu pour de l'information relativement statique, et pas pour se renseigner sur l'état actuel. Pour une imprimante, il peut servir à apprendre qu'elle sait faire de la couleur, ou seulement du noir & blanc, mais pas à connaître la quantité de feuilles de papier restant dans le bac.

(Pour des raisons historiques, certaines mises en œuvre de WebFinger distribuent un XRD, la même chose mais en XML. D'une manière générale, attention à ce que vous trouvez avec un moteur de recherche, lorsque vous demandez « webfinger » : ce seront souvent des informations complètement dépassées.)

Et quel genre d'URI peut-on utiliser en argument ? Ce qu'on veut mais, en pratique, l'usage le plus courant aujourd'hui est avec les URI acct: (normalisés dans le RFC 7565).

WebFinger reste délibérement ouvert : le RFC spécifie un protocole et un format mais pas une sémantique. Ainsi, le JRD peut avoir un contenu très varié selon les applications. L'idée est que chaque application de WebFinger spécialisera ce protocole et ce format, en indiquant plus précisément le type d'URI attendu et les informations contenues dans le JRD de réponse. À noter que ce point avait fait l'objet de vives controverses à l'IETF, à la fin du processus de normalisation. Tel que spécifié, WebFinger semblait à certains terriblement vague, un framework plutôt qu'un protocole. Selon les mots de Pete Resnick lors de la discussion entre l'IESG et les auteurs, « I suspect that the semantics are so underspecified that there could not possibly be interoperable implementations without lots of out-of-band information ». C'est pour cela que le RFC intègre aujourd'hui ces précisions : la sémantique sera dans d'autres spécifications (la section 8 du RFC détaille ce choix et ses conséquences).

La section 3 donne deux exemples d'utilisation, le premier dans le cas d'OpenID Connect et le second pour récupérer des métadonnées sur une page Web. Dans le premier cas, Carol veut s'authentifier auprès d'un site Web et donne son identificateur OpenID Connect, carol@example.com. Le site qui authentifie va utiliser WebFinger (avec l'URI acct:carol@example.com, avec le plan acct:) pour trouver le fournisseur OpenID de Carol. Dans le second cas, le client WebFinger va interroger le site qui héberge la page Web et demander en utilisant comme URI celui de la page Web.

À noter que les versions préliminaires de ce RFC avaient également plein d'exemples très hypothétiques, jamais utilisés en vrai, et qui ont été ensuite supprimés. On y trouvait par exemple un mécanisme possible pour l'autoconfiguration du client de courrier électronique, qui n'apportait rien par rapport au RFC 6186.

Avant de se plonger dans le protocole lui-même, la section 2 rappelle quelques points de vocabulaire. WebFinger étant, comme son nom l'indique, fondé sur le Web, il fait un grand usage des liens, tels que décrits dans le RFC 5988, pour indiquer une relation. La relation a un type et une information liée. En HTTP, le RFC 5988 utilise ainsi les attributs rel (type de la relation) et href (information liée) dans un en-tête Link:. WebFinger représente le même concept en JSON avec des objets JSON links (un tableau JSON), chacun comportant un membre rel et un membre href. Un exemple, pour une entité qui est un article publié sur le Web (le deuxième cas d'exemple cité plus haut, la recherche de métadonnées), les liens seraient :

"links" : [
    {
         "rel" : "copyright",
         "href" : "http://www.example.com/copyright"
    },
    {
         "rel" : "author",
         "href" : "http://blog.example.com/author/steve",
    }
]

Cet exemple se lit : l'entité interrogée via WebFinger a un copyright (qu'on peut trouver en http://www.example.com/copyright) et un auteur, décrit en http://blog.example.com/author/steve.

La section 4 décrit le protocole complet. C'est du REST, donc au dessus de HTTP. Le client WebFinger doit spécifier l'URI de l'entité sur laquelle il veut des informations et il peut aussi spécifier un ou plusieurs types de relations qui l'intéressent (par défaut, il va tout recevoir). À noter que WebFinger impose l'usage de HTTPS, ce protocole étant souvent utilisé pour transporter des données sensibles (section 9.1, et c'était un des points de discussion les plus chauds à l'IETF). La requête WebFinger va utiliser un chemin qui utilise le préfixe .well-known du RFC 5785 et le suffixe webfinger (désormais enregistré dans les noms bien connus). Si l'URI de l'entité qui nous intéresse contient un nom de machine, c'est cette machine que contacte le client WebFinger (sinon, il doit se débrouiller, d'une manière non précisée). La méthode HTTP utilisée est toujours GET (section 9.3 du RFC 2616). Prenons un exemple, celui de l'article http://blog.example.com/article/id/314 sur lequel on voudrait plus d'informations. Le client WebFinger va se connecter à blog.example.com en HTTPS et envoyer la requête HTTP :

GET /.well-known/webfinger?resource=http%3A%2F%2Fblog.example.com%2Farticle%2Fid%2F314 HTTP/1.1
Host: blog.example.com

Le composant de requête (section 3.4 du RFC 3986) resource est l'URI (ici pour-cent encodé) de l'entité qui nous intéresse.

Si le serveur WebFinger connait l'entité en question, et accepte de répondre, il répond par le JRD (les données en JSON, étiquetées application/jrd+json, et décrites plus loin, en section 4.4 du RFC). Dans tous les autres cas, il répond par les codes HTTP traditionnels (400 « tu as oublié un truc, peut-être la resource », 403 « pas question que je te réponde à toi », 404 « je ne connais pas cette entité », 500 « j'ai un problème », 429 « trop de travail, je craque », etc).

Et si le client a inclus un ou plusieurs rel dans sa requête, indiquant qu'il n'est pas intéressé par tous les types de données mais seulement par certains ? Cela n'influe que sur le membre links du JRD, qui n'incluera alors que ce qui est demandé. Reprenons l'exemple de notre page Web et ne cherchons que l'auteur :

GET /.well-known/webfinger?resource=http%3A%2F%2Fblog.example.com%2Farticle%2Fid%2F314&rel=author HTTP/1.1
Host: blog.example.com
...
"links" : [
    {
         "rel" : "author",
         "href" : "http://blog.example.com/author/steve",
    }
]

Quel est l'intérêt (après tout, le client pourrait ainsi bien filtrer les types de liens après les avoir tous récupérés) ? Économiser des ressources sur le serveur (certaines informations peuvent nécessiter des requêtes compliquées dans une base de données) et diminuer le débit réseau. Notez toutefois, si vous écrivez un client, que tous les serveurs ne gèrent pas ce paramètre rel dans la requête et que le client risque donc toujours de tout récupérer, et de devoir trier ensuite.

Le format complet du JRD (JSON Resource Descriptor, annexe A du RFC 6415 et dérivé du XRD) figure en section 4.4. C'est un objet JSON (RFC 7159) comprenant les membres subject, aliases, properties et links que nous avons déjà vu. subject, le seul obligatoire, est un identificateur de l'entité sur laquelle on se renseigne (en général le même que le paramètre resource), properties sont les informations sur l'entité (un registre IANA les stocke, en échange d'une spécification écrite, cf. section 10.4.2) et links les liens. links est le plus complexe. Chaque lien est un objet JSON comportant plusieurs membres. rel est le seul obligatoire et sa valeur est, soit un type enregistré à l'IANA selon le RFC 5988, soit un URI (on peut ainsi « créer » ses propres types). Les autres membres possibles sont type (un type MIME), href (pointe vers la valeur du lien), titles (un texte humainement lisible, par exemple pour le présenter à l'utilisateur, marqué par une étiquette de langue) et properties (informations diverses). Voici un exemple complet, tiré du RFC, toujours au sujet de notre page Web intéressante :

{
       "subject" : "http://blog.example.com/article/id/314",
       "aliases" :
       [
         "http://blog.example.com/cool_new_thing",
         "http://blog.example.com/steve/article/7"
       ],
       "properties" :
       {
         "http://blgx.example.net/ns/version" : "1.3",
         "http://blgx.example.net/ns/ext" : null
       },
       "links" :
       [
         {
           "rel" : "copyright",
           "href" : "http://www.example.com/copyright"
         },
         {
           "rel" : "author",
           "href" : "http://blog.example.com/author/steve",
           "titles" :
           {
             "en" : "The Magical World of Steve",
             "fr" : "Le Monde Magique de Steve"
           },
           "properties" :
           {
             "http://example.com/role" : "editor"
           }
         }
      ]
}

La section 7 du RFC couvre un cas délicat, celui de services WebFinger hébergés. Si on souhaite sous-traiter WebFinger à un tiers, comment l'indique t-on ? La seule solution est de faire une redirection HTTP depuis son site. Par exemple, avec Apache, on mettra dans la configuration :

Redirect /.well-known/webfinger http://wf.example.net/.well-known/webfinger

Et les requêtes WebFinger qu'on recevra seront gérées par le prestataire wf.example.net par le biais d'une redirection HTTP.

La section 8 décrit ce que veut dire « spécifier l'usage de WebFinger pour une application ». On a vu que WebFinger fournissait un protocole et un format très général. Chaque application qui compte se servir de WebFinger doit préciser un certain nombre de choses, notamment le contenu du JRD attendu. Si vous voulez vous servir de WebFinger pour un nouveau service très cool, vous allez devoir lire cette section et rédiger les détails. Première chose, le type d'URI attendu (acct: ? un autre ?) Deuxième chose, comment trouver le serveur à interroger. Si l'URI utilise le plan http:, c'est trivial. Mais pour les acct: ou les mailto: ? L'application doit donc préciser comment on trouve le serveur WebFinger (cela peut être aussi simple que d'avoir un serveur WebFinger central, codé en dur dans les programmes, pour tous les URI de l'application...)

Enfin, l'application doit spécifier le contenu attendu : quelles properties sont obligatoires dans la réponse, par exemple ? Même chose pour les liens : quels types rel peuvent/doivent être utilisés dans les liens ?

Ce n'est pas un peu indiscret, toutes ces informations distribuées à tout vent ? Si, et ce point a fait l'objet de vives discussions à l'IETF, ce qui a fini par donner naissance aux sections 6 et 9.2 de ce RFC. Le principal avantage de WebFinger (un seul endroit où aller pour récupérer toutes les informations sur une entité, et sous une forme structurée, ce qui est très pratique pour les programmes qui vont l'analyser) est aussi son principal risque (comme dit le RFC «  The easy access to user information via WebFinger was a design goal of the protocol, not a limitation »). Le RFC cite l'exemple de données qui permettraient le harcèlement d'une personne. L'article « Abusing social networks for automated user profiling » illustrait bien comment le recoupement d'informations provenant de différents réseaux sociaux permettait de découvrir plein de choses sur les utilisateurs.

Ces sections « vie privée » du RFC rappellent qu'un serveur WebFinger ne distribue que ce qu'il veut. En cas de demande d'information sur une personne, par exemple, la norme technique qu'est ce RFC ne spécifie pas qu'on doive distribuer l'adresse et le numéro de téléphone. C'est un choix des administrateurs du serveur. (Au passage, c'est exactement la même chose pour le protocole whois, RFC 3912, un protocole dont les usages sont proches de ceux de WebFinger. Le RFC spécifie un protocole, pas une politique de distribution des données.)

Ensuite, le serveur n'est pas obligé d'être ouvert à tout le monde. Il peut parfaitement utiliser l'authentification HTTP (ou d'autres mécanismes de contrôle d'accès comme l'adresse IP du client) pour restreindre la distribution d'informations à certains. Un serveur WebFinger est également, cela va de soi, autorisé à fournir des réponses différentes selon le client. Par exemple, on peut imaginer une réponse minimale pour les clients inconnus, et davantage de détails pour ceux qui s'authentifient. Le RFC ne cite pas les questions légales (hors sujet pour une norme technique) mais, par exemple, un serveur WebFinger d'une entreprise qui distribuerait des détails personnels sur ses employés, comme des photos, sans leur autorisation, serait certainement en violation de la directive européenne sur la protection des données personnelles.

La section 9.2 demande donc que, pour tout service WebFinger, il existe une interface permettant aux utilisateurs d'indiquer de manière simple s'ils veulent que des informations à leur sujet soient publiées ou pas, et lesquelles. Par exemple, pour un réseau social typique, on peut imaginer que les utilisateurs choisissent quels éléments d'information sur eux soient publics et, dans ce cas, que seuls les éléments ainsi marqués soient distribués par WebFinger. Le RFC demande aussi que, par défaut, rien ne soit publié (ce qui n'est certainement pas la pratique des gros silos de données comme Facebook).

Les liens fournis en réponse à une requête WebFinger peuvent d'ailleurs eux aussi pointer vers des ressources dont l'accès est contrôlé ou limité. Bref, ce n'est pas de la faute de WebFinger si des informations sensibles circulent, il n'est qu'un outil, à utiliser intelligemment.

Autre problème de sécurité avec WebFinger, le fait que la réponse est différente selon que la ressource existe ou pas (code HTTP 200 dans le premier cas et 404 dans le second). Ainsi, même si la réponse est vide, un client WebFinger peut, par essais répétés, se constituer une liste des ressources existantes. Cela peut permettre d'énumérer les utilisateurs d'un réseau social, ou bien les adresses de courrier valides (information certainement utile pour un spammeur). Le RFC recommande donc que des mesures techniques, comme une limitation du trafic par adresse IP du client, soient déployées.

Autre cas où l'utilisation maladroite de WebFinger peut avoir des conséquences néfastes, les requêtes automatiques. Supposons un MUA qui ferait automatiquement une requête WebFinger sur le champ From: du message lorsque celui-ci est lu. Un spammeur pourrait générer un champ From: différent par destinataire et les requêtes WebFinger entrantes lui diraient quels destinataires ont lu le message... Le RFC recommande donc de ne pas effectuer de requêtes WebFinger automatiquement.

Enfin, le RFC note que rien ne garantit que les valeurs renvoyées par WebFinger soient correctes (là encore, c'est un problème que les utilisateurs de whois connaissent déjà bien). Il y a en effet des choses fausses sur le Web.

Question mises en œuvre, ce n'est pas cela qui manque, y compris en logiciel libre. Il en existe une liste incomplète. Par exemple, GNU Social gère ce protocole.

Voici quelques exemples de requêtes WebFinger réelles, faites avec le client REST curl :

% curl -v 'https://packetizer.com/.well-known/webfinger?resource=acct:paulej@packetizer.com'
HTTP/1.1 200 OK
Server: Apache/2.2.22 (Fedora)
Access-Control-Allow-Origin: *
Content-Type: application/jrd+json; charset=UTF-8
...
{
  "subject" : "acct:paulej@packetizer.com",
  "aliases" :
  [
    "h323:paulej@packetizer.com"
  ],
  "properties" :
  {
    "http://packetizer.com/ns/name" : "Paul E. Jones",
    "http://packetizer.com/ns/name#zh-CN" : "保罗‧琼斯",
    "http://packetizer.com/ns/activated" : "2000-02-17T03:00:00Z"
  },
  "links" :
  [
    {
      "rel" : "test1",
      "href" : "http://example.com/author?q=acct%3Apaulej%40packetizer.com",
      "titles" :
      {
        "en-us" : "Test Link"
      }
    },
    {
      "rel" : "test2",
      "href" : "http://example.org/%E7%A7%81%E3%81%AE%E6%96%87%E6%9B%B8.txt"
    },
    {
      "rel" : "http://webfinger.net/rel/avatar",
      "type" : "image/jpeg",
      "href" : "http://www.packetizer.com/people/paulej/images/paulej.jpg"
    },
    {
      "rel" : "http://specs.openid.net/auth/2.0/provider",
      "href" : "https://openid.packetizer.com/paulej"
    },
    {
      "rel" : "http://packetizer.com/rel/share",
      "type" : "text/html",
      "href" : "http://hive.packetizer.com/users/paulej/"
    },
    {
      "rel" : "http://webfinger.net/rel/profile-page",
      "type" : "text/html",
      "href" : "http://www.packetizer.com/people/paulej/"
    },
    {
      "rel" : "http://packetizer.com/rel/blog",
      "type" : "text/html",
      "href" : "http://www.packetizer.com/people/paulej/blog/",
      "titles" :
      {
        "en-us" : "Paul E. Jones' Blog"
      }
    },
    {
      "rel" : "http://packetizer.com/rel/businesscard",
      "type" : "text/vcard",
      "href" : "http://www.packetizer.com/people/paulej/paulej.vcf"
    },
    {
      "rel" : "http://schemas.google.com/g/2010#updates-from",
      "type" : "application/atom+xml",
      "href" : "http://www.packetizer.com/people/paulej/blog/blog.xml"
    },
    {
      "rel" : "http://microformats.org/profile/hcard",
      "type" : "text/html",
      "href" : "http://www.packetizer.com/people/paulej/"
    },
    {
      "rel" : "http://bitcoin.org/rel/address",
      "href" : "bitcoin:17XoqvUCrf12H7Vc7c7uDxib8FDMXFx2p6"
    }
  ]
}

Autre exemple, pour l'URI acct:javier@seed.gluu.org, avec beaucoup moins d'information distribuée :

% curl -v 'https://seed.gluu.org/.well-known/webfinger?resource=acct:javier@seed.gluu.org'
...
{
    "subject": "acct:javier@seed.gluu.org",
    "links": [{
        "rel": "http://openid.net/specs/connect/1.0/issuer",
        "href": "https://seed.gluu.org"
    }]
}

En théorie, si on était sérieux, on ajouterait à curl l'option --header "Accept: application/jrd+json" pour indiquer au serveur qu'on ne comprend que ce format, le seul actuellement standard pour WebFinger (la syntaxe jrd+json, c'est-à-dire langage + format, est décrite dans le RFC 6839). Mais beaucoup de serveurs n'en tiennent pas compte (certains vous servent du XRD si vous mettez --header "Accept: application/xrd+xml").

Enfin, pour terminer cet article, une question que se posent certainement tous mes lecteurs qui connaissent le DNS. Pourquoi diable avoir décidé que le serveur WebFinger était le nom de domaine dans l'URI, ce qui manque de souplesse (si l'URI est acct:twitter.com, cela oblige Twitter à avoir le serveur WebFinger au même endroit que le serveur Web) plutôt que d'avoir une indirection, fournie par les très utiles enregistrements SRV ? Je suis d'accord, cela aurait été la bonne solution et cela aurait résolu bien des problèmes. Hélas, le groupe de travail WebFinger a fait un autre choix, pour les raisons suivantes :

  • Le Web n'utilise malheureusement pas les SRV (HTTP est un des rares protocoles où on n'a pas d'intermédiaire entre le nom de domaine et le nom du serveur, obligeant à mettre des adresses directement dans son nom de domaine).
  • JavaScript dans le navigateur (une des principales utilisations prévues) ne permet pas de faire des requêtes SRV.
  • Beaucoup d'hébergeurs DNS sont tellement mauvais qu'il ne permettent pas l'avitaillement d'enregistrements SRV via l'interface Web fournie au client.

Vous pouvez lire une discussion qui avait eu lieu à l'époque.

Autres lectures sur WebFinger, la synthèse de l'auteur du RFC, et un argumentaire pro-WebFinger de sa part.


Téléchargez le RFC 7033


L'article seul

RFC 1996: A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY)

Date de publication du RFC : Août 1996
Auteur(s) du RFC : Paul Vixie (Internet Software Consortium)
Chemin des normes
Première rédaction de cet article le 27 septembre 2013


Avant ce RFC, il n'existait pas de mécanisme dans le DNS pour prévenir les serveurs esclaves de la disponibilité de nouvelles données chez le serveur maître. Il fallait attendre que l'esclave contacte le maître (mécanisme de polling). Depuis notre RFC 1996, un serveur maître peut prévenir ses esclaves avec un message NOTIFY, entraînant ainsi une mise à jour plus rapide des zones DNS.

Avant cela, le rythme de mise à jour était contrôlé par le champ Refresh de l'enregistrement SOA. Ce champ indiquait à quel rythme l'esclave devait contacter le maître à la recherche de nouvelles données. En moyenne, donc, le temps de mise à jour de tous les serveurs faisant autorité (maître et esclaves) était de la moitié du Refresh. Par exemple, la zone eu.org a un Refresh de 3 600 secondes :

% dig SOA eu.org
...
;; ANSWER SECTION:
eu.org.			86400 IN SOA ns.eu.org. hostmaster.eu.org. (
				2013092601 ; serial
				3600       ; refresh (1 hour)
				1800       ; retry (30 minutes)
				604800     ; expire (1 week)
				86400      ; minimum (1 day)
				)
...

Ce qui fait que les esclaves testeront le maître à intervalles d'une heure, lui demandant s'il a des nouvelles données depuis le numéro de série 2013092601. Si le maître répond aux requêtes SOA de ces esclaves avec un numéro de série plus récent, l'esclave transférera la zone (RFC 5936). Le problème est qu'on peut attendre longtemps. Dans le pire cas (si l'esclave a testé le maître juste avant que ce dernier ne soit mis à jour), on attendra une heure. La synchronisation entre serveurs faisant autorité (maîtres et esclaves) contribue donc au délai total de réjuvénation.

Le message NOTIY complète ce mécanisme de polling par un mécanisme d'interruption. Le maître envoit ce message à ses esclaves dès la mise à jour, et ceux-ci testent immédiatement.

À noter que le graphe des relations entre serveurs faisant autorité n'est pas forcément composé que d'un maître et d'esclaves transférant depuis le maître. On peut avoir des configurations plus complexes avec des esclaves transférant depuis un autre esclave, plusieurs maîtres, etc (c'est d'ailleurs pour cela que l'ancienne terminologie de serveur primaire et secondaires a été abandonnée).

La section 3 décrit le NOTIFY. Les messages DNS ont un champ nommé Opcode (section 4.1.1 du RFC 1035) dont les valeurs possibles sont dans un registre IANA. Le principal opcode rencontré dans la nature, et de loin, est le 0, QUERY, indiquant une requête DNS normale. NOTIFY est un autre opcode possible, de numéro 4. Lorsqu'un serveur a des données nouvelles, il envoie un message NOTIFY à tous ses esclaves, message auquel les esclaves répondront, pour rassurer le maître sur la bonne réception de ses informations. Autrement, le maître réessaiera (les NOTIFY, comme la plupart des messages DNS, sont transportés sur UDP et peuvent donc se perdre), un certain nombre de fois (le RFC recommande cinq fois). Le message du maître peut aussi contenir les nouvelles données. Dans les exemples ci-dessous, les maîtres envoient le nouveau SOA de la zone. Si le message avec un nouveau SOA est bien reçu par l'esclave, celui-ci se comporte comme si le délai Refresh était écoulé : il interroge le maître sur son numéro de série (les NOTIFY ne sont pas authentifiés et peuvent donc être trompeurs, cf. section 5) et, s'il y a bien eu mise à jour, transfère la zone.

La section 4 du RFC donne quelques exemples, mais j'ai plutôt inclus les miens. Tout d'abord, un serveur maître sur NSD. Sa configuration pour la zone bortzmeyer.42 comprendra la liste des esclaves à notifier (ici, un seul) :

zone:
     	name: "bortzmeyer.42"
	zonefile: "primary/bortzmeyer.42"
	notify: 204.62.14.153 NOKEY

Maintenant, le serveur a de nouvelles données. Au moment où l'administrateur tape nsdc reload, le serveur envoie un NOTIFY que tcpdump montre ainsi :


22:58:53.934862 IP (tos 0x0, ttl 55, id 0, offset 0, flags [DF], proto UDP (17), length 59)
    217.70.190.232.51962 > 204.62.14.153.53: [udp sum ok] 32223 notify [b2&3=0x2400] SOA? bortzmeyer.42. (31)
22:58:53.935055 IP (tos 0x0, ttl 64, id 26939, offset 0, flags [none], proto UDP (17), length 59)
    204.62.14.153.53 > 217.70.190.232.51962: [bad udp cksum 0x733f -> 0x1d3a!] 32223 notify*- q: SOA? bortzmeyer.42. 0/0/0 (31)

Le maître a notifié, l'esclave a répondu positivement.

Avec BIND, il n'est pas nécessaire de lister les serveurs esclaves, il les trouve par défaut dans l'enregistrement NS de la zone (contrairement à NSD, BIND a un résolveur interne). On peut compléter cette liste (ajouter des esclaves) avec la directive also-notify. Voici une notification envoyée par BIND :


23:11:40.781190 IP6 (hlim 55, next-header UDP (17) payload length: 100) 2001:67c:2218:3::1:4.1396 > 2605:4500:2:245b::42.53: [udp sum ok] 46225 notify [b2&3=0x2400] [1a] SOA? langtag.net. langtag.net. [0s] SOA ns4.generic-nic.net. hostmaster.langtag.net. 2013092301 30480 26400 2419200 86400 (92)
23:11:40.781462 IP6 (hlim 64, next-header UDP (17) payload length: 37) 2605:4500:2:245b::42.53 > 2001:67c:2218:3::1:4.1396: [udp sum ok] 46225 notify*- q: SOA? langtag.net. 0/0/0 (29)

On trouve quelques enregistrements de trafic DNS avec NOTIFY sur pcapr : http://www.pcapr.net/browse?q=dns+notify (avec quelques faux positifs, aussi).

Si on veut envoyer à la main un NOTIFY, à des fins de test ou de déboguage, NSD a un outil utile, la commande nsd-notify :

% nsd-notify -z bortzmeyer.42 ns3.example.net

Si l'esclave n'est pas configuré pour recevoir des notifications de ce maître, NSD répond avec un refus :

[1379966010] nsd-notify[3346]: warning: bad reply from ns3.example.net \
    for zone bortzmeyer.42., error response REFUSED (5).

Alors que le RFC recommandait plutôt d'ignorer ce message NOTIFY inattendu. La configuration dans NSD pour accepter les notifications se fait avec la directive allow-notify :

allow-notify: 217.70.190.232 NOKEY

(Si vous voulez authentifier les NOTIFY, voyez mon autre article sur TSIG.)


Téléchargez le RFC 1996


L'article seul

SNMP v3 sur Unix, pour Cacti et Icinga

Première rédaction de cet article le 25 septembre 2013


Le protocole SNMP d'accès distant à l'information d'une machine est utilisé depuis bientôt un quart de siècle. Bien que la version actuelle de SNMP, la v3, ait été normalisée il y a quinze ans, il semble que les antiques versions 1 et 2 soient toujours largement utilisées. Voici des exemples de configuration d'un serveur Unix avec SNMP v3, et on interrogation par le logiciel de supervision Icinga et le logiciel de statistiques Cacti.

C'est que SNMP v3 est plus complexe, aussi bien lorsqu'on veut lire les RFC qui le normalisent (RFC 3414, RFC 3415, etc) que lorsqu'on regarde la configuration des logiciels clients et serveurs. Mais il présente un avantage décisif en matière de sécurité. En SNMP v1 (RFC 1157), il n'y avait aucune confidentialité : tout écoutant du réseau pouvait savoir ce qu'on faisait. Et aucune authentification sérieuse non plus : le mot de passe (baptisé « communauté » pour faire croire qu'il n'était pas aussi sensible qu'un mot de passe) circulait en clair et était donc interceptable. SNMP v3, au contraire, fournit un authentification fiable et, si on le veut, de la confidentialité.

Sur un serveur Unix, le logiciel Net-SNMP fournit un serveur capable de parler le v3. Sa configuration est baroque mais on trouve d'innombrables documentations en ligne comme celle de Tom Clegg ou celle de Nathan Drier, toutes les deux pour Debian, ou bien celle du Wiki officiel pour Arch Linux.

Par exemple, sur une Debian, je fais :

% sudo aptitude install snmpd

Puis j'édite /etc/snmp/snmpd.conf pour lui dire d'écouter sur toutes les adresses, IPv4 et IPv6. La ligne pertinente est :

agentAddress udp:161,udp6:[::]:161

(Oui, SNMP tourne sur UDP, port 161.) Pendant qu'on édite snmpd.conf, on modifie aussi les variables sysLocation et sysContact pour avoir des informations plus précises. On teste avec lsof que le serveur écoute bien :

% sudo lsof -i:snmp             
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
snmpd   19240 snmp    8u  IPv4 227237      0t0  UDP *:snmp 
snmpd   19240 snmp   11u  IPv6 227238      0t0  UDP *:snmp 

Ici, tout est bon.

Il reste à configurer un utilisateur, avec son mot de passe (qui ne sera pas transmis en clair). Les administrateurs système ordinaires vont choisir un nom « parlant » comme admin. Les paranoïaques vont tirer ce nom au hasard, pour augmenter la difficulté d'une attaque :

% dd if=/dev/random bs=16 count=1 | md5sum   
1+0 records in
1+0 records out
16 bytes (16 B) copied, 4.2661e-05 s, 375 kB/s
b5e9b185d879ee20b27be80195e9522a  -

Et on choisirait b5e9b185d879ee20b27be80195e9522a comme nom d'utilisateur... Pour le reste de cet article, je vais être petit-bras et prendre un nom et un mot de passe lisible, pour faciliter la lecture (le nom d'utilisateur est de toute façon en clair, même si on utilise l'option de chiffrement, qui ne chiffre que les données). Le nom sera clinique et le mot de passe cahuzac (une très mauvaise combinaison dans la réalité, puisque trop facile à trouver).

Le moyen le plus simple de créer un utilisateur est sans doute :

# Oui, il faut arrêter le serveur pour cela...
% /etc/init.d/snmpd stop

% sudo net-snmp-config --create-snmpv3-user -a SHA -x AES
Enter a SNMPv3 user name to create: 
clinique
Enter authentication pass-phrase: 
cahuzac
Enter encryption pass-phrase: 
  [press return to reuse the authentication pass-phrase]

Ici, on a donné à la commande net-snmp-config les paramètres -a SHA (l'algorithme de condensation utilisé pour l'authentification sera donc SHA) et -x AES (l'algorithme de chiffrement utilisé pour la confidentialité sera AES). Le but est d'utiliser systématiquement l'option de chiffrement. On utilise le même mot de passe pour les deux services. Après cette commande, vous devriez avoir un rouser clinique (ou rouser authOnlyUser) dans votre snmpd.conf (rouser = Read-Only User).

Une autre méthode consiste à modifier /var/lib/snmp/snmpd.conf (qui n'est pas le /etc/snmp/snmpd.conf) pour y mettre :

createUser clinique SHA "cahuzac" AES "cahuzac"

Lorsqu'on relancera le démon (c'est pour cela qu'il doit être arrêté), le fichier /var/lib/snmp/snmpd.conf sera réécrit et les mots de passe en clair disparaîtront. Une troisième méthode de création (merci à Vincent Bernat pour le rappel) d'un compte utilise SNMP lui-même, en écrivant dans la table snmpUsmUserTable (par exemple via le programme snmpusm).

On redémarre le serveur et, maintenant, il est temps de tester. Commençons par des essais avec un client SNMP en ligne de commande, snmpwalk, issu du même paquetage Net-SNMP, en supposant que le nom de la machine visée est dans la variable MYSERVER :

% snmpwalk -v 3 -u clinique -a SHA -A  cahuzac -x AES -X cahuzac \
    -l authPriv $MYSERVER

(Préciser -a SHA est obligatoire car, sinon, MD5 est utilisé par défaut. Quant à -l authPriv, Authentication & Privacy, cela active le chiffrement, afin de garantir la confidentialité des données. Voir la section 2.2 du RFC 3415.) Vous devez obtenir quelque chose comme :

SNMPv2-MIB::sysDescr.0 = STRING: Linux foobar.example.net 3.9.3-x86_64-linode33 #1 SMP Mon May 20 10:22:57 EDT 2013 x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (3442047) 9:33:40.47
SNMPv2-MIB::sysContact.0 = STRING: root@example.net
SNMPv2-MIB::sysLocation.0 = STRING: Floor 3, Row 12, Rack 5
...
IF-MIB::ifOutOctets.1 = Counter32: 791502
IF-MIB::ifOutOctets.2 = Counter32: 0
IF-MIB::ifOutOctets.3 = Counter32: 142039121

Si ce n'est pas le cas, à part une mauvaise saisie du mot de passe, vérifiez les points suivants :

  • Tester depuis le serveur, en faisant un snmpwalk ... 127.0.0.1. Si cela marche, mais que cela échoue à distance, vous avez peut-être un pare-feu zélé sur le trajet, ou bien le démon n'écoute que sur les adresses locales (cf. lsof plus haut et, sur une Debian, la variable SNMPDOPTS dans /etc/default/snmpd).
  • Question sécurité, vous avez peut-être installé TCP wrapper. Auquel cas, vérifiez qu'ils autorisent SNMP. Par exemple, si tous les accès se feront depuis les machines 192.0.2.3 et 2001:db8:ba27::3, mettez dans /etc/hosts.allow quelque chose comme snmpd: 192.0.2.3,[2001:db8:ba27::3].

Si cela marche, parfait, on va pouvoir passer à des clients SNMP plus riches. Ah, au passage, la même commande avec une adresse IPv6 (qu'il faut mettre entre crochets) :

% snmpwalk -v 3 -u clinique -a SHA -A  cahuzac -x AES -X cahuzac \
    -l authPriv "udp6:[2001:db8:dc0::1:cafe]"

Configurons maintenant Cacti pour produire de jolis graphes grâces à SNMP. Dans le menu Devices de la console de Cacti, on sélectionne Add (en haut à droite), on va indiquer SNMP Version = 3, le nom, le mot de passe, les algorithmes de cryptographie utilisés. On laisse le champ Context vide. Cacti met apparemment automatiquement le niveau de sécurité à authPriv. Lorsqu'on enregistre cette configuration, Cacti affiche le résultat d'une requête SNMP (description de la machine, contact, localisation, etc). S'il affiche à la place SNMP error, c'est qu'il y a une erreur dans la configuration (vous avez bien testé avec snmpwalk avant ?) Si tout marche, on peut alors créer les graphes via Cacti.

Et pour Icinga ? D'abord, quel est l'intérêt de SNMP pour un logiciel de supervision ? C'est qu'Icinga utilise les mêmes tests que Nagios et qu'un des tests Nagios, check_snmp a une option très pratique pour surveiller le trafic réseau. Les MIB habituelles de SNMP ne fournissent que des valeurs instantanées. On souhaiterait souvent avoir des taux, par exemple des bits/seconde et pas juste un total de bits, afin de pouvoir déclencher une alarme, par exemple en cas d'une attaque par déni de service. Certaines MIB (celle de Juniper) fournissent des variables pour cela, mais tout le monde n'a pas un Juniper. Alors, on va utiliser une option très pratique de check_snmp, --rate, qui enregistre les mesures sur disque pour pouvoir calculer un taux. (Attention donc à ce qu'Icinga ait le droit d'écrire dans le répertoire en question.) Créons une commande :

define command{
        command_name    check_snmp_myserver
        command_line    $USER1$/check_snmp -H $HOSTADDRESS$ -P 3 -a SHA -x AES -U clinique -A cahuzac -X cahuzac  -L authPriv --rate -o $ARG1$ -w $ARG2$ -c $ARG3$  
    }

Et utilisons là dans la configuration :

define service{
       use                              generic-service
       host_name                        myserver
       service_description              OUT_PACKET_RATE
       check_command                   check_snmp_myserver!ifOutUcastPkts.3!1000!4000!
   }

Ici, on utilise la variable SNMP ifOutUcastPkts (nombre de paquets sortants) sur la troisième interface réseau. Si on voit plus de 1 000 p/s, Icinga lève un avertissement, si on voit plus de 3 000 p/s, une alerte. On verra dans le journal :

[1380120148] SERVICE ALERT: myserver;OUT_PACKET_RATE;CRITICAL;SOFT;2;SNMP RATE CRITICAL - *5370*

À noter qu'une autre solution est suggérée dans la documentation d'Icinga, en récupérant les données de MRTG.


L'article seul

RFC 1288: The Finger User Information Protocol

Date de publication du RFC : Décembre 1991
Auteur(s) du RFC : David Paul Zimmerman (Rutgers University, Center for Discrete Mathematics and Theoretical Computer Science (DIMACS))
Chemin des normes
Première rédaction de cet article le 24 septembre 2013


Il y a bien longtemps, dans l'Internet, toutes les machines Unix connectées au réseau avaient un serveur finger. Ce protocole permettait d'obtenir des informations sur les utilisateurs de cette machine, à la fois de l'information statique (leur numéro de téléphone, le numéro de leur bureau à l'université...) mais aussi de l'information dynamique (est-ce qu'ils sont connectés ou pas, actifs ou pas, quand ont-il lu leur courrier pour la dernière fois, ...) Aujourd'hui, on utiliserait Facebook pour cela mais, dans les années 80 et 90, pour se renseigner sur un collègue ou un confrère, on se servait de finger. L'importance croissante donnée à la vie privée a petit à petit conduit au démantelement de cet utile service (remplacé, on l'a vu, par de gros silos de données qui sont bien pires, notamment parce que l'information n'est pas sous le contrôle de l'utilisateur). Finger, normalisé dans ce RFC, n'a plus aujourd'hui qu'un intérêt historique.

Je ne connais pas aujourd'hui beaucoup de serveurs finger encore en activité (mais je suis sûr que les lecteurs de mon blog vont m'en trouver plusieurs). Alors, j'en ai créé un, par nostalgie, blog@www.bortzmeyer.org. Vous pouvez utiliser un client finger comme l'outil Unix du même nom pour l'interroger. Il ne donne pas de renseignements sur une personne mais sur un service, comme le faisaient un certain nombre de serveurs finger. Ainsi, il existait un quake@geophys.washington.edu qui donnait de l'information sur les derniers tremblements de terre détectés, et un nasanews@space.mit.edu qui servait les informations de la NASA sur ses vols spatiaux. Ces deux-là ont disparu, mais les toilettes du MIT diffusent toujours des informations :

% finger @bathroom.mit.edu
Random Hall Bathroom Server v2.1

                         Bonfire Kitchen: vacant for 28 min
                         Bonfire  Lounge: vacant for 3 min
                          Pecker  Lounge: vacant for 2 hr
                          Pecker Kitchen: *IN*USE* for 16 min
   K 282  L  290 K          Clam Kitchen: vacant for 43 min
   ... ... ... ...          Clam  Lounge: *IN*USE* for 33 min
  | o : o | o : x |          BMF  Lounge: vacant for 3 min
  | o : x | o : o |          BMF Kitchen: vacant for 52 min
  | o : o | o : o |         Loop Kitchen: vacant for 75 min
  | o : x | - : o |         Loop  Lounge: vacant for 3 min
 ~~~~~~~~~~~~~~~~~~~  Black Hole  Lounge: vacant for 42 min
                      Black Hole Kitchen: vacant for 33 min
      o = vacant!        Destiny Kitchen: vacant for 2 min
      x = in use          Destiny Lounge: *IN*USE* for 33 min
                                     Foo: vacant for 17 min

For more information finger help@bathroom.mit.edu

(2146055)

Plus sérieux, le projet FreeBSD a toujours un serveur finger actif @freebsd.org donc vous pouvez vous informer sur n'importe quel commiter :


%  finger roberto@freebsd.org 
Login: roberto        			Name: Ollivier Robert
Directory: /home/roberto            	Shell: /usr/local/bin/zsh
Office: Bretigny s/Orge FRANCE		Office Phone: +33-1-69887290
No Mail.
Plan:
Home address: <roberto@keltia.net>
Work address: <ollivier.robert@eurocontrol.int>

Twitter: @Keltounet

pub  1024D/7DCAE9D3 1997-08-21 Ollivier Robert <roberto@keltia.net>
uid                            Ollivier Robert <roberto@keltia.freenix.fr>

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.1 (FreeBSD)

mQGiBDP8ElkRBADQrtDGMaOawsdVCxQTrtCoa+VFeSebgBgIdfrgduTTOteV+bqz
RYa94GBx3Df/LCxEtb8bgcL6DlD/B5nCjzMfwzW+JkqXDz7g96oVWW48jUIeNrYL
qBZruvcopUEmH3iBZU8ig3lpJ5/XbN+IYGP474E2rnTNfaY26E0iWkWqtQCg/wIY
...

Autre serveur finger utile, celui de météorologie qui permet d'obtenir un rapport sur n'importe quelle ville du monde (ici, Budva) :

% date
Tue Feb 16 08:31:00 CET 2016

% finger budva@graph.no
               -= Meteogram for montenegro/budva/budva~3203106 =-               
 'C                                                                   Rain (mm) 
 23                                                                   
 21   ---                                               |             9 mm 
 19                                                     |             8 mm 
 17---   ^^^      ^^^^^^                                |             7 mm 
 15         ======         =====|                       |             6 mm 
 13                     ^^^     |^^^===   ^^^         ==|             5 mm 
 11                             |      =--   ---=--===  |         ^^^ 4 mm 
  9                             |     |                 |=-----       3 mm 
  7              |           |  |     |                 |      ^^^    2 mm 
  5           |  |           |  |     |              |  |             1 mm 
   _10_13 19 01_07_13 19 01_07_13 19 01_07_13 19 01_07_13 19 01_07_13 Hour
 
    NE SE NE  S  S SW NW  N NE  E NE NW NW  W NW NE NE SW NW NW NW SW Wind dir.
     2  2  2  4  2  0  1  2  2  1  2  1  2  3  2  1  1  2  2  2  1  2 Wind(mps)

Legend left axis:   - Sunny   ^ Scattered   = Clouded   =V= Thunder   # Fog
Legend right axis:  | Rain    ! Sleet       * Snow
Mail a "thank you" to finger@falkp.no if you like the service.  

Si vous voulez installer, vous aussi, un serveur finger, je vous mets en garde : c'est un service sensible et qui peut ouvrir des failles de sécurité. Après tout, son rôle est de distribuer de l'information. Et l'information peut être utile à un méchant.

Comment fonctionne ce protocole ? Difficile de faire plus simple (section 2.1). À l'époque, le moyen le plus courant de faire un protocole d'accès à l'information était de réserver un port TCP (ici, 79), de dire au client de se connecter à ce port et d'envoyer sa question sous forme d'une simple chaîne de caractères, et de dire au serveur d'écouter sur ce port, et de répondre à question par... ce qu'il veut. De nombreux protocoles avaient été conçus ainsi, comme whois (port 43, RFC 3912) ou comme daytime (port 13, RFC 867) qui était encore plus simple (même pas de question, de la part du client). Écrire un logiciel client pour ces protocoles est trivial (exercice de première heure de la première année en réseaux) et on peut même se contenter d'un simple telnet :


% telnet www.bortzmeyer.org finger
Trying 2605:4500:2:245b::42...
Connected to www.bortzmeyer.org.
Escape character is '^]'.
blog
Debian GNU/Linux      Copyright (C) 1993-1999 Software in the Public Interest
...
Connection closed by foreign host.

Notez bien (section 2.2) que la fin de la ligne « question » doit être composée de deux caractères, CR et LF. Certains serveurs finger sont plus tolérants que d'autres si vous violez cette règle. Si on utilise netcat comme client, on va préciser ces deux caractères :

% echo -n -e "blog\r\n" | nc www.bortzmeyer.org finger

On peut aussi utiliser un client whois puisque les deux protocoles sont très proches :

% whois -h www.bortzmeyer.org -p finger blog

Et le format de la réponse ? Il n'est pas du tout défini par ce RFC (section 2.5) qui dit juste que c'est du texte libre, conçu pour être analysé par un humain et pas par un programme. (C'est exactement la même chose avec whois.)

Le RFC donne des indications sur les informations utiles à distribuer. Mais il précise aussi que la liste effective est entièrement sous le contrôle de l'administrateur système. Dans le reste de cet article, je donnerai des exemples de configuration empruntés à deux serveurs finger distribués en logiciel libre, efingerd et cfingerd. Par exemple, le RFC cite le numéro de téléphone, l'adresse, le nombre de minutes depuis la dernière activité sur cet ordinateur. Avec cfingerd, on peut décider d'afficher (signe plus) ou au contraire de ne pas activer (signe moins) l'envoi de ces informations, et on peut le faire pour les utilisateurs locaux à la machine (le second booléen) ou distants (le premier booléen). Un exemple dans le cfingerd.conf est :

CONFIG finger_display  = {
...
        +REAL_NAME              = [FALSE, TRUE],
        +DIRECTORY              = [FALSE, TRUE],
        +SHELL                  = [FALSE, TRUE],
        +ROOM_NUMBER            = [FALSE, TRUE],
        +WORK_NUMBER            = [FALSE, TRUE],
        +HOME_NUMBER            = [FALSE, TRUE],
        +LAST_TIME_ON           = [FALSE, TRUE],
        +IF_ONLINE              = [FALSE, TRUE],
        +TIME_MAIL_READ         = [FALSE, TRUE],
        +DAY_MAIL_READ          = [FALSE, TRUE],
        +ORIGINATION            = [FALSE, TRUE],
        +PLAN                   = [TRUE, TRUE],
        +PROJECT                = [TRUE, TRUE],
        +PGP                    = [TRUE, TRUE],
...

Avec efingerd, cela se configure en éditant le script shell luser qui, par défaut, utilise la commande locale finger qui peut être très bavarde (certains serveurs finger affichaient même l'expéditeur du dernier courrier reçu !). Voici un exemple :

Login: stephane       			Name: 
Directory: /home/stephane           	Shell: /usr/bin/zsh
On since Tue Sep 24 06:39 (UTC) on pts/0 from central.example.net
   1 minute 54 seconds idle
Last login Tue Sep 24 06:39 (UTC) on pts/2 from central.example.net
Mail forwarded to "| procmail -d"
New mail received Tue Sep 24 05:41 2013 (UTC)
     Unread since Tue Sep 24 13:28 2013 (UTC)
No Plan.

Notez que ces deux logiciels serveurs permettent de ne pas envoyer d'information sur un utilisateur particulier (bien que le RFC se demande à quoi cela sert de faire tourner un serveur finger dans ces conditions). Avec efingerd, c'est en éditant le script luser.

Parfois, le nom passé au serveur finger n'est pas celui d'un utilisateur humain mais celui d'un service (comme blog plus haut). La section 2.5.5 discute du cas où le service est un distributeur automatique et demande que finger renvoie la liste des produits actuellement disponibles dans la machine...

Une technique courante était de permettre aux utilisateurs de mettre un fichier nommé .plan dans leur répertoire maison. Ce fichier était alors envoyé après la réponse finger et contenait des informations supplémentaires comme une clé PGP. Les serveurs modernes permettent également aux utilisateurs de mettre un programme (et pas un simple fichier texte) dont le résultat sera envoyé au client finger. Inutile de décrire les risques de sécurité que cela entraine (section 3.2.5)...

finger offrait une autre possibilité : avoir la liste de tous les utilisateurs actuellement connectés, en indiquant une question vide. Donc, la commande finger @machine-distante (sans nom devant le @) donnait la liste de qui était branché. Particulièrement indiscrète, cette possibilité (qui n'avait en outre de sens que pour les grosses machines multi-utilisateurs) a été la première à disparaître (éditer le script nouser pour efingerd et option SYSTEM_LIST pour cfingerd).

À noter qu'il existe d'autres serveurs finger que ceux cités, par exemple IcculusFinger qui en prime est disponible sur le site de l'auteur :

% finger ryan@icculus.org 
IcculusFinger v2.1.24


                              /Nothing to report./

--------------------------------------------------------------------
.plan archives for this user: finger ryan?listarchives=1@icculus.org
Powered by IcculusFinger v2.1.24 (http://icculus.org/IcculusFinger/)
Stick it in the camel and go.

Et la sécurité ? Absente du premier RFC, le RFC 742, elle est au contraire très présente dans ce RFC 1288, notamment en section 3. Il y a plusieurs aspects. D'abord, la sécurité de la mise en œuvre du serveur finger, qui fut illustrée par le ver de Morris. Notons que ce n'était pas un problème spécifique au protocole finger : tout serveur réseau devrait être programmé de manière défensive, de façon à ne pas être vulnérable lorsque le client envoie des données inattendues (très longues, par exemple). Ne pas avoir de serveur finger aujourd'hui, à cause d'une faille de sécurité d'un logiciel qui n'est plus utilisé depuis longtemps, est donc idiot.

Mais finger a évidemment un autre problème, déjà cité, vis-à-vis de la vie privée. On n'a pas forcément envie que n'importe qui sur l'Internet soit au courant de ses heures de présence au bureau ou du rythme auquel on reçoit du courrier. C'est pourquoi le RFC exige qu'on puisse ajuster l'information présentée (cfingerd fournit un contrôle très fin dans son fichier de configuration, efingerd vous laisse programmer ce que vous voulez dans les scripts qu'il exécute).

Si vous avez un serveur finger et que vous voulez le superviser depuis Icinga, cela peut se faire avec la configuration :

define service{
        use   generic-service
        host_name            MonServeur
        service_description       Finger
        check_command             check_finger!utilisateur!chaîne à chercher
}

Elle lèvera une alarme si le texte chaîne à chercher n'apparait pas dans la réponse du serveur. La commande check_finger est définie ainsi :

define command {
        command_name    check_finger
        command_line    /usr/local/share/nagios/libexec/check_finger $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$
        }

Et le script check_finger (inspiré d'un équivalent pour whois) est disponible ici.

Notre RFC succède au RFC 1196 et le premier RFC sur finger était le RFC 742. Comme beaucoup de protocoles Internet, finger a d'abord été mis en œuvre (parfois sous le nom de « Name » et pas « Finger »), puis normalisé. La section 1.2 du RFC résume une longue et glorieuse histoire. Le RFC note que la norme actuelle est fondée avant tout sur le comportement du serveur finger d'Unix BSD. Par rapport à son prédécesseur, le RFC 1196, on note surtout une définition plus rigoureuse : le RFC 1196 était souvent très vague. Aujourd'hui, on l'a vu, finger est une survivance du passé, mais le standard IETF de récupération d'information sur une entité, WebFinger (RFC 7033), lui rend hommage par son nom. Autre idée inspirée de finger (et l'utilisant), le réseau social expérimental Thimbl. Comme le dit un contributeur d'Une contre-histoire des Internets, « Je me souviens de finger, seul service interrogeable qui indiquait les services accessibles sur un host »...


Téléchargez le RFC 1288


L'article seul

RFC 7001: Message Header Field for Indicating Message Authentication Status

Date de publication du RFC : Septembre 2013
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 21 septembre 2013


Il existe désormais plusieurs techniques pour authentifier les courriers électroniques. Certaines peuvent nécessiter des calculs un peu compliqués et on voudrait souvent les centraliser sur une machine de puissance raisonnable, dotée de tous les logiciels nécessaires. Dans cette hypothèse, le MUA ne recevra qu'une synthèse (« Ce message vient bien de example.com ») et pourra alors prendre une décision, basée sur cette synthèse. C'est le but de l'en-tête Authentication-Results:, normalisé originellement dans le RFC 5451 quatre ans plus tôt, RFC que ce nouveau RFC met légèrement à jour (il y a peu de changements). Il a lui-même été remplacé, depuis, par le RFC 7601.

Avec des techniques d'authentification comme DKIM (RFC 6376) ou SPF (RFC 7208), les calculs à faire pour déterminer si un message est authentique peuvent être complexes (DKIM utilise la cryptographie) et nécessiter la présence de bibliothèques non-standard. Les installer et les maintenir à jour sur chaque machine, surtout en présence d'éventuelles failles de sécurité qu'il faudra boucher en urgence, peut être trop pénible pour l'administrateur système. L'idée de ce RFC est donc de séparer l'opération en deux : l'authentification est faite sur un serveur, typiquement le premier MTA du site (cf. annexe D pour une discussion de ce choix), celui-ci ajoute au message un en-tête indiquant le résultat de ladite authentification et le MUA (ou bien le MDA, voir la section 1.5.3 pour un bon rappel sur ces concepts) peut ensuite, par exemple par un langage de filtrage comme procmail ou Sieve, agir sur la base de ce résultat. Cet en-tête marche pour tous les protocoles d'authentification et surpasse donc les en-têtes spécifiques comme le Received-SPF: de SPF (section 1 du RFC). Le filtrage des messages non authentifiés n'est pas obligatoire (section 1.4) : agir - ou pas - sur la base de l'en-tête Authentication-Results: est une décision politique locale.

J'ai utilisé le terme de « site » pour désigner un ensemble de machines gérées par la même organisation mais le RFC a un terme plus rigoureux, ADMD (ADministrative Management Domain). La frontière d'un ADMD est la « frontière de confiance » (trust boundary), définie en section 1.2. Un domaine administratif de gestion est un groupe de machines entre lesquelles il existe une relation de confiance, notamment du fait que, à l'intérieur de l'ADMD, l'en-tête Authentication-Results: ne sera pas modifié ou ajouté à tort (section 1.6 : l'en-tête n'est pas protégé, notamment il n'est pas signé). Il existe de nombreuses variantes organisationnelles du concept d'ADMD. Un ADMD inclus typiquement une organisation (ou un département de celle-ci) et d'éventuels sous-traitants. Il a un nom, l'authserv-id, défini en section 2.2.

L'en-tête Authentication-Results: lui-même est formellement défini en section 2. Il appartient à la catégorie des en-têtes de « trace » (RFC 5322, section 3.6.7 et RFC 5321, section 4.4) comme Received: qui doivent être ajoutés en haut des en-têtes et jamais modifiés. La syntaxe de Authentication-Results: est en section 2.2. L'en-tête est composé du authserv-id, le nom de l'ADMD et d'une série de doublets (méthode, résultat), chacun indiquant une méthode d'authentification et le résultat obtenu. L'annexe C fournit une série d'exemples. Elle commence (annexe C.1) par un message sans Authentication-Results: (eh oui, il n'est pas obligatoire). Puis (tiré de l'annexe C.3), une authentification SPF réussie, au sein de l'ADMD example.com, donnera :

        Authentication-Results: example.com;
                  spf=pass smtp.mailfrom=example.net
        Received: from dialup-1-2-3-4.example.net
                      (dialup-1-2-3-4.example.net [192.0.2.200])
                  by mail-router.example.com (8.11.6/8.11.6)
                      with ESMTP id g1G0r1kA003489;
                  Wed, Mar 14 2009 17:19:07 -0800
        From: sender@example.net
        Date: Wed, Mar 14 2009 16:54:30 -0800
        To: receiver@example.com

Rappelez-vous qu'il peut y avoir plusieurs authentifications. Voici un cas (annexe C.4) avec SPF et l'authentification SMTP du RFC 4954 :

       Authentication-Results: example.com;
                  auth=pass (cram-md5) smtp.auth=sender@example.net;
                  spf=pass smtp.mailfrom=example.net
        Received: from dialup-1-2-3-4.example.net (8.11.6/8.11.6)
                      (dialup-1-2-3-4.example.net [192.0.2.200])
                  by mail-router.example.com (8.11.6/8.11.6)
                      with ESMTP id g1G0r1kA003489;
                  Fri, Feb 15 2002 17:19:07 -0800
        Date: Fri, Feb 15 2002 16:54:30 -0800
        To: receiver@example.com
        From: sender@example.net

L'une des authentifications peut réussir et l'autre échouer. Un exemple (annexe C.6) avec deux signatures DKIM, une bonne et une qui était correcte au départ (regardez le premier Authentication-Results:) mais plus à l'arrivée, peut-être parce qu'un gestionnaire de liste de diffusion a modifié le message :

       Authentication-Results: example.com;
              dkim=pass reason="good signature"
                header.i=@mail-router.example.net;
              dkim=fail reason="bad signature"
                header.i=@newyork.example.com
        Received: from mail-router.example.net
                  (mail-router.example.net [192.0.2.250])
              by chicago.example.com (8.11.6/8.11.6)
                  for <recipient@chicago.example.com>
                  with ESMTP id i7PK0sH7021929;
              Fri, Feb 15 2002 17:19:22 -0800
        DKIM-Signature: v=1; a=rsa-sha256; s=furble;
              d=mail-router.example.net; t=1188964198; c=relaxed/simple;
              h=From:Date:To:Message-Id:Subject:Authentication-Results;
              bh=ftA9J6GtX8OpwUECzHnCkRzKw1uk6FNiLfJl5Nmv49E=;
              b=oINEO8hgn/gnunsg ... 9n9ODSNFSDij3=
        Authentication-Results: example.net;
              dkim=pass (good signature) header.i=@newyork.example.com
        Received: from smtp.newyork.example.com
                  (smtp.newyork.example.com [192.0.2.220])
              by mail-router.example.net (8.11.6/8.11.6)
                  with ESMTP id g1G0r1kA003489;
              Fri, Feb 15 2002 17:19:07 -0800
        DKIM-Signature: v=1; a=rsa-sha256; s=gatsby;
              d=newyork.example.com;
              t=1188964191; c=simple/simple;
              h=From:Date:To:Message-Id:Subject;
              bh=sEu28nfs9fuZGD/pSr7ANysbY3jtdaQ3Xv9xPQtS0m7=;
              b=EToRSuvUfQVP3Bkz ... rTB0t0gYnBVCM=
        From: sender@newyork.example.com
        Date: Fri, Feb 15 2002 16:54:30 -0800
        To: meetings@example.net

La liste complète des méthodes figure dans un registre IANA (section 6). De nouvelles méthodes peuvent être enregistrées en utilisant la procédure « Examen par un expert » du RFC 5226.

La section 2.3 détaille l'authserv-id. C'est un texte qui identifie le domaine, l'ADMD. Il doit donc être unique dans tout l'Internet. En général, c'est un nom de domaine comme laposte.net. (Il est possible d'être plus spécifique et d'indiquer le nom d'une machine particulière mais cette même section du RFC explique pourquoi c'est en général une mauvaise idée : comme les MUA du domaine n'agissent que sur les Authentication-Results: dont ils reconnaissent l'authserv-id, avoir un tel identificateur qui soit lié au nom d'une machine, et qui change donc trop souvent, complique l'administration système.)

La section 2.5 explique les résultats possibles pour les méthodes d'authentification (en rappelant que la liste à jour des méthodes et des résultats est dans le registre IANA). Ainsi, DKIM (section 2.5.1) permet des résultats comme pass (authentification réussie) ou temperror (erreur temporaire au cours de l'authentification, par exemple liée au DNS). Des résultats similaires sont possibles pour SPF (section 2.5.3).

Notons la normalisation d'une méthode traditionnelle d'authentification faible, le test DNS du chemin « adresse IP du serveur -> nom » et retour. Baptisée iprev, cette méthode, bien que bâtie sur la pure superstition (cf. section 7.11) est utilisée couramment. Très injuste (car les arbres des résolutions inverses du DNS, in-addr.arpa et ip6.arpa, ne sont pas sous le contrôle du domaine qui envoie le courrier), cette méthode discrimine les petits FAI, ce qui est sans doute un avantage pour les gros, comme AOL qui l'utilisent. Attention aux implémenteurs : aussi bien la résolution inverse d'adresse IP en nom que la résolution droite de nom en adresse IP peuvent renvoyer plusieurs résultats et il faut donc comparer des ensembles. (Cette méthode qui, contrairement aux autres, n'avait jamais été exposée dans un RFC avant le RFC 5451, est décrite en détail dans la section 3, avec ses sérieuses limites.)

Autre méthode mentionnée, auth (section 2.5.4) qui repose sur l'authentification SMTP du RFC 4954. Si un MTA (ou plutôt MSA) a authentifié un utilisateur, il peut le noter ici.

Une fois le code d'authentification exécuté, où mettre le Authentication-Results: ? La section 4 fournit tous les détails, indiquant notamment que le MTA doit placer l'en-tête en haut du message, ce qui facilite le repérage des Authentication-Results: à qui on peut faire confiance (en examinant les en-têtes Received: ; en l'absence de signature, un Authentication-Results: très ancien, situé au début du trajet, donc en bas des en-têtes, ne signifie pas grand'chose). On se fie a priori aux en-têtes mis par les MTA de l'ADMD, du domaine de confiance. L'ordre est donc important. (La section 7 revient en détail sur les en-têtes Authentication-Results: usurpés.)

Ce n'est pas tout de mettre un Authentication-Results:, encore faut-il l'utiliser. La section 4.1 s'attaque à ce problème. Principe essentiel pour le MUA : ne pas agir sur la base d'un Authentication-Results:, même si ce n'est que pour l'afficher, sans l'avoir validé un minimum. Comme le Authentication-Results: n'est pas signé, n'importe qui a pu en insérer un sur le trajet. Le RFC précise donc que les MUA doivent, par défaut, ne rien faire. Et qu'ils doivent ne regarder les Authentication-Results: qu'après que cela ait été activé par l'administrateur de la machine, qui indiquera quel authserv-id est acceptable.

Naturellement, le MTA d'entrée du domaine devrait supprimer les Authentication-Results: portant son propre authserv-id qu'il trouve dans les messages entrants : ils sont forcément frauduleux (section 5). (Le RFC accepte aussi une solution plus simpliste, qui est de supprimer tous les Authentication-Results: des messages entrants, quel que soit leur authserv-id.)

Arrivé à ce stade de cet article, le lecteur doit normalement se poser bien des questions sur la valeur du Authentication-Results:. Quel poids lui accorder alors que n'importe quel méchant sur le trajet a pu ajouter des Authentication-Results: bidons ? La section 7, consacrée à l'analyse générale de la sécurité, répond à ces inquiétudes. 7.1 détaille le cas des en-têtes usurpés. Les principales lignes de défense ici sont le fait que le MUA ne doit faire confiance aux Authentication-Results: que s'ils portent le authserv-id de son ADMD et le fait que le MTA entrant doit filtrer les Authentication-Results: avec son authserv-id. Comme l'intérieur de l'ADMD, par définition, est sûr, cela garantit en théorie contre les Authentication-Results: usurpés. Le RFC liste néanmoins d'autres méthodes possibles comme le fait de ne faire confiance qu'au premier Authentication-Results: (le plus récent), si on sait que le MTA en ajoute systématiquement un (les éventuels Authentication-Results: usurpés apparaîtront après ; mais certains serveurs les réordonnent, cf. section 7.3). Pour l'instant, il n'y a pas de méthode unique et universelle de vérification du Authentication-Results:, le RFC propose des pistes mais ne tranche pas.

Comme toujours en sécurité, il faut bien faire la différence entre authentification et autorisation. Un spammeur a pu insérer un Authentication-Results: légitime pour son authserv-id. Même authentifié, il ne doit pas être considéré comme une autorisation (section 7.2).

Plusieurs mises en œuvre de ce système existent déjà comme dans MDaemon, sendmail (via sid-milter), Courier, OpenDKIM, etc. Si on veut analyser les en-têtes Authentication-Results: en Python, on a le module authres. Parmi les grosses usines à courrier centralisées, Gmail met systématiquement cet en-tête, par exemple :

Authentication-Results: mx.google.com; spf=pass \
           (google.com: domain of stephane@sources.org designates 217.70.190.232 \
               as permitted sender) smtp.mail=stephane@sources.org

Outre Gmail, à la date de publication du RFC, Yahoo et Hotmail ajoutaient cet en-tête.

Les changements depuis le RFC 5451 sont peu nombreux. Outre la correction d'erreurs, on trouve l'intégration du RFC 6577, une libéralisation des règles d'enregistrement de nouvelles méthodes d'authentification, des nouvelles méthodes (dont je n'ai pas parlé ici) comme le VBR du RFC 6212 et divers changements éditoriaux. Le RFC 7601, qui l'a ensuite remplacé, n'a pas non plus fait de changements énormes.


Téléchargez le RFC 7001


L'article seul

RFC 7021: Assessing the Impact of Carrier-Grade NAT on Network Applications

Date de publication du RFC : Septembre 2013
Auteur(s) du RFC : C. Donley (CableLabs), L. Howard (Time Warner Cable), V. Kuarsingh (Rogers Communications), J. Berg (CableLabs), J. Doshi (University of Colorado)
Pour information
Première rédaction de cet article le 20 septembre 2013


Sous le nom générique (et souvent erroné) de NAT se trouve tout un zoo de techniques variées et n'ayant en commun que leur complexité et leur fragilité. Ce nouveau RFC documente les problèmes liés à une technique particulière, nommée « double NAT » ou « NAT 444 » ou encore « CGN ». Lorsqu'un malheureux paquet IP subit deux traductions, qu'est-ce qui va casser ?

L'idée du CGN (un terme marketing, qu'il vaudrait mieux remplacer par NAT 444 pour « deux NAT sur le trajet d'un paquet IPv4 ») est de faire beaucoup d'efforts et de dépenser beaucoup d'argent pour ne pas migrer vers IPv6. Au lieu de déployer IPv6, ce qui simplifierait beaucoup les choses, notamment pour les applications, on déploie de gros routeurs NAT chez le FAI (loin des utilisateurs, d'où le nom de CGN - Carrier-Grade NAT - par opposition au NAT CPE des boxes actuelles). En toute rigueur, on peut avoir du CGN sans avoir du double NAT (c'est par exemple courant dans les offres 3G). Mais ce RFC se focalise sur le cas typique de l'accès Internet à la maison ou au bureau où les paquets IPv4 subiront une double traduction, par une box chez le client puis par le routeur CGN chez le FAI. On aura donc deux NAT à la suite.

Ce RFC n'est pas une analyse théorique. Au contraire, il décrit le résultat de tests effectifs menés par un labo des FAI et deux FAI importants (CableLabs, Time Warner Cable et Rogers), qui ont testé en vrai le NAT 444 et les problèmes qu'il pose. La première campagne de tests a été faite en 2010 et avait montré que des applications comme le streaming vidéo, les jeux en ligne et le partage de fichiers en pair-à-pair avaient des ennuis. Une seconde série de tests a été faite en 2011 par CableLabs seul, en essayant du matériel de plusieurs vendeurs (A10, Juniper, Alcatel-Lucent) pour faire le CGN. D'une manière générale, les tests n'ont été faits qu'avec les applications qui avaient des chances (ou plutôt des malchances) d'avoir des problèmes : un simple accès en lecture seule à une page Web ordinaire ne présente pas de risques et n'a donc pas été testé. La liste des applications testées est longue ;

Ce RFC est essentiellement consacré à rendre compte des résultats de cette seconde campagne de tests.

La section 2 du RFC commence par décrire les architectures utilisés pour les tests. Par exemple, le premier cas (section 2.1.1) est le cas le plus simple : une seule machine terminale (« client »), un seul réseau local, un seul FAI. Le deuxième cas correspond à une maison avec plus d'équipements puisqu'il y a deux machines terminales. Tous les cas avec deux machines chez l'utilisateur permettent de tester des applications pair-à-pair entre ces deux machines. Le troisième cas a deux réseaux locaux mais un seul FAI donc, avec le CGN, possibilité que les machines des deux réseaux se présentent à l'extérieur avec la même adresse publique (voir le cas des Xbox plus loin). Et le quatrième cas a deux machines terminales, chez des FAI différents (donc avec des routeurs CGN différents et des adresses IP différentes).

Divers petits routeurs ont été utilisés comme CPE pendant les tests (Netgear, Linksys, etc). Les machines terminales étaient des ordinateurs Windows ou Mac OS, des consoles Xbox, des tablettes iPad, des lecteurs Blu-Ray connectés, etc.

Résultats ? Les activités les plus traditionnelles comme envoyer et recevoir du courrier, ou comme lire le Web, n'ont pas été affectées par le CGN. Les technologies de transition vers IPv6 comme 6to4 (RFC 3056) avaient été testées lors des essais de 2010 et les résultats étaient très mauvais. Ces tests n'ont pas été refaits en 2011. Autrement, qu'est-ce qui n'a pas marché ?

Plusieurs applications pair-à-pair par exemple de jeu en ligne ou de téléphonie SIP ont échoué dès qu'un CGN était là. Dans le cas de la Xbox, deux utilisateurs situés chez le même FAI n'arrivent pas à se connecter entre eux s'il y a du NAT444. Cela a apparemment été réglé par Microsoft dans une mise à jour de décembre 2011. Dans le cas de PJSIP, les appels passant par un fournisseur SIP marchaient mais pas ceux effectués en pair-à-pair.

μTorrent a fonctionné dans certains cas mais pas dans tous. Il utilise une variété de techniques pour passer à travers les NAT (y compris STUN).

Pourquoi ces échecs, lorsque ça marche avec du NAT « habituel » ? Il existe plusieurs raisons (analysées dans le RFC) mais, pour prendre l'exemple de la Xbox, c'est parce que le serveur des Xbox sait dire à deux consoles qui se connectent depuis la même adresse IPv4 publique : « vous êtes toutes les deux derrière un routeur NAT, communiquez directement sur vos adresses privées ». Cela fonctionne si les deux Xbox sont sur le même réseau local et peuvent en effet se parler sans intermédiaire. Mais s'il y a du CGN, et qu'elles sont sur des réseaux locaux différents, connectés par le même FAI, elles présentent au serveur de Microsoft la même adresse IPv4 publique mais elles ne peuvent pas se joindre avec leurs adresses privées.

Les tests ont été qualitatifs (ça marche ou ça ne marche pas) mais aussi quantitatifs avec mesure de la latence ou de la gigue, pour lesquelles le CGN ne semble pas avoir d'impact négatif.

Soyons optimistes, il y a eu des améliorations entre les tests de 2010 et ceux de 2011, notamment grâce à l'utilisation plus fréquente de STUN ou de relais permettant de contourner les problèmes du NAT. Le RFC ne parle pas de l'aspect économique mais je note que, lorsqu'on évalue le coût des CGN, il faut voir que c'est aux auteurs d'application de payer pour les FAI, en augmentant la complexité de leurs applications pour contourner les obstacles.

Certains problèmes restent et semblent consubstantiels du CGN, comme la difficulté qu'il y a à fournir des informations aux autorités en cas d'enquête sur un comportement anormal : l'adresse IP publique qui est vue par les serveurs distants est partagée entre un grand nombre d'utilisateurs (RFC 6269).

Les résultats bruts des tests de 2010 figurent en section 5 et ceux des tests de 2011 en section 4, sous forme de tableau indiquant ce qui marche et ce qui ne marche pas.

Que recommander après ces résultats ? La section 6 traite de la gestion de ces problèmes liés au double NAT. Elle recommande notamment l'utilisation de PCP (Port Control Protocol, RFC 6887), pour que les applications puissent ouvrir les ports nécessaires dans le routeur CGN.

Un exposé de CableLabs résumant leurs observations est disponible en « Carrier Grade NAT - Observations and Recommendations ».


Téléchargez le RFC 7021


L'article seul

RFC 2993: Architectural Implications of NAT

Date de publication du RFC : Novembre 2000
Auteur(s) du RFC : T. Hain (Microsoft)
Pour information
Première rédaction de cet article le 19 septembre 2013


Ce RFC est la synthèse (vieille de treize ans, mais toujours juste) de l'analyse architecturale du NAT par l'IETF. Elle décrit les conséquences du NAT pour l'Internet et appelle à considérer son usage avec prudence (comme chacun peut le voir, cet appel n'a pas été entendu). C'est le document à lire pour avoir une vision de haut niveau du NAT.

Techniquement, le NAT a été décrit en 1994 dans le RFC 1631 (et dans le RFC 2663). Cette méthode était un des moyens envisagés pour gérer le problème de l'épuisement des adresses IPv4. Mais le RFC 1631 appelait à la prudence : « NAT has several negative characteristics that make it inappropriate as a long term solution, and may make it inappropriate even as a short term solution. » Entre le RFC 1631 et ce RFC 2993 (et encore plus depuis), la traduction d'adresses a été très largement déployée, sans tenir compte de ses inconvénients. Cassandre n'est jamais écoutée... Il avait même été question d'arrêter le développement et le déploiement d'IPv6, avec l'argument que le NAT suffisait à résoudre le problème de l'épuisement d'adresses IPv4 (ce point est développé en détail dans la section 8 du RFC). Il est d'autant plus difficile de faire une analyse des avantages et inconvénients du NAT que le débat est souvent très passionnel. Les Pour font remarquer que le NAT fonctionne sans intervention particulière, pour des applications très populaires (comme le Web ou le courrier). Mieux, le NAT résoud un vieux problème d'IP, la confusion de l'identificateur et du localisateur : l'adresse IP interne est un identificateur, l'externe un localisateur. Le NAT divise l'Internet, autrefois unifié autour de l'unicité de l'adresse IP, en plusieurs domaines indépendants, chacun ayant son propre espace d'adressage (souvent tiré du RFC 1918). Les Contre reprochent au NAT son caractère de bricolage et sa non-transparence pour beaucoup d'applications, notamment pair-à-pair. En effet, si l'application vérifie que l'en-tête IP reste cohérent (c'est le cas de l'AH d'IPsec, cf. section 9) ou si elle transporte des adresses IP dans ses données (comme le fait SIP, et pour de bonnes raisons), elle ne fonctionnera pas à travers le NAT sans gros efforts de programmation (le principe du NAT est de déplacer les coûts, des FAI vers les programmeurs). Le NAT encourage donc l'ossification de l'Internet vers les seules applications client/serveur. Les Contre notent aussi (RFC 2101) que la division en domaines d'adressage différents font que l'adresse IP cesse d'être unique, et que la résolution d'un nom en adresse donne un résultat qui va dépendre de l'endroit où on pose la question.

Plus fondamentalement, l'Internet repose sur un petit nombre d'excellents principes architecturaux, auxquels il doit son succès, notamment le principe de bout en bout. Ce principe a par exemple pour conséquences qu'il n'y a pas d'état maintenu dans le réseau : un équipement intermédiaire peut redémarrer (et donc tout oublier), un changement de routes peut faire passer par de nouveaux équipements intermédiaires et les extrémités, les machines terminales ne s'apercevront de rien, elles ne connaissaient absolument pas les équipements intermédiaires utilisés. Cela contribue fortement à la résilience du réseau. Le NAT met fin à cela.

J'ai écrit NAT jusqu'à présent mais, en fait, le mécanisme de traduction d'adresse le plus répandu dans l'Internet est plutôt le NAPT (Network Address and Port Translation), c'est à dire qu'il ne traduit pas juste une adresse dans une autre mais un couple {adresse interne, port interne} vers un couple {adresse externe, port externe}. Une grande partie des problèmes qu'on rencontre avec le NAT sont en fait spécifiques au NAPT et n'existeraient pas avec du « vrai » NAT.

Le RFC note que bien des choses qu'on peut dire contre le NAT (cassage du principe de bout en bout, problème pour les applications pair-à-pair) s'appliquent aussi aux pare-feux. La principale différence est que le but explicite d'un pare-feu est de s'insérer sur le trajet et de perturber les communications. En cas de problème, son rôle est donc clair. Au contraire, le NAT est souvent perçu comme transparent, et on oublie plus facilement son rôle, notamment lorsqu'il faut déboguer.

S'appuyant sur le RFC 2663, la section 2 du RFC couvre la terminologie, qui est souvent malmenée lorsqu'il s'agit du NAT :

  • NAT (Network Address Translation) est normalement la traduction d'une adresse IP vers une autre. On parle de static NAT lorsque la correspondance entre les deux adresses est fixe et de dynamic NAT lorsqu'elle change automatiquement. Le static NAT nécessite autant d'adresses internes que d'externes et ne règle donc pas le problème de l'épuisement des adresses IPv4.
  • NAPT (Network Address Port Translation) est ce que font réellement les routeurs abusivement appelés NAT, comme la box typique de M. Michu. Elle utilise un numéro de port de la couche 4 pour démultiplexer les paquets à destination de l'adresse IP publique.

Pour étudier l'impact du NAT sur l'Internet, il faut d'abord définir ce qu'est l'Internet. La définition du RFC est que l'Internet est une concaténation de réseaux utilisant les technologies TCP/IP. Selon cette définition, le réseau privé d'une entreprise fait partie de l'Internet. Une définition plus restrictive serait de dire que l'Internet est l'ensemble des machines ayant une adresse IP publique, et pouvant donc envoyer un paquet à toute autre machine de l'Internet. Selon cette seconde définition, un réseau utilisant des adresses IP privées (RFC 1918) et connecté via un NAT ne fait pas partie de l'Internet. En effet, comme le pare-feu, le NAT isole le réseau privé et ne permet pas d'accéder à tous les services de l'Internet. Dans cette définition stricte, seul le réseau public est l'Internet (avec un grand I puisque c'est un objet unique comme l'Atlantique ou le Kilimandjaro).

La section 4 rappelle le principe de bout en bout décrit plus haut (ou dans les RFC 1958 ou RFC 2775). Le document de référence sur ce principe est l'article de J.H. Saltzer, D.P. Reed et David Clark, « End-To-End Arguments in System Design ». Que dit ce principe ? Que tout état mémorisé par une machine du réseau doit être dans les extrémités. Si une machine à l'extrémité redémarre, la communication est fichue de toute façon. En revanche, il faut éviter que le redémarrage d'une machine intermédiaire ne coupe la communication. En effet, il y a beaucoup de machines intermédiaires (faites un traceroute pour voir) et, si la panne de l'une d'elles perturbait le trafic, l'Internet serait très fragile. Cela illustre la grande différence entre un routeur normal et un routeur NAT : lorsque le routeur normal redémarre (ou change, parce qu'on passe par un autre chemin), la communication continue. Au contraire, le redémarrage d'un routeur NAT fait perdre la table de correspondance entre les tuples {adresse, port} externes et les internes, arrêtant toutes les sessions en cours.

Quelques conséquences importantes du principe de bout en bout sont donc :

  • Pas besoin de synchroniser l'état des différents routeurs dans le réseau : un routeur n'a pas de mémoire. En cas de problème, router par un autre chemin est trivial. (Notez que c'est pour cela que faire du NAT lorsqu'on a plusieurs sorties vers l'Internet est très difficile, car il faut que tous les routeurs NAT se partagent leur table de correspondances externe<->interne.)
  • Le nombre de machines terminales croit plus vite que celui des routeurs. Si les routeurs devaient garder un état proportionnel au nombre de machines terminales, le réseau passerait bien moins à l'échelle.
  • L'absence d'état et, plus généralement d'« intelligence » dans les routeurs, fait que les décisions de sécurité n'ont pas besoin d'être gérées par le réseau. Deux machines qui communiquent s'occupent de leur sécurité et n'ont pas à faire confiance aux équipements intermédiaires. C'est important, par exemple, lorsqu'on voyage, et qu'on ne peut pas être sûr de la confiance à accorder au réseau de l'hôtel ou de l'aéroport.
  • Le point ci-dessus s'applique à tous les services : l'absence d'intelligence dans le réseau (qui est liée d'ailleurs à l'idée plus récente de neutralité du réseau) permet à deux machines consentantes de mettre en œuvre des nouveaux services, sans devoir attendre que quoi que ce soit ait été déployé dans le réseau. Un réseau où une grande partie du travail serait faite dans le réseau lui-même et pas aux extrémités, serait très hostile à l'innovation. Au contraire, le succès de l'Internet est dû en grande partie à la possibilité de déployer de nouvelles applications sans permission. (Et je rajoute que l'un des principaux problèmes de l'Internet d'aujourd'hui est son ossification, due largement au NAT, qui empêche de déployer, par exemple un nouveau protocole de transport comme SCTP.)

Les deux sections suivantes sont consacrées à une mise en comparaison des avantages et inconvénients du NAT (la section 11, en conclusion, les résumera sous forme d'un tableau simple). D'abord, en section 5, ses avantages, dans la résolution de plusieurs problèmes réels :

  • En masquant les adresses IP internes aux observateurs extérieurs, il permet de se dispenser de renumérotation lorsqu'on change d'opérateur (le RFC 5887, par la suite, a analysé la difficulté de la renumérotation).
  • En cas d'usage intermittent, le NAT permet d'économiser les adresses IP globales en ne les attribuant qu'en cas d'usage effectif. (Cet argument n'a plus guère de sens aujourd'hui, avec les accès « always on » comme l'ADSL.)
  • L'usage d'adresses privées, auto-allouées localement par l'utilisateur, dispense de justifier, auprès d'une grosse bureaucratie, l'obtention d'adresses IP uniques.
  • Pour beaucoup d'applications, notamment celles de type client/serveur, aucun changement n'est nécessaire dans les machines terminales lorsqu'on déploie le NAT.

Toutes ces raisons expliquent le succès du NAT.

Et les inconvénients ? La section 6 en dresse une liste :

  • Le NAT casse le principe de bout en bout.
  • Le NAT remplace un modèle simple par un modèle plus complexe, plus fragile et plus difficile à déboguer.
  • Il crée un SPOF (le redémarrage du routeur NAT coupe toutes les sessions de toutes les machines du réseau local). Ce point est détaillé dans la section 7.1.
  • Il perturbe des techniques de sécurité comme le AH d'IPsec (RFC 4302). Pour cette raison, mais aussi pour d'autres, AH n'a guère été déployé et cet argument n'est donc peut-être pas le plus fort (alors que le RFC, à l'époque, le considérait comme « One of the greatest concerns »).
  • Les adresses privées semblent très sympas au début (on se les alloue soi-même sans s'embêter et sans rien demander à personne) mais sont une grosse source d'ennuis lorsque deux réseaux privés communiquent, par exemple suite à une fusion d'entreprises, ou si on se connecte à deux réseaux distants utilisant la même plage d'adresses (la section 7.6 donne un exemple).
  • Le NAT casse les protocoles qui ont une connexion de contrôle séparée de la connexion de données, ce qui est fréquent dans le multimédia (SIP, H.323, et tous les protocoles qui fonctionnent en indiquant une référence à une machine tierce). La connexion de données se fait typiquement en utilisant des adresses IP indiquées par le pair... qui ne marcheront pas car ce sont des adresses privées, le pair ne savait pas qu'il était NATé.
  • Le NAT augmente la complexité de la connexion : c'est un facteur de plus à prendre en compte lorsqu'on débogue.
  • Les connexions entrantes sont impossibles par défaut (ce qui pose problème si on veut héberger un serveur sur le réseau local). On peut sur les routeurs NAT typiques définir une correspondance d'un port bien connu (par exemple 80 pour HTTP) vers une machine interne mais cela ne permet qu'un seul serveur pour chaque port bien connu.
  • Depuis l'écriture de ce RFC 2993, UPnP, puis le PCP (Port Control Protocol) du RFC 6887, ont facilité un peu la vie des applications coincées derrière un routeur NAT, en leur permettant un contrôle limité des correspondances statiques entre {adresse, port} externes et internes.

Il y a aussi des inconvénients plus techniques, comme le fait que le délai d'attente de TCP avant de réutiliser un identificateur de connexion (l'état TCP_TIME_WAIT) peut vite être trop long pour un routeur NAT actif, le soumettant à la tentation d'ignorer ce délai minimum (deux fois la durée de vie d'un segment dans le réseau, normalement).

Par contre, ce RFC oublie un inconvénient important du NAPT (mais pas du NAT) : le partage d'adresses IP publiques, dont les conséquences négatives ont été analysées onze ans plus tard dans le RFC 6269.

La question de la sécurité du NAT occupe la section 9. C'est un point d'autant plus important que certaines personnes prétendent parfois que le NAT améliore la sécurité. En fait, notre RFC note que cela peut être tout le contraire, en créant l'illusion d'une barrière, d'un pare-feu, le NAT peut abaisser le niveau de sécurité. Le RFC critique aussi cette idéologie du pare-feu, qui considère que toutes les menaces sont externes, dans le style du limes romain. Si on pense qu'on est protégé derrière son routeur NAT, c'est qu'on ignore une règle de base de la sécurité, qui est que l'attaque vient souvent de l'intérieur.

Si le NAT, par définition, casse les techniques de sécurité qui protègent l'intégrité du paquet, comme l'AH d'IPsec, d'autres techniques de sécurité peuvent passer malgré le NAT. C'est le cas de TLS ou de SSH. Notez que ces techniques fonctionnent dans la couche 7 et restent donc vulnérables à des attaques qu'IPsec aurait empêchées, comme les resets TCP (cf. RFC 2385).

La section 10 contient quelques conseils de déploiement, pour le cas où on décide de faire du NAT. Le RFC recommande de chercher un mécanisme de résolution de noms qui gère le fait que les adresses soient différentes en interne et en externe, et suggère qu'un serveur DNS intégré au routeur NAT est sans doute dans la meilleure position pour faire cela. Il insiste sur le déploiement d'ALG pour les applications qui ne passent pas à travers le NAT (ou bien l'établissement d'un tunnel au dessus du NAT). Il fait remarquer (c'était une idée novatrice à l'époque) qu'il existe plein de variantes de NAPT, avec des comportements différents. Par exemple, si une application émet un paquet depuis le tuple {adresse interne, port interne} vers une destination extérieure, son tuple interne va être réécrit en {adresse externe, port externe}. Si cette application écrit ensuite à une autre destination extérieure, depuis le même tuple {adresse interne, port interne}, celui-ci sera t-il réécrit dans le même tuple {adresse externe, port externe} ou pas ? Tous les routeurs NAT n'ont pas forcément le même comportement sur ce point, et cela influe beaucoup sur les chances d'une application de passer à travers le NAT (RFC 4787).

Le RFC a aussi des suggestions plus surprenantes comme l'idée d'un registre des adresses privées, pour diminuer les risques de collision dans le cas où un client a des VPN vers deux réseaux privés utilisant la même plage d'adresses. Si cela a un sens au sein d'une même organisation (dont on peut espérer qu'elle a déjà un plan d'adressage cohérent, évitant les collisions), l'idée d'un registre plus large va à l'encontre du principe des adresses privées.

Depuis la sortie de ce RFC, l'IETF a accepté le principe d'un travail pour limiter les dégâts du NAT, le groupe de travail Behave, qui a produit plein d'excellents RFC. L'idée même d'un tel travail gênait certains à l'IETF, car ils pensaient qu'améliorer le NAT allait retarder son démantèlement souhaitable. Mais la prévalence du NAT a conduit à une position de compromis, avec un certain nombre de techniques permettant de vivre avec le NAT.

En résumé, ce RFC est hostile à la généralisation du NAT, non pas en disant qu'il ne marche pas (« it is possible to build a house of cards ») mais en notant qu'il restera toujours un bricolage fragile. Le problème de l'épuisement des adresses IPv4 doit se résoudre par le déploiement d'IPv6, pas par le NAT. On notera que cet avis n'a pas été suivi dans les treize années écoulées depuis la parution de ce RFC : l'IETF peut dire ce qu'elle veut, cela ne change rien en pratique. Les décisions ne sont pas prises par elle.


Téléchargez le RFC 2993


L'article seul

RFC 7011: Specification of the IP Flow Information eXport (IPFIX) Protocol for the Exchange of Flow Information

Date de publication du RFC : Septembre 2013
Auteur(s) du RFC : B. Claise (Cisco Systems), B. Trammell (ETH Zurich)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ipfix
Première rédaction de cet article le 16 septembre 2013


Le système IPFIX, successeur désigné de Netflow avait été normalisé dans le RFC 5101, que notre RFC met légèrement à jour. Des routeurs de différentes marques peuvent donc désormais envoyer des informations statistiques à des machines d'administration de différentes origines. L'idée de base, héritée de Netflow, est d'agréger les informations de trafic, pour que le routeur n'ait à envoyer qu'une synthèse, et pas la totalité du trafic. Comme Netflow, IPFIX peut servir à la gestion du réseau, à la supervision mais aussi à l'espionnage.

Un cahier des charges pour IPFIX avait été spécifié dans le RFC 3917. Le système IPFIX lui-même est normalisé depuis le RFC 5101, ce nouveau RFC prenant en charge le protocole d'autres RFC s'occupant du modèle d'informations (RFC 7012 et RFC 5610) ou bien de l'architecture des différents composants d'IPFIX. C'est ainsi qu'IPFIX a des extensions rigolotes comme la technique de compression du RFC 5473, les données complexes du RFC 6313 ou le stockage de donnéees dans des fichiers permanents du RFC 5655.

La terminologie d'IPFIX est en section 2. Il est recommandé de lire le document d'architecture, le RFC 5470. Un point d'observation (Observation Point) est l'endroit du réseau d'où on observe (le port d'un routeur, par exemple). Un domaine d'observation (Observation Domain) est l'ensemble des points d'observation dont les observations vont être agrégées en un seul message IPFIX (un routeur, par exemple). Un flot (flow) est un ensemble de paquets, passant par le même point d'observation, et ayant des caractéristiques communes. la définition est volontairement très ouverte. Un flot ne correspond donc pas forcément à une connexion TCP. Par exemple, un flot peut être défini par :

  • Les en-têtes du paquet : adresses IP de source et de destination, bien sûr, mais aussi les ports, et/ou des champs applicatifs. Donc, « tous les paquets depuis ou vers [2001:db8:1:2]:53 » est un flot, identifiant le trafic DNS de 2001:db8:1:2.
  • Les caractéristiques du traitement du paquet : prochain routeur ou interface de sortie.

Un enregistrement de flot (flow record) est composé de la définition du flot et des valeurs mesurées (nombre total de paquets appartenant à ce flot qui ont été vus, nombre total d'octets). Un gabarit (template) est une structure de données qui décrit ce qui est contenu dans les enregistrements. Un exporteur (exporter), typiquement le routeur, va émettre ces enregistrements, contenant le résultat de ses observations, vers un collecteur (collector) où on fabriquera de jolis graphes.

Notre RFC normalise ensuite le format des paquets (section 3). Comme avec d'autres protocoles, les paquets commencent par un numéro de version, 10 ici (inchangé depuis le RFC 5101), IPFIX marquant sa descendance depuis Netflow, dont la dernière version était la 9. Le RFC décrit aussi l'encodage des données exportées par l'observateur IPFIX (section 6).

Des exemples d'encodage sont fournis dans l'annexe A. Par exemple, A.2.1 utilise des éléments enregistrés à l'IANA (IPFIX permet aussi de définir les siens) :

  • Adresse IP source sourceIPv4Address,
  • Adresse IP destination destinationIPv4Address,
  • Routeur suivant ipNextHopIPv4Address,
  • Nombre de paquets packetDeltaCount,
  • Nombre d'octets octetDeltaCount.

Les trois premiers identifient le flot et les deux derniers sont les mesures par flot. Le gabarit va donc lister ces cinq élements, avec leur taille (quatre octets chacun).

Enfin, notre RFC décrit le mécanisme de transport, au dessus d'UDP, le protocole traditionnel de Netflow, mais aussi de TCP ou bien du protocole recommandé, SCTP. Pour répondre au cahier des charges, qui insistait sur la sécurité, la section 11.1 décrit aussi l'utilisation de TLS. À propos de sécurité, la section 11 se penche aussi sur la confidentialité (IPFIX permet de transporter des informations sur les métadonnées d'une communication, permettant l'analyse de trafic ; même si on n'a pas le contenu des communications, cela peut être très indiscret). Elle attire aussi l'attention du programmeur sur l'importance de s'assurer de l'intégrité des données. IPFIX pouvant être utilisé pour la facturation, un client malhonnête peut avoir une bonne motivation pour modifier ces données.

La section 1.1 décrit les changements depuis le premier RFC, le RFC 5101. Ils sont de peu d'importance et deux logiciels suivant les deux RFC pourront interagir. Il y a eu plusieurs corrections d'erreurs dans la spécification, les définitions d'élements d'information situées dans l'ancien RFC ont toute été sorties, vers le registre IANA, qui fait désormais seul autorité. Une nouvelle section, la 5.2, traite le problème du débordement de certains types temporels, débordement qui se produira en 2032 ou 2038 selon les cas (cela semble loin dans le futur mais les logiciels durent longtemps, rappelez-vous le bogue de l'an 2000).

IPFIX est déjà mis en œuvre dans plusieurs systèmes. Un exemple de mise en œuvre en logiciel libre est Maji. Mais, apparemment Cacti ne sait pas exporter de l'IPFIX, juste du vieux Netflow. Ntop sait faire mais il faut passer à nProbe l'option -V 10 (plein d'exemple dans cet article, merci à Andrew Feren pour les informations). Si vous voulez voir des traces IPFIX, il y en a deux sur pcapr. Wireshark sait analyser de l'IPFIX, il faut lui demander de décoder comme du cflow. Le RFC 5153 donne des conseils aux programmeurs qui veulent créer ou lire de l'IPFIX. Les RFC 5471 et RFC 5472 sont utiles aux administrateurs réseaux qui voudraient déployer IPFIX. Toutefois, aujourd'hui, des années après la sortie du premier RFC, il semble que peu d'opérateurs utilisent IPFIX (v10). La plupart sont restés bloqués sur Netflow (v9). Les « grands » routeurs (Juniper ou Cisco) savent faire de l'IPFIX mais pas forcément les routeurs de bas de gamme.

Deux autres logiciels importants, des collecteurs IPFIX. Il y a bien sûr pmacct mais aussi Vflow. Voici un exemple de fichier de configuration pmacct :

# Les bases de données dans lesquelles on stockera
plugins: memory,sqlite3,pgsql

# La version du schéma de données (7 est la plus récente)
sql_table_version: 7

# Le port UDP où les données IPFIX sont envoyées (cela doit coïncider
# avec la config' du routeur)
nfacctd_port: 2055

# Le ou les critères d'agrégation
aggregate: src_host

Avec une telle configuration, voici ce qui sera enregistré dans la base PostgreSQL :

pmacct=> select ip_src,bytes,packets from acct_v7 ;
    ip_src    | bytes  | packets 
--------------+--------+---------
 10.10.86.133 | 371740 |    2083
 192.0.2.2    | 368576 |    2804
(2 lignes)

Mais, au lieu de PostgreSQL, on aurait pu aussi utiliser le client en ligne de commandes (grâce au plugin memory) :

% pmacct -s
SRC_IP                                         PACKETS               BYTES
192.0.2.2                                      2363                  310176
10.10.86.133                                   1749                  312036

For a total of: 2 entries

Maintenant, si on ajoute au fichier de configuration une agrégation sur d'autres critères :

aggregate: src_host,dst_host,proto,src_port,dst_port

On aura alors bien plus de lignes dans les bases (une par tuple, et le port source du trafic SSH varie à chaque fois) :

% pmacct -s
SRC_IP                                         DST_IP                                         SRC_PORT  DST_PORT  PROTOCOL    PACKETS               BYTES
10.10.86.133                                   192.0.2.2                                      57230     22        tcp         6                     488
10.10.86.133                                   192.0.2.2                                      57250     22        tcp         6                     488
...
192.0.2.2                                      192.0.2.1                                      39802     53        udp         1                     71
192.0.2.2                                      10.10.86.133                                   22        57206     tcp         17                    2539

For a total of: 180 entries

Et idem dans la base PostgreSQL :

pmacct=> select count(*) from acct_v7 ;
 count 
-------
   198
(1 ligne)

On peut utiliser SQL pour faire des sélections, des agrégations... Exemple, tout le trafic depuis une machine, avec la fonction d'agrégation SQL sum et la fonction de sélection SQL where :

pmacct=> select sum(bytes), sum(packets) from acct_v7 where ip_src='192.0.2.2';
  sum   | sum  
--------+------
 326807 | 2492
(1 ligne)

Ou bien tout le trafic UDP :

pmacct=> select sum(bytes), sum(packets) from acct_v7 where ip_proto=17;
  sum   | sum  
--------+------
 111738 | 1574
(1 ligne)

Par défaut, les données sont agrégées, quel que soit leur âge. Si on veut faire des études historiques, il faut demander à garder les données plus anciennes :

aggregate: src_host,dst_host
sql_history: 5m
sql_history_roundoff: m

On voit alors les données « tourner » (notez le order SQL pour classer par ordre rétro-chronologique) :

pmacct=> select ip_src,ip_dst,packets,stamp_inserted,stamp_updated from acct_v7 where ip_dst!='0.0.0.0' order by stamp_updated desc;
    ip_src    |    ip_dst    | packets |   stamp_inserted    |    stamp_updated    
--------------+--------------+---------+---------------------+---------------------
 10.10.86.133 | 192.0.2.2    |    1249 | 2016-05-03 10:25:00 | 2016-05-03 10:28:02
 192.0.2.2    | 10.10.86.133 |    1487 | 2016-05-03 10:25:00 | 2016-05-03 10:28:02
 192.0.2.2    | 192.0.2.1    |     116 | 2016-05-03 10:25:00 | 2016-05-03 10:28:02
 192.0.2.2    | 192.0.2.1    |     252 | 2016-05-03 10:20:00 | 2016-05-03 10:26:02
 192.0.2.2    | 10.10.86.133 |    2906 | 2016-05-03 10:20:00 | 2016-05-03 10:26:02
 10.10.86.133 | 192.0.2.2    |    2354 | 2016-05-03 10:20:00 | 2016-05-03 10:26:02
 10.10.86.133 | 192.0.2.2    |    2364 | 2016-05-03 10:15:00 | 2016-05-03 10:21:02
 192.0.2.2    | 192.0.2.1    |     270 | 2016-05-03 10:15:00 | 2016-05-03 10:21:02
 192.0.2.2    | 10.10.86.133 |    2911 | 2016-05-03 10:15:00 | 2016-05-03 10:21:02
 192.0.2.2    | 10.10.86.133 |    1645 | 2016-05-03 10:10:00 | 2016-05-03 10:16:02
 192.0.2.2    | 192.0.2.1    |     154 | 2016-05-03 10:10:00 | 2016-05-03 10:16:02
 10.10.86.133 | 192.0.2.2    |    1310 | 2016-05-03 10:10:00 | 2016-05-03 10:16:02
(12 lignes)

(Chaque enregistrement dure un peu plus que les cinq minutes configurées car pmacct « bufferise ».)

Voici enfin un exemple de paquet vu par Wireshark. C'est du vrai IPFIX (numéro de version 10).

[Premier paquet, avec les gabarits]

Cisco NetFlow/IPFIX
    Version: 10
    Length: 876
    Timestamp: Jul  8, 2011 21:18:53.000000000 CEST
        ExportTime: 1310152733
    FlowSequence: 0
    Observation Domain Id: 0
    Set 1
        FlowSet Id: Data Template (V10 [IPFIX]) (2)
        FlowSet Length: 248
        Template (Id = 47104, Count = 25)
            Template Id: 47104
            Field Count: 25
            Field (1/25): flowStartMilliseconds
                0... .... .... .... = Pen provided: No
                .000 0000 1001 1000 = Type: flowStartMilliseconds (152)
                Length: 8
            Field (2/25): flowEndMilliseconds
                0... .... .... .... = Pen provided: No
                .000 0000 1001 1001 = Type: flowEndMilliseconds (153)
                Length: 8
            Field (3/25): BYTES_TOTAL
                0... .... .... .... = Pen provided: No
                .000 0000 0101 0101 = Type: BYTES_TOTAL (85)
                Length: 8
            Field (4/25): BYTES_TOTAL [Reverse]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0101 0101 = Type: BYTES_TOTAL (85) [Reverse]
                Length: 8
                PEN: IPFIX Reverse Information Element Private Enterprise (29305)
            Field (5/25): PACKETS_TOTAL
                0... .... .... .... = Pen provided: No
                .000 0000 0101 0110 = Type: PACKETS_TOTAL (86)
                Length: 8
            Field (6/25): PACKETS_TOTAL [Reverse]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0101 0110 = Type: PACKETS_TOTAL (86) [Reverse]
                Length: 8
                PEN: IPFIX Reverse Information Element Private Enterprise (29305)
            Field (7/25): IPV6_SRC_ADDR
                0... .... .... .... = Pen provided: No
                .000 0000 0001 1011 = Type: IPV6_SRC_ADDR (27)
                Length: 16
            Field (8/25): IPV6_DST_ADDR
                0... .... .... .... = Pen provided: No
                .000 0000 0001 1100 = Type: IPV6_DST_ADDR (28)
                Length: 16
            Field (9/25): IP_SRC_ADDR
                0... .... .... .... = Pen provided: No
                .000 0000 0000 1000 = Type: IP_SRC_ADDR (8)
                Length: 4
            Field (10/25): IP_DST_ADDR
                0... .... .... .... = Pen provided: No
                .000 0000 0000 1100 = Type: IP_DST_ADDR (12)
                Length: 4
            Field (11/25): L4_SRC_PORT
                0... .... .... .... = Pen provided: No
                .000 0000 0000 0111 = Type: L4_SRC_PORT (7)
                Length: 2
            Field (12/25): L4_DST_PORT
                0... .... .... .... = Pen provided: No
                .000 0000 0000 1011 = Type: L4_DST_PORT (11)
                Length: 2
            Field (13/25): PROTOCOL
                0... .... .... .... = Pen provided: No
                .000 0000 0000 0100 = Type: PROTOCOL (4)
                Length: 1
            Field (14/25): flowEndReason
                0... .... .... .... = Pen provided: No
                .000 0000 1000 1000 = Type: flowEndReason (136)
                Length: 1
            Field (15/25): paddingOctets
                0... .... .... .... = Pen provided: No
                .000 0000 1101 0010 = Type: paddingOctets (210)
                Length: 6
            Field (16/25):  21 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0001 0101 = Type: 21 [pen: CERT Coordination Center]
                Length: 4
                PEN: CERT Coordination Center (6871)
            Field (17/25): TCP_SEQ_NUM
                0... .... .... .... = Pen provided: No
                .000 0000 1011 1000 = Type: TCP_SEQ_NUM (184)
                Length: 4
            Field (18/25): TCP_SEQ_NUM [Reverse]
                1... .... .... .... = Pen provided: Yes
                .000 0000 1011 1000 = Type: TCP_SEQ_NUM (184) [Reverse]
                Length: 4
                PEN: IPFIX Reverse Information Element Private Enterprise (29305)
            Field (19/25):  14 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0000 1110 = Type: 14 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (20/25):  15 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0000 1111 = Type: 15 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (21/25): 16398 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .100 0000 0000 1110 = Type: 16398 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (22/25): 16399 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .100 0000 0000 1111 = Type: 16399 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (23/25): SRC_VLAN
                0... .... .... .... = Pen provided: No
                .000 0000 0011 1010 = Type: SRC_VLAN (58)
                Length: 2
            Field (24/25): SRC_VLAN [Reverse]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0011 1010 = Type: SRC_VLAN (58) [Reverse]
                Length: 2
                PEN: IPFIX Reverse Information Element Private Enterprise (29305)
            Field (25/25): Unknown(32767)
                0... .... .... .... = Pen provided: No
                .111 1111 1111 1111 = Type: Unknown (32767)
                Length: 65535 [i.e.: "Variable Length"]
        Template (Id = 49155, Count = 3)
            Template Id: 49155
            Field Count: 3
            Field (1/3): TCP_SEQ_NUM
                0... .... .... .... = Pen provided: No
                .000 0000 1011 1000 = Type: TCP_SEQ_NUM (184)
                Length: 4
            Field (2/3):  14 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0000 1110 = Type: 14 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (3/3):  15 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0000 1111 = Type: 15 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
        Template (Id = 49171, Count = 6)
            Template Id: 49171
            Field Count: 6
            Field (1/6): TCP_SEQ_NUM
                0... .... .... .... = Pen provided: No
                .000 0000 1011 1000 = Type: TCP_SEQ_NUM (184)
                Length: 4
            Field (2/6):  14 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0000 1110 = Type: 14 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (3/6):  15 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0000 1111 = Type: 15 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (4/6): 16398 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .100 0000 0000 1110 = Type: 16398 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (5/6): 16399 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .100 0000 0000 1111 = Type: 16399 [pen: CERT Coordination Center]
                Length: 1
                PEN: CERT Coordination Center (6871)
            Field (6/6): TCP_SEQ_NUM [Reverse]
                1... .... .... .... = Pen provided: Yes
                .000 0000 1011 1000 = Type: TCP_SEQ_NUM (184) [Reverse]
                Length: 4
                PEN: IPFIX Reverse Information Element Private Enterprise (29305)
        Template (Id = 49176, Count = 2)
            Template Id: 49176
            Field Count: 2
            Field (1/2):  18 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .000 0000 0001 0010 = Type: 18 [pen: CERT Coordination Center]
                Length: 65535 [i.e.: "Variable Length"]
                PEN: CERT Coordination Center (6871)
            Field (2/2): 16402 [pen: CERT Coordination Center]
                1... .... .... .... = Pen provided: Yes
                .100 0000 0001 0010 = Type: 16402 [pen: CERT Coordination Center]
                Length: 65535 [i.e.: "Variable Length"]
                PEN: CERT Coordination Center (6871)
        Template (Id = 49156, Count = 2)
            Template Id: 49156
            Field Count: 2
            Field (1/2): SRC_MAC
                0... .... .... .... = Pen provided: No
                .000 0000 0011 1000 = Type: SRC_MAC (56)
                Length: 6
            Field (2/2): DESTINATION_MAC
                0... .... .... .... = Pen provided: No
                .000 0000 0101 0000 = Type: DESTINATION_MAC (80)
                Length: 6

[Deuxième paquet, avec les données]

Cisco NetFlow/IPFIX
    Version: 10
    Length: 464
    Timestamp: Jul  8, 2011 21:18:53.000000000 CEST
        ExportTime: 1310152733
    FlowSequence: 0
    Observation Domain Id: 0
    Set 1
        FlowSet Id: (Data) (45840)
        FlowSet Length: 448
        Flow 1
            [Duration: 0.274000000 seconds]
                StartTime: Jun  7, 2011 15:22:38.902000000 CEST
                EndTime: Jun  7, 2011 15:22:39.176000000 CEST
            Permanent Octets: 220
            Permanent Octets: 276 (Reverse Type 85 BYTES_TOTAL)
            Permanent Packets: 4
            Permanent Packets: 4 (Reverse Type 86 PACKETS_TOTAL)
            SrcAddr: 77.250.217.161 (77.250.217.161)
            DstAddr: 192.168.5.219 (192.168.5.219)
            SrcPort: 51413
            DstPort: 52026
            Protocol: 6
            Flow End Reason: End of Flow detected (3)
            Enterprise Private entry: (CERT Coordination Center) Type 21: Value (hex bytes): 00 00 00 00
            Vlan Id: 0
            Vlan Id: 0 (Reverse Type 58 SRC_VLAN)
            [Enterprise Private entry: ((null)) Type 32767: Value (hex bytes): 00 c0 13 00 10 14 8d 68 ed 12 11 18 11 ed 4e 7d ... (Variable Length)]
                String_len_short: 255
                String_len_short: 17
        Flow 2
            [Duration: 0.672000000 seconds]
                StartTime: Jun  7, 2011 15:22:40.813000000 CEST
                EndTime: Jun  7, 2011 15:22:41.485000000 CEST
            Permanent Octets: 336
            Permanent Octets: 164 (Reverse Type 85 BYTES_TOTAL)
            Permanent Packets: 5
            Permanent Packets: 3 (Reverse Type 86 PACKETS_TOTAL)
            SrcAddr: 192.168.5.219 (192.168.5.219)
            DstAddr: 84.97.86.239 (84.97.86.239)
            SrcPort: 52035
            DstPort: 43572
            Protocol: 6
            Flow End Reason: End of Flow detected (3)
            Enterprise Private entry: (CERT Coordination Center) Type 21: Value (hex bytes): 00 00 00 dd
            Vlan Id: 0
            Vlan Id: 0 (Reverse Type 58 SRC_VLAN)
            [Enterprise Private entry: ((null)) Type 32767: Value (hex bytes): 00 c0 13 00 10 a3 c6 5c 68 02 19 12 11 8e be b7 ... (Variable Length)]
                String_len_short: 255
                String_len_short: 17
        Flow 3
            [Duration: 2.046000000 seconds]
                StartTime: Jun  7, 2011 15:22:40.813000000 CEST
                EndTime: Jun  7, 2011 15:22:42.859000000 CEST
            Permanent Octets: 336
            Permanent Octets: 164 (Reverse Type 85 BYTES_TOTAL)
            Permanent Packets: 5
            Permanent Packets: 3 (Reverse Type 86 PACKETS_TOTAL)
            SrcAddr: 192.168.5.219 (192.168.5.219)
            DstAddr: 142.68.133.226 (142.68.133.226)
            SrcPort: 52036
            DstPort: 50006
            Protocol: 6
            Flow End Reason: End of Flow detected (3)
            Enterprise Private entry: (CERT Coordination Center) Type 21: Value (hex bytes): 00 00 03 51
            Vlan Id: 0
            Vlan Id: 0 (Reverse Type 58 SRC_VLAN)
            [Enterprise Private entry: ((null)) Type 32767: Value (hex bytes): 00 c0 13 00 10 54 cc ca 16 02 19 12 11 74 3f 5e ... (Variable Length)]
                String_len_short: 255
                String_len_short: 17
        Flow 4
            [Duration: 0.162000000 seconds]
                StartTime: Jun  7, 2011 15:22:43.806000000 CEST
                EndTime: Jun  7, 2011 15:22:43.968000000 CEST
            Permanent Octets: 60
            Permanent Octets: 40 (Reverse Type 85 BYTES_TOTAL)
            Permanent Packets: 1
            Permanent Packets: 1 (Reverse Type 86 PACKETS_TOTAL)
            SrcAddr: 192.168.5.219 (192.168.5.219)
            DstAddr: 84.221.224.151 (84.221.224.151)
            SrcPort: 52047
            DstPort: 44809
            Protocol: 6
            Flow End Reason: End of Flow detected (3)
            Enterprise Private entry: (CERT Coordination Center) Type 21: Value (hex bytes): 00 00 00 a2
            Vlan Id: 0
            Vlan Id: 0 (Reverse Type 58 SRC_VLAN)
            [Enterprise Private entry: ((null)) Type 32767: Value (hex bytes): 00 c0 13 00 10 60 40 f2 6b 02 00 14 00 00 00 00 ... (Variable Length)]
                String_len_short: 255
                String_len_short: 17
        Flow 5
            [Duration: 0.335000000 seconds]
                StartTime: Jun  7, 2011 15:22:43.804000000 CEST
                EndTime: Jun  7, 2011 15:22:44.139000000 CEST
            Permanent Octets: 60
            Permanent Octets: 40 (Reverse Type 85 BYTES_TOTAL)
            Permanent Packets: 1
            Permanent Packets: 1 (Reverse Type 86 PACKETS_TOTAL)
            SrcAddr: 192.168.5.219 (192.168.5.219)
            DstAddr: 113.160.54.234 (113.160.54.234)
            SrcPort: 52044
            DstPort: 39621
            Protocol: 6
            Flow End Reason: End of Flow detected (3)
            Enterprise Private entry: (CERT Coordination Center) Type 21: Value (hex bytes): 00 00 01 4f
            Vlan Id: 0
            Vlan Id: 0 (Reverse Type 58 SRC_VLAN)
            [Enterprise Private entry: ((null)) Type 32767: Value (hex bytes): 00 c0 13 00 10 a0 86 d6 62 02 00 14 00 00 00 00 ... (Variable Length)]
                String_len_short: 255
                String_len_short: 17
...

Questions lectures, vous pouvez regarder cet exposé à FRnog.


Téléchargez le RFC 7011


L'article seul

RFC 7012: Information Model for IP Flow Information eXport (IPFIX)

Date de publication du RFC : Unknown month 2013 September
Auteur(s) du RFC : B. Claise (Cisco), B. Trammell (ETH Zurich)
Chemin des normes
Première rédaction de cet article le 16 septembre 2013


Le protocole IPFIX d'envoi par un routeur de résumés statistiques sur le trafic qu'il voit passer (RFC 7011), dépend d'un modèle de données, que décrit notre RFC, qui remplace l'ancien RFC 5102.

Le RFC 7011 qui normalise le protocole IPFIX indique comment transporter les données de l'exporteur (typiquement un routeur) vers le récolteur (typiquement la machine d'administration du réseau) mais n'indique pas quelles données sont transportées. Notre RFC va jouer ce rôle, équivalent à celui du SMI du RFC 2578 pour SNMP.

Notre RFC est assez simple (son prédécesseur, le RFC 5102 était très long, mais c'est parce qu'il intégrait la liste des éléments d'information disponibles, elle est désormais dans un registre IANA). Un élément d'information a un nom (par exemple destinationTransportPort), une description (cet élément indique le port de destination du flot), un type (ici unsigned16, nombre entier sur 16 bits) et d'autres informations utiles comme un ElementID qui identifie de manière unique un élément d'information. Les types sont décrits en détail dans la section 3 mais sont très classiques (entiers de différentes factures, booléens, adresses MAC, chaînes de caractères en Unicode, etc). Plus originaux sont les sémantiques de la section 3.2. Si les éléments ont par défaut la sémantique quantity (ils affichent la valeur actuellement mesurée), d'autres sont différents, par exemple en indiquant un total (sémantique d'odomètre). Ainsi, les éléments ayant une sémantique de totalCounter repartent de zéro lorsqu'ils ont atteint leur valeur maximale. Ceux ayant la sémantique identifier ne sont pas des nombres (même quand leur valeur est numérique, comme les numéros d'AS) et ne doivent donc pas être additionnés.

Voici un exemple complet, tiré du registre. Certains champs sont obligatoires, comme le nom, la description, le type (ici un entier non signé de 64 bits) ou l'ElementID (qui peut être un nombre simple attribué par l'IANA, pour les éléments « officiels » comme le 85 montré ici, ou bien complété par un numéro d'organisation pour les autres). D'autres sont facultatifs comme l'unité (ici, des octets ; une erreur dans les unités a déjà entraîné la perte d'une sonde spatiale). Le nom suit parfois des conventions de nommage (section 2.3). Par exemple, les éléments dont le nom commence par post identifient une mesure faite après un traitement par une middlebox, par exemple une traduction d'adresse. Voici l'élément octetTotalCount :

octetTotalCount
   Description:
      The total number of octets in incoming packets for this Flow at
      the Observation Point since the Metering Process
      (re-)initialization for this Observation Point.  The number of
      octets include IP header(s) and IP payload.
   Abstract Data Type: unsigned64
   Data Type Semantics: totalCounter
   ElementId: 85
   Status: current
   Units: octets

Le vrai format source du registre (regardez https://www.iana.org/assignments/ipfix/ipfix.xml depuis autre chose qu'un navigateur Web) est XML (section 7.3), avec un schéma en Relax NG. La définition ci-dessus est en fait :


<record>
<name>octetTotalCount</name>
<dataType>unsigned64</dataType>
<group>flowCounter</group>
<dataTypeSemantics>totalCounter</dataTypeSemantics>
<elementId>85</elementId>
<applicability>all</applicability>
<status>current</status>
<description>
<paragraph>
The total number of octets in incoming packets
for this Flow at the Observation Point since the Metering
Process (re-)initialization for this Observation Point.  The
number of octets includes IP header(s) and IP payload.
</paragraph>
</description>
<units>octets</units>
<xref type="rfc" data="rfc5102"/>
<revision>0</revision>
<date>2013-02-18</date>
</record>

Les éléments dans le registre IANA sont décrits en XML car cela permet de produire automatiquement du code ou des fichiers de configuration à partir du registre. Mais le protocole IPFIX lui-même n'utilise pas du tout XML.

Les changements depuis le RFC 5102 sont décrits en section 1.1. Le principal est que la liste des éléments d'information, au lieu d'être listée dans le RFC, est désormais dans un registre IANA. D'autre part, le mécanisme pour modifier cette liste a été légèrement changé (section 7.4). Il est décrit en détail dans le RFC 7013. En gros, pour ajouter un nouvel élément d'information, il faut un examen par un expert (le RFC 5226 décrit toutes ces procédures).


Téléchargez le RFC 7012


L'article seul

RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

Date de publication du RFC : Mai 2008
Auteur(s) du RFC : D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk
Chemin des normes
Première rédaction de cet article le 15 septembre 2013


L'une des rares normes de l'UIT encore utilisées sur l'Internet est X.509, une norme décrivant un format de certificats électroniques pour prouver son identité. X.509, comme toutes les normes UIT, est très complexe et probablement impossible à mettre en œuvre correctement et complètement. C'est pourquoi les applications sur l'Internet utilisent en général un sous-ensemble de X.509, décrit par ce RFC.

Ce sous-ensemble de X.509 (ou, plus exactement, de la version 3 de X.509) est souvent nommé PKIX, pour « Public-Key Infrastructure using X.509 ». C'est lui qui est derrière toutes les utilisations des certificats X.509 qu'on voit sur l'Internet, par exemple le fameux petit cadenas de HTTPS. La section 2 décrit les motivations pour avoir créé ce sous-ensemble. Il s'agit notamment de faciliter l'usage des certificats en mettant l'accent sur l'interopérabilité des programmes (n'importe quel certificat PKIX doit être compris par n'importe quel programme PKIX, ce qui n'est pas du tout garanti avec le X.509 original, où deux mises en œuvre de X.509 peuvent être parfaitement conformes au standard... et néanmoins incapables d'interopérer) et le déterminisme (savoir comment le certificat va être compris, ce qui est difficile avec le X.509 original, souvent trop vague). Tous les utilisateurs de X.509 (pas seulement l'IETF avec son PKIX) doivent donc définir un sous-ensemble de X.509, le profile (dans la langue de Whitfield Diffie). L'importance de cette notion de sous-ensemble est bien résumée par le RFC : « unbounded choices greatly complicate the software ». Au contraire, l'UIT travaille autour du principe « satisfaire tout le monde » et toute demande est donc prise en compte dans la norme, la rendant ainsi trop riche pour être programmée correctement.

Le format de certificat X.509 en est à sa troisième version, la première ayant été publiée par l'UIT et l'ISO en 1988. Plusieurs protocoles Internet se servent de ce format, le premier ayant été le projet PEM du RFC 1422 en 1993. C'est entre autres l'expérience de ce projet qui avait mené aux versions 2, puis 3 de X.509.

Ce RFC est uniquement une norme technique : il ne donne aucune règle sur les questions juridiques ou politiques, il ne dit pas, par exemple, comment une AC doit vérifier une demande de certificat, ni ce que doit faire un navigateur Web lorsqu'un certificat est invalide pour une raison ou pour une autre.

La section 3 pose l'architecture et les rôles de la PKIX, notamment les notions d'utilisateurs (end entity), qui demandent des certificats, et d'Autorités de Certification, qui les signent.

En 3.1, elle explique ce qu'est un certificat : lorsqu'on utilise la cryptographie asymétrique, on utilise la clé publique de son correspondant pour chiffrer les messages qu'on lui envoie. Mais comment savoir que c'est bien sa clé publique à lui, et pas celle d'un méchant qui écoute les communications, et pourra les déchiffrer si on utilise la clé qu'il nous a fournie ? Un certificat est l'affirmation, signée par une Autorité de Certification, qu'une clé publique est bien celle d'un utilisateur donné (subject, dans le jargon X.509). On nomme cette affirmation le lien (binding) entre la clé et le sujet.

Le certificat contient aussi diverses informations comme sa date d'expiration. Un certificat est donc juste une structure de données dont les champs sont la clé publique, la signature de l'AC, la date d'expiration, etc. Rendons cela plus concret avec un exemple sur un vrai certificat X.509, celui du site https://app.capitainetrain.com/. Pour simplifier les operations ultérieures, commençons par copier le certificat en local, avec openssl :

% openssl s_client -connect app.capitainetrain.com:443 > capitainetrain.pem < /dev/null
depth=1 C = US, O = "GeoTrust, Inc.", CN = RapidSSL CA
verify error:num=20:unable to get local issuer certificate
verify return:0
DONE

On aurait aussi pu utiliser GnuTLS pour récupérer le certificat :

% gnutls-cli --print-cert app.capitainetrain.com < /dev/null > capitainetrain.pem

On peut maintenant regarder le certificat et y découvrir les informations mentionnées plus haut :

% openssl x509 -text -in capitainetrain.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 555296 (0x87920)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, O=GeoTrust, Inc., CN=RapidSSL CA
        Validity
            Not Before: Sep 30 02:22:13 2012 GMT
            Not After : Oct  2 09:04:29 2015 GMT
        Subject: serialNumber=HjJWka0qtZ2MV9EYsbjRf51Mbcd/LYOQ, OU=GT04045327, OU=See www.rapidssl.com/resources/cps (c)12, OU=Domain Control Validated - RapidSSL(R), CN=app.capitainetrain.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cd:af:c5:f8:ac:db:3b:10:fc:af:05:2f:ec:e5:
                    ...
           X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://rapidssl-crl.geotrust.com/crls/rapidssl.crl
           ...
   Signature Algorithm: sha1WithRSAEncryption
         95:d4:fe:88:bc:9c:f8:b7:d5:72:52:c1:c8:98:04:ee:82:f7:
    ...

On y trouve le numéro de série du certificat, 555296, le nom de l'AC émettrice (C=US, O=GeoTrust, Inc., CN=RapidSSL CA, à savoir RapidSSL, une AC low-cost), la période de validité (jusqu'au 2 octobre 2015), le titulaire (app.capitainetrain.com), la clé publique, l'endroit où récupérer les CRL, et le tout avec la signature de l'AC.

Il y a aussi d'autres informations qui ne sont pas affichées par défaut par openssl. Par exemple, les usages permis (merci à Laurent Frigault pour son aide à ce sujet). Il faut utiliser l'option -purpose :

% openssl x509 -text -purpose -in capitainetrain.pem
...
Certificate purposes:
SSL client : Yes
SSL client CA : No
SSL server : Yes
SSL server CA : No
...

Ce certificat peut être utilisé pour un serveur TLS (anciennement nommé SSL), l'usage le plus courant des certificats, sur l'Internet.

Dans les normes, cette structure de données est décrite en ASN.1 et encodée en DER, suivant la norme X.690.

La section 4 de notre RFC décrit rigoureusement le sous-ensemble de X.509 utilisé dans l'Internet. Voici une partie de cette description d'un certificat, montrant les champs les plus importants :

   Certificate  ::=  SEQUENCE  {
        tbsCertificate       TBSCertificate,
        signatureAlgorithm   AlgorithmIdentifier,
        signatureValue       BIT STRING  }

   TBSCertificate  ::=  SEQUENCE  {
        version         [0]  EXPLICIT Version DEFAULT v1,
        serialNumber         CertificateSerialNumber,
        issuer               Name,
        validity             Validity,
        subject              Name,
        subjectPublicKeyInfo SubjectPublicKeyInfo,
        ...
        }

Ici, signatureValue est la signature apposée par l'AC. Elle s'applique à un certificat, le tbsCertificate. Celui-ci a un numéro de série unique, un émetteur (l'AC, identifiée par un nom complet - Distinguished Name ou DN), une période de validité (entre telle date et telle date), un titulaire (subject), la clé publique dudit titulaire, etc. Vous pouvez voir tous ces champs dans l'exemple de app.capitainetrain.com montré plus haut.

Comme toujours en bonne cryptographie, plusieurs algorithmes de signature sont possibles, afin de faire face aux progrès de la cryptanalyse. Les RFC 3279, RFC 4055 et RFC 4491 donnent la liste des algorithmes standard dont bien sûr le fameux RSA. Évidemment, il faut utiliser des algorithmes de cryptographie forts, à la sécurité connue et éprouvée. Les AC ne devraient pas, par exemple, accepter de signer des certificats utilisant des algorithmes aux faiblesses identifiées (comme plusieurs l'avaient fait avec le vieil MD5).

Comment identifier un titulaire (champ subject) ? C'est un des points délicats de X.509, qui permet une grande variété de noms. Dans l'Internet, le plus fréquent est d'utiliser un nom de domaine, soit comme spécifié par le RFC 4519 (section 2.4), soit en utilisant l'extension X.509 « noms alternatifs » (section 4.2.1.6 de notre RFC). Cette dernière extension permet aussi d'utiliser comme identificateur une adresse IP, un URI, etc. La grande variété des types de « noms » dans X.509, et la difficulté de la comparaison de ces noms créent d'ailleurs pas mal de risques de sécurité.

L'extension « noms alternatifs » sert aussi si, derrière une même adresse IP, on a plusieurs sites. On voit ainsi quatre noms possibles pour www.digicert.com :

% openssl x509 -text -in digicert.pem  
...
X509v3 Subject Alternative Name: 
   DNS:www.digicert.com, DNS:digicert.com, DNS:content.digicert.com, DNS:www.origin.digicert.com

Ce champ subject est évidemment d'une importance vitale. Le but de la signature du certificat est précisément de lier une clé publique à un identificateur (subject). L'AC doit donc vérifier le contenu de ce champ. Par exemple, CAcert n'inclut dans les certificats signés que les champs que cette AC a vérifié. Pour un nom de domaine, CAcert teste qu'il se termine par un des noms dont l'utilisateur a prouvé la possession (preuve typiquement apportée en répondant à un courrier envoyé au titulaire du domaine).

Les noms (subjects) ne sont pas forcément limités à l'ASCII, ils peuvent inclure de l'Unicode et la section 7 de ce RFC décrit les règles spécifiques à suivre dans ce cas. Notamment, les noms doivent être canonicalisés en suivant le RFC 4518. Pour les noms de domaine, le type utilisé par X.509, IA5String, ne permet hélas que l'ASCII et les IDN devront donc être représentés sous forme d'un A-label (www.xn--potamochre-66a.fr au lieu de www.potamochère.fr, par exemple). Même chose pour les IRI du RFC 3987 qui devront être convertis en URI.

Une possibilité peu connue de X.509 est l'extension « Name constraints » (section 4.2.1.10) qui permet de signer des certificats d'AC avec une limite : l'AC qui a ainsi reçu une délégation ne peut signer que des certificats obéissant à cette contrainte (si le titulaire du certificat est un URI ou une adresse de courrier, la contrainte s'applique au nom de domaine compris dans l'URI ou l'adresse). On peut ainsi déléguer à une AC qui ne pourra signer que si le nom de domaine du titulaire se termine en .fr, par exemple. Cela résoud une faille de sécurité importante de X.509 (celle qui a motivé le RFC 6698) : le fait que n'importe quelle AC puisse signer un nom de n'importe quel domaine, que le titulaire de ce nom de domaine soit le client de l'AC ou pas. Mais, en pratique, cette extension semble peu utilisée.

Enfin, la section 6 du RFC décrit le mécanisme de validation d'un certificat, par exemple lorsqu'un navigateur Web se connecte en HTTPS à un serveur et reçoit un certificat prouvant que ce serveur est bien celui demandé.

La section 8 étudie en détails toutes les questions de sécurité liées à X.509. D'abord, comme tous les éléments décrits dans ce RFC (les certificats et les CRL) sont signés, leur distribution ne nécessite pas de précautions particulières : à l'arrivée, et quel que soit le mécanisme de transport utilisé, le destinataire pourra vérifier l'intégrité de ces éléments.

Plus délicate est la question des procédures que suit l'AC avant de signer un certificat : c'est là que se situent l'essentiel des faiblesses de X.509. Par exemple, est-ce qu'une AC doit vérifier que le nom de domaine n'est pas proche d'un autre ?

Le RFC oublie, semble t-il, de dire que prendre soin de choisir une « bonne » AC n'est pas très utile puisque n'importe quelle AC de confiance peut émettre un certificat pour n'importe quel nom. Si Google est client de GeoTrust, qui signe donc les certificats de gmail.com, rien n'empêche DigiNotar, avec qui Google n'a aucun lien, de signer aussi des certificats pour gmail.com. Le point critique n'est donc pas l'AC qu'on choisit pour signer ses certificats, mais les AC auxquelles nos clients choisissent de faire confiance. Qu'une seule de ces AC trahisse ou soit piratée et tout le système s'écroule. Or, justement, comment sont choisies ces AC de confiance ? Très peu d'utilisateurs examinent la liste (le « magasin ») d'AC de leur logiciel. Ils font une confiance aveugle à l'éditeur du logiciel, qui décide selon ses propres critères, d'inclure telle ou telle AC. Il y a donc des AC qui ne sont que dans certains navigateurs Web (rendant les certificats signés par ces AC difficiles à utiliser). Pour limiter ces difficultés, les éditeurs de navigateurs Web incluent beaucoup d'AC (des centaines, dans un navigateur typique), rendant difficile de valider leur sécurité. Petit exercice : cherchez dans votre navigateur la liste des AC acceptées (sur Firefox, Edit -> Preferences, puis Advanced puis View certificates) et lisez-la. Vous découvrirez plein d'organisations inconnues et lointaines.

Au cas où il faille ajouter ou retirer une AC, on ne peut pas demander à l'utilisateur de le faire. Il faut donc une mise à jour du logiciel, ou bien une distribution, par un autre canal, d'une liste d'AC (distribution sécurisée, par exemple, par une signature avec la clé privée de l'éditeur du logiciel).

L'AC doit évidemment gérer avec le plus grand soin la clé privée de ses propres certificats. Si un méchant copie cette clé, il pourra se faire passer pour l'AC et émettre des faux certificats. À une moins échelle, c'est aussi vrai pour l'utilisateur : si sa clé privée est compromise, il sera possible de se faire passer pour lui, et la signature de la clé publique par l'AC ne changera rien.

Notons que le RFC ne semble pas parler du cas où la clé privée de l'AC est bien gardée et inaccessible mais où le système d'information de l'AC a été piraté, permettant à l'attaquant de faire générer des « vrais/faux certificats ». C'est pourtant la menace principale, comme l'avaient illustrés les cas de Comodo et DigiNotar.

Cela nous amène à un autre point faible de X.509, la révocation. Des clés privées vont forcément tôt ou tard être copiées illégalement par un attaquant, qui va pouvoir alors se faire passer pour le titulaire du certificat. Si une clé privée est copiée à l'extérieur, ou qu'on soupçonne sérieusement qu'elle est copiée, comment empêcher l'attaquant de jouir des fruits de son forfait ? Ou, sans chercher un cas aussi dramatique, on peut aussi imaginer qu'un employé qui avait accès à la clé privée quitte l'organisation et qu'on souhaite, par précaution, qu'il ne puisse pas utiliser cette connaissance. Une solution est d'attendre l'expiration (rappelez-vous que les certificats X.509 ont une période de validité, entre deux dates, celle de début de validité et celle d'expiration). Mais cela peut prendre longtemps. Il faut donc émettre tout de suite une révocation, une annulation du certificat, signée par l'AC. X.509 permet aux AC d'émettre des CRL (Certificate Revocation List), qui sont des listes de certificats révoqués, signées par l'AC qui avait émis le certificat original. Étant signées, les CRL n'ont même pas besoin (comme les certificats, d'ailleurs) d'être distribuées par un canal sûr.

Le problème est de distribuer celles-ci efficacement. Comme l'ont montré plusieurs études, la révocation marche mal car il est difficile de s'assurer que tous les clients ont reçu l'information. Il y a plusieurs raisons à cela, le RFC n'en note qu'une : la révocation n'est pas temps réel. Entre le moment où la CRL est émise et celui où elle est traitée par tous les consommateurs, un certain temps peut s'écouler. (Une solution possible est le protocole OCSP, dans le RFC 6960.)

Voici une CRL de RapidSSL (celle annoncée dans le certificat de app.capitainetrain.com vu plus haut) :

% openssl crl -text -inform DER -in rapidssl.crl
Certificate Revocation List (CRL):
        Version 2 (0x1)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: /C=US/O=GeoTrust, Inc./CN=RapidSSL CA
        Last Update: Sep 13 12:03:00 2013 GMT
        Next Update: Sep 23 12:03:00 2013 GMT
...
   Serial Number: 070B6B
        Revocation Date: Aug 27 10:56:39 2013 GMT
...

On voit ainsi que le certificat de numéro de série 461675 (070B6B en hexadécimal) a été révoqué le 27 août 2013. Les raisons de la révocation sont également indiquées par certaines AC. Dans ce cas, on verrait :

    Serial Number: 18F...
        Revocation Date: Sep  3 07:58:20 2012 GMT
        CRL entry extensions:
            X509v3 CRL Reason Code: 
                Key Compromise
    Serial Number: 5FD...
        Revocation Date: Aug 12 12:59:20 2012 GMT
        CRL entry extensions:
            X509v3 CRL Reason Code: 
                Key Compromise
...

Enfin, trois annexes du RFC seront particulièrement utiles pour les programmeurs. Ceux-ci doivent d'abord noter que X.509 est très complexe et très difficile à implémenter. La première lecture recommandée, pour avoir une idée du travail, est le « X.509 Style Guide » de Peter Gutmann. L'annexe A liste les structures de données de X.509, en syntaxe ASN.1. On y trouve même des héritages d'un lointain passé comme :

poste-restante-address INTEGER ::= 19

L'annexe B donne des conseils aux programmeurs sur la mise en œuvre de X.509. L'annexe C donne des exemples de certificats et de CRL. Le programme dumpasn1 est utilisé pour les afficher. Attention, cet outil ne lit que le DER, pas le PEM. Si on a un certificat au format PEM, il faut d'abord le convertir :

% openssl x509 -inform pem -outform der -in capitainetrain.pem -out capitainetrain.der

Et on peut alors l'analyser :

% dumpasn1  capitainetrain.der|more

   0 1330: SEQUENCE {
   4 1050:   SEQUENCE {
   8    3:     [0] {
  10    1:       INTEGER 2
         :       }
  13    3:     INTEGER 555296
  18   13:     SEQUENCE {
  20    9:       OBJECT IDENTIFIER sha1WithRSAEncryption (1 2 840 113549 1 1 5)
...
  95   30:     SEQUENCE {
  97   13:       UTCTime 30/09/2012 02:22:13 GMT
 112   13:       UTCTime 02/10/2015 09:04:29 GMT
...
 294   31:       SET {
 296   29:         SEQUENCE {
 298    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
 303   22:           PrintableString 'app.capitainetrain.com'
         :           }
...

Si vous préférez un truc moderne et qui brille, l'outil interactif en ligne ASN.1 JavaScript decoder est remarquable (et, lui, il accepte le PEM).

Ce sous-ensemble (« profile ») de X.509 avait à l'origine été normalisé dans le RFC 3280, que ce RFC met à jour. La liste des changements est décrite en section 1. Rien de crucial, mais on notera que la nouvelle norme fait une part plus grande à l'internationalisation.

Merci à Manuel Pégourié-Gonnard pour la correction d'erreurs.


Téléchargez le RFC 5280


L'article seul

RFC 7010: IPv6 Site Renumbering Gap Analysis

Date de publication du RFC : Septembre 2013
Auteur(s) du RFC : B. Liu, S. Jiang (Huawei Technologies), B. Carpenter (University of Auckland), S. Venaas (Cisco Systems), W. George (Time Warner Cable)
Pour information
Réalisé dans le cadre du groupe de travail IETF 6renum
Première rédaction de cet article le 14 septembre 2013


Si on pouvait facilement renuméroter (changer les adresses IP) d'un réseau, beaucoup de problèmes seraient moins graves. Par exemple, il y aurait moins de demande pour des adresses PI. Mais, comme l'explique bien le RFC 5887, renuméroter, en pratique, est difficile, et les administrateurs réseaux, à juste titre, font tout ce qu'ils peuvent pour l'éviter. Pour essayer de résoudre ce problème, l'IETF a un groupe de travail 6renum, dont voici le troisième RFC. 6renum travaille à faciliter la rénumérotation en IPv6. Ce RFC 7010 est consacré à l'analyse des trous : que manque t-il comme protocole IETF pour faciliter la renumérotation ?

C'est un enjeu important pour l'Internet : sans renumérotation facile, les administrateurs réseaux se tourneront encore plus massivement vers les adresses PI, qui exercent une pression sur la table de routage (RFC 4984). Le RFC 6879, plus pratique, décrivait un certain nombre de scénarios de renumérotation et ce nouveau document, le RFC 7010 va bâtir sur ces scénarios en regardant ce qui gêne leur réalisation (et qui nécessitera un travail à l'IETF). Les machines ayant une adresse IP statique, typiquement les serveurs, sont traitées dans un autre document, le RFC 6866. De même, le cas d'une rénumérotation urgente et non planifiée, par exemple suite à la faillite d'un FAI, n'est pas couvert ici.

Donc, d'abord (section 2), qu'appelle t-on une rénumérotation réussie ? Que voudrait-on comme propriétés ? Une rénumérotation part d'un ancien préfixe et arrive à un nouveau. Pour les moyennes et grandes organisations, on a pu recevoir ce nouveau préfixe par des moyens humains (message électronique, par exemple). Pour les petites, on a pu le recevoir par une délégation, genre DHCPv6-PD (Prefix Delegation, RFC 3633). Dans les deux cas, on voudrait plein de choses :

  • Le nouveau préfixe devrait être reçu automatiquement et correctement,
  • Les adresses IP dans ce nouveau préfixe devraient être acquises automatiquement par les machines, sans intervention humaine,
  • Les endroits où se trouvent configurées ces adresses devraient se mettre à jour,
  • Même si ça se passe tout seul, on souhaiterait être notifié de ce changement et pouvoir le superviser,
  • Enfin, on voudrait que la rénumérotation ne casse pas les sessions applicatives en cours (pensez à SSH...) Comme ce RFC ne regarde que les renumérotations contrôlées (pas celles faites en urgence, à l'arrache), cet objectif peut être atteint en ayant une période de transition qui soit plus longue que la durée de vie de ces sessions applicatives.

Comme le savent les lecteurs du RFC 5887, on en est loin...

Et quels sont les protocoles, les outils et les procédures qui peuvent nous aider à s'approcher de ces beaux objectifs (section 3) ? Les protocoles sont les suivants :

  • Les messages RA (Router Advertisment, RFC 4861) permettent d'annoncer les préfixes IPv6 utilisés sur le lien local,
  • SLAAC (StateLess Address AutoConfiguration, RFC 4862) permet aux machines de se configurer une adresse IPv6 après avoir entendu les RA,
  • RA + SLAAC ne sont pas la seule solution, IPv6 a aussi DHCP (RFC 3315 et RFC 3633 pour la délégation de préfixe),
  • Il y eu aussi un système utilisant ICMP spécifiquement pour la rénumérotation, décrit dans le RFC 2894 et qui ne semble pas avoir jamais été déployé.

Il y a aussi des outils :

  • Les moyens et grands réseaux ne se gèrent pas à la main, ils se servent d'IPAM, qui gardent trace des adresses et de leur allocation,
  • Dès que le réseau a une taille non triviale, il est fréquent que les modifications ne soient pas propagées manuellement mais par un outil comme Chef ou Puppet,
  • Cette propagation des configurations peut aussi se faire avec des outils utilisant NETCONF (RFC 4741) ou d'autres protocoles de transport. Pour des détails pratiques, on peut consulter l'article de Leroy et Bonaventure, « Preparing network configurations for IPv6 renumbering »,

Et des procédures :

  • Le RFC 4192 décrit en détail comment renuméroter un réseau IPv6 sans flag day, sans un jour J où le soleil se coucherait sur un réseau complètement migré,
  • Le RFC 6879, déjà cité, étudie des cas de renumérotation et fait des recommandations opérationnelles.

Mais, en pratique, cela ne suffit pas. La section 5 se penche sur le premier problème, la configuration des adresses dans les machines terminales et les routeurs. D'abord, l'interaction entre SLAAC et DHCP, une source de frustration fréquente pour les administrateurs réseaux IPv6. En gros, ces deux protocoles permettent de faire la renumérotation. S'ils sont présents tous les deux sur un réseau, c'est plus compliqué et il faut bien les coordonner. Le plus simple est quand même de n'en avoir qu'un seul (ce qui est, heureusement, le cas le plus courant). Normalement, il existe des indications dans les messages permettant de coordonner les deux protocoles (options M et O du RA, cf. RFC 4861, section 4.2). Mais ils sont traités comme indicatifs seulement. Résultat, les différents systèmes d'exploitation ne les interprètent pas de la même manière. On n'est donc pas sûr, par exemple, qu'on puisse renuméroter avec les RA des machines qui avaient été configurées en DHCP (ManagedFlag passant de 1 à 0). De même, les RFC 4862 et RFC 3315 ne sont pas clairs sur ce que doit faire une machine cliente DHCP lorsqu'elle voit des nouveaux préfixes être annoncés par des RA. Un problème analogue se pose en sens inverse (transition de DHCP vers SLAAC).

Et pour les routeurs ? Logiquement, tout devrait bien se passer sauf que, contrairement aux machines terminales qui acceptent toutes de changer d'adresse IP en vol, certains routeurs doivent être redémarrés lorsque cela leur arrive.

Comme souvent en renumérotation, on s'épargnerait bien des problèmes en utilisant des noms dans les configurations et pas des adresses IP. Mais le RFC note, à juste titre, que ce n'est pas toujours le cas pour les routeurs.

Une fois machines terminales et routeurs renumérotés, il reste à mettre à jour des tas de configurations et de bases de données qui stockent encore les anciennes adresses. C'est l'objet de la section 6. Premier exemple, les zones DNS. La zone peut être maintenue à la main, avec un éditeur et il faudra alors faire un rechercher/remplacer. Ou bien on peut utiliser les mises à jour dynamiques (RFC 3007). Cette fonction existe depuis longtemps, est mise en œuvre dans plusieurs logiciels serveurs mais, pour que chaque machine puisse individuellement faire la mise à jour, il faut un mécanisme d'autorisation, et gérer une clé dans chaque machine n'est pas pratique. Il est plus commun que la mise à jour du DNS soit faite par le serveur DHCP, pour le compte des machines terminales (RFC 4704). Cela marche très bien si la renumérotation est faite par DHCP. Si on a utilisé SLAAC, il n'existe pas de solution évidente (aujourd'hui : des réflexions sont en cours, par exemple dans draft-ietf-dhc-addr-registration).

Il reste à traiter le cas des adresses IP éparpillées un peu partout, notamment dans des ACL. Il n'existe pas de solution générale pour ce problème. Mais notre RFC recommande que, lorsqu'on utilise des adresses IP dans des configurations, on définisse une variable au début et on l'utilise ensuite, pour limiter la douleur de la renumérotation. Un exemple en shell Unix avec Netfilter, pour un routeur Unix qui transmet vers un serveur HTTP :

# Define the variable
WEBSERVER=2001:db8:cafe::1:34a

# By default, block everything
ip6tables --policy FORWARD DROP

# Allow ICMP. We could be more selective.
ip6tables --append FORWARD --protocol icmp --destination ${WEBSERVER} --jump ACCEPT

# Rate limiting
ip6tables --append FORWARD --protocol tcp --destination ${WEBSERVER} --dport 80 --tcp-flags SYN SYN -m hashlimit \
   --hashlimit-name Web --hashlimit-above 3/second --hashlimit-mode srcip \
   --hashlimit-burst 7 --hashlimit-srcmask 28 --jump DROP

# Allow HTTP and HTTPS
ip6tables --append FORWARD --protocol tcp --destination ${WEBSERVER} \
         --dport 80:443 --jump ACCEPT

Ainsi, le script n'utilise qu'une seule fois l'adresse, au début, et est donc bien plus facile à modifier. Un programme comme ack-grep est très pratique pour trouver tous ces cas où une adresse est stockée dans la configuration :

# ack-grep --all 2001:db8:cafe::1:42   
network/interfaces
14:        address 2001:db8:cafe::1:42   

nsd3/nsd.conf
15:        ip-address: 2001:db8:cafe::1:42   
...

Pour simplifier ce problème des adresses IP dispersées un peu partout, notre RFC recommande l'utilisation d'outils de gestion de configuration comme Chef ou Puppet : on change la configuration à un endroit et elle est ensuite poussée vers tous les serveurs. Il existe aussi des outils non-libres, spécifiques à un vendeur particulier, pour assurer cette tâche et le RFC regrette l'absence d'une norme complète (NETCONF ne règle pas tous les cas) et ouverte pour cette question de mise à jour.

Pour que l'opération de migration vers les nouvelles adresses se passe bien, il faut aussi des mécanismes de gestion des événements, notamment de notification (« Un nouveau préfixe est arrivé »). Ces notifications permettraient, par exemple, d'invalider les caches DNS (pour forcer une mise à jour), ou de changer les configurations de filtrage (le RFC 2827 demande qu'on ne laisse pas sortir de son réseau les paquets ayant une adresse IP source autre que celles du réseau ; mettre ce filtrage en œuvre nécessite de connaître le préfixe du réseau local, et d'en changer si nécessaire). Cette notification n'est pas triviale, notamment si on utilise SLAAC (puisque, dans ce cas, aucun serveur central n'est informé du changement d'adresse d'une machine)

Le DNS pose d'ailleurs d'autres questions. En raison du TTL des enregistrements DNS, les nouvelles informations ne peuvent pas être réjuvénées instantanément. Si la rénumérotation du réseau est prévue suffisemment à l'avance, la bonne pratique est d'abaisser ces TTL avant, de faire le changement, puis de remonter les TTL.

Les sections 9 et 10 résument les trous qu'il y a actuellement dans les protocoles TCP/IP, et dont le comblement rendrait la rénumérotation plus facile :

  • Un mécanisme pour informer le routeur qu'il doit se rénuméroter lui-même, et pour choisir une adresse dans le préfixe délégué. Et une meilleure gestion de sa propre renumérotation par le routeur (ne nécessitant pas de redémarrage).
  • Une meilleure spécification des interactions SLAAC<->DHCP, notamment sur la renumérotation en DHCP de machines numérotées par SLAAC et réciproquement.
  • Le problème de la mise à jour du DNS par les machines SLAAC reste entier.
  • L'usage trop important d'adresse IP « codées en dur », non dérivées d'une unique variable facile à changer. Certains systèmes ne permettent même pas une telle dérivation.
  • Un mécanisme de notification « attention, les adresses vont changer / ont changé ».
  • L'interaction avec les TTL DNS reste compliquée.

La section 10 se spécialise dans les trous considérés comme insolubles, et dont le groupe 6renum ne s'occupera donc pas :

  • La mise à jour des zones DNS pour le cas où elles sont extérieures à l'organisation, par exemple chez un hébergeur DNS qui fournit uniquement une interface Web pour les mettre à jour.
  • La synchronisation des entrées AAAA (nom -> adresse) et PTR (adresse -> nom) dans le DNS. Cette synchronisation est d'autant plus insoluble que les zones « directes » et « inverses » (ip6.arpa) peuvent très bien être gérées par des hébergeurs différents.
  • Créer des types d'enregistrement DNS explicitement pour faciliter la renumérotation a déjà été tenté avec le A6 du RFC 2874. Trop complexe, le A6 a été peu déployé et a officiellement été abandonné avec le RFC 6563. L'idée de séparer le préfixe de l'adresse et son suffixe lors de la résolution DNS reste dans l'air mais le groupe 6renum n'a pas l'intention de s'y attaquer.
  • Les protocoles de transport comme TCP lient une connexion aux adresses IP de source et de destination. Cela a des tas d'inconvénients (en cas de renumérotation, les connexions cassent) mais c'est considéré comme un problème de grande ampleur, loin des capacités du groupe 6renum.
  • Un problème analogue se pose dans certaines applications, qui cassent les sessions lorsqu'une adresse IP d'une des parties change.

Voilà, nous avons fait le tour des problèmes, il reste à lire la section 11, spécialisée dans les questions de sécurité. Par exemple, si on a des ACL sur les adresses IP, et qu'elles interdisent à certains méchants de se connecter à l'adresse IP d'un serveur, la rénumérotation ne doit pas invalider cette liste noire : la règle doit être mise à jour pour pointer vers la nouvelle adresse IP du serveur.

Mais on peut aussi noter que la configuration automatique, souhaitée par le RFC, amène aussi ses propres risques, comme illustré par l'accident de Cloudflare ou comme un cas rigolo avec Ansible.


Téléchargez le RFC 7010


L'article seul

reveal.js, faire des supports de présentation webeux

Première rédaction de cet article le 11 septembre 2013


Récemment, je me suis posé la question de savoir s'il existait des alternatives rigolotes au logiciel de création de présentations que j'utilise d'habitude, LaTeX/Beamer. J'ai découvert qu'il existait notamment tout un tas d'outils fondés sur les techniques Web et j'ai choisi de commencer à utiliser reveal.js. Je documente ici quelques points techniques découverts à cette occasion.

Ces outils Web ont en commun d'utiliser des techniques qui sont maîtrisées par beaucoup de gens (mais pas par moi) comme HTML, CSS ou JavaScript. Si on utilise un des thèmes pré-définis avec reveal.js, l'utilisation de ce logiciel est très simple. Il existe plusieurs tutoriels, voici celui que je recommande.

Mais si on utilise ces outils Web, c'est souvent pour modifier et mettre son propre thème. Pour des modifications simples et limitées, ajouter son code CSS est suffisant. Pour des modifications plus fondamentales, il faut aller plus loin. La procédure d'écriture de son propre thème est documentée mais pas vraiment triviale. D'abord, il faut installer quelques outils, notamment node.js et le gestionnaire de tâches Grunt. Sur une Debian stable (sur la version de développement, surnommée « sid », c'est un peu plus simple, sur une Ubuntu, ça marche pareil), voici comment j'ai fait (en partant des instructions officielles de reveal.js). D'abord, installer node.js. Cela peut se faire de plusieurs façons, mais je tenais à avoir un paquetage Debian installé, pour faciliter les mises à jour ultérieures. (Et merci à l'auteur d'un bon article sur cette procédure.)

% wget -N http://nodejs.org/dist/node-latest.tar.gz
# aptitude install python g++ make checkinstall
% tar xzvf node-latest.tar.gz 
% cd node-v*
% ./configure
# checkinstall

Deux avertissements importants pour la dernière étape : checkinstall doit tourner sous root (à moins qu'il existe une méthode plus astucieuse) et surtout, il faut penser à changer le numéro de version dont la syntaxe par défaut ne plait pas à Debian. Lorsque checkinstall demande :

This package will be built according to these values: 

0 -  Maintainer: [ stephane@tyrion ]
1 -  Summary: [ Node.js ]
2 -  Name:    [ nodejs ]
3 -  Version: [ v0.10.18 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ checkinstall ]
7 -  Architecture: [ i386 ]
8 -  Source location: [ node-v0.10.18 ]
9 -  Alternate source location: [  ]
10 - Requires: [  ]
11 - Provides: [ node ]
12 - Conflicts: [  ]
13 - Replaces: [  ]

Il faut changer la version :

Enter a number to change any of them or press ENTER to continue: 3
Enter new version: 
>> 0.10.18

Ensuite, on se retrouve avec un paquetage node.js installé :

ii  nodejs    0.10.18-1 i386         Node.js

Maintenant, Grunt. Il n'est pas dans Debian pour un problème de licence. Mais le gestionnaire de paquetages de JavaScript npm l'installe sans problème :

# npm install -g grunt-cli

Ensuite, plus qu'à récupérer reveal.js et à installer les dépendances :

% cd reveal.js
% npm install

Pour créer ou modifier un thèmes, il faut utiliser le langage SASS, le CSS étant trop primitif pour les thèmes compliqués de reveal.js. On installe le programme qui va traduire le SASS en CSS :

# aptitude install ruby-sass

Et on peut alors s'attaquer à la réalisation (ou la modification en partant d'un des thèmes existants) d'un thème en éditant un fichier d'extension .scss. La documentation de reveal.js guide un peu (mais il faut vraiment lire les commentaires dans le fichier template/settings.scss). Voici une partie de mon thème :


$mainColor: #000000;
$headingColor: #000000;
$headingTextShadow: none;
$headingTextTransform: none;
$backgroundColor: #ffffff;
$mainFont: 'arial', sans-serif;
$headingFont: 'arial', sans-serif;

// Custom CSS rules

.reveal em {
   font-style: normal;
   font-weight: bold;
}

.reveal pre {
  font-size: 110%;
}

// Add this element *before* the slides section

.reveal  #decoheader {
   display: block; 
   position: absolute; 
   top: 0%; 
   left: 0%; 
   margin: 0px; 
   height: 12%; 
   width: 100%; 
   background-color: #000099; 
   z-index: 50;
}

Vous voyez que le SASS comprend une bonne partie de CSS normal, comme les trois règles à la fin. Malheureusement, il n'existe pas de guide de création d'un nouveau thème, expliquant les pièges et les problèmes (par exemple, je pense que l'utilisation de position: absolute dans mon code ci-dessus est responsable de certains problèmes avec mon thème mais je ne peux pas en être sûr).

Une fois qu'on a terminé son SASS, on le compile en CSS :

% grunt sass

% find . -name 'bortzmeyer*'
./css/theme/source/bortzmeyer.scss
./css/theme/source/bortzmeyer.scss~
./css/theme/bortzmeyer.css

À chaque modification du .scss, on refera ce grunt sass. Vous pouvez voir le résultat sur mon exposé DNS à la Cantine (et vous rendrez compte ainsi que je ne connais pas grand'chose à CSS).

Autre manipulation technique qu'on peut avoir à faire avec reveal.js, l'impression en PDF. Elle est documentée, n'est pas extrêmement pratique mais marche comme indiquée. (Attention, cela produit un PDF d'une taille ridiculement élevée.)

Enfin, d'autres extensions nécessiteront JavaScript. Par exemple, reveal.js ne permet pas, par défaut, de mettre un compteur affichant la page courante. Ce besoin a déjà été exprimé. Pour moi, la solution de mohikaner marche : on ajoute son code JavaScript à la page HTML (il doit y avoir une solution plus propre, surtout pour partager ce code entre plusieurs exposés, mais je ne me suis pas penché sur la question), et on ajoute un élément de la classe correspondante dans le source HTML :


<div id="decofooter">
    <p><a href="http://www.bortzmeyer.org/">Stéphane Bortzmeyer</a> - 
       <span class="slidenumber"/></p>
</div>


L'article seul

Exposé général sur le DNS à la Cantine

Première rédaction de cet article le 10 septembre 2013
Dernière mise à jour le 27 septembre 2013


Hier, lundi 9 septembre, j'ai eu le plaisir de faire un exposé général sur le DNS (c'est quoi, à quoi ça sert, ça fait mal ?) pour la toute première occurrence des conférences « Il était une fois... Internet ». Ces conférences visent « [...] expliquer et d'aider à comprendre comment fonctionne Internet. Chaque conférence développe un thème précis, regroupant aussi bien le fonctionnement général, des détails techniques, des notions théoriques ou des exemples de configurations. ».

Cette causerie était aussi l'occasion de tordre le cou à quelques idées reçues sur le DNS et les noms de domaine, idées reçues qui semblent assez fréquentes (non, les noms de domaines ne sont pas limités à l'ASCII, non, il ne faut pas confondre résolveur et serveur faisant autorité, non le nombre de composants dans un nom de domaine n'a aucune importance, etc).

En pratique, le public était encore assez geek mais cela pourra changer pour les futures conférences si la formule est maintenue.

Les supports utilisés sont disponibles ici. C'est du reveal.js, un système que j'ai récemment choisi (et sur lequel j'ai testé quelques trucs un peu avancés). Je débute dans toutes ces techniques Web donc la présentation n'est pas parfaite sur tous les navigateurs (ça semble marcher mieux avec Chromium). Bref, vous pouvez regarder, si vous ne connaissez pas reveal.js, c'est la touche F pour passer en plein écran (Esc pour en sortir), et N pour la page suivante. Sinon, pour le papier, une version relativement imprimable est disponible.

Les vidéos sont désormais disponibles sur http://data.confs.fr/dns-bortzmeyer/. Merci beaucoup à Skhaen pour l'idée et l'organisation.


L'article seul

RFC 6986: GOST R 34.11-2012: Hash Function

Date de publication du RFC : Août 2013
Auteur(s) du RFC : V. Dolmatov (Cryptocom), A. Degtyarev (Cryptocom)
Pour information
Première rédaction de cet article le 5 septembre 2013


Ce RFC documente en anglais une norme russe de l'organisme GOST. GOST R 34.11-2012 est une fonction de condensation cryptographique. Elle pourra notamment être utilisée pour DNSSEC.

Les algorithmes GOST (un abus de langage puisque GOST est normalement le nom de l'organisme de normalisation) sont une alternative russe aux algorithmes de cryptographie d'origine états-unienne comme RSA ou ECDSA (qui peuvent être remplacés par GOST R 34.10-2001) ou comme SHA-2 (qui peut être remplacé par GOST R 34.11-2012, qui fait l'objet de ce RFC). Pour être utilisés dans les protocoles IETF, il leut fallait une documentation en anglais. GOST R 34.10-2001 avait été documenté dans le RFC 5832. Notre RFC 6986 documente le petit dernier membre de la famille (son prédécesseur pour la condensation, GOST R 34.11-94, était dans le RFC 5831). Notez que les algorithmes GOST sont normalisés pour un usage dans le cadre de DNSSEC (RFC 5933).

Comme les autres algorithmes GOST, notre R 34.11-2012 est donc un algorithme officiel en Russie. Il a été approuvé par le décret n° 216 de l'agence fédérale chargée de la régulation technique, en août 2012. À terme, il vise à remplacer l'ancien R 34.11-94. C'est un algorithme de condensation cryptographique, qui peut produire des condensats de 256 ou 512 bits.

Je ne vais pas essayer de vous expliquer son principe de fonctionnement (sections 4 à 10), car c'est trop loin de mon domaine de compétence. Si vous êtes plus courageux que moi, notez qu'il y a beaucoup de maths et que, dans le formatage texte brut des RFC, ce n'est pas forcément idéal.

Questions mises en œuvre, notez qu'OpenSSL 1.0.1c n'a apparemment pas d'algorithmes de condensation GOST par défaut. openssl dgst -h pour voir la liste. Il faut apparemment éditer le openssl.cnf pour y avoir accès.


Téléchargez le RFC 6986


L'article seul

RFC 7017: IMAP Access to IETF Email List Archives

Date de publication du RFC : Août 2013
Auteur(s) du RFC : R. Sparks (Oracle)
Pour information
Première rédaction de cet article le 3 septembre 2013


Dans son travail, l'IETF utilise énormément les listes de diffusion. Afin de s'assurer que le travail de normalisation soit ouvert et transparent, ces listes sont publiquement accessibles. Mais il n'existe pas de moyen très pratique de naviguer dans les archives de ces listes, alors qu'il serait tentant de pouvoir le faire en utilisant le protocole normalisé d'accès à des boîtes aux lettres, IMAP. Ce court RFC est le cahier des charges du projet « Accès en IMAP aux archives des listes IETF ».

Les principaux accès à ces listes actuellement se font via le Web (qui fait l'objet d'un travail analogue pour améliorer ce service, cf. RFC 6778) ou en travaillant sur des copies locales des boîtes (pas forcément pratique). Bien des membres de l'IETF réclament un accès IMAP (RFC 3501), chaque liste étant représentée par une boîte IMAP. On pourra ainsi utiliser son client IMAP favori (mutt, Thunderbird, etc) pour accéder à ces archives.

Les exigences les plus importantes de ce cahier des charges (section 2) :

  • Même si l'archive est publique (le cas le plus fréquent) et accessible par tous, il faudra que le système permette de se loguer (avec la base d'identité du datatracker), afin de pouvoir marquer les messages (lu, non lu, etc). Il est souhaitable que d'autres annotations soient possibles, comme décrit dans les RFC 5257 et RFC 5464. Pour l'accès « anonyme », le système devra utiliser le mécanisme SASL du RFC 4505, ou bien un compte spécial (login anonymous / mot de passe anonymous...)
  • À part ces marques et ces annotations, il ne faut évidemment pas que les utilisateurs puissent modifier ou supprimer les messages.
  • Il faut que les fonctions de recherche d'IMAP soient mises en œuvre, avec les fonctions décrites dans le RFC 6778, de préférence en utilisant les extensions à IMAP des RFC 5256 (le tri), RFC 6237 (recherche multi-boîtes, depuis remplacé par le RFC 7377) et RFC 6203 (la recherche floue...)

Si vous êtes programmeur et que vous envisagez de se lancer dans ce travail, attention, la section 3 précise que le système devra prévoir une future extension aux adresses de courrier en Unicode.

Des problèmes de sécurité ? La section 4 en voit quelques uns. La fonction de recherche peut être très gourmande en CPU et en E/S. Un client méchant ou simplement avide pourrait mettre à genoux le serveur en multipliant les requêtes. Le système doit donc être capable de limiter la consommation de ressources par utilisateur. Un problème analogue se pose pour les annotations, dont il faut limiter la consommation d'espace disque.

Je n'ai pas trouvé trace d'un appel d'offres formel de l'IETF correspondant à ce RFC. Plus tard, peut-être ?


Téléchargez le RFC 7017


L'article seul

La cryptographie nous protège t-elle vraiment de l'espionnage par la NSA ou la DGSE ?

Première rédaction de cet article le 1 septembre 2013


Cet article est une exploration, essentiellement théorique, d'un problème technique intéressant : l'utilisation de la cryptographie est-elle utile lorsqu'on veut protéger sa vie privée contre l'espionnage massif auquel se livrent des agences gouvernementales comme la NSA ou la DGSE ? Je vous le dis tout de suite, il n'y a pas de réponse simple.

Notez bien la définition du problème : je ne parle pas des attaques par le pirate du coin (celui qui sniffe votre réseau Wi-fi au cyber-café), car la cryptographie est certainement indispensable contre lui, contre cet attaquant ordinaire. Et je ne parle pas non plus du cas où l'agence d'espionnage vous cible individuellement. Si la NSA a décidé que vous êtes un objectif intéressant et met tous ses moyens à vous espionner, il n'y a pas grand'chose à faire (le plus probable est qu'ils utilisent un spyware dans votre ordinateur, ou bien une écoute électromagnétique, à moins qu'ils ne préfèrent la méthode bien décrite dans xkcd). Dans ce cas, on fait de la gestion de risque, mais on n'espère pas être invulnérable.

Non, je me focalise sur l'espionnage de masse, passant à l'échelle, et visant des tas de gens dont la NSA ou la DGSE ne savent pas a priori s'ils sont une cible intéressante ou pas. C'est cet espionnage qui a fait l'objet récemment d'une prise de conscience, suite aux révélations d'Edward Snowden. Il a parlé de la NSA (et du GCHQ) mais il n'y a aucun doute que d'autres agences font pareil. En France, en raison d'une tradition d'obéissance au monarque qui remonte à longtemps, on n'a pas encore vu de « lanceur d'alerte » héroïque et désobéissant comme Snowden mais cela ne veut pas dire qu'un tel espionnage n'a pas lieu.

Mais comment savoir exactement les capacités de la NSA ? L'adage classique de la sécurité s'applique tout à fait ici : « Ceux qui savent ne parlent pas, ceux qui parlent ne savent pas ». Comme j'écris beaucoup sur ce blog, vous pouvez en déduire que je ne sais pas grand'chose. Il faut donc commencer par un sérieux avertissement : comme les agences secrètes sont... secrètes, on ne peut pas savoir exactement à quoi s'attendre. Cela n'empêche pas les Jean-Kevin de toute sorte d'affirmer bien haut « la crypto, c'est nul, on sait bien que la NSA peut tout casser et tout lire, lol, mdr ». Il faut juste se rappeler que ce genre d'affirmations ne vaut rien.

Est-ce que seuls les Jean-Kevin disent n'importe quoi ? Évidemment non. Les chercheurs en sécurité sont connus pour leur goût pour le sensationnalisme et les annonces spectaculaires, qui seront oubliés trois mois après. Chaque année, à Blackhat ou Defcon, il y a une annonce comme quoi la cryptographie est fichue, l'Internet à poil, et que nous allons tous mourir. En 2011, c'était BEAST, qui devait mettre fin à TLS. En 2013, on a eu la prédiction comme quoi RSA serait cassé dans cinq ans (un article particulièrement grotesque dans le sensationnalisme fut celui de Technology Review).

Bon, maintenant que j'ai critiqué ceux qui disaient n'importe quoi, que peut-on dire de sérieux ? Revenons un peu sur la cryptographie dans son service de confidentialité. Alice et Bob veulent communiquer secrètement. Ils chiffrent leurs communications, empêchant un tiers naïf de comprendre ce qu'ils se disent. Mais pour un tiers plus motivé et ayant davantage de moyens ? Il peut utiliser plusieurs méthodes anti-crypto (je ne cite que celles qui passent à l'échelle par automatisation, sans nécessiter de kidnapper Bob et de le faire parler) :

  • L'espion peut installer du spyware dans les logiciels de tout le monde (le nom de code « GENIE » à la NSA concerne apparemment un tel programme). C'est d'autant plus facile pour la NSA que la majorité des logiciels sont produits par des entreprises états-uniennes. La cryptographie ne protège qu'en transit, pas si une des machines terminales trahit.
  • Puisque, dans mon hypothèse de départ, l'attaquant est un État doté d'importants moyens matériels, il peut aussi utiliser la force brute. Si la clé de chiffrement fait 256 bits, on peut (en théorie) essayer systématiquement les 2^256 valeurs. Aucun algorithme (à part le one-time pad) ne résiste aux attaques par force brute. Mais, avec les tailles de clé utilisées dans les systèmes cryptographiques sérieux, c'est probablement irréaliste en pratique.
  • Il peut trouver une faille dans les logiciels de cryptographie. S'il casse GnuPG et la mise en œuvre de TLS utilisée dans Firefox, il aura déjà accès à bien des choses. Les logiciels de cryptographie sont des logiciels comme les autres et ont des bogues.
  • Il peut casser les protocoles de cryptographie. Il est étonnamment difficile de réaliser un protocole sûr, même quand les algorithmes sous-jacents sont corrects, comme le montrent les différentes failles de TLS (comme celle de renégociation). Sans compter la faille récurrente par laquelle trébuchent tant de mises en œuvre de la cryptographie : le générateur de nombres aléatoires (RFC 4086).
  • Il peut enfin casser les algorithmes de cryptographie eux-mêmes. C'est le plus spectaculaire (et c'est pour cela que les Jean-Kevin du monde entier aiment bien affirmer des choses comme « on sait bien que la NSA a cassé RSA depuis des années - sans doute dans son centre de recherches de la zone 51 ») mais pas le plus facile, loin de là. Les mathématiques résistent longtemps et, surtout, leurs progrès sont imprévisibles (comme le note à juste titre Schneier). Peut-être que, dans cinq ans, un étudiant dans sa chambre va subitement trouver un moyen simple de décomposer en facteurs premiers, cassant ainsi RSA. Peut-être. Et peut-être pas. Les affirmations comme quoi « RSA sera cassé dans cinq ans » sont ridicules : on ne prévoit pas les percées en maths comme les progrès de l'ingénierie (cf. la loi de Moore).
  • L'attaquant peut aussi contourner la cryptographie en se faisant passer pour le correspondant. C'est ce qu'on nomme une attaque de l'homme du milieu et cela a par exemple été utilisé par le gouvernement iranien en 2011. Leur méthode était de détourner le trafic HTTPS vers une machine gouvernementale et de présenter un « vrai/faux » certificat obtenu auprès d'une AC piratée, comme Diginotar. Ainsi, Alice croyait parler avec Bob alors qu'elle parlait à un espion... Le fait que la communication soit chiffrée n'aide pas si on parle au méchant.
  • L'attaquant peut aussi, s'il a l'autorité d'un État derrière lui, ne pas s'embêter et aller prendre les données où elles sont, chez le fournisseur de service. C'est ce que fait le programme PRISM, révélé par Snowden, avec la complicité des gros silos de données comme Facebook ou Gmail. (Dans certains États - mais pas les États-Unis depuis le Patriot Act - il faut normalement l'autorisation d'un juge. Mais il existe des écoutes illégales comme dans l'affaire des gendarmes de l'Élysée.)
  • Une faiblesse souvent oubliée est celle des métadonnées : même quand on n'a pas accès aux communications elles-mêmes, les seules métadonnées peuvent être une mine de renseignements (ce qu'on nomme l'analyse de trafic). Les métadonnées peuvent être le qui (Alice écrit à Bob), le quand et le combien (pour une session HTTP, la taille des données transférées indique si on a lu un fichier ou si on en a envoyé un). C'est d'autant plus vrai que les métadonnées, contrairement à la plupart des contenus, sont structurées, conçues pour être analysées par des programmes informatiques (car elles servent à la facturation ou au routage).

À noter que certaines de ces attaques peuvent se faire dans le temps : la NSA enregistre la conversation à tout hasard... et la lira dans dix ou vingt ans, quand les progrès de la technique ou de la science le lui permettront. Pensez donc aussi à cela : cette conversation sera t-elle toujours « sensible » dans dix ans ?

Maintenant, quelles protections peut fournir la crypto contre ces attaques ? Attention, cela va être plus laborieux que la description des attaques.

  • Contre le malware installé sur la machine de l'utilisateur, rien à faire. La crypto suppose une plate-forme sûre. Il est possible que des machines construites à partir de composants sécurisés (TPM) résolvent le problème mais je ne suis pas optimiste, notamment parce que ces composants sont plus souvent utilisés pour contrôler l'utilisateur que pour l'aider à se protéger.
  • Contre les attaques par force brute, il faut des clés suffisamment longues. Rappelez-vous du pouvoir de l'exponentielle. 2 puissance 256, par exemple, est un nombre qui défie l'imagination humaine. Il ne suffit pas de dépenser beaucoup d'argent et d'acheter des grosses machines pour tester 2^256 possibilités... (Attention, avec certains algorithmes, il existe des attaques appelées « force brute » mais qui intègrent en fait plusieurs astuces pour ne pas tout essayer. C'est ce qui explique que la longueur de la clé ne soit pas le seul paramètre à prendre en compte.) On entend souvent dire que le calcul quantique va tout changer en permettant des bonds colossaux de performance. Mais, malgré les prétentions des commerciaux qui vendent des « ordinateurs quantiques », on en est très loin. Les résultats concrets avec ces ordinateurs restent du domaine du laboratoire. Et, comme le note Schneier, les systèmes cryptographiques ont bien d'autres failles, plus faciles à exploiter que le cassage de la clé par le mythique ordinateur quantique.
  • Et contre les failles dans les logiciels ? Code source disponible, bonnes pratiques de programmation, examen par les pairs... Aucune de ces techniques ne fait de miracle mais, ensemble, elles aident à avoir une assez bonne sécurité. (J'ai lu sur un forum un texte d'un Jean-Kevin proclamant avec assurance que « la NSA a une porte dérobée dans PGP ». Inutile de dire qu'il ne fournissait aucune preuve.)
  • Pour les failles dans les protocoles de cryptographie, c'est à peu près la même approche : protocoles publiés, examinés publiquement par de nombreux experts. Il restera forcément des failles (on en découvre de nouvelles de temps en temps, dont certaines étaient peut-être déjà connues de la NSA) mais c'est mieux que rien. Notez que les protocoles non publiés utilisés dans les produits commerciaux fermés ne valent pas grand'chose. À chaque conférence de sécurité, un chercheur explique comment il en a rétro-ingénieré un. Parfois, un protocole secret chanceux tient le coup plus longtemps (RC4...) mais c'est rare.
  • Pour les algorithmes de cryptographie, c'est un pari sur l'avenir : on espère que l'algorithme ne sera pas cassé. À part l'espérance, la contre-attaque est la même que pour les programmes et les protocoles, à savoir la publication et l'analyse de sécurité au grand jour. On ne sait bien sûr pas où en est la NSA (on dit parfois qu'ils ont dix ou vingt ans d'avance sur la recherche publiée) mais l'ensemble des chercheurs qui travaillent et publient fait néanmoins un bon travail. Si RSA faiblit et devient vraiment trop incertain, on pourra passer aux courbes elliptiques (RFC 6090). Notez quand même qu'une bonne partie des chercheurs compétents ne publie pas, parce qu'ils travaillent pour la NSA, ou parce qu'ils préfèrent vendre leurs découvertes plutôt que d'aider l'humanité (si vous arrivez à trouver une décomposition en facteurs premiers facile, et que vous publiez, vous gagnez les 10 000 euros de la médaille Fields, soit bien moins que si vous vendez l'information à la NSA ou un de ses équivalents en Russie ou en Chine).
  • Contre l'attaque de l'homme du milieu, les solutions envisagées (encore largement expérimentales) tournent autour d'ajouts ou de remplacement du système des AC, comme le système DANE du RFC 6698 ou comme Perspectives.
  • Par contre, contre l'utilisation d'un gros silo de données comme Gmail ou Facebook, qui donne accès à toutes ses données à la NSA, la crypto ne peut rien. Elle ne protège que le voyage des données, mais tout est stocké en clair chez les fournisseurs de PRISM.
  • Enfin, pour la protection des métadonnées, le problème est compliqué. Les intermédiaires ont besoin des métadonnées pour acheminer le trafic et il n'est donc pas évident de les dissimuler (il existe des pistes de recherche mais pas encore de solution applicable). C'est pour cela que PGP ne chiffre pas les en-têtes. Pour sécuriser le courrier électronique, par exemple, il faudrait combiner PGP et SMTP sur TLS (RFC 3207 et attention : en pratique, SMTP sur TLS a des tas de limites, question sécurité).

Tout cela n'était que des solutions techniques car cet article se focalise sur l'aspect technique des choses. Mais, évidemment, le problème de fond est politique et c'est dans des changements politiques profonds qu'il faut chercher les vraies solutions. Il n'est pas normal qu'il faille être expert en crypto pour avoir une vie privée !

Autres bonnes lectures après cet article : l'interview d'un des développeurs de GnuPG ou bien un très bon article de Dan Goodin expliquant comment contourner (et non pas casser) la crypto ou encore celui de Peter Bright sur les vraies capacités de la NSA. Voir aussi l'article de Matthew Green qui fait le tour des techniques connues et inconnues pour déchiffrer le trafic TLS.

Conclusion ? Il faut évidemment de la cryptographie, ne serait-ce que « dans le doute », et à cause des nombreux attaquants moins équipés que la NSA. Snowden lui-même note que cela gêne l'attaquant. Mais ce n'est pas une solution magique et, dans son analyse de sécurité, il faut se demander « et si elle était cassée, quelles seraient les conséquences pour moi ? ».

Merci aux twittériens entre autres (hélas, je n'ai pas pensé à noter tout le monde) Nicolas Caproni, Ollivier Robert (également relecteur de cet article), Marc Levy, Geoffroy Couprie, Gildas Ribot, Damien Clauzel, et les autres. Merci à Gérard Fadrelle pour m'avoir rappelé l'attaque de l'homme du milieu que j'avais bêtement oubliée. Merci surtout au relecteur anonyme qui a fait l'essentiel de la relecture mais ne souhaite pas que son nom apparaisse.


L'article seul

RFC 7020: The Internet Numbers Registry System

Date de publication du RFC : Août 2013
Auteur(s) du RFC : R. Housley (Vigil Security), J. Curran (ARIN), G. Huston (APNIC), D. Conrad (Virtualized, LLC)
Pour information
Première rédaction de cet article le 29 août 2013


Le bon fonctionnement de l'Internet dépend de l'unicité de certains nombres, notamment les adresses IP. Comment ces nombres sont-ils alloués de manière à respecter cette unicité et d'autres propriétés souhaitables ? Ce RFC remplace l'ancien RFC 2050 qui décrivait le système d'allocation des adresses IP en 1996.

Comme son prédécesseur, ce RFC ne propose pas une nouvelle politique : il documente ce qui se fait actuellement. Cette documentation est d'autant plus difficile que la gouvernance des adresses IP est un sujet complexe, à l'intersection de la technique (les limites de taille de l'espace d'adressage, les limites de traitement des routeurs), de la politique et de l'économie. Contrairement à la gouvernance des noms de domaine, celle des adresses IP fait peu de bruit et est surtout traitée dans des cercles fermés. Malgré cela, il n'y a certainement pas de consensus quant à la gestion de ces adresses et ce RFC n'est pas exempt de parti pris. Dans cet article, j'essaie de coller à la description qu'ont choisi les auteurs du RFC mais rappelez-vous que tout le monde ne la trouve pas correcte, loin de là (j'avais un point de vue plus personnel dans mon article sur le RFC 2050).

On notera aussi que le titre du RFC fait référence au système d'allocation des nombres, pas seulement des adresses IP. Il traite en effet également des numéros d'AS, qui étaient absents du RFC 2050.

Donc, commençons par la section 2, les buts. Pourquoi faut-il une gestion des nombres ? On ne peut quand même pas être propriétaire du nombre 3676198671278441090, quand même ? Pourquoi ces organisations et ces règles ? Le premier but de cette gestion est la gestion de la pénurie : les adresses IPv4, notamment, sont en nombre fini et dramatiquement insuffisant. Le bon fonctionnement de l'Internet nécessitant qu'une adresse IP soit unique (ce blog est en 2605:4500:2:245b::42 ; si une autre machine avait cette adresse, à laquelle iraient les paquets ?), il faut un mécanisme pour s'assurer qu'une adresse ne soit allouée qu'une fois. Si l'espace d'adressage était immense, tirer un nombre au hasard dans cet espace assurerait une quasi-unicité (c'est ainsi qu'on fait pour les clés cryptographiques). Mais il ne l'est pas.

Et ce n'est pas le seul but de la gestion des adresses. Le routage dans l'Internet est hiérarchique. Il n'est pas possible qu'un routeur de la DFZ connaisse toutes les adresses du monde, sa mémoire n'y suffirait pas, sans parler du rythme de changement des tables de routage que cela imposerait. On regroupe donc les adresses en préfixes et le routage fonctionne sur ces préfixes, pas sur les adresses individuelles. Mais cela ne marche que si les adresses sont agrégeables, si elles sont suffisamment proches les unes des autres pour être regroupées en préfixes. Si 2001:db8:1:a::/64 est routé par un opérateur et 2001:db8:1:b::/64 par un autre, on ne pourra pas agréger ces annonces en un seul 2001:db8:1::/48. C'est donc le deuxième but de la politique de gestion des adresses IP, permettre l'agrégation. (Par contre, la politique de routage, à savoir ce que les routeurs acceptent en pratique ou pas, est indépendante du système d'enregistrement des nombres. Elle est décidée par chaque opérateur séparément.)

Troisième et dernier but, conserver et publier (typiquement, via whois), des informations fiables sur les titulaires des préfixes, de manière à pouvoir les contacter en cas de problème pratique (par exemple de sécurité, cf. section 7). L'un des rôles des registres est de s'assurer que ces informations soient correctes. En pratique, les données actuellement publiées sont souvent de qualité médiocre (erronées, pas à jour, etc.) D'autre part, rien n'étant parfait en ce monde, on a déjà vu des cas où deux registres avaient alloué le même nombre.

Comme le notait déjà le RFC 2050, ces buts peuvent être contradictoires entre eux. Ainsi, utiliser le mieux possible le nombre limité d'adresses IPv4 nécessiterait des micro-allocations (donner un /29 à celui qui n'a pas besoin de beaucoup d'adresses) alors que le routage demande de l'agrégation et donc d'allouer plutôt les préfixes en grands morceaux. D'autre part, ces trois buts peuvent être en contradiction avec d'autres intérêts. Par exemple, la publication des informations sur les titulaires et responsables techniques des préfixes peut être utilisée par les spammeurs pour collecter des adresses.

La section 3 du RFC décrit les organisations qui mettent en œuvre ce système de registre des nombres, et leurs relations. L'allocation hiérarchique des adresses IP et des numéros d'AS est enracinée à l'IANA qui distribue des ressources aux RIR qui les distribuent à des LIR qui les distribuent à des utilisateurs finaux (en simplifiant un peu). L'IANA est une fonction, pas une organisation (aujourd'hui, la fonction IANA est assurée par l'ICANN, suivant le MoU décrit dans le RFC 2860). Les documents IANA relatifs à ce rôle de registre des nombres sont notamment le ICANN Address Supporting Organization (ASO) MoU, le ICP-2: Criteria for Establishment of New Regional Internet Registries et le Internet Assigned Numbers Authority (IANA) Policy for Allocation of ASN Blocks to Regional Internet Registries. En pratique, les politiques d'allocation sont plutôt du ressort des RIR (décrits à l'origine dans le RFC 1366) et ces politiques doivent plutôt être cherchées sur les sites Web des RIR.

Mais d'autres organisations jouent aussi un rôle comme l'IETF qui édicte les normes techniques (mais, normalement, pas les politiques d'allocation précises, voir le RFC 6177 pour un exemple de débat) et qui réserve certains nombres (RFC 6890). La section 5 revient d'ailleurs sur les rôles respectifs de l'IETF et de l'ICANN.

La section 4 du RFC quitte ces considérations organisationnelles (ou bureaucratiques, si on veut être plus méchant) pour la technique, en notant qu'il est aussi de la responsabilité des registres de nombres de fournir un service de résolution DNS d'adresses IP en noms (via la gestion de domaines en in-addr.arpa et ip6.arpa) et d'assurer un service whois conforme à la norme technique (RFC 3912).

La section 6 décrit les changements depuis le RFC 2050, il y a dix-sept ans (lorsque l'ICANN n'existait même pas). Par exemple, le RFC 2050 décrivait un mécanisme d'appel à l'IANA lorsqu'on était mécontent d'une décision d'un autre acteur. Ce mécanisme a été supprimé (les RIR ont des procédures internes d'appel, par exemple le RIPE-NCC).


Téléchargez le RFC 7020


L'article seul

Attaques de la Syrian Electronic Army contre les noms de domaines

Première rédaction de cet article le 27 août 2013
Dernière mise à jour le 28 août 2013


Mardi 27 août, la « Syrian Electronic Army » a attaqué plusieurs noms de domaines importants, comme ceux du New York Times et de Twitter. Voici mon résumé, ainsi que des éléments concrets que j'avais recueilli sur le moment.

L'attaque a porté sur le bureau d'enregistrement Melbourne IT. Une fois cet intermédiaire piraté, la SEA a pu modifier à sa guise les données et notamment les serveurs de noms des domaines visés.

Ces données ont été récoltées entre 21 et 22 h UTC le 27 août. D'abord, le piratage du domaine nytimes.com. Mon Unbound sur ma machine (qui fait suivre les requêtes aux résolveurs de Free) voit :


% dig SOA nytimes.com.                   

; <<>> DiG 9.9.2-P1 <<>> SOA nytimes.com.
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8602
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1

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

;; ANSWER SECTION:
nytimes.com.		86308	IN	SOA	ns1.syrianelectronicarmy.com. admin.sea.sy. 2013082701 86400 7200 3600000 86400

;; AUTHORITY SECTION:
nytimes.com.		86374	IN	NS	ns1.syrianelectronicarmy.com.
nytimes.com.		86374	IN	NS	ns2.syrianelectronicarmy.com.

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Aug 27 22:59:11 2013
;; MSG SIZE  rcvd: 145

À ce stade, on ne peut pas encore dire s'il y a empoisonnement DNS ou piratage du registre ou du bureau d'enregistrement ?

Quelques minutes après, en demandant directement au registre :


; <<>> DiG 9.9.2-P1 <<>> @d.gtld-servers.net. NS nytimes.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2190
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;nytimes.com.			IN	NS

;; AUTHORITY SECTION:
nytimes.com.		172800	IN	NS	ns27.boxsecured.com.
nytimes.com.		172800	IN	NS	ns28.boxsecured.com.

Ces boxsecured.com (un hébergeur états-unien) sont suspects : l'un répond REFUSED, l'autre donne un SOA étrange :


; <<>> DiG 9.9.2-P1 <<>> @212.1.211.141 SOA nytimes.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61161
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1
;; WARNING: recursion requested but not available

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

;; ANSWER SECTION:
nytimes.com.		86400	IN	SOA	ns5.boxsecured.com. ssuliman.hotmail.co.uk. 2013082703 86400 7200 3600000 86400

;; AUTHORITY SECTION:
nytimes.com.		86400	IN	NS	ns6.boxsecured.com.
nytimes.com.		86400	IN	NS	ns5.boxsecured.com.

   Domain Name: NYTIMES.COM
   Registrar: MELBOURNE IT, LTD. D/B/A INTERNET NAMES WORLDWIDE
   Whois Server: whois.melbourneit.com
   Referral URL: http://www.melbourneit.com
   Name Server: NS27.BOXSECURED.COM
   Name Server: NS28.BOXSECURED.COM
   Status: serverDeleteProhibited
   Status: serverTransferProhibited
   Status: serverUpdateProhibited
   Updated Date: 27-aug-2013
   Creation Date: 18-jan-1994
   Expiration Date: 19-jan-2014

Et Twitter ? twitter.com dans whois montre un piratage (le TLD .sy est la Syrie) :

Admin Name........... SEA SEA
  Admin Address........ 1355 Market Street
  Admin Address........ Suite 900
  Admin Address........ 
  Admin Address. San Francisco
  Admin Address........ 94103
  Admin Address........ CA
  Admin Address........ UNITED STATES
  Admin Email.......... sea@sea.sy
  Admin Phone.......... +1.4152229670
  Admin Fax............ +1.4152220922

Même bureau d'enregistrement que nytimes.com, Melbourne IT. Par contre, les serveurs de noms n'ont pas été changés. Pourquoi ? Manque de temps pour la SEA ? Ou peut-être une protection spéciale, un « super-verrou » contre les modifications, soit au registre, soit au bureau d'enregistrement. Ce qui fait que, dans le cas de Twitter, l'utilisateur ordinaire ne voit rien. Par contre, twimg.com (hébergement d'images pour Twitter) a un whois analogue mais des serveurs de noms changés.

Une heure après, le registre de .com servait à nouveau la bonne information :


% dig @a.gtld-servers.net NS nytimes.com

; <<>> DiG 9.9.2-P1 <<>> @a.gtld-servers.net NS nytimes.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57384
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;nytimes.com.			IN	NS

;; AUTHORITY SECTION:
nytimes.com.		172800	IN	NS	dns.ewr1.nytimes.com.
nytimes.com.		172800	IN	NS	dns.sea1.nytimes.com.
CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - CK0RFQAOES8CTVNVNH4G6Q85NOQAQ8I9 NS SOA RRSIG DNSKEY NSEC3PARAM
CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20130903044137 20130827033137 8795 com. j5+5FlHHaxax14Oj+MWS+KZAbRb6L9ERQkP6uf/naSfrAbjgWEqW3J3B xp8mCDRkbD0m6/E5Ax/Q8xPB5PqV/KxbaKZb05XxyNlwpN3wFFYlFhW/ Zyn1GbcfWrpHUQH2oTDNDfq7Am+HXbkRU60TwOjICpgkDMZqxHR8hww3 IFk=
O6B9DUFQLHV3BU9UG6OASLHH80ECTS95.com. 86400 IN NSEC3 1 1 0 - O6C0FKNFS7M5TK0HI5HN4O5JKU9PTV22 NS DS RRSIG
O6B9DUFQLHV3BU9UG6OASLHH80ECTS95.com. 86400 IN RRSIG NSEC3 8 2 86400 20130903110913 20130827095913 8795 com. YE2lkYOtVz8iIz31zHReEzQf93S2LAH+ZPMJt5K7vQQoydWJf/dDgqyu 1tDRy4pz+cAXIQYqqodYb/8c0/kMm0dCheUtUUKrhOYH39AqwiN+oMdY 2jxHbS7VPPP3Mj3RNPLj74JeO6pTqfz7a4Ibt5Z6ombsR8H+xbWXI7Li Mks=

;; ADDITIONAL SECTION:
dns.ewr1.nytimes.com.	172800	IN	A	170.149.168.134
dns.sea1.nytimes.com.	172800	IN	A	170.149.173.133

;; Query time: 144 msec
;; SERVER: 192.5.6.30#53(192.5.6.30)
;; WHEN: Tue Aug 27 23:57:25 2013
;; MSG SIZE  rcvd: 603

(Le sea1 dans dns.sea1.nytimes.com n'a rien à voir avec la SEA, il indique la ville, Seattle.) Mais il est amusant de noter que le whois au bureau d'enregistrement indiquait toujours la mauvaise information, ce qui semble indiquer que le registre a modifié l'information directement, en ignorant le bureau d'enregistrement :


% whois nytimes.com

Whois Server Version 2.0

Domain names in the .com and .net domains can now be registered
with many different competing registrars. Go to http://www.internic.net
for detailed information.

   Server Name: NYTIMES.COM
   IP Address: 141.105.64.37
   Registrar: MELBOURNE IT, LTD. D/B/A INTERNET NAMES WORLDWIDE
   Whois Server: whois.melbourneit.com
   Referral URL: http://www.melbourneit.com

   Domain Name: NYTIMES.COM
   Registrar: MELBOURNE IT, LTD. D/B/A INTERNET NAMES WORLDWIDE
   Whois Server: whois.melbourneit.com
   Referral URL: http://www.melbourneit.com
   Name Server: DNS.EWR1.NYTIMES.COM
   Name Server: DNS.SEA1.NYTIMES.COM
   Status: serverDeleteProhibited
   Status: serverTransferProhibited
   Status: serverUpdateProhibited
   Updated Date: 27-aug-2013
   Creation Date: 18-jan-1994
   Expiration Date: 19-jan-2014

>>> Last update of whois database: Tue, 27 Aug 2013 21:58:26 UTC <<<

[...]

Domain Name.......... nytimes.com
  Creation Date........ 1994-01-18
  Registration Date.... 2011-08-31
  Expiry Date.......... 2014-01-20
  Organisation Name.... SEA
  Organisation Address. 620 8th Avenue
  Organisation Address. 
  Organisation Address. 
  Organisation Address. New York
  Organisation Address. 10018
  Organisation Address. NY
  Organisation Address. UNITED STATES

Admin Name........... SEA SEA
  Admin Address........ SEA
  Admin Address........ 620 8th Avenue
  Admin Address........ 
  Admin Address. Syria
  Admin Address........ 10018
  Admin Address........ SY
  Admin Address........ SYRIAN ARAB REPUBLIC
  Admin Email.......... sea@sea.sy
  Admin Phone.......... +1.2125561234
  Admin Fax............ 

Tech Name............ NEW YORK TIMES DIGITAL
  Tech Address......... 229 West 43d Street
  Tech Address......... 
  Tech Address......... 
  Tech Address......... New York
  Tech Address......... 10036
  Tech Address......... NY
  Tech Address......... UNITED STATES
  Tech Email........... hostmaster@NYTIMES.COM
  Tech Phone........... +1.2125561234
  Tech Fax............. +1.1231231234
  Name Server.......... ns27.boxsecured.com
  Name Server.......... ns28.boxsecured.com

À noter que sharethis.com a aussi été attaqué mais qu'il est chez un bureau d'enregistrement différent et qu'il n'est pas sûr que la même méthode ait été employée.

Des rapports fiables signalent également un détournement de huffingtonpost.co.uk (un registre différent mais le même bureau d'enregistrement) mais je n'ai pas pu l'observer moi-même. Mais il est sûr que le problème ne frappait pas que .com. Voici la sortie du whois de twitter.co.uk, vingt minutes après que le .com ait été réparé :


% whois twitter.co.uk

    Domain name:
        twitter.co.uk

    Registrant:
        Twitter Inc

    Registrant type:
        Non-UK Corporation

    Registrant's address:
        1355 Market Street Suite 900
        San Francisco
        CA
        94103
        United States

    Registrar:
        Melbourne IT t/a Internet Names Worldwide [Tag = MELBOURNE-IT]
        URL: http://www.melbourneit.com.au/contacts

    Relevant dates:
        Registered on: 05-Mar-2005
        Expiry date:  05-Mar-2015
        Last updated:  27-Aug-2013

    Registration status:
        Registered until expiry date.

    Name servers:
        ns1.syrianelectronicarmy.com
        ns2.syrianelectronicarmy.com

    WHOIS lookup made at 23:20:51 27-Aug-2013

[...]

Cela plaide donc encore plus pour un piratage du bureau d'enregistrement, Melbourne IT, qui a été confirmé par Melbourne IT quelques heures après.

Quelques articles intéressants sur ce piratage :

Et c'est l'occasion de relire et revoir :


L'article seul

RFC 6998: A Mechanism to Measure the Routing Metrics along a Point-to-point Route in a Low Power and Lossy Network

Date de publication du RFC : Août 2013
Auteur(s) du RFC : M. Goyal (University of Wisconsin, Milwaukee), E. Baccelli (INRIA), A. Brandt (Sigma Designs), J. Martocci (Johnson Controls)
Expérimental
Réalisé dans le cadre du groupe de travail IETF roll
Première rédaction de cet article le 27 août 2013


Le protocole RPL (Routing Protocol for Low power and Lossy Networks), normalisé dans le RFC 6550, est conçu pour des réseaux de machines très bon marché, ayant peu de capacités (mémoire et calcul), étant souvent très limitées en énergie, et étant connectées par des liens de qualité médiocre. Un tel environnement peut par exemple se rencontrer dans des réseaux de capteurs dispersés dans un environnement industriel. Une partie des machines du réseau va se dévouer pour router les paquets des autres. RPL permet de trouver et de diffuser des routes mais celle choisie ne sera pas forcément optimale. D'où ces deux extensions à RPL permettant à un routeur de 1) mesurer une métrique donnée en émettant un paquet de contrôle vers la destination, paquet qui accumulera au fur et à mesure, dans les routeurs intermédiaires, les informations à propos de la route utilisée actuellement et, 2) découvrir à la demande une route meilleure (si tant est qu'il y en a une).

C'est que ce n'est pas une vie que d'être routeur dans un LLN (Low power and Lossy Network, les réseaux difficiles dont je parlais au paragraphe précédent). Le RPL classique du RFC 6550 essaie de faciliter les choses en limitant le réseau à un graphe acyclique dirigé vers un puits de données et en calculant toutes les routes à l'avance (ce qu'on nomme un protocole proactif). Une extension à RPL, nommée P2P-RPL (P2P pour pair-à-pair) et normalisée dans le RFC 6997, permet à RPL de devenir réactif et donc de calculer des routes à la demande. Elle permet aussi de trouver des routes plus courtes, en évitant le passage par le sommet du graphe pré-établi. Le routeur utilise, pour ces calculs, les métriques du RFC 6551 (latence, capacité, qualité, et autres métriques dans le registre IANA). Mais comment connaître leur valeur effective dans un réseau ? Eh bien, en les mesurant, tout simplement.

Le protocole RPL ne transmettant pas cette information pour toutes les routes, c'est au routeur qui en a besoin de demander. Il génère un paquet de contrôle RPL d'un nouveau type, Measurement Request indiquant ce qu'il veut savoir à propos du chemin entre lui-même et la destination. Chaque routeur sur le trajet va mettre à jour ce paquet avec le coût (pour la métrique demandée) du lien effectivement emprunté. Au bout, le destinataire répondra au demandeur, avec un message de contrôle Measurement Reply, contenant toute l'information accumulée. Le demandeur pourra alors agir (changer d'avis pour certaines routes, par exemple).

En fait, les deux messages utilisent le même type de paquets, les Measurement Object de code 0x06 (section 3 et registre IANA). Un bit dans son en-tête, le bit T (pour Type) sert à distinguer si ce Measurement Object est un Measurement Request ou un Measurement Reply. Le paquet contient surtout des options Metric Container (section 6.7.4 du RFC 6550 et section 2.1 du RFC 6551) qui accumuleront au fur et à mesure les valeurs demandées.

Il est intéressant de comparer ce mécanisme à celui de traceroute qui n'accumule pas les mesures mais compte sur une réponse de chaque routeur intermédiaire vers la source ; des options avaient été proposées pour un traceroute « enregistreur » - Record Route du RFC 791 ou option IP du RFC 1393 - mais elles n'ont eu aucun succès.

Notez bien que, dans un réseau ad hoc, rien ne garantit que tous les routeurs accepteront de procéder à cet enregistrement de données. Ils ont parfaitement le droit de refuser de le faire (voir la section 5 de notre RFC), par exemple pour économiser leur batterie ou bien parce qu'ils trouvent une telle demande trop indiscrète (section 8 du RFC).

Il existe déjà plusieurs mises en œuvre de cette extension expérimentale et un test d'interopérabilité a été documenté. Sinon, un bon article consacré aux mesures de P2P-RPL est « The P2P-RPL Routing Protocol for IPv6 Sensor Networks: Testbed Experiments ».

Merci à Emmanuel Baccelli pour sa relecture attentive.


Téléchargez le RFC 6998


L'article seul

RFC 6980: Security Implications of IPv6 Fragmentation with IPv6 Neighbor Discovery

Date de publication du RFC : Août 2013
Auteur(s) du RFC : F. Gont (SI6 Networks / UTN-FRH)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 26 août 2013


Ce court RFC traite un problème de sécurité lorsqu'on combine la fragmentation avec le protocole NDP d'IPv6. Il interdit désormais cette combinaison, qui pouvait être exploitée pour des attaques sur le réseau local.

NDP est normalisé dans le RFC 4861 (que ce RFC 6980 met à jour). Ce protocole est utilisé pour bien des choses, notamment pour résoudre une adresse IPv6 en adresse MAC et pour découvrir les routeurs du réseau local, ainsi que les préfixes des adresses IP de ce réseau (pour l'auto-configuration). Ses faiblesses de sécurité (très proches de celles d'ARP en IPv4) sont bien connues (RFC 3756). Notamment, n'importe quelle machine peut émettre des paquets NDP et répondre aux questions adressées à une autre machine. Ou bien l'attaquant peut se faire passer pour le routeur et émettre des « RAcailles », ces faux paquets RA (Router Advertisment).

Il existe plusieurs moyens de gérer ces dangers. On peut mettre des ACL statiques dans les commutateurs, n'autorisant les RA que sur le port où se trouve le routeur. Ou bien on peut utiliser la solution un peu plus sophistiquée du RA guard (RFC 6105). On peut aussi surveiller le trafic, avec un IPS ou bien un logiciel comme NDPmon ou ramond, et lever une alarme lorsque quelque chose d'anormal se produit. Mais toutes ces techniques ont un défaut commun : elles reposent sur une analyse du paquet pour détecter si c'était du NDP et il est trop facile de les tromper en fragmentant le paquet. S'il est en deux parties, avec les informations permettant de reconnaître et d'analyser le NDP dans le deuxième paquet, aucun des systèmes existants ne voit ce qui se passe, alors que la machine terminale réassemblera le paquet et se fera donc avoir. À l'heure actuelle, la totalité des mises en œuvre de RA guard est ainsi vulnérable (cf. RFC 7113). Bien sûr, des outils comme les IPS pourraient réassembler les paquets eux-aussi, pour voir le paquet original, mais c'est plus difficile pour les commutateurs Ethernet. Et cela leur fait courir un risque (si l'attaquant génère des quantités de fragments afin d'épuiser la mémoire des réassembleurs, pour faire une attaque par déni de service).

C'est d'autant plus balot que les vrais paquets NDP sont rarement assez grands pour avoir réellement besoin de la fragmentation (section 2). Même si un routeur a besoin d'annoncer de nombreux préfixes dans ses RA, il peut le faire en plusieurs datagrammes IP, il n'est pas nécessaire de tout mettre dans un seul grand datagramme fragmenté. Bref, la fragmentation est quasi-inutile pour NDP alors qu'elle est dangereuse. (Une exception partielle est décrite en section 3, pour SEND, dans le RFC 3971, dans le cas où il y a des gros certificats à transmettre. Je ne la mentionne pas davantage puisque SEND n'est quasiment jamais utilisé. Il résoud radicalement presque tous les problèmes de sécurité de NDP mais le manque de mises en œuvre de ce protocole, et la difficulté qu'il y a à distribuer les clés cryptographiques nécessaires font qu'en pratique, SEND n'est pas une approche envisageable. Voir la conférence de l'auteur à DEEPSEC.)

La section 4 résume les raisons d'abandonner la fragmentation pour NDP :

  • Il existe déjà des mises en œuvre d'IPv6 qui ignorent les paquets NDP fragmentés,
  • Dans la vraie vie, comme expliqué en sections 2 et 3, les paquets NDP réels ne sont pas assez grands pour être fragmentés.

Donc, la section 5 du RFC expose la nouvelle règle, qui met à jour le RFC 4861 : une machine qui émet des paquets NDP ne doit pas fragmenter ces paquets. (Une exception partielle est faite pour les messages Certification Path Advertisement utilisés par SEND. Mais, pour tous les messages habituels, la règle est l'interdiction de la fragmentation.) À la réception, les paquets NDP fragmentés doivent être ignorés.

Si vous voulez créer vous-même de tels paquets NDP fragmentés (qui seront ignorés par les systèmes modernes, vous pouvez utiliser la boîte à outils SI6 présenté dans mon article sur le hacking IPv6, avec l'option -y. Par exemple :

# ./ra6 -y 8  -i eth1 -d 2001:db8:8bd9:8bb0:ba27:ebff:feba:9094          

va générer deux fragments, huit octets n'étant pas assez pour mettre le RA. tcpdump les voit ainsi :

08:34:29.122863 IP6 fe80::8609:88f4:14:a635 > 2001:db8:8bd9:8bb0:ba27:ebff:feba:9094: frag (0|8) ICMP6, router advertisement, length 8
08:34:29.122883 IP6 fe80::8609:88f4:14:a635 > 2001:db8:8bd9:8bb0:ba27:ebff:feba:9094: frag (8|8)

Notez que tcpdump ne s'est pas laissé avoir : il a bien identifié le premier fragment comme appartenant à un RA.


Téléchargez le RFC 6980


L'article seul

Latence rigolote chez F-Contact

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


Ah, les plaisirs de la fracture numérique. Pas besoin d'aller au fin fond de l'Afrique pour la tester, il suffit de partir en vacances au centre de la France, sur les bords de l'Indre, charmante région, aux excellents fromages de chèvre, mais à la connexion lamentable.

C'est une zone blanche. Très blanche. Au point que le seul opérateur mobile qu'on capte (parfois) est F-contact, opérateur collectif créé pour desservir ces zones blanches. La voix passe dans certains cas. Et les données ? Avec un abonnement Orange 3G, j'obtiens une connexion GPRS et admirez la latence :

% ping -i 30 -c 10 192.134.4.20
PING 192.134.4.20 (192.134.4.20) 56(84) bytes of data.
64 bytes from 192.134.4.20: icmp_req=1 ttl=45 time=12799 ms
64 bytes from 192.134.4.20: icmp_req=2 ttl=45 time=20330 ms
64 bytes from 192.134.4.20: icmp_req=3 ttl=45 time=10799 ms
64 bytes from 192.134.4.20: icmp_req=4 ttl=45 time=13417 ms
64 bytes from 192.134.4.20: icmp_req=5 ttl=45 time=13496 ms
64 bytes from 192.134.4.20: icmp_req=6 ttl=45 time=24128 ms
64 bytes from 192.134.4.20: icmp_req=7 ttl=45 time=34604 ms
64 bytes from 192.134.4.20: icmp_req=8 ttl=45 time=38724 ms
64 bytes from 192.134.4.20: icmp_req=9 ttl=45 time=34504 ms
64 bytes from 192.134.4.20: icmp_req=10 ttl=45 time=21644 ms

--- 192.134.4.20 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 270031ms
rtt min/avg/max/mdev = 10799.256/22445.025/38724.983/9779.967 ms, pipe 2

Dix secondes minimum, vingt-deux en moyenne, soit le temps pour la lumière de faire quinze fois le trajet de la Terre à la Lune. Faire le trajet de l'Indre à l'Internet est bien plus long... Mais pas une seule perte de paquet, par contre.

Pour comparer, dans une région mieux connectée, en UMTS, la même machine et la même clé 3G obtiennent :

% ping -c 10 -i 10 192.134.4.20
...
--- 192.134.4.20 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 90049ms
rtt min/avg/max/mdev = 60.149/289.710/959.800/296.908 ms

Avec une telle latence, quasiment aucun service ne marche (à part ping) comme vu plus haut. Pas TCP, c'est sûr, car il ne patiente jamais assez pour que la connexion puisse être établie. Mais le DNS ne marche pas non plus car le Unbound installé sur ma machine timeoute systématiquement (alors que la réponse arrive, on la voit avec tcpdump, mais horriblement tard). On comprend pourquoi les gens qui ont tenté une mise en œuvre du RFC 1149 n'ont jamais utilisé autre chose que ping. Il faudrait sans doute déployer des applications spécifiques, fondées sur des protocoles adaptés comme celui du RFC 5050.

Pierre Beyssac me fait remarquer que beaucoup d'applications Web auront leurs propres problèmes car elles chargent le code qui va après chercher des données en Ajax, avec leurs propres délais de garde, bien plus courts.

Désolé, je ne peux pas vous montrer un traceroute car les routeurs de l'opérateur trichent et envoient une réponse bidon. Mais si vous aimez la technique, j'ai découvert à cette occasion (merci à MarcBrice) l'excellent site http://www.antennesmobiles.fr/ qui donne accès à la localisation de toutes les antennes de France avec leurs caractéristiques. J'étais situé entre deux antennes Bouygues, distante chacune de six kilomètres.

Comment une telle latence est possible ? Je n'ai pas d'explications. Mais elle peut être volontaire, F-contact servant prioritairement à la voix, introduire une latence est un moyen de décourager son usage pour les données.


L'article seul

RFC 6984: Interoperability Report for Forwarding and Control Element Separation (ForCES)

Date de publication du RFC : Août 2013
Auteur(s) du RFC : W. Wang (Zhejiang Gongshang University), K. Ogawa (NTT Corporation), E.H. Haleplidis (University of Patras), M. Gao (Hangzhou BAUD Networks), J. Hadi Salim (Mojatatu Networks)
Pour information
Réalisé dans le cadre du groupe de travail IETF forces
Première rédaction de cet article le 25 août 2013


Un élément essentiel de la culture IETF est l'importance donnée aux programmes qui marchent : rough consensus and running code. D'où les fréquents tests d'interopérabilité, entre diverses mises en œuvre des protocoles IETF, afin de vérifier que, non seulement le code tourne mais qu'il peut interagir avec d'autres instances. Le groupe de travail ForCES, qui normalise des protocoles de communication internes aux routeurs, a ainsi procédé à deux ateliers de tests d'interopérabilité, ce RFC documentant le second.

Le premier avait eu lieu en 2009 à l'université de Patras et avait été documenté dans le RFC 6053. Le second a eu lieu en février 2011 à l'ITL (Internet Technology Lab) à l'université de Zhejiang Gongshang. (Oui, je sais, c'est long, entre l'atelier et la publication du compte-rendu dans un RFC...)

Rappelons ce que fait ForCES : il normalise la communication entre les éléments d'un routeur (ou autre engin du réseau : la norme parle de NE pour Network Element). Le but est de permettra la construction de routeurs en kit, en assemblant des parties d'origines différentes, mais parlant toutes ForCES. Le système ForCES est riche et complexe et cet atelier d'interopérabilité testait cinq composants : le protocole de communication entre CE (Control Element) et FE (Forwarding Element), normalisé dans le RFC 5810, le protocole de transport sous-jacent (RFC 5811), le modèle des FE (RFC 5812), la bibliothèque standard (RFC 6956) et le mécanisme de haute disponibilité (dont le RFC n'a pas encore été publié). Des CE et FE d'origines diverses ont été connectés entre eux, se sont parlé, la bonne compréhension a été vérifiée et tcpdump et Wireshark ont été utilisés pour un contrôle supplémentaire.

Trois mises en œuvre de ForCES ont été testées, les mêmes qu'à l'atelier précédent (ForCES n'a pas pour l'instant suscité un intérêt massif) : celle de NTT, celle de l'université de Patras, et celle faite en commun entre l'université de Zhejiang Gongshang et la société BAUD Network. Les Grecs n'ayant pu se déplacer, ils ont participé aux tests à distance, connectés via un VPN (dans la réalité, bien sûr, les FE et les CE seront toujours proches, souvent dans le même boîtier physique). Globalement, les tests ont été des succès, à part un problème embêtant avec l'encapsulation des données dans une réponse ForCES (voir les détails plus loin). Comme toujours, ces tests ont permis de découvrir des erreurs ou des approximations dans les RFC.

Les communications utilisaient IPsec, puisque le RFC sur le transport de ForCES, RFC 5811, fait obligation à chaque mise en œuvre de ForCES d'avoir IPsec (mais pas forcément de l'activer par défaut : c'est sa disponibilité qui est obligatoire, pas son usage).

Un exemple d'un des scénarios testés (section 3.4) : deux machines terminales sur deux réseaux locaux différents étaient connectées via deux routeurs OSPF. L'un était un routeur classique, l'autre une machine ForCES dont le CE (Control Element) parlait OSPF avec le routeur classique pendant que le FE (Forwarding Element) transmettait les paquets. Ce scénario nécessitait que le CE communique au FE les règles qu'il avait apprises en OSPF et testait la mise en œuvre correcte de plusieurs fonctions du RFC 6956. Une variante de ce test remplaçait le routeur classique par une autre machine ForCES : les deux CE se parlaient en OSPF et chacun disait ensuite à son FE ce qu'il devait faire des paquets IP.

La section 4 donne les résultats complets des tests. Il y a une très grande majorité de succès mais aussi deux échecs, qui vont nécessiter du travail chez les programmeurs.

Mais le principal problème de l'atelier a été un problème lors de la communication de tableaux (et pas de simples valeurs scalaires) entre deux programmes. Le problème est que ForCES permet plusieurs encodages possibles pour les données complexes (RFC 5810, section 6 et notamment 6.4). La règle est que chaque élément ForCES peut choisir librement parmi ces encodages (pas moins de trois possibilités légales, dans l'exemple discuté dans la section 5 de notre RFC). Mais un programme considérait que la réponse venait forcément dans l'encodage de la question, et plantait si ce n'était pas le cas. Bien qu'il soit clairement en tort, notre RFC considère qu'il vaut mieux en effet générer une réponse en utilisant le même encodage que la question ou la commande. Personnellement, je pense plutôt que c'était très gentil de donner un vaste choix aux CE et FE (par exemple pour optimiser le cas de grands tableaux ayant beaucoup de vide) mais que cela mène forcément à ce genre de problèmes. Traditionnellement, les protocoles IETF préfèrent l'interopérabilité à la liberté et ForCES était peut-être allé trop loin dans les possibilités de choix.


Téléchargez le RFC 6984


L'article seul

RFC 6994: Shared Use of Experimental TCP Options

Date de publication du RFC : Août 2013
Auteur(s) du RFC : J. Touch (USC/ISI)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF tcpm
Première rédaction de cet article le 24 août 2013


Le protocole TCP dispose d'un champ « Options » permettant d'indiquer des fonctions spécifiques. Ce champ commence par un identificateur d'option (sur un octet) et deux valeurs sont réservées pour des options expérimentales, non enregistrées. Deux, c'est trop peu, et, en prime, il y a parfois collision entre deux options expérimentales différentes. Notre RFC propose donc un nouveau mécanisme éliminant ces collisions, en ajoutant un deuxième identificateur, l'ExID, dans les options expérimentales.

Le champ « Options » est décrit dans le RFC 793. Il a deux formes mais la plus courante est composée d'un octet indiquant l'option, d'un octet indiquant la longueur de l'option et de données spécifiques à l'option (un TLV, donc). Les options sont enregistrées à l'IANA et sont aujourd'hui au nombre d'une trentaine. 30 sur 256 possibles, cela justifie de les allouer avec prudence (RFC 2780) et les gens qui veulent juste essayer une idée amusante, sans enregistrer leur option, n'avaient pas de solution simple avant que le RFC 4727 ne réserve les options 253 et 254 pour les expérimentations. Si vous avez une idée qui nécessite une option TCP, et que vous voulez la mettre en œuvre, prenez un de ces deux numéros et mettez-le dans vos paquets TCP, vous serez dans la légalité (le RFC 3692 dit toutefois que cela ne doit pas être activé par défaut).

Mais ces expérimentations risquent de se marcher sur les pieds entre elles. Par exemple, le RFC 6013 s'alloue l'option 253. Si vous voulez tester une option en même temps que celle du RFC 6013, il ne vous reste plus qu'un numéro, ce qui peut être insuffisant (certains systèmes nécessitent plusieurs options). À noter que cet usage d'un numéro d'option expérimental est légal (c'est fait pour) mais qu'il existe aussi des squatteurs, qui utilisent des numéros normalement réservés sans les avoir enregistrés proprement. Les options 31 et 32 avaient ainsi été squattées autoritairement, comme 76 à 78, 33, 69, 70, et 76 à 78 (ces derniers dans des produits commerciaux). Le registre IANA les note comme « known unauthorized use without proper IANA assignment ».

Plusieurs approches ont été suggérées à l'IETF pour régler ce problème. Il a été proposé d'élargir l'espace des numéros d'options (Internet-Draft draft-eddy-tcpm-addl-exp-options) et/ou de libéraliser les règles d'allocation, actuellement très strictes (il faut un RFC sur le chemin des normes pour réserver une option). Ce RFC 6994 utilise une autre approche : il crée un « sous-espace » à l'intérieur des options expérimentales, dans lequel on peut (mais ce n'est pas obligatoire) enregistrer sans trop de formalités une expérimentation et son identificateur. C'est désormais l'approche recommandée pour les nouvelles options expérimentales TCP (et obligatoire si l'option expérimentale est déployée sur l'Internet public).

Le principe (section 3) est de remplacer la structure {numéro d'option, longueur, valeur} par {numéro d'option, longueur, ExID, valeur} où le ExID est l'identificateur d'une expérimentation. La taille des ExID (16 ou 32 bits) permet d'en avoir beaucoup et donc d'avoir une politique d'enregistrement libérale sans craindre d'épuiser une ressource finie. L'IANA les enregistre donc sur une base toute simple : « premier arrivé, premier servi » (RFC 5226 pour les différentes options d'allocation possibles). Le registre de ces ExID est en ligne (il compte actuellement trois expérimentations dont le Fast Open TCP qui a été décrit dans le RFC 7413).

Bon, mais l'ExID fait 16 ou 32 bits, alors ? C'est subtil : les 16 premiers bits doivent être uniques pour identifier une expérimentation. Les 16 bits optionnels suivants servent de nombre magique, pour éviter le risque de collision avec des mises en œuvre de TCP qui ne connaissent pas ce RFC (ou bien l'ignorent) et mettent leurs données juste après l'octet de longueur. Si on veut économiser de la place, on choisit un ExID de 16 bits, si on veut minimiser le risque de collision, on prend 32 bits.

Que va donc faire une mise en œuvre de TCP qui rencontre ces options (section 3.2) ? Si l'option est 253 ou 254, elle doit lire l'ExID et ignorer l'option s'il s'agit d'une expérimentation qui lui est inconnue.

Mais les collisions, alors ? Elles peuvent toujours exister. Si une implémentation ancienne de TCP utilise l'option 253 et met au début des données qu'elle envoie la valeur 0x15df, et que le récepteur TCP, conforme à ce nouveau RFC 6994, croit qu'il s'agit de l'expérimentation 5599, qu'il connait, et se met à analyser l'option comme telle ? Il n'y a pas de solution magique. La section 4 de notre RFC recommande aux receveurs TCP d'être robustes face à de telles collisions, ou bien de mettre en œuvre un mécanisme de contrôle de la cohérence des données, pour rejeter les faux positifs.

Un problème classique (et non spécifique à TCP) avec les options expérimentales est qu'un jour, elles seront peut-être normalisées et qu'il faudra alors gérer une transition depuis l'option expérimentale vers l'option standard. La section 5 couvre ce cas mais ne recommande pas une stratégie particulière. Elle se contente de dire qu'envoyer les deux options (l'expérimentale et la standard) dans le même paquet est une mauvaise idée (l'espace des options est limité en TCP).

La section 6 discute des autres approches qui auraient pu être choisies. Par exemple, au lieu des ExID, on aurait pu marquer les options avec un identificateur de l'organisation qui dirige l'expérience, en utilisant les OUI de l'IEEE ou bien les Enterprise Numbers de l'IANA (RFC 1155). Mais les OUI sont très chers (comme souvent à l'IEEE), plus de 1 800 dollars. Les PEN (Private Enterprise Numbers) sont gratuits mais ne sont normalement pas allouables à un individu. Et, dans les deux cas, ces nombres sont plus grands que l'ExID (les PEN n'ont pas de taille définie actuellement mais ils sont déjà trop nombreux pour 16 bits) alors que l'espace est limité dans le champ Options de TCP, puisque tout octet prend la place d'un octet utile aux données.

Si on regarde les versions de développement de Linux et de FreeBSD, on ne trouve rien dans ce dernier (sys/netinet/tcp_input.c dans tcp_dooptions()), qui ne connait pas, par défaut, les options expérimentales. Pour Linux, seul Fast Open est reconnu. Le code dans net/ipv4/tcp_input.c, tcp_parse_options() dit :


case TCPOPT_EXP:
        /* Fast Open option shares code 254 using a
         * 16 bits magic number. It's valid only in
         * SYN or SYN-ACK with an even size.
         */
        if (opsize < TCPOLEN_EXP_FASTOPEN_BASE ||
            get_unaligned_be16(ptr) != TCPOPT_FASTOPEN_MAGIC ||
            foc == NULL || !th->syn || (opsize & 1))
                break;
        foc->len = opsize - TCPOLEN_EXP_FASTOPEN_BASE;
        if (foc->len >= TCP_FASTOPEN_COOKIE_MIN &&
            foc->len <= TCP_FASTOPEN_COOKIE_MAX)
                memcpy(foc->val, ptr + 2, foc->len);
        ...
}

TCPOPT_FASTOPEN_MAGIC vaut 0xF989 (l'ExID sur 16 bits dans le registre IANA).


Téléchargez le RFC 6994


L'article seul

RFC 6979: Deterministic Usage of DSA and ECDSA Digital Signature Algorithms

Date de publication du RFC : Août 2013
Auteur(s) du RFC : T. Pornin
Pour information
Première rédaction de cet article le 24 août 2013


Les algorithmes de signature DSA et ECDSA ont une particularité qui est souvent oubliée : chaque signature doit utiliser un nombre imprévisible. On peut, par exemple, générer ce nombre par un processus aléatoire. Mais tous les systèmes qui voudraient utiliser DSA ou ECDSA n'ont pas forcément un tel générateur aléatoire. Ce RFC propose une autre méthode : fabriquer ce nombre par dérivation déterministe d'un certain nombre de paramètres, produisant le même effet, sans pour autant nécessiter de source d'aléa.

Ces deux algorithmes sont très utilisés dans le monde. (À noter qu'ECDSA repose sur les courbes elliptiques, décrites dans le RFC 6090.) Mais cette nécessité de générer un nombre unique et imprévisible par signature n'a pas d'équivalent avec des algorithmes comme RSA. Le pourquoi de cette nécessité est bien expliqué dans un article de Nate Lawson. Si vous l'oubliez, vous serez piraté, comme Sony l'a été. Mais que ce nombre soit aléatoire n'est pas strictement nécessaire. En fait, l'aléatoire a deux défauts :

  • Il rend les tests difficiles puisque deux exécutions successives du même programme ne donneront pas le même résultat. Ces tests ne peuvent pas facilement vérifier si le nombre est bien imprévisible.
  • Et, surtout, toutes les machines n'ont pas forcément un générateur aléatoire de bonne qualité (cf. RFC 4086), notamment les engins spécialisés comme les cartes à puce. Cela peut mener à préférer RSA, pourtant plus consommateur de ressources.

L'algorithme permettant de générer un nombre unique et imprévisible, mais sans générateur aléatoire, est décrit dans les sections 2 et 3 de notre RFC (il est fondé sur l'idée de derandomization, décrite dans « How Risky is the Random-Oracle Model? »). Je ne vais pas résumer cet algorithme ici (la cryptographie, c'est trop fort pour moi) mais ses propriétés importantes sont :

  • Les signatures sont des signatures DSA ou ECDSA traditionnelles. Les vérificateurs de signature n'ont pas besoin de connaître ce nouvel algorithme et n'ont donc pas besoin d'être modifiés.
  • Les clés, elles, doivent, comme avant, être générées aléatoirement (comme avec RSA).

L'annexe A contient un exemple détaillé de calcul du nombre unique pour une signature.

Si vous envisagez de programmer cet algorithme de génération déterministe de signature, faites bien attention à la section 4, qui résume les problèmes de sécurité. Par exemple, comme rappelé plus haut, la procédure de ce RFC ne s'applique pas aux clés qui doivent, comme avant, être générées aléatoirement. Pour des engins sans générateur aléatoire, comme les carte à puce de bas et de milieu de gamme, cela peut par exemple être fait à l'usine, pendant la fabrication de l'engin.

D'autre part, comme la génération de la signature est déterministe, le même messsage aura donc toujours la même signature (tant qu'on garde la même clé privée, bien sûr). Cela n'est pas un problème dans certaines applications (RSA, tel que décrit dans le RFC 3447, fait pareil). Ainsi, TLS (RFC 5246), SSH (RFC 4251) ou CMS (RFC 5652) peuvent utiliser cet algorithme déterministe sans risque pour leur sécurité.

À noter que, de manière surprenante pour un RFC, la section 5 est consacrée aux risque de brevets sur cet algorithme (apparemment assez faibles). C'est surprenant car, comme la situation change tout le temps (nouveaux brevets, brevets reconnus comme futiles, etc), cette information est normalement distribuée en ligne et pas mise dans un RFC stable (c'est expliqué dans le RFC 3979). Les brevets actuellement connus pour ce RFC sont sur le site Web de l'IETF.

L'annexe B contient une mise en œuvre, en Java, de cet algorithme (copiée ici dans le fichier DeterministicDSA.java). On peut l'utiliser, par exemple, ainsi :


import java.math.BigInteger;
import org.ietf.DeterministicDSA;

public class TestDeterministicDSA {
    
    // http://stackoverflow.com/questions/5470219/java-get-md5-string-from-message-digest
    private static String binary2string(byte []bin) {
	StringBuilder binString = new StringBuilder();
	for (int i = 0; i < bin.length; i++) {
	    String hex = Integer.toHexString(bin[i]);
	    if (hex.length() == 1)
		{
		    binString.append('0');
		    binString.append(hex.charAt(hex.length() - 1));
		}
	    else
		binString.append(hex.substring(hex.length() - 2));
	}
	return binString.toString();
    }

    public static void main (String args[]) {
	int i;
        DeterministicDSA dsa = new DeterministicDSA("SHA-256");
	String signature;
        // We use the private key for the appendix A.2.1 of the RFC
	BigInteger p = new BigInteger("86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED8873ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779", 16);
	BigInteger q = new BigInteger("996F967F6C8E388D9E28D01E205FBA957A5698B1", 16);
	BigInteger g = new BigInteger("07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA417BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD", 16);
	BigInteger x = new BigInteger("411602CB19A6CCC34494D79D98EF1E7ED5AF25F7", 16);
	dsa.setPrivateKey(p, q, g, x);
	for (i=0; i<args.length; i++) {
	    dsa.update(args[i].getBytes());
	    signature = binary2string(dsa.sign());
	    System.out.println(args[i] + " -> " + signature);
	    dsa.reset();
	}
    }
   
}

Et on retrouve les valeurs indiquées dans le RFC (ce qui est logique pour un processus déterministe...) :

 
% java TestDeterministicDSA sample test
sample -> 302d02150081f2f5850be5bc123c43f71a3033e9384611c54502144cdd914b65eb6c66a8aaad27299bee6b035f5e89
test -> 302c021422518c127299b0f6fdc9872b282b9e70d079081202146837ec18f150d55de95b5e29be7af5d01e4fe160

Téléchargez le RFC 6979


L'article seul

Nouvelles attaques facilitant l'empoisonnement DNS

Première rédaction de cet article le 2 août 2013


À la réunion de l'IETF à Berlin le premier août, Haya Shulman a présenté le résultat de ses recherches sur des techniques permettant d'améliorer (en parlant avec le point de vue de l'attaquant) les attaques par empoisonnement DNS. Cela illustre un vieil adage de la sécurité : « les attaques ne régressent jamais, au contraire elles deviennent plus efficaces avec le temps ». Concrètement, cela veut dire que des attaques qui semblaient théoriques deviennent pratiques.

Il s'agit de plusieurs attaques différentes, permettant d'empoisonner un cache plus facilement. Ces attaques n'ont pas forcément de rapport entre elles mais, dans certains cas, une des attaques décrites peut faciliter les autres. La principale, de loin, est un mécanisme astucieux pour exploiter la fragmentation. On suscite la création d'une réponse qui sera fragmentée (dig -4 +dnssec @$NAMESERVER ANY $DOMAIN, où $DOMAIN est un domaine contenant suffisamment de données pour dépasser la MTU), et on obtient un paquet normal et un fragment (ici, vus avec tcpdump) :

09:05:06.032332 IP (tos 0x0, ttl 64, id 30286, offset 0, flags [none], proto UDP (17), length 59)
    192.0.2.69.47170 > 198.51.100.1.53: 53344+ [1au] ANY? example. (31)
09:05:06.034638 IP (tos 0x0, ttl 60, id 27730, offset 0, flags [+], proto UDP (17), length 1388)
    198.51.100.1.53 > 192.0.2.69.47170: 53344*- 22/0/1 example. SOA master.nic.example. ... |domain]
09:05:06.034662 IP (tos 0x0, ttl 60, id 27730, offset 1368, flags [none], proto UDP (17), length 1495)
    198.51.100.1 > 192.0.2.69: ip-proto-17

Toutes les techniques anti-spoofing (le Query ID du DNS, le port source UDP, même la