Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

echoping

Ève

Recherche dans ce blog :

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


RFC 7384: Security Requirements of Time Protocols in Packet Switched Networks

Date de publication du RFC : Octobre 2014
Auteur(s) du RFC : T. Mizrahi (Marvell)
Pour information
Réalisé dans le cadre du groupe de travail IETF tictoc
Première rédaction de cet article le 30 octobre 2014


De plus en plus de protocoles sur l'Internet dépendent d'une horloge correcte. L'époque où les machines étaient vaguement mises à une heure approximative, de façon purement manuelle, est révolue. Aujourd'hui, il est essentiel de connaître l'heure exacte, et cela implique des dispositifs automatiques comme NTP. C'est encore plus essentiel quand il s'agit de protocoles de sécurité, comme DNSSEC (pour déterminer si une signature a expiré) ou X.509 (pour savoir si un certificat est encore valable). Mais cette utilisation du temps comme donnée dans un protocole de sécurité pose elle-même des problèmes de sécurité : si un attaquant perturbe NTP, ne risque-t-il pas d'imposer une fausse heure, et donc de subvertir des protocoles de sécurité ? D'où le groupe de travail TICTOC de l'IETF, dont voici le premier RFC : le cahier des charges des solutions de sécurité pour les protocoles de synchronisation d'horloges, comme NTP.

Deux de ces protocoles sont largement déployés aujourd'hui : un protocole IETF, NTP (RFC 5905) et PTP, alias IEEE 1588 (pas disponible en ligne, comme toutes les normes du dinosaure IEEE). NTP inclus des mécanismes de sécurité, une authentification par secret partagé (RFC 5905, notamment section 7.3) et une autre par clé publique (Autokey, RFC 5906). Par contre, si PTP a un mécanisme d'authentification expérimental (annexe K de la norme), celui-ci ne semble pas avoir été formalisé complètement. Les déploiements de PTP sont donc non sécurisés.

On ne part donc pas de zéro, en tout cas pour NTP, qui a déjà une bonne partie des mécanismes demandés par ce cahier des charges. Ce RFC vise (section 1) un public composé des auteurs de logiciels de synchronisation (pour s'assurer qu'ils mettent en œuvre correctement les mécanismes de sécurité normalisés) et des auteurs de normes (qui vont devoir ajouter des mécanismes de sécurité là où ils manquent). Il peut aussi être utile aux opérationnels, lorsqu'ils révisent ou auditent la sécurité de leur système de synchronisation d'horloges. À partir de questions simples (« quelles sont les menaces ? », « quels sont les coûts de la sécurité ? », « quelles sont les dépendances croisées (par exemple une authentification des serveurs de temps via un certificat dont l'usage dépend d'une horloge correcte) ? »

Un petit mot sur la terminologie au passage : PTP et NTP n'ont pas le même vocabulaire mais l'analyse de notre RFC traite ensemble les deux protocoles et utilise donc un vocabulaire commun. Ainsi, les termes « maître » (master) et « esclave » (slave) servent pour PTP et NTP (bien qu'en NTP, on dise plutôt « serveur » et « client »). Un « grand-maître » (grandmaster) est une machine qui a un accès direct à une horloge, sans passer par le protocole réseau.

Donc, commençons par l'analyse des menaces (section 3). On se base surtout sur l'article de l'auteur du RFC, T. Mizrahi, « Time synchronization security using IPsec and MACsec » (ISPCS 2011). Mais le RFC contient d'autres références à lire.

D'abord, une distinction entre attaquants internes et externes. Les externes sont juste connectés au même Internet que leurs victimes, ils n'ont aucun privilège particulier. Les internes, par contre, soit ont accès à une partie des clés cryptographiques utilisées, soit ont un accès au réseau sur lequel se trouvent leurs victimes et peuvent donc mener certaines attaques. Ils peuvent par exemple générer du faux trafic qui a plus de chances se sembler authentique. Se défendre contre ces Byzantins sera donc plus difficile. Si aucun mécanisme de sécurité n'est déployé, les attaquants internes et externes ont les mêmes possibilités.

Autre distinction importante entre les attaquants, ceux capables d'être Homme du Milieu et les autres. Un homme du milieu est placé de telle façon qu'il peut intercepter les paquets et les modifier. Les autres peuvent injecter des paquets (y compris en rejouant des paquets qu'ils ont lu) mais pas modifier le trafic existant.

Maintenant, quelles sont les attaques possibles ? La section 3.2 en fournit une longue liste. Rappelez-vous que ce sont des attaques théoriques : beaucoup sont déjà empêchées par les techniques de sécurité existant dans NTP (si elles sont activées...) Un homme du milieu peut modifier les paquets, en changeant les informations sur le temps, donnant ainsi de fausses informations. Tout va sembler OK mais les ordinateurs vont s'éloigner de l'heure réelle. Un attaquant actif peut aussi fabriquer, en partant de zéro, un faux paquet, contenant ces fausses informations. Il peut se faire passer pour le maître, trompant ainsi les esclaves, ou pour un esclave, donnant des informations au maître qui vont lui faire envoyer une réponse erronée au vrai esclave. Là aussi, tout semblera marcher, les horloges seront synchronisées, mais l'information sera fausse. Si l'attaquant a du mal à modifier des paquets ou à les générer (par exemple en raison d'une mesure de sécurité), il peut aussi tenter de rejouer des paquets du passé qu'il aura copiés. Cela permet potentiellement de faire reculer les horloges des victimes.

Un autre moyen de se faire accepter comme le maître, au lieu d'usurper l'identité du vrai maître, est de tricher dans le processus de choix du maître. Par exemple, en PTP, le maître est choisi par un algorithme nommé BMCA (Best Master Clock Algorithm) et le tricheur peut donc arriver à se faire désigner comme maître (rappelez-vous que PTP n'a guère de sécurité).

Un attaquant homme du milieu peut aussi jeter les paquets (faisant croire qu'un maître n'est pas joignable) ou les retarder délibérement : ce retard peut permettre de modifier l'horloge, puisque les participants au protocole NTP utilisent le temps d'aller-retour pour calculer l'heure chez le pair. Certaines protections anti-rejeu (comme le fait de vérifier qu'on ne reçoit pas de copie d'un paquet déjà reçu) ne marchent pas contre cette attaque.

Certaines de ces attaques peuvent se faire par des moyens très divers, situés dans la couche 2 ou dans la couche 3 : ARP spoofing, par exemple.

Une solution évidente à bien des problèmes de sécurité est la cryptographie. Mais attention, elle ouvre la voie à de nouvelles attaques comme l'envoi de paquets mal formés qui mènent à des calculs cryptographiques très longs, réalisant ainsi une attaque par déni de service. Une autre attaque par déni de service moins sophistiquée serait de noyer la machine sous un volume énorme de paquets NTP ou PTP.

L'attaquant peut aussi viser le grand-maître : si ce dernier utilise le GPS, un attaquant qui peut envoyer des faux signaux GPS peut tromper le grand-maître, trompant en cascade tous les autres participants. Aucune défense située dans le protocole de synchronisation ne sera alors effective, puisque l'attaque a lieu en dehors de ce protocole. Elle échappe donc au groupe de travail TICTOC.

Bien sûr, il y a aussi des menaces exploitant une faille des programmes qui mettent en œuvre les protocoles, plutôt que des protocoles eux-mêmes, par exemple les attaques par réflexion utilisant NTP, lorsque le serveur accepte trop facilement des requêtes normalement utiles uniquement pour le déboguage.

Plus sophistiquées (peut-être trop pour être utilisées en vrai), les reconnaissances d'un réseau conduites grâce aux protocoles de synchronisation d'horloge. Un attaquant, pour préparer de futures attaques, commence par reconnaître sa cible, chercher les machines, etc. Avec la synchronisation d'horloges, il peut, passivement, collecter des informations qui, par leur fréquence et leur contenu, permettent, entre autres, de fingerprinter des machines spécifiques.

Les attaques possibles sont résumées en section 3.3, avec un tableau qui indique pour chaque attaque l'impact (horloges complètement faussées, précision diminuée - mais l'horloge reste proche du temps réel, ou déni de service) et le type d'attaquant qui peut les effectuer (interne ou externe, devant être homme du milieu ou pas).

De cette liste d'attaques et de leurs caractéristiques, notre RFC va tirer un certain nombre d'exigences auxquelles devront se conformer les solutions de sécurité. Chacune de ces exigences aura un niveau d'impérativité (les MUST et SHOULD du RFC 2119) selon l'impact et selon le type d'attaquant. Par exemple, les attaques qui peuvent être faites par un attaquant externe sont plus graves (le nombre d'attaquants potentiels est plus élevé) et ont donc plus souvent un MUST (section 4 pour la discussion sur les niveaux). Notez que la solution n'est pas forcément interne au protocole de synchronisation d'horloges : utiliser IPsec ou IEEE 802.1AE est souvent une bonne solution.

La section 5 donne la liste des exigences elle-mêmes. La première est l'authentification : il FAUT un mécanisme d'authentification (vérifier que la machine est bien ce qu'elle prétend être) et d'autorisation (vérifier que la machine qui annonce être un maître en a le droit). Notamment, les esclaves doivent pouvoir vérifier les maîtres. Ces mécanismes doivent être récursifs, car les protocoles de synchronisation d'horloges passent souvent par des relais intermédiaires (en NTP, une machine de strate 3 ne reçoit pas directement l'horloge, mais le fait via la machine de strate 2 - le RFC 5906 avait inventé le terme de proventication, contraction de provenance et authentication pour décrire cette question). Cette authentification permet de répondre aux attaques par usurpation d'identité. Sans cela, des attaques triviales sont possibles.

Par contre, l'authentification des esclaves par les maîtres est facultative (MAY) car un esclave malveillant ne peut pas tellement faire de mal à un maître (à part peut-être le déni de service par l'afflux d'esclaves non autorisés) et qu'un esclave a peu de maîtres alors qu'un maître a beaucoup d'esclaves, dont l'authentification pourrait nécessiter trop de travail.

Le RFC impose aussi l'existence d'un mode « fermé » où seuls des pairs authentifiés peuvent participer (il existe sur l'Internet beaucoup de serveurs NTP publics, acceptant des connexions de la part d'inconnus).

Le RFC exige un mécanisme de protection contre les attaques d'un homme du milieu essayant de diminuer la qualité des données, par exemple en retardant délibérement des paquets. En NTP, c'est par exemple le fait d'avoir plusieurs maîtres.

Après l'authentification (et l'autorisation), l'intégrité des paquets : notre RFC exige un mécanisme d'intégrité, permettant de s'assurer qu'un méchant n'a pas modifié les paquets en cours de route. Cela se fait typiquement par un ICV. La vérification de l'intégrité peut se faire à chaque relais (ce qui est plus simple), ou bien de bout en bout (ce qui protège si un des relais est un vilain byzantin).

L'usurpation d'identité est ensuite couverte : le RFC exige (MUST) un mécanisme permettant d'empêcher un attaquant de se faire passer pour le maître. Comme son nom l'indique, le maître peut modifier les horloges des autres machines à volonté et empêcher une usurpation est donc critique. Le RFC impose en outre un mécanisme contre le rejeu (car ce sont des attaques triviales à monter) et un moyen de changer les clés cryptographiques utilisées (cela a l'air évident mais certains protocoles - comme OSPF, cf. RFC 6039 - sont très pénibles pour cela, et en pratique les clés ne sont pas changées).

Les demandes suivantes sont moins fortes, car concernant des attaques moins graves ou plus difficiles à faire. Par exemple, il faudrait, si possible (SHOULD), fournir des mécanismes contre les attaques par déni de service.

Enfin viennent les simples suggestions, comme de prévoir un mécanisme assurant la confidentialité des paquets. Comme aucune information vraiment secrète ne circule dans les messages de synchronisation d'horloges, cette suggestion est un simple MAY.

Ces exigences sont résumées dans la section 6, sous la forme d'un tableau synthétique.

La section 7 rassemble un ensemble de questions diverses sur la sécurité des protocoles de synchronisation d'horloge. Par exemple, la section 7.4 se penche sur les interactions entre cette synchronisation et des protocoles extérieurs de sécurité comme IPsec. La 7.5 expose un cas plus embêtant, le problème d'œuf et de poule entre la synchronisation d'horloges et des protocoles qui utilisent l'heure dans leurs mécanismes de sécurité. Par exemple, si on utilise TLS avec authentification X.509 à un moment quelconque pour se connecter, une horloge correcte est nécessaire (vérification de la non-expiration du certificat), alors que NTP n'est pas forcément déjà disponible. Il faut donc une horloge stable, pour ne pas trop dériver en attendant que NTP prenne le relais.

Enfin, la section 8 rappelle que le problème difficile de la distribution des clés n'est pas encore traité, que ce soit dans ce RFC ou dans les protocoles.

Voici un court exemple de sécurisation avec NTP. Je n'ai pas utilisé la technique Autokey du RFC 5906 mais la plus ancienne (voire archaïque), qui utilise des clés privées. L'un des avantages est la portabilité, on sait que cela va marcher sur tous les clients et serveurs NTP. Sur le serveur, je crée les clés :

% sudo ntp-keygen  -M     
Built against OpenSSL OpenSSL 1.0.1i 6 Aug 2014, using version OpenSSL 1.0.1j 15 Oct 2014
Generating new md5 file and link
ntpkey_md5_alarmpi->ntpkey_MD5key_alarmpi.3623647899

% sudo ln -s ntpkey_md5_alarmpi ntp.keys

% cat ntp.keys
...
11 SHA1 2db9278081f6b410cfb826317b87cf95d5b90689  # SHA1 key
12 SHA1 cc52f97bc43b6c43a4cbe446813f0c6c3bd54f7c  # SHA1 key

Et j'indique dans la configuration que je n'autorise (notrust) que les clients du réseau local, et s'ils s'authentifient avec la clé n° 11 :

keys /etc/ntp/ntp.keys
trustedkey 11
...
restrict default noquery nopeer nomodify notrap
...
restrict 2a01:e35:8bd9:8bb0:: mask ffff:ffff:ffff:ffff:: notrust

Avec une telle restriction, les clients qui ne s'authentifient pas ne reçoivent pas de réponse (même pas une réponse négative), ce qui rend les problèmes d'authentification difficiles à déboguer, d'autant plus que Wireshark n'indique apparemment nulle part si les paquets sont authentifiés ou pas. Côté client, il faut donc montrer patte blanche, d'abord copier les clés puis :

keys /etc/ntp/ntp.keys
trustedkey 11

server my-favorite-server key 11

Et, cette fois, le serveur répond et tout se passe bien.

Si vous voulez faire de l'Autokey (cryptographie à clé publique), vous pouvez consulter la documentation officielle ou bien, en français, l'article de Laurent Archambault (ou, en général, son cours NTP). Si, au lieu d'être sur Unix avec la mise en œuvre de référence ntpd, vous gérez un routeur Cisco, voyez en français cet article. Si vous utilisez le programme des gens d'OpenBSD, OpenNTPD, tant pis pour vous, il n'a aucun mécanisme de sécurité. Je n'ai pas trouvé de documents ANSSI sur la sécurisation des protocoles de synchronisation d'horloge. Le NIST a un service NTP authentifié (notez la complexité des procédures d'inscription !). Pendant longtemps, la référence en français était l'excellent article d'Alain Thivillon mais il est trop ancien aujourd'hui.


Téléchargez le RFC 7384


L'article seul

RFC 7381: Enterprise IPv6 Deployment Guidelines

Date de publication du RFC : Octobre 2014
Auteur(s) du RFC : K. Chittimaneni (Dropbox), T. Chown (University of Southampton), L. Howard (Time Warner Cable), V. Kuarsingh (Dyn), Y. Pouffary (Hewlett Packard), E. Vyncke (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 26 octobre 2014


Le déploiement d'IPv6 continue, trop lentement, mais il continue et de plus en plus d'organisations font désormais fonctionner ce protocole. Ce document est une série de conseils sur le passage à IPv6 au sein d'une organisation (le RFC dit « enterprise » mais je ne vois pas de raison de traduire par « entreprise », ce qui limiterait arbitrairement aux organisations privées prévues pour faire gagner de l'argent à leurs actionnaires). Les précédents RFC de conseils sur le déploiement d'IPv6 ciblaient des organisations spécifiques (comme les opérateurs réseaux dans le RFC 6036), celui-ci s'adresse à toute organisation qui dispose d'un réseau et d'administrateurs pour s'en occuper (les particuliers, ou toutes petites organisations sans administrateurs réseaux, ne sont pas traités).

Bref, vous êtes l'heureux titulaire du titre d'administrateurs réseaux dans une organisation qui est pour l'instant encore attardée et qui n'utilise que le protocole du siècle dernier, IPv4. Votre mission, que vous l'acceptiez ou pas, est de passer à IPv6, sachant en outre que vous n'avez probablement pas le droit d'abandonner complètement IPv4. Que faire ? Le RFC 4057 décrivait ces réseaux d'organisation, qui se distinguent du réseau SOHO par la présence d'administrateurs réseau compétents et dévoués. Il s'agit donc de réseaux gérés, contrairement au réseau de la maison de M. Toutlemonde. Le, la ou les administrateurs réseau doivent gérer un réseau interne, comprenant des serveurs, des postes de travail, des imprimantes, et parfois des routeurs internes. Ce réseau est connecté à l'Internet via au moins un routeur. Plusieurs serveurs sont prévus pour être accessibles de l'extérieur, par exemple le serveur de courrier. Donc, pour résumer le cahier des charges :

  • Déployer IPv6 sans casser IPv4, qui doit continuer à fonctionner,
  • Perturber le moins possible le service. L'utilisateur professionnel veut que ça continue à marcher, les changements techniques indispensables (comme le passage à IPv6) doivent pouvoir être ignorés dans le cadre de son travail.

La pénurie d'adresses IPv4 a des conséquences même sur ceux qui s'obstinent à ne pas déployer IPv6. Par exemple, comme le note le RFC 6302, les serveurs Internet, face au déploiement de techniques comme le CGN, ne peuvent plus se contenter de journaliser l'adresse IP source de leurs clients, ils doivent aussi noter le port source. D'autre part, même si on croit pouvoir se passer d'IPv6, certains réseaux ont déjà de l'IPv6 sans le savoir (parce qu'il est activé par défaut sur beaucoup de systèmes) et cela a des conséquences de sécurité (cf. RFC 6104 pour un exemple et le RFC 7123 pour une vision plus générale de ce problème).

Notre RFC propose trois phases pour l'opération de déploiement :

  • Préparation et détermination,
  • Phase interne,
  • Phase externe.

Les deux dernières ne sont pas forcément exécutées dans cet ordre. Par exemple, si on gère un site Web et que beaucoup de clients potentiels ont déjà IPv6, il est logique de commencer par la phase externe, doter ce site d'une connectivité IPv6. En outre, bien des applications de gestion, comme celles de comptabilité sont affreusement archaïques et n'auront pas IPv6 de si tôt, ce qui relativise l'urgence de la phase interne. D'un autre côté, bien des systèmes d'exploitation ont IPv6 par défaut, et le RFC 7123 note que cela pose des problèmes de sécurité qui mériteraient peut-être une attention immédiate, et donc une priorité à la phase interne. Autre cas où la phase interne doit sans doute passer en premier : si l'espace d'adressage du RFC 1918 commence à ne plus suffire ou bien si une fusion/acquisition a mené à assembler deux réseaux qui utilisaient les mêmes préfixes, entraînant un grand désordre et l'envie, chez l'administrateur réseau, de se reconvertir comme affineur de fromage dans l'Hérault, ou de déployer IPv6. Comme le notait le RFC 6879, la fusion/acquisition de deux organisations est souvent une bonne occasion pour passer à IPv6, car fusionner deux réseaux IPv4 en adressage privé est toujours long et compliqué. Bref, chaque organisation va devoir déterminer ses priorités et décider de commencer, après la première phase de préparation, par la phase interne ou par l'externe. Autrefois, il y avait aussi la catégorie « c'est bien compliqué tout cela, est-ce que ça en vaut la peine ? » mais sa taille diminue. Certaines objections techniques qui étaient valables à une époque (RFC 1687) ont depuis été traitées.

Donc, maintenant, au travail, avec la première phase, Préparation & Détermination (section 2 du RFC). Le RFC recommande de nommer un « chef de projet professionnel ». Ce qui est sûr est qu'il faut gérer le projet sérieusement, car c'est après tout un changement important dans l'infrastructure, avec plein d'interdépendances. La phase de Préparation & Détermination va, entre autres, servir à décider si on priorise la Phase Interne ou la Phase Externe. La première phase découvrira sans doute des problèmes inattendus et elle se fera donc en plusieurs itérations (« zut, ce plan ne marchera pas, il faut en trouver un autre »).

D'abord, l'inventaire de l'existant. Il faut faire la liste des matériels en déterminant pour chacun s'il est prêt pour IPv6. Il y aura du matériel déjà prêt (au sens où il fait déjà tourner un système capable d'IPv6), du matériel qui pourra recevoir une mise à jour logicielle, et du matériel qu'il faudra remplacer car aucun système avec IPv6 n'existe pour ce matériel. Par exemple, les routeurs (sauf le bas de gamme) sont probablement prêts, mais les objets connectés (genre caméras ou imprimantes) ne le sont souvent pas.

Après le matériel, le logiciel. Il faut faire le tour des applications pour déterminer lesquelles passeront en IPv6 sans problèmes. Si certains logiciels ne sont pas prêts, il faut demander au vendeur. Je suis toujours surpris que les vendeurs expliquent leur manque d'IPv6 par l'argument « aucun client ne l'a demandé ». Parfois, bien sûr, le vendeur ment mais, parfois, les clients semblent effectivement d'une timidité maladive et n'osent pas dire aux vendeurs, même gentiment « excusez-nous de vous demander pardon, mais pourrions-nous avoir de l'IPv6 un jour, s'il vous plait ? »

Lorsque l'application est développée/maintenue en interne, c'est l'occasion de se pencher sur les pratiques de codage. Est-ce que les applications ne sont pas d'un trop bas niveau, intégrant des détails non pertinents comme la taille de l'adresse IP ? Parmi les RFC dont la lecture peut être utile aux programmeurs à ce stade, citons le RFC 4038 sur le rapport entre les applications et IPv6, le RFC 6724 sur la sélection de l'adresse IP source, et le RFC 6555, sur l'algorithme des globes oculaires heureux, si utile lorsqu'on a à la fois IPv4 et IPv6. Un autre point important, mais non mentionné par ce RFC, est que le cycle de vie d'un logiciel développé en interne est long : ce qui est programmé aujourd'hui sera toujours en service dans de nombreuses années. Il faut donc adopter des bonnes pratiques de programmation (programmation réseau de haut niveau, valable aussi bien pour IPv4 que pour IPv6) aujourd'hui, même si la migration vers IPv6 semble lointaine.

C'est l'occasion d'aborder la question cruciale de la formation. Aujourd'hui, il existe encore des écoles ou universités qui enseignent IP sans parler d'IPv6, ou en le réduisant à deux heures de cours à la fin de l'année, dans un fourre-tout « divers sujets ». C'est consternant et cela veut dire que la formation à IPv6 dépendra surtout du technicien lui-même, ou bien de son employeur (section 2.3 du RFC).

Autre gros morceau dans la phase de préparation et détermination, la question de la sécurité. Évidemment, on veut que le réseau soit aussi sûr en IPv6 qu'en IPv4. Au passage, j'ai fait un long exposé à ce sujet. Je ne suis pas d'accord avec l'approche du RFC. Le RFC note qu'IPv6 n'est pas intrinsèquement plus sûr qu'IPv4 juste parce qu'il est plus récent, ce qui est du bon sens. Mais il prend ensuite une approche unilatérale, en notant qu'il existe beaucoup de failles de sécurité dans le code IPv6 car il n'a guère été testé au feu. C'est exact mais le RFC oublie de dire que c'est la même chose pour les attaquants : leurs programmes sont rarement adaptés à IPv6. Mon expérience est que les attaquants et les défenseurs sont aussi peu préparés à IPv6 et que, en pratique, la sécurité des deux protocoles est à peu près équivalente. Le RFC, comme le font souvent les professionnels de la sécurité, pessimistes par profession, ne voit que les faiblesses de la défense. En tout cas, tout le monde est d'accord pour dire que la formation (paragraphe précédent...) est essentielle.

Le RFC tord le cou à quelques mythes comme quoi la sécurité d'IPv6 serait meilleure (il oublie les mythes inverses, tout aussi répandus). Par exemple, IPv6 ne rend pas impossible le balayage d'un réseau, juste parce qu'il a d'avantage d'adresses. Le RFC 5157 décrit plusieurs techniques de balayage qui sont faisables avec IPv6 (et qui sont effectivement mises en œuvre dans des outils existants). Mais s'il est vrai qu'IPv6 n'empêche pas le balayage, ce nouveau RFC, dans son analyse trop rapide, oublie de dire que le balayage est bien plus facile et rapide en IPv4, comme le montre la disponibilité d'outils (comme massscan) qui balaient tout l'Internet IPv4 en quelques heures ! De même, notre nouveau RFC rappelle qu'IPv6 n'a pas de sécurité cryptographique par défaut (contrairement à une légende répandue par des zélotes d'IPv6 au début, cf. RFC 6434 pour l'enterrement de cette légende). Pire (et, là, ce RFC 7381 est gravement en tort) : la section 2.4.1 explique que c'est une bonne chose pour la sécurité qu'il n'y ait pas de chiffrement car il faut pouvoir espionner le trafic de ses utilisateurs, un argument vraiment incroyable à l'ère post-Snowden.

Le RFC est plus raisonnable par la suite en notant que certaines pratiques de sécurité relèvent plus de la magie que de la raison. Par exemple, les ULA en IPv6 (RFC 4193) ou les adresses privées en IPv4 (RFC 1918) n'apportent aucune sécurité en elles-même, contrairement à ce que croient naïvement certains administrateurs réseau.

Notre RFC fait le point sur les failles de sécurité qui sont spécifiques à IPv6 :

  • Les adresses de protection de la vie privée (RFC 4941) ne la protègent que partiellement mais, surtout, compliquent la vie de l'administrateur réseaux, en limitant la traçabilité des machines. Si un journal montre que 2001:db8:1:1:c144:67bd:5559:be9f s'est connecté au serveur LDAP, comment savoir quelle machine était 2001:db8:1:1:c144:67bd:5559:be9f puisque, s'il utilisait le RFC 4941, il a pu changer d'adresse souvent, sans que cela soit enregistré quelque part ? Une solution possible est d'utiliser un logiciel qui écoute le réseau et stocke dans une base de données les correspondances entre adresses MAC et adresses IPv6 (un logiciel comme ndpmon, donc). Si on contrôle complètement les machines terminales, on peut aussi interdire les extensions « vie privée ». On peut enfin forcer l'usage de DHCP en demandant au routeur d'envoyer toutes les annonces avec le bit M (qui indique que DHCP est disponible, RFC 4861, section 4.2) et qu'aucun préfixe ne comporte le bit A (ce qui interdira l'auto-configuration sans état, RFC 4861, section 4.6.2). Cela suppose que toutes les machines ont un client DHCP v6, ce qui n'est pas gagné aujourd'hui. Pire : on sait qu'aujourd'hui le comportement des différents système en présence des bits M et A varie énormément.
  • Et les en-têtes d'extension ? Leur analyse est difficile et, résultat, certains systèmes de sécurité ne savent pas les traiter, permettant ainsi au méchant d'échapper à la détection ou au filtrage, simplement en ajoutant des en-têtes au paquet IPv6 (RFC 7113 pour un exemple).
  • La fragmentation est une source classique de casse-tête. Elle existe aussi en IPv4 mais IPv6 la restreint à la source, les routeurs intermédiaires ne peuvent pas fragmenter. Du point de vue sécurité, la principale question liée à la fragmentation est le fait que, au nom d'une sécurité mal comprise, certains réseaux bloquent le protocole ICMP, malgré le RFC 4890, gênant ainsi la détection de MTU et empêchant donc de facto la fragmentation. Autres problèmes liés à la fragmentation, mais qui ne sont pas spécifiques à IPv6, le risque d'utilisation de fragments pour échapper à la détection (RFC 6105 pour un exemple), et le réassemblage de fragments qui se recouvrent (RFC 5722).
  • Pour la résolution d'adresses IP en adresses MAC, IPv6 utilise NDP et plus ARP. Le RFC classe cela comme « une importante différence » mais, en fait, du point de vue de la sécurité, les deux protocoles sont très proches. Ils fonctionnent en diffusant à tous l'adresse convoitée, et ils font une confiance absolue à la première réponse reçue. Aucune authentification n'existe (IPv6 a des solutions, mais très peu déployées, cf. RFC 3971 et RFC 3972).
  • Enfin, dernier problème qu'on n'avait pas avec de l'IPv4 pur, un réseau double-pile, IPv4 et IPv6, augmente la surface d'attaque en offrant davantage de possibilités au méchant. Au minimum, il faut faire attention à ce que les politiques de sécurité soient les mêmes en IPv4 et en IPv6 afin d'éviter (je l'ai déjà vu), un pare-feu strict en IPv4 mais très laxiste en IPv6.

Maintenant, le routage. Un grand réseau interne va probablement utiliser un IGP. Lequel ? Plusieurs protocoles gèrent IPv6 (RIPng, IS-IS, OSPF). A priori, pour faciliter la vie des techniciens, il est logique d'utiliser le même protocole de routage en IPv4 et en IPv6. Petit piège dans le cas d'OSPF : OSPF v2 (pour IPv4) et OSPF v3 (pour IPv6) sont proches mais ne sont pas exactement le même protocole (le RFC oublie qu'OPSF v3 peut désormais gérer IPv4, cf. RFC 5838, mais il est vrai que c'est très peu fréquent).

Et l'adressage (section 2.6) ? Il est évidemment radicalement différent en IPv4 et en IPv6. En IPv4, l'essentiel du travail sur l'adressage a pour but d'économiser les quelques adresses qu'on détient, pour tout faire fonctionner malgré la pénurie. En IPv6, ce problème disparait et on peut donc se concentrer sur un plan d'adressage propre. Le document à lire pour faire de jolis plans d'adressage en IPv6 est le RFC 5375.

L'une des décisions à prendre sera d'utiliser des adresses PA ou PI. Les premières sont attribuées par l'opérateur réseau qui nous connecte à l'Internet. Pas de formalités particulières à remplir, elles sont typiquement allouées en même temps que la connectivité est mise en place. Leur inconvénient est qu'on dépend de l'opérateur : le multi-homing va être plus difficile, et, si on change d'opérateur, on est parti pour une pénible renumérotation (RFC 5887). En outre, il peut être difficile d'obtenir la taille de préfixe souhaitée, malgré le RFC 6177 : certains opérateurs ne fileront qu'un /56, voire un /60. Les secondes adresses, les adresses PI, résolvent ces problèmes mais les obtenir nécessite d'affronter la bureaucratie des RIR. Pour les réseaux internes, notre RFC recommande un /64 pour les réseaux des utilisateurs, et un /127 pour les interconnexions point-à-point, comme dit dans le RFC 6164. IPv6 ne nécessite pas les masques de longueur variable, très communs en IPv4 pour essayer de grappigner quelques malheureuses adresses. Utiliser, par exemple, un /80 pour un Ethernet de plusieurs machines utilisateur empêcherait d'utiliser l'auto-configuration (RFC 4862) sans gain utile, et au risque de perturber les futures réorganisations du réseau.

Une fois le plan d'adressage fini, il reste à distribuer les adresses aux machines. Autrefois, on n'utiliisait que SLAAC, parce que c'était la seule possibilité. Le RFC note, avec un très grand optimisme, que DHCP est désormais une alternative mûre (en fait, bien des machines clientes n'ont pas encore de client DHCP, voilà pourquoi je trouve le RFC trop optimiste). Pour le réseau fermement administré, DHCP a l'avantage de garder trace de la correspondance entre adresse MAC et adresse IP, en un point central. Pour faire l'équivalent avec SLAAC, il faudrait un logiciel de supervision comme ndpmon cité plus haut. Autre avantage de DHCP, le serveur DHCP est l'endroit logique où faire des mises à jour dynamiques du DNS pour refléter les changements d'adresses IP. Dernier mot sur le DNS : il est déconseillé de mettre des données pour les ULA dans le DNS mondial.

La phase de Préparation et de Détermination se termine avec une analyse des outils disponibles pour l'administrateur réseaux. Il arrive en effet trop souvent que l'outil utilisé, par exemple, pour le déploiement de nouvelles versions de logiciels, ne soit finalement pas compatible IPv6. S'il a été écrit dans les dix dernières années, cela montre une grande incompétence de la part de son auteur mais ça arrive. Parmi les erreurs faites par les programmeurs, le manque de place pour la représentation des adresses, que ce soit en forme texte (RFC 5952) ou sous leur forme binaire. Ceci dit, tant que le réseau est en double-pile, certaines fonctions (par exemple l'interrogation des agents SNMP) peuvent continuer à se faire en IPv4.

S'il est logique de commencer par la phase Préparation & Détermination, le choix de la phase suivante dépend, comme on l'a vu, des caractéristiques propres à l'organisation dont on gère le réseau. Le RFC commence par la phase externe (section 3) mais ce n'est que l'ordre de présentation, pas forcément l'ordre recommandé.

Donc, la phase externe : il s'agit de migrer en IPv6 les composants du réseau visibles de l'extérieur. Il va évidemment falloir obtenir une connectivité IPv6 d'un opérateur réseau. Il est fortement recommandé d'utiliser de l'IPv6 natif, plus simple à déboguer et évitant les problèmes comme la taille de MTU. Mais, si cela n'est pas possible (dans certaines régions du monde, il est très difficile de trouver un opérateur qui sache faire de l'IPv6), il faudra se résigner à utiliser un tunnel, par exemple vers Hurricane Electric, qui fournit un service stable et pro. Si les adresses utilisées sont des adresses PA, ledit opérateur s'occupera du routage externe. Si ce sont des PI, l'opérateur pourra parfois les router pour le compte du client, et le client devra parfois faire du BGP lui-même. Évidemment, l'obtention d'un préfixe PI va dépendre des règles du RIR local. Par exemple, en Europe, le RIPE-NCC n'impose plus d'être multihomé pour avoir un préfixe PI.

Notre RFC ne traite pas des problèmes spécifiques à chaque service. Par exemple, cela aurait pu être l'occasion d'expliquer que, si annoncer une adresse IPv6 pour un serveur HTTP peut présenter un risque (pour les clients qui croient avoir une connectivité IPv6 alors qu'elle est imparfaite, cf. RFC 6556), en revanche, mettre des adresses IPv6 à ses serveurs DNS n'en présente aucun, puisque les clients DNS mettent en œuvre depuis longtemps un algorithme de test et de sélection des différents serveurs d'une zone. Cela explique sans doute que, selon le rapport ODRIF, il y ait beaucoup plus de zone sous .fr avec du DNS IPv6 que de zones avec un serveur Web IPv6. (Notez que Google fait, curieusement, le contraire : leurs sites Web sont IPv6 depuis longtemps mais leurs zones DNS non.)

Il faudra évidemment penser à la sécurité. Le RFC rappelle que, si on filtre, il ne faut surtout pas bloquer stupidement tout ICMP, indispensable à certaines fonctions d'IPv6 (voir le RFC 4890 pour une discussion détaillée, que notre RFC résume en donnant la liste minimale des types de messages ICMP qui doivent être autorisés).

Il y a des règles de sécurité générales, qui s'appliquent à IPv6 aussi bien qu'à IPv4 : attention aux applications (pensez à mettre bash à jour, par exemple...), mettez en place des mécanismes contre l'usurpation d'adresses (RFC 2827), protégez les routeurs (RFC 6192), etc. Et il y a quelques règles spécifiques d'IPv6 comme les attaques contre le cache NDP (RFC 6583) : il est recommandé de limiter le rythme des requêtes NDP et de bloquer le trafic entrant sauf vers les adresses publiques.

La supervision doit aussi faire l'objet d'une grande attention. Notre RFC recommande de surveiller séparément IPv4 et IPv6, pour être averti si un des deux protocoles défaille. Prenons l'exemple d'un serveur HTTP. Si vous testez son bon fonctionnement avec curl ou wget, vous ne serez pas prévenu si IPv4 ou IPv6 est en panne. En effet, ces deux programmes passent automatiquement aux adresses IP suivantes si l'une d'elles ne fonctionne pas. Il faut donc un test explicitement limité à IPv4 et un limité explicitement à IPv6. Avec Icinga et le check_http des monitoring plugins, cela peut être :

define service{
        use                             generic-service        
        hostgroup_name                  WebServers
        service_description             HTTP4
        check_command                   check_http!-4
        }

define service{
        use                             generic-service        
        hostgroup_name                  WebServers
        service_description             HTTP6
        check_command                   check_http!-6
        }

Il reste la phase interne (section 4) qui, rappelez-vous, peut être faite avant, après ou en même temps que la phase externe, selon les caractéristiques de votre réseau et vos choix. Il s'agit cette fois de migrer en IPv6 le réseau interne, ses applications métier, ses commutateurs, ses postes de travail... A priori, comme il y a peu de chances que toutes les applications et systèmes IPv4 soient prêts demain à migrer, le réseau interne va rester mixte pendant longtemps. Pour la connectivité, la règle habituelle s'applique : « double-pile quand on peut, tunnel quand on n'a pas le choix ». La double-pile (IPv4 et IPv6 sur tous les équipements) est la solution la plus simple pour la gestion du réseau. Le tunnel, fragile et faisant dépendre IPv6 d'IPv4, sert pour les cas où on est coincés à n'utiliser que des systèmes antédiluviens.

En interne également, on va se poser la question de la sécurité. Les gestionnaires de réseaux d'organisations sont souvent peu satisfaits des adresses IP « vie privée » du RFC 4941, car elles rendent difficile la traçabilité (« 2001:db8:1:1:c144:67bd:5559:be9f a fait des accès répétés au serveur LDAP, c'est qui, déjà, 2001:db8:1:1:c144:67bd:5559:be9f ? ») Ou bien on force l'utilisation de DHCP, ou bien on utilise un outil comme ndpmonqui garde trace des correspondances entre adresses MAC et adresses IP.

Comme pour les ARP et DHCP d'IPv4, les techniques de base du réseau IPv6 (les RA de NDP, et DHCP) n'offrent aucune sécurité et il est trivial, par exemple, d'envoyer des « RAcailles », des faux RA (RFC 6104). Il est donc très recommandé de déployer des techniques comme celles du RFC 6105. Vérifiez auprès de votre fournisseur de commutateurs qu'elles sont disponibles ! Dans le futur, les techniques issues du projet SAVI (Source Address Validation Improvement, cf. RFC 6959) aideront peut-être.

Pour assurer le bon fonctionnement du réseau interne, une des questions qui perturbent le plus les administrateurs d'un réseau IPv6 est le choix du mécanisme principal de configuration des machines terminales. SLAAC (RFC 4862) ou DHCP (RFC 3315) ? Il n'y a pas de réponse simple, chacune des deux solutions ayant ses avantages et ses inconvénients. SLAAC est certainement plus simple et plus rapide à déployer mais DHCP permet davantage de contrôle, ce qui est en général apprécié dans les réseaux d'organisations. En pratique, malheureusement, il faudra sans doute les deux car aucun des deux mécanismes ne permet de tout faire. Par exemple, DHCP n'a pas d'option pour indiquer les routeurs à utiliser (il faudra donc compter sur les RA de SLAAC, ou sur une configuration statique). Et SLAAC ne permet pas d'indiquer les serveurs NTP. Si les deux protocoles, DHCP et SLAAC, permettent désormais d'indiquer les résolveurs DNS, aucun des deux n'est encore suffisant pour tous les usages et, en pratique, il est difficile de choisir.

Autre question essentielle, la résilience face aux pannes. Cela passe par la redondance des équipements comme les routeurs. NDP permet aux machines de maintenir une liste de routeurs disponibles et de passer à un autre en cas de panne (RFC 4861, section 7.3). Par défaut, la bascule se fait en 38 secondes (RFC 4861, section 10), ce qui est bien trop long dans beaucoup de cas. Il est donc souvent préférable d'utiliser des techniques comme VRRP (RFC 5798).

Autre problème à regarder de près pendant la phase Interne, les machines terminales, de l'ordinateur de bureau à la machine à café connectée, en passant par l'imprimante et la caméra de vidéo-surveillance. Les ordinateurs ont quasiment tous IPv6 aujourd'hui (mais pas forcément activé par défaut). Mais certaines fonctions peuvent manquer (adresses privées du RFC 4941, client DHCPv6, client RA qui comprend les résolveurs DNS du RFC 6106...) Il est également possible que des algorithmes comme la bonne sélection de l'adresse source (RFC 6724) ou les globes oculaires heureux (RFC 6555) soient manquants ou désactivés. Or, sans eux, l'utilisation d'un système double-pile (IPv4 et IPv6) est bien plus pénible. Il faut donc s'assurer de bien connaître le comportement par défaut des systèmes qu'on utilise sur les réseaux locaux.

Quant aux autres engins, non considérés comme des ordinateurs, il est malheureusement fréquent, en 2014, qu'ils n'aient toujours pas IPv6 (alors même qu'ils sont souvent bâtis sur des systèmes, comme Linux, qui ont IPv6 depuis longtemps). Enfin, le dernier gros problème de la phase interne sera les systèmes utilisés dans l'infrastructure de l'organisation (le système de téléphonie, par exemple) qui ne sont pas toujours prêts pour IPv6. Là encore, il est essentiel que les clients se fassent entendre et tapent sérieusement sur les vendeurs les plus attardés.

On a parlé à plusieurs reprises de réseaux double-pile car c'est l'approche la plus réaliste aujourd'hui. Pourra-t-on un jour simplifier sérieusement le réseau en supprimant enfin le bon vieil IPv4 et en ayant à nouveau un réseau mono-protocole, entièrement IPv6 ? C'est bien le but à long terme, dit avec optimisme la section 5 de notre RFC. Atteindre ce but ne nécessite même pas que tout l'Internet soit entièrement passé en IPv6. Il existe des techniques permettant aux machines d'un réseau purement IPv6 de parler avec les derniers survivants de l'ère IPv4 (cf. par exemple RFC 6144). Au début, une bonne partie du trafic devra passer par ces relais ou des traducteurs NAT64. Mais au fur et à mesure que le reste de l'Internet devient accessible en IPv6 (RFC 6883), ces techniques deviennent naturellement de moins en moins utilisées.

Tous les conseils ci-dessus étaient génériques, s'appliquant à toutes sortes d'organisations. La section 6 traite maintenant des cas particuliers de certaines organisations. Par exemple, les gens dont le métier est de distribuer du contenu sur l'Internet (par exemple via un CDN) ont intérêt à lire les RFC 6883 et RFC 6589.

Un autre cas particulier, qui permettra de finir sur une note optimiste, est celui des campus universitaires. Ils sont aujourd'hui très souvent passés à IPv6. Les NREN ont en général IPv6 depuis le début des années 2000. L'intérêt pour les techniques nouvelles, et la mission de recherche et d'éducation, faisait des universités l'endroit logique pour les premiers déploiements. C'est évidemment souvent le département d'Informatique qui était le premier à migrer ses machines et ses services vers IPv6. Le réseau Eduroam est également accessible avec IPv6 puisqu'il repose sur 802.1x (qui est indifférent à la version du protocole IP utilisée) et non pas sur ces horribles portails captifs (dont un des inconvénients est d'être limité à un protocole).

La grande majorité des universités qui ont déployé IPv6 n'utilise pas d'ULA, ni traduction d'adresses. Presque toujours, elles utilisent des adresses PA fournies par le NREN.


Téléchargez le RFC 7381


L'article seul

RFC 7375: Secure Telephone Identity Threat Model

Date de publication du RFC : Octobre 2014
Auteur(s) du RFC : J. Peterson (NeuStar)
Pour information
Réalisé dans le cadre du groupe de travail IETF stir
Première rédaction de cet article le 26 octobre 2014


Elle est loin, l'époque où l'Internet et le téléphone étaient deux mondes complètement séparés. Aujourd'hui, le téléphone n'est qu'une application parmi toutes celles tournant sur l'Internet. et les problèmes de sécurité du téléphone sont donc des problèmes Internet. D'où ce RFC qui décrit les menaces d'usurpation d'identité qui planent sur la téléphonie sur IP (cf. SIP, RFC 3261).

La plupart des attaques utilisant le téléphone commencent en effet par un mensonge sur le numéro d'appel : l'attaquant va se débrouiller pour présenter un numéro d'appel qui n'est pas le sien. Souvent, en effet, le numéro de l'appelant est utilisé pour mettre en œuvre une politique de sécurité : on décroche parce qu'on connait le numéro, ou bien on prend au sérieux un appel d'urgence parce qu'on sait qu'on pourra retrouver l'éventuel mauvais plaisant via son numéro ou encore on donne accès à un répondeur en n'utilisant pour toute authentification que le numéro d'appel. Bien sûr, quelqu'un qui ne veut pas révéler son numéro peut toujours ne pas le présenter. Mais beaucoup de correspondants ne décrocheront pas s'ils reçoivent un appel sans numéro. C'est pour cela que les spammeurs du téléphone préfèrent présenter un numéro, n'importe lequel. D'où la création du groupe de travail STIR de l'IETF, groupe qui est chargé de travailler sur ce problème (une description du problème figure dans le RFC 7340). Le but de STIR est de faire en sorte que, quand on voit un numéro entrant s'afficher, on soit raisonnablement sûr que ce soit bien un numéro que l'appelant est autorisé à utiliser.

On ne peut pas traiter le problème à la source : l'attaquant contrôle son téléphone et peut lui faire faire ce qu'il veut. Il faut donc traiter le problème dans le réseau téléphonique, ou bien à l'arrivée, et pouvoir distinguer les numéros autorisés des autres. Une fois qu'on aura cette distinction, on pourra appliquer les politiques de sécurité de son choix (par exemple ne pas décrocher si le numéro présenté n'est pas vu comme sérieusement authentifié).

Ce RFC se focalise sur la triche lors de l'appel. Une fois la connexion établie, d'autres attaques sont possibles (écouter le trafic en cours de route, rediriger les paquets IP vers une autre destination ou, tout simplement utiliser les nombreuses possibilités de SIP pour transférer un appel) mais elles nécessitent typiquement plus de moyens que l'usurpation de numéro, qui peut souvent être faite en n'ayant pas d'autres outils que son téléphone.

Autre piège qui n'est pas traité par le groupe STIR : des téléphones ont des fonctions de carnet d'adresses ou d'annuaire et peuvent donc afficher, à la place du numéro d'appel, le nom de la personne appelante. Cela permet d'autres attaques : par exemple, si l'annuaire n'est pas bien sécurisé, on peut imaginer que l'attaquant glisse un nom d'apparence légitime pour son numéro d'appel, et que le destinataire sera alors trompé, sans qu'il y ait eu usurpation de numéro. C'est une vraie possibilité mais elle nécessite des solutions très différentes (sécurisation des carnets d'adresse et des annuaires).

La section 2 de notre RFC décrit les différents acteurs. Il y a les utilisateurs, aux extrêmités, avec leurs téléphones, simples engins sans trop de complications ou au contraire smartphones très riches. Il y a les intermédiaires, par exemple les relais SIP (on ne fait pas de la téléphonie en direct, en général, ne serait-ce que parce que le destinataire n'est pas forcément joignable en ce moment), et il y a les attaquants. Les intermédiaires peuvent modifier les caractéristiques de l'appel en cours de route, par exemple en jetant le numéro d'appel ou en substituant un autre. Ainsi, une passerelle entre la téléphonie IP et le PSTN pourra substituer au numéro indiqué dans un paquet IP son propre numéro, pour une meilleure traçabilité. Quant aux attaquants, on suppose qu'ils ont un téléphone (!) et peuvent passer un appel depuis le lieu de leur choix. Comme indiqué plus haut, ils peuvent indiquer un faux numéro (les téléphones traditionnels ne permettaient pas cela mais c'est possible avec les engins modernes). Pire, ayant accès à l'Internet, on suppose qu'ils peuvent envoyer des paquets IP quelconques, sans passer par un téléphone ou un softphone. Enfin, notre RFC ne prend délibérement pas en compte le risque d'une trahison ou d'un piratage des intermédiaires. Certes, l'attaquant qui contrôlerait les serveurs intermédiaires pourrait faire beaucoup de dégâts mais ce n'est pas ce qui se fait aujourd'hui, dans la grande majorité des cas d'usurpation de numéro.

Après les acteurs, place aux attaques (section 3). L'attaquant peut chercher à usurper un numéro de téléphone donné (par exemple pour se faire passer pour une personne précise) ou bien il peut juste chercher à usurper n'importe quel numéro de téléphone valide (pour ne pas exposer le sien, qui permettrait de remonter jusqu'à lui). Un exemple du premier cas est celui de l'accès à une boîte vocale, lorsque l'authentification se fait uniquement sur la base du numéro présenté. Certes, il serait sans doute préférable d'utiliser (en plus, ou à la place du numéro présenté) une authentification plus forte mais, en pratique, un certain nombre de systèmes n'authentifient qu'avec le numéro appelant, surtout les services commerciaux comme la vidéoconférence où on ne souhaite pas trop embêter le client. Ajouter une authentification par, par exemple, un code numérique à taper, compliquerait les choses pour l'utilisateur. Si le système appelé pouvait savoir si le numéro de téléphone a été correctement authentifié, il pourrait, par exemple, n'imposer la frappe du code numérique que dans le cas où le numéro n'est pas fiable. Comme ces services sont souvent appelés de manière répétitive, on peut aussi compter sur l'historique, par exemple savoir s'il est normal ou pas que tel numéro entrant soit authentifié.

Et le spam, plaie du téléphone comme il l'est du courrier électronique ? Comment empêcher les appels automatiques (robocallers) ? Pour éviter les plaintes, et qu'on remonte jusqu'à eux, les spammeurs ne veulent pas présenter leur vrai numéro. Par exemple, Bouygues Telecom m'appele toujours depuis une ligne qui ne présente pas le numéro d'appelant. Résultat, je ne décroche plus pour de tels appels. Les spammeurs ont donc intérêt à présenter un numéro, mais qui ne soit pas le leur. Leur tâche est donc plus facile que dans le cas précédent, où ils devaient usurper un numéro précis. Par contre, cette fois, l'appelé ne peut pas compter sur l'historique pour évaluer l'appel.

Un des problèmes de l'authentification des appels entrants est le manque de temps. Si c'est une machine qui est appelée (comme dans le cas précédent, celui du répondeur), on peut la faire patienter, le temps qu'on vérifie. Si c'est un humain qu'il faut contacter, c'est plus délicat. Faut-il lui signaler un appel qu'on n'a pas encore eu le temps d'authentifier ? Cette nécessité d'agir en temps réel peut rendre certaines techniques (par exemple de longs calculs cryptographiques) difficiles à faire accepter. Les SMS n'ont pas ce problème : on peut retarder leur distribution sans conséquences sérieuses.

La téléphone connait aussi des attaques par déni de service. Un attaquant peut appeler simplement pour épuiser des ressources limitées, et déguiser alors son numéro pour éviter des représailles (ou tout simplement pour éviter d'être mis en liste noire). Il peut être capable d'utiliser plusieurs fournisseurs et plusieurs téléphones, pour faire une dDoS. Comme le robocaller, l'attaquant qui vise un déni de service n'a pas besoin d'usurper un numéro de téléphone particulier. Tout numéro qui n'est pas le sien conviendra (il voudra probablement le faire varier rapidement, pour éviter les contre-mesures fondées sur des listes noires). Une exception est le cas de l'attaque par réflexion, où l'attaquant veut faire croire à la culpabilité d'un tiers, et usurpe donc le numéro de ce tiers.

Les contre-mesures sont donc les mêmes que pour les appels automatiques des spammeurs : vérifier que les numéros présentés sont des numéros possibles (cela bloque les attaques les moins sophistiquées, celles où l'attaquant met n'importe quoi au hasard), et traiter différemment les appels où on peut être sûr que les numéros sont légitimes (dans le cas d'une attaque, jeter systèmatiquement les numéros non garantis, par exemple). Un tel traitement différencié n'est toutefois pas acceptable pour les appels d'urgence, qui ont l'obligation de répondre à tout.

Et, pour finir le RFC, les scénarios d'attaque possibles (section 4). Si l'attaquant et sa victime (l'appelant et l'appelé) sont tous les deux en SIP, l'attaquant n'a qu'à mettre le numéro qu'il veut dans le champ From: de la requête SIP INVITE. Si les deux sont au contraires connectés au PSTN (la téléphonie traditionnelle), l'attaquant doit avoir le contrôle du PABX qu'utilise son téléphone. Le PABX envoie une requête Q.931 SETUP avec le numéro de son choix qui va se retrouver dans l'appel SS7, champ Calling Party Number. Et si l'attaquant est en IP et la victime sur le PSTN ? Comme dans le premier cas, il met le numéro qu'il veut dans le message SIP et la passerelle IP<->PSTN va le transmettre à l'appelé. Arrivé là, vous vous demandez sans doute quelles sont les solutions possibles à ces attaques, qui semblent si simples à faire ? Mais ce RFC ne fait que l'analyse des menaces, les solutions seront dans des RFC futurs.


Téléchargez le RFC 7375


L'article seul

RFC 7386: JSON Merge Patch

Date de publication du RFC : Octobre 2014
Auteur(s) du RFC : P. Hoffman (VPN Consortium), J. Snell
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 15 octobre 2014


La commande HTTP PATCH permet d'envoyer à un serveur HTTP un document représentant les différences entre l'état d'une ressource sur le serveur et l'état souhaité par le client HTTP. Cette liste de différences peut prendre plusieurs formats et ce RFC en spécifie un nouveau, JSON merge patch, un format de patch conçu pour JSON.

En fait, le format normalisé par ce RFC n'est pas spécifique à HTTP et pourra même servir avec d'autres protocoles. Mais la commande PATCH du RFC 5789 sera sans doute sa principale utilisation. Une ressource au format JSON merge patch est un objet JSON elle-même. Pour chaque clé, si la ressource cible a également cette clé, la valeur est remplacée par celle du patch. Si elle ne l'a pas, on ajoute le couple clé/valeur. Et si la valeur dans le patch est null, on supprime le couple clé/valeur de la ressource cible. Ainsi, si on a ce document JSON sur le serveur :

{
       "a": "b",
       "c": {
         "d": "e",
         "f": "g"
       }
}

et qu'on envoie le patch suivant en HTTP (notez le type MIME de notre nouveau format) :

PATCH /target HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json

{
       "a":"z",
       "c": {
         "f": null
       }
}

On obtiendra :

{
       "a": "z",
       "c": {
         "d": "e"
       }
}

(La valeur de a a été changée, et le couple indexé par c / f a été supprimé.)

Ce format, centré sur le résultat plutôt que sur les opérations, suit donc des principes assez différents de son homologue XML du RFC 5261.

On notera donc que tous les contenus JSON ne sont pas patchables ou, en tout cas, pas de manière propre et facile, avec ce format. Par exemple, si des null sont effectivement utilisés, ou bien si la structure du texte JSON n'est pas celle d'un objet. Mais, bon, ce format est très simple, est lui-même en JSON, et le RFC est très court et facile à comprendre (ce qui n'aurait pas été le cas si on avait voulu tout prévoir), on ne peut pas tout avoir.

La section 2 du RFC précise les règles à suivre lors du traitement des patches. Elle est rédigée en pseudo-code (attention, l'indentation dans le RFC est complètement ratée, cf. l'errata #4132) et est assez simple pour être citée ici :

   define MergePatch(Target, Patch):
     if Patch is an Object:
       if Target is not an Object:
         Target = {} # Ignore the contents and set it to an empty Object
       for each Name/Value pair in Patch:
         if Value is null:
           if Name exists in Target:
             remove the Name/Value pair from Target
         else:
           Target[Name] = MergePatch(Target[Name], Value)
       return Target
     else:
       return Patch

Parmi les points à noter, le fait qu'un patch qui n'est pas un objet JSON (par exemple un tableau) va toujours remplacer l'intégralité de la ressource cible, ou le fait qu'on ne peut pas modifier une partie d'une ressource cible qui n'est pas elle-même un objet (il faut la changer complètement).

Le patch va agir sur les valeurs, pas sur leur représentation. Ainsi, on n'a aucune garantie qu'il préservera l'indentation du texte JSON ou la précision des nombres. De même, si la ressource cible tire profit des faiblesses de la norme JSON, elle peut ne pas sortir intacte : par exemple, si la ressource cible a plusieurs membres qui ont la même clé (ce qui n'est pas formellement interdit en JSON mais donne des résultats imprévisibles).

Un exemple plus détaillé de patch JSON se trouve en section 3. On part de ce document :

{
       "title": "Goodbye!",
       "author" : {
         "givenName" : "John",
         "familyName" : "Doe"
       },
       "tags":[ "example", "sample" ],
       "content": "This will be unchanged"
}

Et on veut changer le titre, ajouter un numéro de téléphone, retirer le nom de famille de l'auteur, et retirer l'élément sample du tableau tags. On envoie cette requête :

PATCH /my/resource HTTP/1.1
Host: example.org
Content-Type: application/merge-patch+json

{
       "title": "Hello!",
       "phoneNumber": "+01-123-456-7890",
       "author": {
         "familyName": null
       },
       "tags": [ "example" ]
}

Et on obtient ce document :

{
       "title": "Hello!",
       "author" : {
         "givenName" : "John"
       },
       "tags": [ "example" ],
       "content": "This will be unchanged",
       "phoneNumber": "+01-123-456-7890"
}

Notez qu'il a fallu remplacer complètement le tableau tags : il n'y a pas de mécanisme pour retirer juste un élément du tableau (comme expliqué au début). Des tas d'exemples figurent dans l'annexe A, si vous voulez écrire une suite de tests.

Le type MIME application/merge-patch+json figure désormais dans le registre IANA (cf. section 4 du RFC), aux côtés de l'équivalent XML décrit dans le RFC 7351, application/xml-patch+xml.


Téléchargez le RFC 7386


L'article seul

RFC 7377: IMAP4 Multimailbox SEARCH Extension

Date de publication du RFC : Octobre 2014
Auteur(s) du RFC : B. Leiba (Huawei Technologies), A. Melnikov (Isode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 14 octobre 2014


Nouvelle extension IMAP normalisée, pour effectuer une recherche dans plusieurs boîtes aux lettres simultanément, avec la nouvelle commande ESEARCH. Proposée initialement par le RFC 6237, à titre expérimental, cette extension accède désormais au statut de norme.

Par défaut, une recherche IMAP (commande SEARCH, RFC 3501, sections 6.4.4 et 7.2.5, puis étendue par les RFC 4466 et RFC 4731) ne cherche que dans la boîte aux lettres courante. Si on n'est pas sûr de la boîte où se trouve le ou les messages intéressants, et qu'on veut chercher dans plusieurs boîtes, la seule solution est de faire une boucle, effectuant séquentiellement des SELECT pour changer de boîte et un SEARCH à chaque fois. Ces commandes ne peuvent pas être exécutées en parallèle car il n'y a pas de moyen de distinguer leurs résultats (les réponses SEARCH n'indiquent pas quelle était la boîte). La nouvelle commande permet au serveur de faire les recherches en parallèle, s'il le peut, et évite des allers-retours entre client et serveur.

Donc, la nouvelle commande ESEARCH (à ne pas confondre avec la capacité ESEARCH du RFC 4731, même si les deux RFC ont des points communs, comme le format des réponses), présentée en section 2. Sa disponibilité est annoncée par la capacité MULTISEARCH dans la bannière du serveur IMAP. (Cette capacité figure dans le registre IANA.) Voici un exemple où on cherche des messages parlant du Tchad dans les boîtes folder1 et celles sous folder2 (C = client, et S serveur IMAP) :

C: mytag ESEARCH IN (mailboxes "folder1" subtree-one "folder2") subject "chad"
S: * ESEARCH (TAG "mytag" MAILBOX "folder1" UIDVALIDITY 1) UID ALL 3001:3004,3788
S: * ESEARCH (TAG "mytag" MAILBOX "folder2/salmon" UIDVALIDITY 1111111) UID ALL 50003,50006,50009,50012
S: mytag OK done

La syntaxe pour indiquer les boîtes aux lettres où on cherche est celle de la section 6 du RFC 5465, avec l'ajout de subtree-one (utilisé ci-dessus pour folder2) qui, contrairement à subtree, s'arrête au premier niveau (donc la boîte folder2/tuna/red ne serait pas cherchée). Avertissement du RFC au programmeur : subtree peut aller très loin (pensez à une hiérarchie de boîte aux lettres mise en œuvre avec un système de fichiers hiérarchiques, et des liens symboliques qui vont se promener ailleurs) et il faut donc prêter attention au risque d'écroulement du serveur. Voir aussi la section 2.4, qui autorise le serveur à refuser les recherches trop gourmandes, avec le code LIMIT du RFC 5530, et la section 5, sur la sécurité, qui note que cette extension multi-boîtes peut être dangereuse pour le serveur. Un client méchant ou maladroit peut demander un gros travail au serveur, avec juste une commande.

Le RFC note que le mot-clé personal est le moyen le plus pratique de fouiller dans toutes les boîtes de l'utilisateur. Si celui-ci désigne au contraire des boîtes par leur nom, et que le serveur gère les ACL du RFC 4314, il faut avoir le droit de lecture sur ces boîtes (et celui de découverte, si les boîtes ne sont pas explicitement nommées, par exemple si on utilise subtree). Pas question de retourner des résultats pour des boîtes que l'utilisateur n'est pas censé lire.

À noter qu'un serveur qui accepte les recherches floues du RFC 6203 peut les accepter également pour les recherches dans des boîtes multiples.

La réponse est décrite dans la section 2.1 : elle consiste en lignes ESEARCH (cf. RFC 4731). Les messages doivent être identifiés par leur UID (RFC 3501, section 2.3.1.1) comme ci-dessus, pas par leurs numéros (qui n'ont de sens que pour une boîte sélectionnée). Le ALL (RFC 4731, section 3.1), indique qu'on retourne la totalité des messages qui correspondent au critère de recherche. Pour le premier dossier, le folder1, ces messages sont ceux d'UID 3001 à 3004 (une séquence, définie dans la section 9 du RFC 3501) et le message d'UID 3788.

La section 3 du RFC donne un exemple plus complexe, avec deux recherches multi-boîtes en parallèle, chacune identifiée par une étiquette différente :

C: tag1 ESEARCH IN (mailboxes "folder1" subtree "folder2") unseen
C: tag2 ESEARCH IN (mailboxes "folder1" subtree-one "folder2") subject "chad"
S: * ESEARCH (TAG "tag1" MAILBOX "folder1" UIDVALIDITY 1) UID ALL 4001,4003,4005,4007,4009
S: * ESEARCH (TAG "tag2" MAILBOX "folder1" UIDVALIDITY 1) UID ALL 3001:3004,3788
S: * ESEARCH (TAG "tag1" MAILBOX "folder2/banana" UIDVALIDITY 503) UID ALL 3002,4004
S: * ESEARCH (TAG "tag1" MAILBOX "folder2/peach" UIDVALIDITY 3) UID ALL 921691
S: tag1 OK done
S: * ESEARCH (TAG "tag2" MAILBOX "folder2/salmon" UIDVALIDITY 1111111) UID ALL 50003,50006,50009,50012
S: tag2 OK done

Des implémentations de cette norme ? Il y en a apparemment une, en logiciel non-libre, chez Oracle. Cette extension semble rare (et cela a été noté dans les débats à l'IETF : méritait-elle vraiment d'avancer sur le chemin des normes ?). J'ai testé quelques serveurs et je n'ai pas vu la capacité MULTISEARCH dans un Zimbra récent, ou dans la version de Courier actuellement chez Debian. Rien non plus dans des services en ligne comme laposte.net ou Gmail.

Depuis le RFC 6237, qui décrivait cette extension pour la première fois, peu de changements, les principaux sont (section 7) :

  • Passage au statut de norme,
  • Recherches floues,
  • Et quelques autres détails.

Téléchargez le RFC 7377


L'article seul

Un nouveau logiciel post-Snowden dans ma logithèque, TextSecure

Première rédaction de cet article le 12 octobre 2014
Dernière mise à jour le 13 octobre 2014


Je suis désormais, comme beaucoup de gens, l'heureux utilisateur de TextSecure qui a complètement remplacé, sur mon smartphone, l'application SMS par défaut.

À quoi sert TextSecure ? C'est un logiciel de messagerie instantanée, conçu pour être très simple d'usage, pour servir de remplaçant « tel quel » aux logiciels SMS actuels, tout en offrant une meilleure protection de la vie privée, dans certains cas. Remplaçant « tel quel », car l'idée de base est que les utilisateurs normaux (le célèbre M. Michu) ne devraient pas avoir à renoncer à quoi que ce soit pour avoir une meilleure sécurité, dans un monde post-Snowden. En effet, M. Michu peut mettre TextSecure, gérer tous ses SMS avec, et il ne verra guère de différence. Contrairement à bien d'autres outils de sécurisation, qui sont, au minimum, moins faciles à utiliser que les outils habituels, au pire, franchement hostiles aux utilisateurs, TextSecure peut être recommandé aux parents, aux ministres, et autres populations non-geeks, sans se dire qu'on leur joue un mauvais tour. Sans doute n'offre-t-il pas de sécurité en béton, mais il ne fait rien perdre à l'utilisateur non plus. On peut résumer TextSecure en disant qu'il offre un très bon compromis entre facilité d'usage et sécurité.

Bon, qu'est-ce que voit l'utilisateur, avec TextSecure ? Justement, rien de particulier : il s'en sert comme de l'outil SMS par défaut. Le principal changement est que certains messages vont être marqués d'un joli cadenas : si le correspondant utilise également TextSecure, les messages sont chiffrés automatiquement avec sa clé. Si on est simple utilisateur, on a donc un peu plus de vie privée, et on en aura de plus en plus au fur et à mesure que TextSecure se répand.

TextSecure peut utiliser deux transports différents (mais on peut débrayer l'un ou l'autre), le SMS et la liaison « données » du smartphone (ce second transport se nomme PUSH dans la terminologie TextSecure, et est utilisé par défaut pour les correspondants qui ont également TextSecure). Le mode PUSH peut être intéressant si on a un quota SMS limité mais pas en Internet, et le mode SMS dans le cas contraire. Les messages apparaissent en vert traditionnel quand ils ont été transportés en SMS et en bleu autrement (curieux choix de couleur : les messages en vert ne sont pas forcément les plus sûrs, puisqu'ils ne sont en général pas chiffrés, c'est peut-être une copie aveugle de ce que fait Apple, suggère Jean Champémont).

TextSecure peut aussi chiffrer toute la base des SMS reçus et stockés. Ainsi, même si on vole votre téléphone, vos communications resteront sûres. Attention : si vous oubliez la phrase de passe, tout est fichu. Pensez à sauvegarder.

Si maintenant on est un utilisateur pas simple, qui veut savoir comment ça marche, on se pose quelques questions. Voici celles que je me posais et les réponses que j'ai pu trouver. Notez que la société qui développe TextSecure, OpenWhisper, a aussi une bonne FAQ.

D'abord, on a dit que TextSecure trouvait automatiquement les contacts de l'utilisateur qui étaient également utilisateurs de TextSecure. Ouh là là, se dit le paranoïaque moyen, c'est pas bon pour la vie privée. Comment il fait ? Il envoie tout mon carnet d'adresses à la société qui gère TextSecure, pour comparaison ? Cela serait catastrophique pour la sécurité. Le problème est difficile : si on veut de la sécurité maximale, il faudrait envoyer zéro bit d'information à l'extérieur. Mais le cahier des charges de TextSecure n'est pas « la sécurité maximale et rien d'autre », c'est « la meilleure sécurité du monde ne sert à rien si elle n'est pas déployée, car trop complexe ou trop pénible ». Pas question, donc, de se passer d'un système de découverte automatique. Il existe des algorithmes complexes et très astucieux (décrits dans ce remarquable article), mais le problème reste largement ouvert.

L'expert en sécurité qui sommeille dans chacun de mes lecteurs a déjà compris que les métadonnées de la communication, elles, sont en clair et que des tiers peuvent donc savoir qui écrit à qui et quand, même si le contenu des messages est chiffré. Comme le note Alda Marteau-Hardi « les metadata sont connues d'OpenWhisper [si on utilise PUSH] ou de ton opérateur mobile [si on utilise le SMS traditionnel], au final ».

Au fait, toujours si je suis expert en sécurité paranoïaque, pourquoi ferais-je confiance à OpenWhisper plus qu'à la NSA ou à Orange ? La principale raison est que TextSecure est un logiciel libre : le code est disponible, et des experts en sécurité l'ont déjà lu et personne n'a encore trouvé de défaut significatif. Notez que le code du serveur utilisé par OpenWhisper est également disponible en ligne mais c'est moins utile puisque, de toute façon, on ne peut pas vérifier que le serveur effectif exécute bien ce code.

Et si je lis dix RFC le matin avant mon petit déjeuner et que je veux connaître le protocole exact utilisé ? Pas de problème, ce protocole est documenté.

OK, mais il reste le gros problème de la cryptographie, authentifier le type en face. C'est bien joli de tout chiffrer mais, si Alice croit parler à Bob alors qu'elle parle en fait à Mallory, le chiffrement ne sert pas à grand'chose. Comment TextSecure traite-t-il ce problème ? À la première communication, TextSecure fait confiance. C'est risqué, si un Homme du Milieu se trouvait là, mais ce système, dit TOFU (Trust On First Use) a l'avantage d'être trivial d'utilisation. Il correspond donc bien au cahier des charges de TextSecure, qui veut que le logiciel soit effectivement utilisé et, pour cela, qu'il ne rebute pas ses utilisateurs. Ce modèle est également utilisé par SSH et, comme le note le RFC 5218, est une des principales causes de son succès. Je n'ai pas encore testé ce qui se passait si le correspondant réinitialise sa clé mais, d'après la documentation, TextSecure vous prévient (puisque cela peut indiquer une attaque de l'Homme du Milieu).

Si on veut, on peut toujours vérifier, lors d'une rencontre AFK, la clé de son correspondant, soit en la lisant à l'écran (la mienne est BdY73Lfk12kv9iTVUTGIL6VZrpbg+6V1q+ZsZMrpu2p3 en Base64 ou bien 05 d6 3b dc b7 e4 d7 69 2f f6 24 d5 51 31 88 2f a5 59 ae 96 e0 fb a5 75 ab e6 6c 64 ca e9 bb 6a 77 en suite de chiffres hexadécimaux), soit via des codes QR. Voici d'ailleurs le mien :

Comme beaucoup de points de TextSecure, c'est bien documenté en ligne. Mais, et c'est à mon avis une des plus grosses faiblesses de TextSecure, je n'ai trouvé aucun moyen d'enregistrer le fait qu'on a vérifié, afin, par exemple, d'afficher les messages ultérieurs d'une couleur différente si le correspondant a ainsi été solidement authentifié. (La question est discutée dans la bogue #314.)

X_cli (qui met aussi son code QR TextSecure sur sa page d'accueil) m'a suggéré une technique rigolote et, à ma connaissance, jamais utilisée : mettre la clé TextSecure dans une identité PGP, que les gens qui ont vérifié pourront signer. C'est fait pour ma clé CCC66677 :

% gpg --list-keys CCC66677
...
uid  TextSecure fingerprint (05 d6 3b dc b7 e4 d7 69 2f f6 24 d5 51 31 88 2f a5 59 ae 96 e0 \
                 fb a5 75 ab e6 6c 64 ca e9 bb 6a 77) \
                 <BdY73Lfk12kv9iTVUTGIL6VZrpbg+6V1q+ZsZMrpu2p3@base64>
...

Au passage, pour exporter la clé publique, le plus simple est d'afficher le code QR, de partager par courrier électronique, et le message contient la clé en Base64. Si on la veut en liste de chiffres hexadécimaux, on peut se servir de ce petit script Python base64-to-hexas.py.

Autre défaut, et une exception à la règle comme quoi installer TextSecure ne fait rien perdre par rapport à l'application par défaut, envoyer un message à plusieurs personnes n'est pas possible simplement (il faut d'abord créer un groupe statique). Il y a également un intéressant article sur les groupes.

À noter qu'il existe des logiciels concurrents. Le plus proche me semble être Telegram. Une discussion de comparaison entre TextSecure et Telegram a eu lieu sur Ycombinator.

Merci à Amaelle Guiton et Adrienne Charmet pour avoir servi de cobayes et pour les intéressantes discussions.


L'article seul

RFC 7365: Framework for Data Center (DC) Network Virtualization

Date de publication du RFC : Octobre 2014
Auteur(s) du RFC : Marc Lasserre, Florin Balus (Alcatel-Lucent), Thomas Morin (France Telecom Orange), Nabil Bitar (Verizon), Yakov Rekhter (Juniper)
Pour information
Réalisé dans le cadre du groupe de travail IETF nvo3
Première rédaction de cet article le 11 octobre 2014


Ce nouveau RFC décrit le cadre général de la virtualisation de réseaux en utilisant IP comme substrat. Il est issu du projet NVO3 de l'IETF, qui a produit une description du problème (dans le RFC 7364) et ce document. À ce stade, ce n'est pas encore un protocole concret, même s'il existe déjà des solutions techniques partielles pour ce problème.

La cible est constituée des grands centres de données, hébergeant des centaines de milliers de machines virtuelles, et qu'on souhaite pouvoir gérer de manière souple (par exemple en déplaçant facilement une machine virtuelle d'une machine physique à une autre, sans l'éteindre et sans la changer d'adresse IP). Le RFC 7364 décrit plus en détail le problème à résoudre (et il est donc recommandé de le lire d'abord), ce RFC 7365 étant le cadre de(s) la(les) solution(s). Comme on envisage des grands ensembles de machines, et qu'on cherche à être très dynamique (reconfigurations fréquentes), il faudra beaucoup d'automatisation (pas question de modifier des tables à la main parce qu'une machine s'est déplacée).

Il définit donc un vocabulaire et un modèle pour ces réseaux virtuels. Donc, on parle de réseaux NVO3 (NVO3 networks). Il s'agit de créer des réseaux virtuels (VN pour virtual networks, ou bien overlays) fonctionnant au-dessus d'un protocole de couche 3, IP. Ces réseaux virtuels fournissent aux clients (qui peuvent appartenir à des organisations distinctes, voire concurrentes) soit un service de couche 3, soit un service de couche 2 . Les réseaux virtuels sont créés au-dessus d'un substrat, l'underlay, qui est le « vrai » réseau sous-jacent. Le substrat est toujours de couche 3, comme le nom du projet NVO3 l'indique. Chaque VN aura un contexte, un identificateur qui figurera dans les paquets encapsulés et qui permettra à l'arrivée de distribuer le paquet au bon VN. Le réseau NVO3 utilisera des NVE (Network Virtualization Edge) qui seront les entités qui mettent en œuvre ce qui est nécessaire pour la virtualisation. Un NVE a au moins une patte vers le client (qui envoie des paquets sans savoir qu'il y a virtualisation) et une autre vers le réseau IP qui transporte le trafic entre les NVE. Un NVE n'est pas forcément un équipement physique, cela peut être, par exemple, le commutateur virtuel d'un hyperviseur.

Les sections 2 et 3 présentent le modèle de référence utilisant ce vocabulaire, et ses composants. Les systèmes des clients (tenant systems) sont connectés aux NVE, via un VAP (virtual access point, qui peut être une prise physique ou bien virtuelle, par exemple un VLAN ID). Un même NVE peut présenter aux clients plusieurs VNI (virtual network instance, une instance particulière de réseau virtuel). NVE et système du client peuvent être physiquement dans la même boîte, ou bien il peut s'agir de systèmes distants (le schéma 2 du RFC n'est pas une représentation physique, mais logique). Dans le premier cas, la communication de l'information peut se faire par une API locale, dans le second, par un protocole réseau. Les NVE échangent l'information entre eux (comme des routeurs avec un IGP) ou bien ils sont connectés à une NVA (Network Virtualization Authority) qui leur fournit les informations sur l'état du réseau (qui est membre, comment joindre les membres, etc). Il y aura donc un protocole entre NVE, ou bien entre NVE et NVA. Le NVA n'est évidemment pas forcément un serveur unique, cela peut être une grappe, pour la redondance. Les machines qui forment l'underlay font du routage IP normal et ne connaissent pas, a priori, les systèmes des clients. La gestion de ce réseau underlay se fait avec les mêmes outils OAM que n'importe quel réseau IP.

Le réseau virtuel (l'overlay) devra donc utiliser une forme ou l'autre d'encapsulation pour faire passer ses paquets sur l'underlay. Cela pourra être GRE, IPsec, L2TP, etc. Ce n'est pas tout de tunneler, il faut aussi un mécanisme de contrôle, rassemblant et distribuant l'information dans le réseau. Un tel mécanisme peut être centralisé (comme dans le cas de SDN) ou réparti (comme l'est traditionnellement le routage dans l'Internet).

Quant un NVE fournit un service de couche 2, les systèmes des clients ont l'impression de se connecter à un Ethernet normal (comme avec le RFC 4761 ou le RFC 4762). S'il fournit un service de couche 3, les systèmes des clients voient un réseau IP, comme avec le RFC 4364.

Autre service important, la possibilité de déplacer des VM à l'intérieur du centre de données. Permettre des déplacements à chaud, sans arrêter la VM, est évidemment très souhaitable, mais cela aura des conséquences sur des points comme les caches ARP (qu'il faut mettre à jour si une VM se déplace, alors qu'elle pense rester dans le même réseau de niveau 2).

La section 4 du RFC décrit quelques aspects essentiels dans les discussions sur les réseaux virtuels. D'abord, les avantages et inconvénients des réseaux virtuels. Sur le papier, ils offrent des tas d'avantages : les systèmes des clients n'ont à s'occuper de rien, ils bénéficient d'un réseau certes virtuel mais qui a les mêmes propriétés qu'un vrai, tout en étant plus souple, avec des changements plus rapides. Même les adresses (MAC et IP) sont séparées de celles de l'underlay donc les clients sont isolés les uns des autres. Malheureusement, il y a quelques problèmes en pratique : pas de contrôle sur le réseau sous-jacent et même pas d'information sur lui, par exemple sur son utilisation, ou sur des caractéristiques comme le taux de perte de paquets (RFC 2680). Il y a donc un risque de mauvaise utilisation des ressources réseaux. Et si plusieurs overlays partagent le même underlay, l'absence de coordination entre les réseaux virtuels, chacun ayant l'impression qu'il est tout seul (« each overlay is selfish by nature »), peut encore aggraver les choses. Mais, bon, des réseaux virtuels existent depuis de nombreuses années, et marchent.

Autre exemple, parmi ceux cités par le RFC, des difficultés à réaliser proprement ce projet, le cas de la diffusion. On veut pouvoir fournir des services qui existent sur les réseaux physiques, comme la capacité à diffuser à tous les membres du réseau, avec un seul paquet. Comment fournir le même service avec des réseaux virtuels ? Il va falloir automatiquement répliquer le paquet pour le transmettre ensuite à tous les réseaux physiques qui contribuent au réseau virtuel. Cela peut se faire de manière violente (dupliquer le paquet en autant d'exemplaires qu'il y a de machines et le transmettre à chacune en unicast) ou bien de manière plus subtile mais plus complexe avec le multicast. La première solution minimise l'état à conserver dans les routeurs, la seconde minimise la capacité réseau consommée.

La mise en œuvre concrète de la virtualisation va nécessiter des tunnels, connectant les différents réseaux physiques. Qui dit tunnel dit problèmes de MTU, en raison des octets consommés par les en-têtes du format de tunnel utilisé. Ces quelques octets en plus diminuent la MTU du réseau virtuel. En théorie, la fragmentation résout le problème mais elle a un prix élevé en performances (idem si fragmentation et réassemblage étaient faits dans le système de virtualisation et non pas, comme la fragmentation IP habituelle, par les machines terminales et - en IPv4 - les routeurs). La découverte de la MTU du chemin (RFC 1981 et RFC 4821) permet de se passer de fragmentation mais, en pratique, elle marche souvent mal. Il semble que la meilleure solution soit de faire en sorte que le réseau virtuel présente une MTU « habituelle » (1 500 octets, la MTU d'Ethernet) et, pour réaliser cela, que la MTU de l'underlay soit assez grande pour que les octets de l'encapsulation puissent être ajoutés sans problèmes (utilisation de jumbogrammes).

Enfin, les réseaux virtuels posent des problèmes de sécurité spécifiques (section 5). Un système client ne doit pas pouvoir attaquer le réseau sous-jacent (il ne doit même pas le voir), et un système client ne doit pas pouvoir attaquer un autre système client (par exemple, s'ils sont dans des réseaux virtuels séparés, il ne doit pas pouvoir lui envoyer directement de paquet, même si les deux systèmes clients se trouvent être sur la même machine physique).

Du point de vue du client, le critère est la capacité du réseau NVO3 à distribuer son trafic au bon endroit, et à séparer les trafics. Un tcpdump chez un client ne doit pas montrer les paquets d'un réseau virtuel d'un autre client (ce qui ne dispense évidemment pas d'utiliser le chiffrement, pour les attaques effectuées par le réseau sous-jacent). Et les machines doivent pouvoir faire confiance au VNI (identificateur du réseau virtuel) indiqué dans un paquet. Comme avec le RFC 2827, une machine client ne doit pas pouvoir injecter des paquets mentant sur le réseau virtuel auquel elle appartient.

Des futurs protocoles conformes à ce schéma sont en cours d'examen dans le groupe de travail, mais qui seront en concurrence avec des protocoles déjà existants qui ont les mêmes objectifs, comme celui du RFC 4364.

Merci à Thomas Morin et Marc Lasserre pour leur relecture.


Téléchargez le RFC 7365


L'article seul

RFC 7364: Problem Statement: Overlays for Network Virtualization

Date de publication du RFC : Octobre 2014
Auteur(s) du RFC : T. Narten (IBM), E. Gray (Ericsson), D. Black (EMC), L. Fang, L. Kreeger (Cisco), M. Napierala (AT&T)
Pour information
Réalisé dans le cadre du groupe de travail IETF nvo3
Première rédaction de cet article le 11 octobre 2014


En informatique, depuis les débuts des temps, on a de plus en plus virtualisé. Le processeur, puis la mémoire, puis des machines entières. Désormais, il est donc logique qu'on cherche à virtualiser le réseau. Par exemple, est-il possible de fournir, dans un centre d'hébergement de données, plusieurs centres de données virtuels, chacun complètement isolé des autres, et permettant de déployer, non pas une seule machine mais tout un réseau ? Il n'y a pas encore de solution technique complète pour ce problème mais ce RFC fournit au moins une description détaillée du problème.

Les organisations qui géreront ces centres de données virtuels seront distinctes, peut-être concurrentes. Il est donc essentiel que les différents réseaux soient parfaitement isolés les uns des autres, avec des espaces d'adressage distincts et des communications uniquement faites de manière explicite (comme s'ils étaient deux réseaux physiques connectés par un routeur). Pas question, par exemple, qu'une de ces organisations puisse sniffer le trafic d'une autre.

Le but est de gagner en souplesse d'administration. Installer un « data center » coûte cher, prend du temps, et l'infrastructure physique ne peut pas être facilement modifiée ensuite. En virtualisant tout, on pourrait imaginer que le gérant du centre de données physique loue des centres de données virtuels à différents acteurs, qui à leur tour loueront des services hébergés dans ces centres virtuels. On aura ainsi du virtuel sur du virtuel sur...

Si la virtualisation est bien faite, le locataire n'aura même pas besoin de savoir quelle est la technique sous-jacente utilisée.

Bon, c'est très joli, comme projet, mais est-ce réaliste ? Notre RFC se concentre sur la première étape, cerner le problème et poser les questions auxquelles il va falloir répondre. C'est le rôle du groupe de travail IETF nommé NVO3, et ce RFC, avec le RFC 7365, est sa première publication. Le chiffre 3 dans le nom fait référence au fait que le groupe se concentre sur les solutions de virtualisation mises en œuvre dans la couche 3 (que ces solutions fournissent un service de couche 3 ou de couche 2). Un autre document, le RFC 7365, spécifie notamment le vocabulaire utilisé. Notre RFC y ajoute le concept de réseau supérieur (overlay network), qui désigne le réseau virtuel bâti au-dessus du réseau physique. Un exemple réalisé dans la couche 2 est 802.1Q qui fait de l'encapsulation de trames de niveau 2 dans d'autres trames.

Donc, quels sont les problèmes à résoudre, se demande la section 3 de notre RFC ? On s'attend à pouvoir déplacer les machines virtuelles d'un serveur à l'autre. En cas de virtualisation du réseau lui-même, cette mobilité doit être possible sans tenir compte de la position physique des serveurs. La machine virtuelle doit pouvoir garder son adresse IP (sinon, cela casserait les sessions TCP en cours, sans parler de la nécessité de mettre à jour le DNS, et autres informations), mais aussi son adresse MAC. En effet, des licences logicielles peuvent être liées à cette adresse MAC. En outre, d'autres perturbations pourraient surgir (système d'exploitation qui ne gère pas correctement un changement d'adresse MAC qu'il n'a pas décidé lui-même).

Dans le centre de données classique, l'adresse IP d'un serveur dépend de sa position. Par exemple, si on a un sous-réseau (et donc un routeur) pour une rangée d'armoires, préserver l'adresse IP impose de ne pas changer de rangée. Ce n'est pas une contrainte trop grave pour un serveur physique, qu'on déplace rarement. Mais ce serait très pénible pour des machines virtuelles, dont l'intérêt est justement la souplesse de placement.

Pour permettre un placement des machines à n'importe quel endroit, il est tentant d'avoir un réseau complètement plat, sans routeurs intermédiaires, ou bien en annonçant des routes spécifiques à une machine (/32 en IPv4) dans l'IGP. Mais cette absence de partitionnement, jointe à l'augmentation du nombre de machines que permet la virtualisation, met une sacrée contrainte sur les tables qu'utilisent les machines pour stocker les coordonnées de leurs voisins (ARP ou NDP en couche 2, l'IGP en couche 3). En couche 2, au lieu de stocker les adresses MAC de ses quelques voisines physiques, une machine devra stocker les milliers d'adresses MAC des machines virtuelles « voisines ». Sans compter le trafic ARP que cela représentera (cd. RFC 6820 ; un million de machines généreront plus de 468 240 ARP par seconde soit l'équivalent de 239 Mb/s).

L'exigence de souplesse et d'agilité, afin de permettre l'utilisation optimale du matériel, nécessite de séparer la configuration du réseau physique et celle du réseau logique. Le RFC donne l'exemple d'un centre de données virtuel qui serait mis en œuvre sur un petit groupe de machines physiques proches. Puis le client veut agrandir son centre et il n'y a pas de place aux alentours, on doit donc lui allouer des machines physiques situées relativement loin dans le centre physique. Cela doit pouvoir marcher, indépendamment du fait que le centre de données du client est désormais réparti en deux endroits.

Autre exigence, que les adresses utilisées sur un centre de données virtuel ne dépendent pas de celles utilisées sur un autre centre virtuel présent sur la même infrastructure physique. Dit autrement, deux clients doivent pouvoir numéroter leurs centres comme ils veulent, sans se coordonner entre eux, et sans tenir compte du plan d'adressage du réseau physique sous-jacent.

Ces exigences sont fort ambitieuses, surtout si on les combine avec la demande que la transmission des paquets suive un chemin optimal. Car la virtualisation, celle du réseau comme celle d'autres ressources, a toujours un coût en termes de performance. Par exemple, lorsqu'une machine virtuelle change de place, le meilleur routeur par défaut peut être différent, alors que cette machine n'est pas consciente de son déplacement et de la nécessité de changer. Autant que possible, l'infrastructure sous-jacente devrait faire cela pour elle. Et encore, un routeur IP classique ne garde pas d'état. Mais s'il y avait des middleboxes à état sur le trajet, comme des pare-feux ?

Pour résumer les services attendus du système de virtualisation : fournir un espace d'adressage isolé, et séparer les paquets de ceux des autres clients (on ne veut pas qu'un tcpdump sur une machine virtuelle montre les paquets d'un autre client). La section 4 décrit la classe de solutions envisagée, celle des réseaux virtuels bâtis au-dessus (d'où le terme d'overlay) des réseaux physiques. Chaque réseau virtuel (pour le centre de données virtuel d'un client) serait un réseau supérieur. Lorsqu'un paquet doit être transmis, il sera encapsulé et voyagera dans un tunnel à l'extrémité duquel il sera décapsulé (technique dit map and encap). Le point d'entrée du tunnel devra faire l'opération de recherche de correspondance (map), indiquant, pour une adresse de destination donnée, quel sera le point de sortie du tunnel. Ce point d'entrée encapsulera ensuite (encap) en mettant en adresse de destination de l'en-tête externe, l'adresse du point de sortie du tunnel. Comme le groupe de travail NVO3 ne considère que les réseaux virtuels mis en œuvre sur la couche 3, les adresses externes (celles de l'en-tête externe du paquet) seront forcément des adresses IP. Les adresses internes (celles du paquet avant encapsulation, ou après décapsulation) peuvent être de couche 2 ou de couche 3.

Il faudra aussi, dans bien des cas, connecter le réseau virtuel à l'extérieur (notamment à l'Internet). Cela nécessitera un routeur connecté à l'extérieur qui, après la décapsulation, transmettra le paquet par les procédés habituels (transmission IP normale, dans le cas d'une connexion à l'Internet). Même chose pour connecter deux réseaux virtuels entre eux. Si ces réseaux fournissent un service de couche 3, c'est de l'interconnexion IP classique, via un routeur.

D'un point de vue plus quantitatif, le RFC note (section 4.4) que ce système de réseaux virtuels devra fonctionner dans un environnement de grande taille (des milliers de commutateurs et des dizaines, voire des centaines de milliers de machines virtuelles) et devra donc bien passer à l'échelle. De plus, le réseau virtuel pourra être très dispersé au sein du réseau physique, avec ses fonctions mises en œuvre sur des tas de machines physiques relativement éloignées, qui travailleront aussi pour beaucoup d'autres réseaux virtuels. Le tout sera sans doute très mouvant (un des buts de la virtualisation est la souplesse, la capacité à changer souvent).

Dans le futur, on construira peut-être des centres de données physiques prévus depuis le début uniquement pour héberger des réseaux virtuels et conçus donc à cet effet. Mais, pour l'instant, ce n'est pas le cas et le RFC demande donc aussi que les solutions de virtualisation soient déployables de manière incrémentale, sans exiger une refonte complète de tout le réseau. Ainsi, les routeurs IP qui sont sur le trajet d'un tunnel ne devraient pas avoir à en être conscients. Pour eux, les paquets du tunnel sont des paquets IP comme les autres. De même, le multicast ne devrait pas être obligatoire (car il est peu déployé).

Le cahier des charges est donc gratiné. Heureusement, il n'est pas prévu que le réseau physique sous-jacent s'étende à tout l'Internet. On parle ici de virtualiser un centre de données, placé sous une administration unique.

Néanmoins, la réalisation de cette vision grandiose va nécessiter du travail. Le RFC envisage deux secteurs de travail : celui du contrôle et celui des données. Pour le contrôle, il faudra trouver des mécanismes efficaces pour créer, gérer et distribuer les tables de correspondance (celles qui permettent au point d'entrée de tunnel de trouver le point de sortie). Cela fera peut-être l'objet d'un tout nouveau protocole. Ce mécanisme devra permettre l'arrivée et le départ d'une machine virtuelle dans le réseau supérieur en mettant à jour ces tables rapidement et efficacement.

Pour les données, il existe déjà pas mal de formats d'encapsulation et, ici, il serait sans doute mieux de les réutiliser. Le RFC décourage donc ceux qui voudraient inventer encore un nouveau format.

La section 5 est justement consacrée aux systèmes existants et qui pourraient fournir des idées, voire des réalisations déjà opérationnelles. D'abord, on peut se servir de BGP et MPLS pour faire des réseaux virtuels IP, le RFC 4364 décrit comment. Cette solution est déjà déployée en production. Sa principale limite, selon notre RFC, est le manque de compétences BGP disponibles, alors que cette solution nécessite du BGP partout. Les mêmes protocoles permettent de faire des réseaux virtuels Ethernet (RFC en cours d'écriture).

Bon, alors, autre solution, utiliser les VLAN de 802.1. Ils fournissent une virtualisation en couche 2 en présentant plusieurs réseaux Ethernet virtuels sur un seul réseau physique. Mais ils ne reposent pas sur IP donc ne sont pas utilisables si on a, par exemple, un équipement comme un routeur sur le trajet. À l'origine, on était limité à 4 096 réseaux différents sur un seul réseau physique, mais cette limite est passée à 16 millions depuis IEEE 802.1aq.

Cette dernière technique, également nommée SPB, utilise IS-IS pour construire ses réseaux virtuels.

Et TRILL ? Il utilise lui aussi IS-IS pour fournir des réseaux de couche 2 différents. En France, cette technique est par exemple déployée chez Gandi.

Plus exotique est le cas de LISP (RFC 6830). Son but principal n'est pas de virtualiser le data center mais il pourrait contribuer, puisqu'il fournit des réseaux virtuels IP au-dessus d'IP (donc, service de couche 3, mis en œuvre avec la couche 3).

Enfin, bien que non cité par le RFC, il faudrait peut-être mentionner VXLAN, bien décrit en français par Vincent Bernat et en anglais par le Network Plumber.

À noter qu'un groupe de travail de l'IETF, ARMD, avait travaillé sur un problème proche, celui posé par la résolution d'adresses IP en adresses MAC (avec ARP ou NDP) dans les très grands centres de données où tout le monde était sur le même réseau de couche 2. Le résultat de leurs travaux avait été documenté dans le RFC 6820.

En résumé, notre RFC conclut (section 6) que le problème est complexe et va nécessiter encore du travail...

Merci à Nicolas Chipaux et Ahmed Amamou pour leur relecture.


Téléchargez le RFC 7364


L'article seul

Mon glossaire en informatique pour ce blog

Première rédaction de cet article le 7 octobre 2014


Ce blog comprend un certain nombre d'articles techniques en français sur l'informatique. J'essaie d'utiliser moins de mots anglais que la moyenne des informaticiens. Résultat, dans ce domaine où le vocabulaire est très anglicisé, des termes français perturbent les francophones, qui ne les comprennent pas car ils ne sont pas largement répandus. D'où une liste partielle des termes les moins classiques.

Mais d'abord, les principes que j'essaie de suivre dans l'écriture de ces articles :

  • Quand l'article est en français (une minorité est en anglais), l'écrire en français correct. Cela veut dire pas trop de fautes de grammaire ou d'orthographe mais également pas de mots en anglais s'il existe un meilleur terme en français. Utiliser un terme en anglais est souvent un signe de paresse (ce qui peut être une bonne idée) ou de non-compréhension (ce qui est plus grave).
  • Ne pas refuser par principe tout terme anglais. Le français, comme toutes les langues, récolte de temps en temps des termes étrangers et il serait ridicule de vouloir figer la langue dans un état donné. Dans la technique, le vocabulaire est en général défini par ceux qui inventent et maîtrisent la technique, comme l'a bien montré Pol Corvez à propos du vocabulaire de la marine.
  • S'agissant de l'anglais, une difficulté supplémentaire est que bien des mots anglais viennent du français, ont franchi la Manche avec Guillaume le Conquérant et nous reviennent aujourd'hui à travers l'Atlantique. C'est le cas de termes comme challenge comme le note Henriette Walter dans son excellent livre.
  • Je ne privilégie pas forcément les traductions officielles (celles qui sont publiées au Journal Officiel et qui doivent obligatoirement être employées par l'administration française, dont ce blog ne dépend heureusement pas). La plupart du temps, elles sont élaborées en comité fermé, sans tenir aucun compte des usages existants, et sans même comprendre le concept traduit. Ceux et celles qui cherchent ces termes officiels peuvent consulter FranceTerme. Ceux qui préfèrent suivre l'usage peuvent suivre Wikipédia mais cette encyclopédie utilise en général davantage de termes français que l'usage courant, surtout dans le langage parlé. (Il y a aussi le Bitoduc.)

Alors, embarquons-nous maintenant pour un pot-pourri de termes divers que j'ai eu besoin de citer dans mes articles. D'abord, un des plus difficiles, socket. Il y a eu des tentatives humoristiques de traduction (chaussette...) mais puisqu'une socket sert à se brancher sur le réseau, je préfère dire prise (c'est l'équivalent d'une prise électrique, mais pour le logiciel). Je n'ai jamais vu personne utiliser le « connecteur logiciel » officiel.

Et le très fréquent buffer ? Là aussi, j'ai vu des traductions amusantes qui essayaient de coller au mot anglais comme buffet (c'est vrai qu'on stocke des choses dans un buffet...) mais je préfère tampon (qui est aussi le terme officiel). Au lieu de mettre les données dans le buffet, je les tamponne.

Et le cache ? Je ne le traduis pas car je n'ai pas trouvé de bon terme (le terme officiel, antémémoire, est bien trop restrictif, le concept de cache en informatique est bien plus riche que celui d'antémémoire puisqu'on trouve par exemple des serveurs cache pour le Web). Mais comme le mot cache en français a un autre sens, cela peut faire des phrases très bizarres, comme « pour mieux accéder à la ressource, on la cache » ou « on la met dans une cache à proximité »...

Et le très répandu (le mot et la chose...) bug ? J'utilise bogue, le terme officiel, qui évoque les piquants de la châtaigne, et qui permet de les chasser avec un débogueur. Mais j'avais un professeur d'informatique qui appelait le défaut une bourde et gdb un débourdeur, termes qui fleuraient bon le terroir.

Terme plus rare mais qui était aussi difficile à traduire, le nonce (au fait, l'article du Wikipédia anglophone le réduit à un usage dans la cryptographie alors qu'il est courant dans les protocoles réseau, même quand il n'y a pas de cryptographie du tout). Utiliser le terme anglais entraîne des risques de confusion avec l'ambassadeur du pape. Il n'y a pas de traduction officielle. Cela a été un long débat, documenté dans un autre article, avant que je ne choisisse numnique.

Passons maintenant au streaming. La quantité énorme d'octets qui sont poussés chaque jour vers les temps de cerveau disponibles, grâce à cette technique, nécessite un terme. C'est la diffusion en flux pour le Journal Officiel, terme qui me semble bien lourd. Ou bien parler de « flux temps réel » ? Comme le terme anglais est construit pour évoquer la rivière, on pourrait parler de rivièrage ? De ruissellement (« Tu regardes YouTube sur ta Freebox en ruissellement ») ? Ou, toujours en filant la métaphore aquatique, de diffusion en flot ? en courant ? Je ne me suis pas vraiment décidé.

Le nom stream pose d'ailleurs les mêmes problèmes. La norme HTTP 2 (dérivée de SPDY) avance sérieusement et, quand je ferai l'article sur le RFC HTTP 2, comment je traduirai stream, un concept très important pour ce protocole ?

Et le flow, concept très utilisé dans les réseaux (rien à voir avec le streaming, traité plus haut), par exemple dans les protocoles comme IPFIX (RFC 3917) ? J'utilise en général flot dans le contexte de l'analyse du trafic réseau (cas d'IPFIX). Mais flux pourrait également convenir. Sauf que je l'utilise pour le terme suivant.

Toujours dans les choses qui coulent d'un point à un autre, les feeds de syndication. Je dis flux, qui est également le terme officiel, et apparemment le plus utilisé en pratique.

Passons au monde du routage maintenant. L'anglais a deux termes, routing, qui désigne la construction des tables de routage par les routeurs (on dit aussi control), et forwarding, qui est le passage d'un paquet d'un routeur à un autre, en suivant les tables de routage. En français, routing se traduit bien par routage mais forwarding n'a pas de traduction équivalente. Je propose simplement transmission.

Une des raisons pour lesquelles l'usage abusif de l'anglais me hérisse, c'est que c'est souvent le résultat d'une incompréhension. La proximité même des deux langues fait que les faux amis sont nombreux, et on voit souvent des gens utiliser un terme anglais (pourquoi pas) à contre-sens (c'est déjà plus embêtant). Un exemple fameux est le logiciel malveillant stupidement traduit par « logiciel malicieux », ce qui n'a rien à voir. Un autre exemple est regular expression traduit par « expression régulière » (elles n'ont rien de régulier, ces expression rationnelles). Attention donc à la paresse, elle peut cacher une absence de compréhension du concept.

Passons maintenant à un autre terme difficile : hash (et hashing), à savoir le résultat d'une fonction qui va produire une chaîne de bits, souvent de longueur constante mais surtout de taille réduite, donc plus facile à manipuler (notamment à signer), à partir d'un texte de longueur quelconque. Pour une fois, la traduction officielle et l'usage coïncident pour parler de hachage (pour traduire hashing ; je ne trouve pas de traduction officielle pour le hash, le résultat du hachage). Je n'aime guère ce terme qui donne l'impression que le résultat est une purée quelconque, ce qui fait perdre la principale caractéristiques des fonctions de « hachage », leur reproductibilité. Je préfère donc parler de condensation, ce qui a l'avantage de donner des termes dérivés comme condensat pour hash. À noter qu'il s'agit de condensation au sens de réduction, pas au sens de passage à l'état solide (passage qui, lui, est réversible)... (Je ne suis pas toujours cohérent dans mes articles : j'ai parfois utilisé le terme « résumé » à la place de « condensat ».)

Maintenant, prenons un terme plus rare et bien moins utilisé, scheme, au sens qu'il a dans les URI (RFC 3986, section 3.1). Par exemple, dans http://présumés-terroristes.fr/, le plan est http:. L'usage est souvent de le traduire par schéma mais je préfère personnellement plan (en français, un schéma est plus approximatif qu'un plan, ce second terme convient donc mieux au caractère très formalisé des plans d'URI). En tout cas, ce n'est pas un « protocole » et il ne faut pas utiliser ce terme qui montre qu'on n'a rien compris aux URI (un URI est un identificateur, pas un localisateur, il n'y a pas forcément de protocole utilisable dedans, même quand le plan est http:).

Bon, sauf si on travaille au W3C, on n'utilise pas ce terme de « plan » tous les jours. Mais il y a aussi des termes qui sont très importants en informatique, des concepts essentiels, mais pour lesquels la traduction frustre toujours les terminologues les plus avertis. C'est le cas de la scalability, la capacité d'un système à garder ses propriétés essentielles lorsqu'on change sérieusement d'échelle (par exemple quand on passe de mille à un million d'utilisateurs). Le terme revient tout le temps dans les discussions à l'IETF (« The scalability of ARP is very poor since every machine on the link must process every ARP request ») et le traduire est difficile. La traduction officielle est « extensibilité », ce qui est à la limite du contre-sens. L'extensibilité est une autre propriété des systèmes, la capacité à recevoir de nouvelles fonctions. Ici, il ne s'agit pas d'étendre le protocole, par exemple en lui ajoutant des fonctions, mais d'étendre le nombre d'utilisateurs. Je parle donc de passage à l'échelle en sachant bien que c'est nettement moins percutant que le terme anglais.

Passons ensuite à la génération de textes (par exemple une page HTML) à partir d'un template. Mais comment on dit template en français ? La traduction officielle est « modèle », ce qui me semble curieux (un modèle est plutôt conçu pour être copié tel quel, alors que l'expansion d'un template va donner des résultats différents selon la valeur des variables utilisées). Wikipédia ne traduit pas, mais propose éventuellement « patron », ce qui est joli (ce terme vient de la couture) mais ne me semble pas meilleur (un patron est également appliqué tel quel, il n'y a pas l'idée qui est essentielle avec les templates, d'incarnation d'une entité spécifique, en combinant template et variables). Je préfère donc de loin le terme de gabarit au sens où il est utilisé par les maquettistes.

Bon, et puisque j'écris ce paragraphe au moment des manifestations de Hong-Kong, c'est le moment de traduire le terme de réseau mesh. Il n'y a, semble-t-il, pas de traduction officielle (peut-être que l'État français n'aime pas cette idée de citoyens se connectant directement entre eux ?) Réseau maillé semble le plus fréquent mais c'est un peu idiot, tous les réseaux sont maillés. Cette traduction ne rend pas compte de la propriété importante des réseaux mesh, leur auto-organisation, qui permet la résistance à la censure.

Et le log des connexions, comment l'appeler ? Je ne trouve pas de traduction officielle mais Wikipédia propose de parler d'historique, ce qui est raisonnable. Pour une fois, je préfère une traduction littérale : le log en anglais vient de la marine (pour parler du journal de bord) et je propose donc de parler tout simplement de journal (et, donc, loguer une information est l'écrire dans le journal ou la journaliser, quoique ce dernier terme entre en collision avec certains systèmes de fichiers).

Enfin, certains termes sont problématiques, non pas parce qu'ils viennent de l'anglais, mais tout simplement parce qu'ils sont techniquement incorrects. C'est ainsi que je ne parle pas de propagation DNS, ni de cryptage.

Mille mercis à tous ceux et toutes celles qui ont discuté avec moi de terminologie, notamment sur Twitter (pardon, Gazouilleur), à chaque fois que je demande « et vous, comment vous traduiriez ce terme ? ».

Et il y a plein d'autres termes pas évidents à traduire et sur lesquels je vous laisse réfléchir (merci à Bertrand Petit pour les suggestions) : closure (le terme venant des maths, il faut probablement chercher une traduction dans ce secteur), mixin, bytecode, tail-recursivity (récursivité terminale semble répandu ?), mapping (je suggère « correspondance »), garbage collector...


L'article seul

RFC 3646: DNS Configuration options for Dynamic Host Configuration Protocol for IPv6 (DHCPv6)

Date de publication du RFC : Décembre 2003
Auteur(s) du RFC : R. Droms
Chemin des normes
Première rédaction de cet article le 7 octobre 2014


Les options DHCP IPv6 normalisées dans ce RFC permettent au serveur DHCP d'envoyer au client la liste des résolveurs (serveurs récursifs) DNS (ainsi que les domaines à utiliser pour les fonctions de recherche).

Il existe trois moyens d'indiquer à une machine IPv6 quels sont les résolveurs DNS à interroger (ceux qui, sur Unix, seront mis dans /etc/resolv.conf). Le premier moyen est statique, c'est la configuration manuelle de la machine. Les deux autres sont dynamiques. L'un utilise les RA (Router Advertisement, RFC 4862), en y ajoutant les options normalisées dans le RFC 6106. L'autre utilise DHCP pour IPv6 (RFC 3315), plus les options de notre RFC 3646. Le choix entre les deux derniers moyens dépend des capacités des clients IPv6 du réseau local et aussi de questions de goût.

La première option (section 3 du RFC) permet d'indiquer les résolveurs (ou serveurs récursifs). Elle a le code 23 (dans le registre IANA) et sa valeur est une liste d'adresses IPv6, sur lesquelles écoute un résolveur DNS.

La seconde option (section 4 du RFC) est une liste de domaines dans lesquels chercher le nom indiqué par l'utilisateur (s'il tape ping foobar et que la liste comprend example.org et internautique.fr, on essaiera foobar.example.org, puis foobar.internautique.fr). Son code est 24. À noter que le comportement d'un résolveur en présence d'une telle liste de recherche (option search dans /etc/resolv.conf si on est sur Unix) est mal spécifié et que des surprises sont fréquentes (cf. RFC 1535, notamment sa section 6).

Comme avec toute utilisation de DHCP, il n'y a aucune sécurité (section 6) : un serveur DHCP malveillant peut diriger les pauvres clients vers des résolveurs menteurs, par exemple. Notre RFC conseille l'utilisation de l'authentification DHCP (RFC 3315, section 21), qui ne semble pas déployée, ni même mise en œuvre dans les clients et serveurs courants.


Téléchargez le RFC 3646


L'article seul

Suspendre l'exécution d'un programme Unix pendant un temps précis ?

Première rédaction de cet article le 30 septembre 2014
Dernière mise à jour le 2 octobre 2014


Supposons que vous développiez en C sur Unix et que vous deviez suspendre l'exécution du programme pendant exactement N μs. Par exemple, vous voulez envoyer des paquets sur le réseau à un rythme donné. La réaction immédiate est d'utiliser sleep. Mais il y a en fait plein de pièges derrière ce but a priori simple.

Le plus évident est que sleep prend en argument un nombre entier de secondes :

unsigned int sleep(unsigned int seconds);

Sa résolution est donc très limitée. Qu'à cela ne tienne, se dit le programmeur courageux, je vais passer à usleep :

int usleep(useconds_t usec);

Celui-ci fournit une résolution exprimée en μs et, là, on va pouvoir attendre pendant une durée très courte. Testons cela en lançant un chronomètre avant l'appel à usleep() et en l'arrêtant après, pour mesurer le temps réellement écoulé :

% ./usleep 1000000
1 seconds and 67 microseconds elapsed

OK, pour une attente d'une seconde, le résultat est à peu près ce qu'on attendait. Mais pas à la μs près. Le noyau est un Linux, système multitâche préemptif et des tas d'autres tâches tournaient sur la machine, le noyau a donc d'autres choses à faire et un programme ne peut pas espérer avoir une durée d'attente parfaitement contrôlée. Ici, l'erreur n'était que de 0,0067 %. Mais si je demande des durées plus courtes :

% ./usleep 100
0 seconds and 168 microseconds elapsed

J'ai cette fois 68 % d'erreur. La durée écoulée en trop (le temps que l'ordonnanceur Linux remette mon programme en route) est la même mais cela fait bien plus mal sur de courtes durées. Bref, si usleep() a une résolution théorique de la microseconde, on ne peut pas espérer avoir d'aussi courtes durées d'attente :

% ./usleep 1  
0 seconds and 65 microseconds elapsed

Avec une telle attente minimale, un programme qui, par exemple, enverrait à intervalles réguliers des paquets sur le réseau serait limité à environ 15 000 paquets par seconde. Pas assez pour certains usages.

Là, le programmeur va lire des choses sur le Web et se dire qu'il faut utiliser nanosleep :

struct timespec
  {
    __time_t tv_sec;		/* Seconds.  */
    long int tv_nsec;		/* Nanoseconds.  */
  };

int nanosleep(const struct timespec *req, struct timespec *rem);

Celui-ci permet d'exprimer des durées en nanosecondes, cela doit vouloir dire qu'il peut faire mieux que usleep(), non ?

% ./nsleep 1000  
0 seconds and 67 microseconds elapsed

Eh bien non. Le problème n'est pas dans la résolution de la durée passée en argument, il est dans l'ordonnanceur de Linux. (À noter qu'il existe d'autres bonnes raisons d'utiliser nanosleep() plutôt que usleep(), liées au traitement des signaux.) La seule solution est donc de changer d'ordonnanceur. Il existe des tas de mécanismes pour cela, allant jusqu'à la recompilation du noyau avec des options davantage « temps réel ». Ici, on se contentera d'appeler sched_setscheduler() qui permet de choisir un nouvel ordonnanceur. Attention, cela implique d'être root, d'où le changement d'invite dans les exemples :

# ./nsleep-realtime 1000
0 seconds and 16 microseconds elapsed

Le noyau utilisé n'est pas réellement temps-réel mais, en utilisant l'ordonnanceur SCHED_RR, on a gagné un peu et les durées d'attente sont plus proches de ce qu'on demandait. (Les gens qui veulent de la latence vraiment courte, par exemple pour le jeu vidéo, utilisent des noyaux spéciaux.)

Ce très court article ne fait qu'effleurer le problème compliqué de l'attente sur un système Unix. Il existe par exemple d'autres façons d'attendre (attente active, select sur aucun fichier, mais avec délai d'attente maximal, dormir mais jusqu'à un certain moment comme illustré par ce programme, etc). Je vous conseille la lecture de « High-resolution timing » et de « Cyclictest » ainsi évidemment que celle de StackOverflow. Le code source des programmes utilisé ici est usleep.c et nsleep.c. Plus compliqué, le programme test_rt4.c utilise des timers, des signaux, bloque le programme sur un seul processeur, interdit le swap et autres trucs pour améliorer la précision.

Merci à Michal Toma pour l'idée, à Laurent Thomas pour son code et à Robert Edmonds pour plein de suggestions.


L'article seul

RFC 7322: RFC Style Guide

Date de publication du RFC : Septembre 2014
Auteur(s) du RFC : H. Flanagan (RFC Editor), S. Ginoza (RFC Editor)
Pour information
Première rédaction de cet article le 27 septembre 2014


Comme pour toute série de documents, il vaut mieux que les RFC soient cohérents dans leur style. Si certains RFC mettent les références entre parenthèses et d'autres entre crochets, la tâche du lecteur qui doit lire plusieurs RFC sera plus pénible. D'où cette série de règles, que le RFC Editor impose aux auteurs de RFC.

Rappelons que les RFC et leur RFC Editor sont décrits dans le RFC 4844, et que l'organisation du travail dudit RFC Editor est décrite dans le RFC 6635. L'actuel éditeur est Heather Flanagan, une des auteures de ce RFC 7322.

Les auteurs de RFC sont typiquement des ingénieurs informaticiens, qui n'ont pas forcément eu une formation en écriture et ignorent souvent les règles de base. La section 1 leur rappelle d'abord que le guide de style n'est pas là pour les embêter, mais pour que les RFC soient clairs et cohérents, à la fois en interne et entre eux. Le premier RFC Editor, Jon Postel, avait défini des règles s'imposant à tous les auteurs. Elles sont, en moyenne, bien plus souples que celles qu'imposent les journaux scientifiques ou les conférences et ne devraient donc pas trop gêner les participants à l'IETF.

Ce RFC 7322 est prévu pour être plutôt stable (une des fonctions du système des RFC est de garder les documents disponibles pendant de nombreuses années) et ne contient donc que des règles très solides, qui ont peu de chances de bouger avant de nombreuses années. Il a un inséparable compagnon en ligne, qui le complète avec les règles tout aussi importantes mais peut-être moins stables ou plus récentes.

Les règles de style des RFC ne sont pas spécialement extraordinaires : elles suivent avant tout le CMOS, le Chicago Manual of Style, la référence largement reconnue chez les auteurs anglophones, notamment dans les domaines scientifiques et techniques (mais très traditionaliste, et pas disponible en ligne). Le guide complète le CMOS, notamment pour les questions que ce dernier traite mal, comme la présence de codes informatiques au milieu du texte en anglais.

Enfin, comme tous les RFC commencent comme Internet-Drafts, la lecture du guide d'écriture des ID est également nécessaire à l'auteur débutant.

Armé de ce guide et des bons principes, le (enfin, actuellement, la) RFC Editor va alors (section 2) relire le document, corriger les erreurs, signaler aux auteurs les problèmes que le RFC Editor ne peut pas corriger seul, réparer les incohérences... Le but est qu'il y ait une forte cohérence à l'intérieur du document, presque aussi forte entre les RFC d'un même cluster et un peu moindre entre tous les RFC. (Les clusters sont des groupes de RFC portant sur une norme technique commune, et publiés en même temps, comme par exemple le cluster HTTP/1.1. On trouve une discussion plus détaillée en ligne.)

Attention, le travail du RFC Editor n'est pas technique (au sens de l'informatique). Les problèmes techniques doivent être traités par les auteurs et l'exactitude technique doit toujours avoir le pas sur le style. En aucun cas, le RFC Editor ne doit changer le sens du texte. (En pratique, toute activité éditoriale implique des frictions entre auteurs et éditeurs. L'un des buts du guide est de les minimiser, en expliquant clairement les règles.)

Après la philosophie, les règles (section 3). La première est la langue : pas le choix, les RFC doivent être en anglais. Mais lequel ? Celui de quel côté de la mare ? Britannique ou états-unien ? Faut-il écrire minimisation ou minimization ? meter ou metre ? Sur ce point, comme sur pas mal d'autres, le guide est ouvert : l'auteur fait comme il veut mais doit être cohérent. S'il ne l'est pas, le RFC Editor passera tout en orthographe états-unienne.

Les règles de ponctuation sont celles du CMOS (deux espaces après le point, la virgule avant le dernier élément d'une énumération, etc).

Les noms de domaine utilisés doivent être ceux du RFC 2606 pour éviter toute collision avec des noms réels. Les URI doivent être entre chevrons, comme le demande l'annexe C du RFC 3986. Notez bien que cette règle sur les URI ne s'applique qu'au texte seul (ce qui est le cas des RFC), et c'est pour cela que je ne l'applique pas sur ce blog (où j'écris https://www.example.org/parici).

La capitalisation n'est pas imposée mais elle doit être cohérente, selon les règles de cohérence du document sur les termes. Les mots importants d'un titre ou d'une section sont tous capitalisés, donc on écrit Extension for Named Searches (RFC 5466) et pas Extension for named searches ou Extension For Named Searches.

Et les citations ? Là encore, contrairement à ce qu'on voit souvent dans les revues scientifiques ou les actes des colloques, pas de règle impérative, à part le fait que la citation est entre crochets. Autrement, on peut citer en indiquant un court identificateur, comme « [TRILL-OAM] » (exemple pris dans le RFC 7276), ou en indiquant un numéro comme « [2] » (ce que fait par exemple le RFC 6410).

Et les abréviations ? Elle doivent être détaillées à leur première occurrence (avec l'abréviation entre parenthèses), par exemple « JavaScript Object Notation (JSON) » (vu dans le RFC 7072). On a évidemment le droit à une exception pour les abréviations que tout participant à l'IETF connaît certainement comme TCP ou HTTP. En cas d'oubli, vous avez une liste d'abréviations en ligne.

Enfin, la section 4 de notre RFC décrit la structure normale d'un RFC. Un RFC comporte un certain nombre d'éléments, pas forcément obligatoires. La première page a un contenu obligatoire, avec les avertissements juridiques (« boilerplates ») normalisés par le RFC 5741 (voir aussi le site de l'IETF trust). Elle indique aussi le ou les auteurs et leur organisation. On répète souvent que les participants à l'IETF ne représentent qu'eux-mêmes et pas leur employeur. Mais c'est largement faux, sauf pour la minorité assez riche pour se payer elle-même le temps de participation (et les voyages aux réunions). D'ailleurs, justement, l'employeur de l'auteur est indiqué dans le RFC. À noter que, si plusieurs auteurs ont le même employeur, on ne mentionne parfois ce dernier qu'une fois. Cela rend le texte ambigu : dans le RFC 6382, D. McPherson et R. Donnelly sont-ils au chômage ou bien sont-ils, comme le troisième auteur F. Scalzo, des employés de Verisign ?

La première page indique aussi le numéro ISSN des RFC, 2070-1721 et quelques autres métadonnées.

Le RFC doit aussi contenir un résumé, pour les lecteurs paresseux ou pressés. Publié seul (par exemple dans les catalogues des RFC), il doit être lisible en lui-même, sans faire appel au RFC (donc, sans citations faisant référence à la bibliographie). Souvent, il est simplement fait avec un copier/coller des premiers paragraphes de l'introduction, ce qui est autorisé mais pas forcément optimum.

Il y a parfois aussi une note, qui n'a pas été écrite par les auteurs, mais ajoutée par une des autorités qui a examiné le RFC. Par exemple, le RFC 4408 avait une note de l'IESG exprimant sa prudence vis-à-vis du problème, alors très controversé, d'authentification du courrier électronique. On peut aussi citer le RFC 4776, qui contient une note du RFC Editor expliquant que ce RFC a été publié uniquement pour corriger une erreur dans la valeur du code d'une option DHCP.

Ensuite, le corps du RFC. Il y a des parties qui dépendent du sujet du RFC. Ainsi, les RFC décrivant une MIB incluent en général le texte standard présentant les MIB (voir par exemple le RFC 4898, section 2). Et il y a des parties qu'on trouve dans tous les RFC. Certains termes ont un sens particulier dans les RFC. Ainsi, le lecteur anglophone mais non habitué aux RFC s'étonnera peut-être des MUST ou SHOULD écrits en majuscules. Ils sont définis dans le RFC 2119, l'écriture en majuscules signifiant un sens plus spécifique que le sens vague qu'ils peuvent avoir en anglais.

Les auteurs envoient parfois au RFC Editor un document pas complètement fini, notamment parce que les affectations de codes spécifiques par l'IANA n'ont pas encore été faites (RFC 5226). Par exemple, l'Internet-Draft sur le protocole Babel, draft-chroboczek-babel-routing-protocol, contenait le texte « IANA has registered the UDP port number TBD, called "babel", for use by the Babel protocol. » Une fois un port réservé officiellement, le « TBD » (To Be Done) a été remplacé et le RFC 6126 dit « IANA has registered the UDP port number 6697, called "babel", for use by the Babel protocol. ».

À la fin du RFC, se trouvent des sections plus ou moins standardisées, comme la fameuse (et obligatoire) « Security Considerations » (RFC 3552), qui doit permettre de s'assurer que les auteurs du RFC ont pensé aux problèmes de sécurité éventuels. Facultative, en revanche, la section sur les questions liées à l'internationalisation du protocole (RFC 2277).

Reste la bibliograpĥie : elle comporte deux parties, une avec les références normatives et une avec le reste. Une des conséquences est que, si une référence normative est un Internet-Draft pas encore publié, la publication du futur RFC devra attendre. Une référence non-normative, elle, peut être un Internet-Draft non publié. Dans ce cas, il est marqué comme « Work in Progress » pour bien indiquer son manque de stabilité. Quand un RFC est cité, c'est parfois via son numéro de norme ou de BCP (Best Current Practice) car une telle référence est plus stable. Les URI sont autorisés dans la bibliographie, à condition qu'ils soient raisonnablement stables. Ainsi, BCP47 désignait au début le RFC 4646 et le RFC 4647 (oui, un BCP peut correspondre à plusieurs RFC) et, lorsque le RFC 4646 a été remplacé par le RFC 5646, le numéro de BCP n'a pas changé, pointant toujours vers la version la plus récente des bonnes pratiques.

Le RFC se termine aussi par des remerciements aux contributeurs. Le guide note qu'il n'y a pas de règles précises concernant qui est noté comme contributeur. C'est à l'initiative des auteurs. Par exemple, je suis cité comme contributeur dans dix-sept RFC mais cela correspond à des niveaux de participation très différents, d'une vraie participation à juste quelques corrections de détail. Et certains auteurs ont choisi de régler le problème des contributeurs avec une formule attrape-tout comme dans le RFC 4408 « The authors would also like to thank the literally hundreds of individuals who have participated in the development of this design. They are far too numerous to name [...] ».

Un dernier détail, les adresses de courrier électronique dans les RFC doivent être intactes (pas de modification comme rfc-editor (at) rfc-editor.org). Le but des adresses est de pouvoir contacter les auteurs et cela implique de ne pas faire de modifications.

Voilà, c'est fini. Ah, que faire en cas de conflit insoluble entre un auteur et le RFC Editor ? Comme rappelé par l'annexe A, on suit les procédures du RFC 6635.


Téléchargez le RFC 7322


L'article seul

Faut-il changer la clé DNSSEC de la racine ?

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


Voici le genre de question qui ne va pas angoisser le célèbre M. Michu, mais que se posent sérieusement des tas de techniciens de l'Internet. Cette question a suscité la création récente d'une liste de diffusion très animée, et fera l'objet d'une réunion à la rencontre ICANN de Los Angeles en octobre prochain.

De quoi s'agit-il et de quoi discute-t-on sur cette liste ksk-rollover ? Les informations diffusées par le DNS sont sécurisées par des signatures cryptographiques, un système connu sous le nom de DNSSEC. Comme le DNS, DNSSEC est décentralisé mais arborescent. Le résolveur DNS qui veut valider (vérifier ces signatures) trouve la clé publique de la zone dans la zone parente, et ainsi de suite jusqu'à la racine, le sommet du DNS, qui est un cas particulier, le résolveur doit en connaître la clé. Typiquement, elle est incluse dans la distribution du logiciel et installée automatiquement. Aujourd'hui, cette clé de la racine, clé de voute de l'authentification des données DNS, est une RSA, a l'identificateur 19036, et vaut :

.	IN DNSKEY 257 3 8 (
	   AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQ
	   bSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh
	   /RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuYEhg37NZWA
	   JQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaDX6RS6CXp
           oY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3
           LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGO
           Yl7OyQdXfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGc
           LmqrAmRLKBP1dfwhYB4N7knNnulqQxA+Uk1ihz0=
  ) ; KSK; alg = RSASHA256; key id = 19036

(Il y a en fait plusieurs sortes de clés, celle qui est importante, le point de départ de la confiance - trust anchor - est la KSK, Key Signing Key.) Mais, si on la change, comment mettre à jour (en anglais to roll over) les dizaines de milliers (et demain les centaines de milliers) de résolveurs qui l'utilisent ?

Avant cela, demandons-nous pourquoi la changer ? Il peut y avoir au moins deux cas où nous serions obligés de la changer : si elle est compromise (si la clé privée est copiée par un méchant) ou si les progrès de la cryptanalyse la rendent trop peu sûre. Aujourd'hui, aucun de ces deux cas ne se présente. Mais, si cela arrivait (et, au moins pour le premier cas, cela peut arriver du jour au lendemain), nous serions bien embêtés car on n'a jamais essayé une opération aussi complexe.

C'est le principal argument des « changeurs », ceux qui veulent qu'on change de clé : cela n'est pas nécessaire maintenant mais cela permet de tester les procédures et de s'assurer qu'on sait faire, de manière à ne pas être pris au dépourvu en cas de problème. Ils ajoutent que, pour l'instant, seules 10 à 20 % des requêtes DNS passent par un résolveur validant mais que DNSSEC se répand et que donc, plus on attend, plus ce sera dur. Les « conserveurs », eux, disent que c'est déjà trop tard, et que c'est embêtant de changer une donnée aussi critique juste pour faire des tests. Le risque de tout casser (et de donner ainsi une mauvaise réputation à DNSSEC) est trop important.

Par exemple, sur la machine Ubuntu où je tape cet article, il faudrait, si la décision de changer de clé est prise, que je récupère la nouvelle clé (évidemment de manière sécurisée, pas en copiant/collant depuis Twitter) et que j'édite /etc/unbound/root.key. Pas évident d'obtenir cela de nombreux administrateurs système dispersés et qui ne lisent pas forcément tous les jours la liste dns-operations... Il existe en théorie des solutions qui éviteraient de mettre à jour manuellement. Certaines sont dépendantes du logiciel. Unbound a son programme unbound-anchor qui récupère la clé sur le serveur de l'IANA, en HTTPS, et en vérifiant le certificat. Il y a aussi les mises à jour automatiques ou semi-automatiques des logiciels : si on met à jour son résolveur ainsi, on aura la nouvelle clé. Si on n'est pas trop pressé, cela marchera. Et il y a la technique du RFC 5011 qui permet d'indiquer dans le DNS que l'ancienne clé est révoquée et de publier la nouvelle, signée avec l'ancienne (cela ne marche pas si l'ancienne clé privée a été copiée par un attaquant ; comme le disait l'auteur du RFC dans la discussion sur la liste ksk-rollover « If you lose your last trust anchor, you're screwed. »). Le gros problème du RFC 5011 est qu'il n'a jamais été testé au feu.

Et il y a aussi les questions bureaucratiques, qui prendront certainement dix fois plus de temps que les discussions techniques (pourtant déjà très bavardes), dans le marigot qu'est la gouvernance d'Internet. Pour l'instant, aucune décision n'a été prise. Les discussions se poursuivent...

Et mon opinion personnelle à moi ? Je crains qu'il ne soit effectivement trop tard pour changer la clé de manière propre. Elle est présente en trop d'endroits qu'on ne maitrise pas. Il faudrait mettre en place un vaste programme de mise à jour des logiciels, pour s'assurer que tous mettent en œuvre le RFC 5011 proprement. Quand ce sera fait, dans dix ou vingt ans, on pourra remettre sur le tapis la question du changement (rollover) de clé.


L'article seul

Remerciements à ceux qui m'aident pour ce blog

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


Ce blog est signé de mon nom, car c'est moi qui écris tous les articles et qui ai le dernier mot avant publication. Mais il bénéficie de l'aide de plusieurs personnes.

Cela va être difficile de citer tout le monde. Pour les relectures techniques, avec corrections des innombrables bogues dans le texte, je mentionne dans l'article les contributeurs. Mais il y a aussi un énorme travail qui ne se voit pas, c'est la relecture littéraire, avec corrections des fautes de français. Pour cela, je dois un million de remerciements (et quelques chocolats) à André Sintzoff, qui relit tous les articles impitoyablement et trouve au moins une faute de français à chaque fois (parfois dans des cas très subtils qui nécessitent plusieurs lectures du Grevisse, mais parfois des erreurs grossières).

Et merci aussi à Yannick Palanque pour ses propres corrections orthographiques et grammaticales.


L'article seul

RFC 7323: TCP Extensions for High Performance

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


Téléchargez le RFC 7323


L'article seul

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

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


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

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

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

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

Les ORCHID ont les propriétés suivantes :

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

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

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

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

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

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

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

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

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

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


Téléchargez le RFC 7343


L'article seul

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


Téléchargez le RFC 7321


L'article seul

RFC 7372: Email Authentication Status Codes

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


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

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

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

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

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

Les codes sont respectivement :

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

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

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

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

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

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

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

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

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

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


Téléchargez le RFC 7372


L'article seul

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

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


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

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

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

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

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

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

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

va devenir :

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

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

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

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

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

Merci à Florian Maury pour sa relecture.

Une bonne explication technique de ces problèmes est celle de Moxie Marlinspike.


Téléchargez le RFC 7366


L'article seul

RFC 7352: Sieve Email Filtering: Detecting Duplicate Deliveries

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

require ["duplicate"]

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

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

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

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

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


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

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


Téléchargez le RFC 7352


L'article seul

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

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