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.
Date de publication du RFC : Décembre 2015
Auteur(s) du RFC : P. Hoffman (ICANN), A. Sullivan
(Dyn), K. Fujiwara (JPRS)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 19 décembre 2015
Comme beaucoup de protocoles très utilisés sur l'Internet, le DNS est ancien. Très ancien (la première norme, le RFC 882, date de 1983). Les normes techniques vieillissent, avec l'expérience, on comprend mieux, on change les points de vue et donc, pour la plupart des protocoles, on se lance de temps en temps dans une révision de la norme. Mais le DNS est une exception : la norme actuelle reste fondée sur des textes de 1987, les RFC 1034 et RFC 1035. Ces documents ne sont plus à jour, modifiés qu'ils ont été par des dizaines d'autres RFC. Bref, aujourd'hui, pour comprendre le DNS, il faut s'apprêter à lire de nombreux documents. En attendant qu'un courageux et charismatique participant à l'IETF se lance dans la tâche herculéenne de faire un jeu de documents propre et à jour, ce nouveau RFC 7719 se limitait à une ambition plus modeste : fixer la terminologie du DNS. Depuis, il a été remplacé par un document plus récent, le RFC 8499.
En effet, chacun peut constater que les discussions portant sur le DNS sont difficiles : on manque de terminologie standard, et celle des RFC officielles ne suffit pas, loin de là. Souvent, le DNS a tellement changé que le RFC officiel est même trompeur : les mots ne veulent plus dire la même chose. D'autres protocoles ont connu des mises à jour de la norme. Cela a été le cas de SMTP, passé successivement du RFC 772 à l'actuel RFC 5321, en passant par plusieurs révisions successives. Ou de XMPP, qui a vu sa norme originale mise à jour dans le RFC 6120. Et bien sûr de HTTP, qui a connu récemment un toilettage complet. Mais personne n'a encore osé faire pareil pour le DNS. Au moins, ce nouveau RFC 7719 traite l'un des problèmes les plus criants, celui du vocabulaire. Le RFC est évidemment en anglais, les traductions proposées dans cet article, et qui n'ont pas de valeur « officielle » sont de moi seul.
Notre RFC 7719 rassemble donc des définitions pour des termes qui étaient parfois précisément définis dans d'autres RFC (et il fournit alors un lien vers ce RFC original), mais aussi qui n'étaient définis qu'approximativement ou parfois qui n'étaient pas définis du tout (et ce RFC fournit alors cette définition). Du fait du flou de certains RFC anciens, et des changements qui ont eu lieu depuis, certaines définitions sont différentes de l'original. Le document a fait l'objet d'un consensus relatif auprès des experts DNS mais quelques termes restent délicats. Notez aussi que d'autres organisations définissent des termes liés au DNS par exemple le W3C a sa propre définition de « domaine ».
Ironiquement, un des termes les plus difficiles à définir est
« DNS » lui-même. D'accord, c'est le sigle de Domain Name
System mais ça veut dire quoi ? « DNS » peut désigner le
schéma de nommage (les noms de domaine
comme signal.eu.org
, leur syntaxe, leurs
contraintes), la base de données répartie (et faiblement
cohérente) qui associe à ces noms
des informations (comme des certificats,
des adresses IP, etc), ou
le protocole requête/réponse (utilisant le
port 53) qui permet d'interroger cette
base. Parfois, « DNS » désigne uniquement le protocole, parfois,
c'est une combinaison des trois éléments indiqués plus haut
(personnellement, quand j'utilise « DNS », cela désigne uniquement
le protocole).
Bon, et ces définitions rigoureuses et qui vont mettre fin aux discussions, ça vient ? Chaque section du RFC correspond à une catégorie particulière. D'abord, en section 2, les noms eux-même, ces fameux noms de domaine :
www.madmoizelle.com
), le
vocabulaire s'en ressent. Par exemple, on va dire que
com
est
« au-dessus de madmoizelle.com
» (vision
arborescente) ou bien
« à la fin de www.madmoizelle.com
» (vision texte).
Notez aussi que la représentation des noms de domaine dans les
paquets IP n'a
rien à voir avec leur représentation texte (par exemple, les
points n'apparaissent pas).ldap.potamochère.fr.
est un FQDN alors que
ldap
tout court ne l'est pas). En toute
rigueur, un FQDN devrait toujours s'écrire avec un point à la
fin (pour représenter la racine) mais ce n'est pas toujours le
cas.www.laquadrature.net
, il y a trois
composants, www
,
laquadrature
et net
.brienne.tarth.got.example
peut être un nom
de machine mais www.&#$%?.example
ne peut
pas l'être. Le terme de « nom de machine » est parfois aussi
utilisé pour parler du premier composant d'un nom de domaine
(brienne
dans brienne.tarth.got.example
).fr
ou
name
sont des TLD. N'utilisez surtout pas le terme erroné
d'« extension ».www.cl.cam.ac.uk
est un sous-domaine de
cl.cam.ac.uk
, qui est un sous-domaine de
cam.ac.uk
et ainsi de suite, jusqu'à la
racine, le seul domaine à n'être sous-domaine de
personne.vader IN CNAME anakin
, l'alias est
vader
(et c'est une erreur de dire que
c'est « le CNAME »).anakin
est le CNAME, le « nom canonique ».com
, co.uk
et
eu.org
sont des
suffixes publics. Rien dans la syntaxe du nom n'indique qu'un
nom de domaine est un suffixe public, puisque ce statut ne
dépend que d'une politique d'enregistrement (qui peut changer).Fini avec les noms, passons à l'en-tête des messages DNS et aux codes qu'il peut contenir. Cet en-tête est défini dans le RFC 1035, section 4.1. Il donne des noms aux champs mais pas forcément aux codes. Ainsi, le code de réponse 3 indiquant qu'un domaine demandé n'existe pas est juste décrit comme name error et n'a reçu son mnémonique de NXDOMAIN (No Such Domain) que plus tard. Notre RFC définit également :
Voici un renvoi depuis la racine vers .fr
:
% dig @l.root-servers.net A blog.imirhil.fr ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16572 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 5, ADDITIONAL: 11 ... ;; AUTHORITY SECTION: fr. 172800 IN NS d.ext.nic.fr. fr. 172800 IN NS d.nic.fr. fr. 172800 IN NS e.ext.nic.fr. fr. 172800 IN NS f.ext.nic.fr. fr. 172800 IN NS g.ext.nic.fr.
Passons maintenant aux enregistrements DNS, stockés dans cette base de données répartie (section 4 du RFC) :
Voici un ensemble d'enregistrements (RRset), comptant ici deux enregistrements :
rue89.com. 600 IN MX 50 mx2.typhon.net. rue89.com. 600 IN MX 10 mx1.typhon.net.
Et voici un pseudo-enregistrement OPT, tel qu'affiché par dig, avec une indication de la taille maximale et l'option client subnet (RFC pas encore publié) :
;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ; CLIENT-SUBNET: 13.176.144.0/24/0
Ensuite, un sujet chaud où le vocabulaire est particulièrement peu défini, et très mal utilisé (voir les forums grand public sur le DNS où les discussions prennent un temps fou car les gens utilisent mal les mots) : les différents types de serveurs et clients DNS (section 5) :
getaddrinfo()
ou
getnameinfo()
. Sur
Unix, le résolveur minimum fait en
général partie de la libc et trouve
l'adresse du ou des résolveurs complets dans /etc/resolv.conf
.f.root-servers.net
fait autorité pour la
racine, d.nic.fr
fait autorité pour
pm
, etc. Des logiciels comme
NSD ou
Knot
assurent cette fonction. Les serveurs faisant autorité sont
gérés par divers acteurs, les registres,
les hébergeurs DNS (qui sont souvent en même temps
bureaux d'enregistrement), mais aussi par
M. Michu. La commande dig NS $ZONE
vous
donnera la liste des serveurs faisant autorité pour la zone
$ZONE
.NS .
» à un des serveurs de sa
liste. Ainsi, tant qu'un moins un des serveurs de la vieille
liste répond, le résolveur est sûr d'apprendre la liste actuelle./etc/resolv.conf
le
serveur primaire ») n'a pas de sens.forwarders
).Voici, vu par tcpdump, un exemple d'initialisation d'un résolveur BIND utilisant la racineYeti :
15:07:36.736031 IP6 2a01:e35:8bd9:8bb0:21e:8cff:fe76:29b6.35721 > 2001:6d0:6d06::53.53: \ 21476% [1au] NS? . (28) 15:07:36.801982 IP6 2001:6d0:6d06::53.53 > 2a01:e35:8bd9:8bb0:21e:8cff:fe76:29b6.35721: \ 21476*- 16/0/1 NS yeti-ns.tisf.net., NS yeti-ns.lab.nic.cl., NS yeti-ns.wide.ad.jp., NS yeti.ipv6.ernet.in., NS yeti-ns.as59715.net., NS ns-yeti.bondis.org., NS yeti-dns01.dnsworkshop.org., NS dahu2.yeti.eu.org., NS dahu1.yeti.eu.org., NS yeti-ns.switch.ch., NS bii.dns-lab.net., NS yeti.bofh.priv.at., NS yeti-ns.conit.co., NS yeti.aquaray.com., NS yeti-ns.ix.ru., RRSIG (619)
La question était « NS .
» (quels sont les
serveurs de la racine) et la réponse contenait les noms des seize
serveurs racine.
Voici aussi des exemples de résultats avec un résolveur ou bien avec un serveur faisant autorité. Si je demande à un serveur faisant autorité (ici, un serveur racine), avec mon client DNS qui, par défaut, demande un service récursif (flag RD, Recursion Desired) :
% dig @2001:620:0:ff::29 AAAA www.iab.org ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54197 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 9, ADDITIONAL: 13 ;; WARNING: recursion requested but not available ... ;; AUTHORITY SECTION: org. 172800 IN NS b0.org.afilias-nst.org. ...
C'est pour cela que dig affiche WARNING: recursion requested but not available. Notez aussi que le serveur, ne faisant autorité que pour la racine, n'a pas donné la réponse mais juste un renvoi aux serveurs d'Afilias. Maintenant, interrogeons un serveur récursif (le service de résolveur public Yandex DNS) :
% dig @2a02:6b8::feed:0ff AAAA www.iab.org ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63304 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ... ;; ANSWER SECTION: www.iab.org. 1800 IN AAAA 2001:1900:3001:11::2c
Cette fois, j'ai obtenu une réponse, et avec le
flag RA, Recursion
Available. Si je pose une question sans le
flag RD (Recursion Desired,
avec l'option +norecurse
de dig) :
% dig +norecurse @2a02:6b8::feed:0ff AAAA www.gq.com ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59438 ;; flags: qr ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ... ;; ANSWER SECTION: www.gq.com. 293 IN CNAME condenast.map.fastly.net.
J'ai obtenu ici une réponse car l'information était déjà dans le cache (la mémoire) de Yandex DNS (on le voit au TTL, qui n'est pas un chiffre rond, il a été décrémenté du temps passé dans le cache). Si l'information n'est pas dans le cache :
% dig +norecurse @2a02:6b8::feed:0ff AAAA blog.keltia.net ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19893 ;; flags: qr ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0 ...
Je n'obtiens alors pas de réponse (ANSWER: 0). Si je demande au serveur faisant autorité pour cette zone :
% dig +norecurse @2a01:e0d:1:3:58bf:fa61:0:1 AAAA blog.keltia.net ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62908 ;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 6, ADDITIONAL: 15 ... ;; ANSWER SECTION: blog.keltia.net. 86400 IN AAAA 2a01:240:fe5c:1::2 ...
J'ai évidemment une réponse et, comme il s'agit d'un serveur faisant autorité, elle porte le flag AA (Authoritative Answer, qu'un résolveur ne mettrait pas). Notez aussi le TTL qui est un chiffre rond (et qui ne change pas si on rejoue la commande).
Passons maintenant à un concept relativement peu connu, celui de zones, et le vocabulaire associé :
gouv.fr
n'est pas
une zone séparée, il est dans la même zone que
fr
(cela se teste facilement :
gouv.fr
n'a pas d'enregistrement NS ou de
SOA).wikipedia.org
est org
.ns1.mazone.example
, le résolveur
doit passer par les serveurs de
mazone.example
, qui est déléguée à
ns1.mazone.example
et ainsi de suite... On
rompt ce cercle vicieux en ajoutant, dans la zone parente, des
données qui ne font pas autorité sur les adresses de ces
serveurs (RFC 1034, section 4.2.1). Il faut donc bien veiller à les garder synchrones avec
la zone fille. (Tanguy Ortolo me suggère d'utiliser
« enregistrement de raccord » plutôt que « colle ». Cela décrit
bien leur rôle, en effet.)ip6.arpa
ou sous
les domaines très longs de certains CDN.*
dans une zone déclenche la synthèse
automatique de réponses pour les noms qui n'existent pas dans la
zone. Si la zone foo.example
contient
bar.foo.example
et
*.foo.example
, une requête pour
thing.foo.example
renverra le contenu de
l'enregistrement avec le joker, une requête pour
bar.foo.example
donnera les données de bar.foo.example
.
Voyons ici la colle retournée par un serveur faisant autorité (en
l'occurrence un serveur de .net
) :
% dig @a.gtld-servers.net AAAA labs.ripe.net ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18272 ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 9 ... ;; AUTHORITY SECTION: ripe.net. 172800 IN NS ns3.nic.fr. ripe.net. 172800 IN NS sec1.apnic.net. ripe.net. 172800 IN NS sec3.apnic.net. ripe.net. 172800 IN NS tinnie.arin.net. ripe.net. 172800 IN NS sns-pb.isc.org. ripe.net. 172800 IN NS pri.authdns.ripe.net. ... ;; ADDITIONAL SECTION: sec1.apnic.net. 172800 IN AAAA 2001:dc0:2001:a:4608::59 sec1.apnic.net. 172800 IN A 202.12.29.59 sec3.apnic.net. 172800 IN AAAA 2001:dc0:1:0:4777::140 sec3.apnic.net. 172800 IN A 202.12.28.140 tinnie.arin.net. 172800 IN A 199.212.0.53 tinnie.arin.net. 172800 IN AAAA 2001:500:13::c7d4:35 pri.authdns.ripe.net. 172800 IN A 193.0.9.5 pri.authdns.ripe.net. 172800 IN AAAA 2001:67c:e0::5
On notera :
pri.authdns.ripe.net
: ce serveur étant
dans la zone qu'il sert, sans son adresse IP, on ne pourrait
jamais le joindre.sec1.apnic.net
. Ce n'est pas
strictement indispensable (on pourrait l'obtenir par une
nouvelle requête), juste une optimisation.ns3.nic.fr
et
sns-pb.isc.org
ne sont pas renvoyées. Le
serveur ne les connait probablement pas et, de toute façon,
elles seraient hors-bailliage.Voyons maintenant, un ENT,
gouv.fr
:
% dig @d.nic.fr ANY gouv.fr ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42219 ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1
Le serveur fait bien autorité pour ce domaine (flag AA dans la réponse), le domaine existe (autrement, le status aurait été NXDOMAIN, pas NOERROR) mais il n'y a aucun enregistrement (ANSWER: 0).
Allez courage, ne faiblissons pas, il reste encore la question de l'enregistrement des noms de domaine (section 7) :
bortzmeyer.org
:-)
C'est le registre qui décide de la politique d'enregistrement,
qui peut être très variable selon les zones (sauf dans celles
contrôlées par l'ICANN, où une certaine
uniformité est imposée). Mes lecteurs français noteront que,
comme le terme « registre » est court et largement utilisé, le
gouvernement a inventé un nouveau mot, plus long et jamais vu
auparavant, « office d'enregistrement ».Enfin, pour terminer, la section 8 de notre RFC couvre DNSSEC. Pas grand'chose de nouveau ici, DNSSEC étant plus récent et donc mieux défini.
Je rappelle que ce RFC n'est plus le document final, ce rôle est désormais tenu par son successeur, le RFC 8499.
Date de publication du RFC : Décembre 2015
Auteur(s) du RFC : P. Saint-Andre (&yet)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF precis
Première rédaction de cet article le 15 décembre 2015
Bien des protocoles Internet manipulent des noms qui doivent être parlants pour les utilisateurs et donc, de nos jours, doivent pouvoir être en Unicode. Les noms purement ASCII appartiennent à un passé révolu. Le groupe de travail PRECIS de l'IETF établit des règles pour ces noms, de manière à éviter que chaque protocole, chaque application, ne soit obligé de définir ses propres règles. Ce nouveau RFC contient les règles pour un sous-ensemble de ces noms : les noms qui visent plutôt à communiquer avec un utilisateur humain (par opposition aux noms qui sont indispensables aux protocoles réseaux, traités dans le RFC 7613). Ce RFC a été depuis remplacé par le RFC 8266.
Ces noms « humains » sont typiquement ceux qui sont présentés aux utilisateurs. Ils doivent donc avant tout être « parlants » et il faut donc qu'ils puissent utiliser la plus grande part du jeu de caractères Unicode, sans restrictions arbitraires (contrairement aux identificateurs formels du RFC 7613, pour lesquels on accepte des limites du genre « pas d'espaces »).
Le terme utilisé par le RFC pour ces noms « humains » est nicknames, terme qui vient du monde de la messagerie instantanée. Il n'y a pas de terme standard pour les désigner, certains protocoles (comme le courrier) parlent de display names (par opposition au login name ou account name), d'autres utilisent encore d'autres termes (l'article « An Introduction to Petname Systems » peut vous intéresser). Par exemple, dans un message électronique, on pourrait voir :
From: Valérie Pécresse <vp@les-républicains.fr>
Et, dans cet exemple, vp
serait le nom formel
(mailbox name dans le courrier, login
name pour se connecter), alors que Valérie
Pécresse
est le nickname, le nom
montrable aux humains. (Le concept de display
name dans le courrier est normalisé dans la section
3.4.1 du RFC 5322, son exact équivalent
XMPP, le nickname, est
dans XEP-0172.)
Comme l'illustre l'exemple ci-dessus, on veut évidemment que le nom puisse être en Unicode, sauf pour la petite minorité des habitants de la planète qui utilisent une langue qui peut s'écrire uniquement en ASCII.
Ces noms « parlants », ces nicknames, ne servent pas qu'à désigner des humains, ils peuvent aussi être utilisés pour des machines, des sites Web (dans les signets), etc.
On pourrait penser qu'il n'y a rien à spécifier pour permettre leur internationalisation. On remplace juste ASCII par Unicode comme jeu de caractères autorisé et vas-y, poupoule. Mais Unicode recèle quelques surprises et, pour que les nicknames fonctionnent d'une manière qui paraitra raisonnable à la plupart des utilisateurs, il faut limiter légèrement leur syntaxe.
Ces limites sont exposées dans la section 2 de notre RFC, qui
définit un profil de PRECIS. PRECIS,
Preparation, Enforcement, and Comparison of
Internationalized Strings est le sigle qui désigne le
projet « Unicode dans tous les identificateurs » et le groupe de
travail IETF qui réalise ce projet. PRECIS définit (RFC 7564) plusieurs classes d'identificateurs et
les nicknames sont un cas particulier de la
classe FreeformClass
, la moins restrictive
(celle qui permet le plus de caractères).
Outre les restrictions de FreeformClass
(qui n'est pas complètement laxiste : par exemple, cette classe ne
permet pas les caractères de contrôle), le profil
Nickname
:
Thérèse
" et "Thérèse
" sont le
même nom,À noter qu'un nickname doit avoir une taille non nulle, après l'application des ces règles (autrement, un nickname de trois espaces serait réduit à... zéro).
Une fois ce filtrage et cette canonicalisation faite, les nicknames sont encodés en UTF-8 et peuvent être comparés par une simple égalité bit à bit.
La section 3 de notre RFC fournit quelques exemples amusants et instructifs de nicknames :
Foo
" et "foo
" sont
acceptables, mais sont le même nom (en application de la régle
d'insensibilité à la casse),Foo Bar
" est permis (les espaces sont
autorisés, avec les quelques restrictions indiquées plus
haut),Échec au roi ♚
" est permis,
rien n'interdit les symboles comme cette pièce du jeu
d'échecs, le caractère Unicode
U+265A,Henri Ⅳ
" est permis (ouvrez
l'œil : c'est le chiffre romain à la fin, U+2163) mais la
normalisation NFKC (précédée du passage en minuscules) va faire
que ce nom est équivalent à "henri iv
"
(avec, cette fois, deux caractères à la fin).Comme le rappelle la section 4 de notre RFC, les applications doivent maintenant définir l'utilisation de ces noms parlants, où peut-on les utiliser, etc. L'application peut donc avoir des règles supplémentaires, comme une longueur maximale pour ces nicknames, ou des caractères interdits car ils sont spéciaux pour l'application.
L'application ou le protocole applicatif a également toute
latitude pour gérer des cas comme les duplicatas : j'ai écrit plus
haut que "Foo Bar
" et "foo
bar
" étaient considérés comme le même
nickname mais cela ne veut pas dire que leur
coexistence soit interdite : certaines applications permettent à
deux utilisateurs distincts d'avoir le même
nickname. Même chose avec d'autres règles
« métier » comme la possibilité d'interdire certains noms (par
exemple parce qu'ils sont grossiers).
Le profil Nickname
est désormais ajouté au
registre IANA (section 5 du RFC).
Date de publication du RFC : Décembre 2015
Auteur(s) du RFC : S. Farrell (Trinity College, Dublin), R. Wenning, B. Bos (W3C), M. Blanchet (Viagenie), H. Tschofenig (ARM)
Pour information
Première rédaction de cet article le 15 décembre 2015
Depuis les révélations d'Edward Snowden, les initiatives se multiplient pour « durcir l'Internet », c'est-à-dire le rendre plus résistant à la surveillance généralisée, telle que pratiquée par plusieurs pays (par exemple la France, où les politiques profitent cyniquement des attentats islamistes pour faire passer de plus en plus de lois liberticides). Début 2014, à Londres, s'est ainsi tenu l'atelier STRINT, qui a rassemblé une centaine de participants pour réfléchir à la meilleure façon de renforcer l'Internet contre cet espionnage. Ce RFC est le compte-rendu (très tardif) de cet atelier. Il résume les principales interventions, et les suggestions faites à cette occasion.
L'engagement de l'IETF à lutter contre la surveilance généralisée date de sa réunion de Vancouver, et a été formalisé dans le RFC 7258. C'est à la suite de cette réunion canadienne qu'a été tenu l'atelier STRINT, coorganisé par le projet STREWS, l'IAB et le W3C. STRINT signifie « Strengthening the Internet Against Pervasive Monitoring » et l'atelier s'est tenu juste avant la réunion IETF 89 à Londres.
L'atelier a été un succès. Prévu pour un petit nombre de participants (cent maximum : le but était de travailler, pas de faire des discours devant une immense salle), il a été rempli en peu de temps. (Outre les 100 participants physiques, jusqu'à 165 personnes ont suivi l'atelier à distance.) 67 articles avaient été soumis.
La section 2 du RFC résume les conclusions de l'atelier :
La section 3 de notre RFC revient sur les buts de l'atelier. Une fois qu'on a décidé que la surveillance généralisée était une attaque, et qu'il fallait la combattre (RFC 7258), que faire de plus ?
Pour atteindre ces buts, l'atelier était structuré pour maximiser les discussions (section 4 du RFC). Les papiers acceptés n'étaient pas présentés (les participants étaient supposés les avoir lus avant).
Quels furent les sujets couverts dans les sessions de l'atelier (section 5 du RFC) ? La session d'ouverture a discuté de questions plutôt « méta » comme la quantité minimale de métadonnées qui est vraiment nécessaire aux protocoles IETF pour faire leur travail, comme la recherche de « fruits à portée de main » (des solutions qui pourraient être déployées très rapidement), ou comme le niveau de sécurité considéré comme « suffisant » (il ne faut pas espérer atteindre une sécurité parfaite, quand l'attaquant a les moyens de la NSA).
La première session portait (section 5.2) sur les menaces. Pas de sécurité sérieuse sans une étude détaillée des menaces. Ce n'est pas la même chose de se protéger contre la DGSE ou le FSB et de se protéger contre le lycéen boutonneux dans son garage. La surveillance généralisée met en cause un modèle traditionnel de menaces, fondé sur une étude coût/bénéfice de la défense (ou de l'attaque d'ailleurs). Dans ce modèle traditionnel, on regardait ce que valait l'objectif à défendre et on calculait les dépenses de sécurité réalistes en fonction de cela. (L'attaquant faisait un calcul similaire, et pouvait migrer vers un autre objectif, si le premier envisagé était trop coûteux.) Mais, avec la surveillance généralisée, il n'y a plus de décisions d'attaquer tel ou tel objectif : on attaque tout le monde. Et l'attaquant étant en général un État, il ne fait pas de calcul de ROI (certaines bureaucraties étatiques sont même contentes quand c'est cher, cela permet de se « construire un empire » en réclamant des budgets toujours plus élevés).
Est-ce que la surveillance généralisée est plus facile s'il y a un petit nombre de silos très protégés (les GAFA, Google, Facebook, etc) ou s'il y a une multitude de petits sites, chacun avec son CozyCloud ou son YunoHost, chacun moins bien protégé que les grosses entreprises professionnelles, mais bénéficiant de la dispersion des données ? Si Facebook est certainement, pour un attaquant, un objectif plus difficile à craquer que le VPS de M. Michu, c'est également un objectif beaucoup plus intéressant : si on le craque, on a les données de centaines de millions de M. Michu. Le RFC suggère donc qu'il vaut mieux ne pas tout mettre chez les GAFA et disperser les objectifs. (Gentiment, il oublie de rappeler que certains attaquants n'ont pas besoin de pirater les GAFA : ils ont PRISM pour cela.)
La session a aussi mis en évidence l'importance d'utiliser un vocabulaire rigoureux quand on parle des menaces et des solutions techniques, surtout quand on s'adresse à un public non-spécialiste. Ainsi, les solutions contre les attaques de l'Homme du Milieu ne « protègent » pas contre ces attaques : elles les rendent simplement visibles. C'est la réaction aux alertes qui déterminera si on est protégé ou pas (pensez au traditionnel avertissement des navigateurs Web : « voulez-vous continuer malgré ce certificat mal fichu ? »).
Une autre session portait sur l'usage des outils de sécurité (section 5.3). Ce n'est pas tout de concevoir des outils géniaux, il faut encore qu'ils soient utilisés. Aujourd'hui, on constate que ce n'est pas assez le cas. Combien de messages circulent en clair quand ils devraient être chiffrés avec PGP ? Combien de SMS envoyés de manière à être lisibles par tous alors qu'il faudrait utiliser Signal (ex-TextSecure) ? Combien de webmestres renoncent à activer HTTPS parce qu'ils ne veulent pas payer une AC et subir ses procédures et son interface Web mal faite ?
Le RFC note que, dans ce dernier cas, ils ont raison, vu la faille fondamentale de ce système des AC : n'importe quelle AC peut émettre un certificat pour n'importe quel domaine. Donc, il suffit qu'une seule des centaines d'AC reconnues par le logiciel soit compromise pour faire s'effondrer tout l'édifice. Des solutions techniques existent (cf. RFC 6962 ou le RFC 6698, curieusement oublié ici).
Un des problèmes à l'usage des outils de sécurité peut être le modèle de confiance utilisé. Dans X.509, c'est « toutes les AC ont raison ». C'est très dangereux pour la sécurité. PGP a un modèle « réseau de confiance » qui a l'inconvénient de ne bien marcher que pour des petites communautés (il n'est pas réellement transitif). Un modèle longtemps méprisé par les experts en sécurité (ceux avec qui, si on les écoute, on ne déploie jamais aucune solution de sécurité, car aucune n'est parfaite) est le TOFU, utilisé par SSH ou Signal. Il a l'avantage d'être beaucoup plus facile pour les utilisateurs, mais l'attaque de l'Homme du Milieu reste possible pour la première connexion. La technique de l'« épinglage des clés » (RFC 7469) est une variante de TOFU.
Et pour SIP ? La constatation de l'atelier était que les fonctions de cryptographie dans SIP, pourtant bien normalisées, étaient peu utilisées. L'argument des opérateurs SIP est que les mises en œuvre de ce protocole sont peu interopérables et que la seule solution pour que ça marche est de modifier les échanges en cours de route, rajoutant ou enlevant des en-têtes SIP pour s'adapter à chaque logiciel. (S'ils ont raison, cela signifie que les RFC sur SIP n'étaient pas clairs, ou bien que les programmeurs ne les ont pas lus.)
Peut-être que WebRTC en tirera les leçons (RFC 8827). Après tout, WebRTC est mis en œuvre par les auteurs de navigateurs et ceux-ci n'ont pas les mêmes intérêts que les opérateurs SIP (les intermédiaires adorent modifier les données et détestent la sécurité de bout en bout).
Et pour XMPP (RFC 6120), pourquoi les techniques de sécurité existantes ne sont-elles pas plus fréquemment utilisées ? XMPP a de l'authentification et du chiffrement du canal, grâce à TLS, et de l'authentification et du chiffrement de bout en bout, grâce à OTR (qui a par contre le gros défaut d'être mal intégré au protocole XMPP). Mais le problème identifié pendant la session est plutôt que XMPP est peu utilisé. Contrairement au courrier électronique, où tout le monde utilise les solutions standard (SMTP et IMF), pour la messagerie instantanée, M. Michu fait une confiance aveugle à des systèmes fermés et privatifs comme Skype, dont la sécurité est inconnue ou inexistante.
Il y avait bien sûr une session consacrée aux questions non techniques (section 5.4) car on sait bien maintenant que « la sécurité n'est pas un produit, c'est un processus ». Installer un outil technique ne suffit pas. Il faut aussi traiter les questions d'éducation des utilisateurs, les questions politiques, les questions juridiques... Ainsi, l'excuse du terrorisme est largement utilisée par les États pour justifier des politiques répressives, tellement répressives qu'elles auraient été largement considérées comme inacceptables il y a seulement quelques années (voir par exemple ce qui se fait en France en ce moment avec l'état d'urgence). Il y aussi, note le RFC, le problème des traités internationaux pro-commerce (comme TTIP) qui contiennent souvent des mesures anti-vie privée.
On note que, d'une façon générale, ces problèmes non techniques étaient traditionnellement peu pris en compte par les organisations comme l'IETF, ou par les informaticiens en général. Cela fait très longtemps que les chercheurs en médecine, par exemple, ont des comités d'éthique qui se penchent sur les conséquences de leur travail. Faudrait-il faire la même chose pour les SDO ? Pour l'instant, les normes qui ont reçu une évaluation extérieure sur les questions de vie privée (comme l'API de géolocalisation) l'ont été ponctuellement, sans démarche systématique.
Cela n'interdit pas d'améliorer les outils et une session était consacrée à cette activité (section 5.5 du RFC). D'abord, l'atelier a discuté de la sécurité opportuniste (au sens de « essayer de chiffrer autant que possible, même sans authentification, ce serait mieux que rien »), en considérant qu'elle n'avait pas été assez utilisée jusqu'à présent. L'une des difficultés de cet opportunisme est de ne pas donner de faux sentiments de sécurité à l'utilisateur. Par exemple, il y avait un consensus dans l'atelier que, si un logiciel tente TLS et y réussit, mais sans authentification, il ne doit pas présenter à l'utilisateur des signes rassurants, genre petit cadenas. Le chiffrement ainsi obtenu est un progrès mais il ne faut pas donner l'impression qu'on s'arrête là.
Un aspect délicat à l'heure actuelle est de l'attitude à avoir
lorsqu'on ne peut pas chiffrer : est-ce parce que le pair ne sait
effectivement pas ou bien parce qu'un Homme du Milieu a réussi à
empêcher le chiffrement ? Pour des sessions qu'on veut sécurisées
(https://...
vers sa banque), il faut
évidemment s'arrêter là. Mais pour les autres, il serait
intéressant, plutôt que de se rabattre sur de la communication en
clair, ce qui est souvent le choix, de se souvenir des
communications précédentes avec ce pair et de décider en fonction
du passé si ce problème de chiffrement est normal (une forme de
TOFU).
Là aussi, la terminologie est importante. Les descriptions des connexions utilisant le « chiffrement, si possible » (sécurité opportuniste) parlent souvent d'« échec » si la session chiffrée n'a pu être établie alors qu'un tel échec n'est pas pire que si on n'avait même pas essayé. Il faudrait plutôt parler d'« amélioration » quand on a réussi à lancer le chiffrement (et ne rien dire si on n'y est pas arrivé). Là aussi, le fait que les concepteurs de protocoles, les experts en sécurité et les programmeurs ne soient pas des spécialistes de l'interface utilisateur va jouer : il n'est pas évident de communiquer des informations sur le niveau de sécurité à l'utilisateur.
Autre point sur lequel il faudrait améliorer les outils, le fait de chiffrer systématiquement, sans action explicite de l'utilisateur. Sinon, il y a un risque que l'utilisateur ne chiffre que les documents sensibles, ce qui facilite la tâche des espions, en leur indiquant quels sont les documents importants. (C'est un des problèmes de PGP, je trouve.)
Il serait également intéressant d'améliorer TOFU. Un des gros problèmes de ce modèle, tel qu'il est utilisé dans SSH, est qu'il n'existe pas de mécanisme propre pour changer la clé d'un serveur (par exemple parce qu'on a mis à jour le logiciel). Idem si on utilise Signal : si votre correspondant a perdu son téléphone et en a acquis un nouveau, il faut manuellement vérifier la nouvelle identité (TOFU ne peut pas savoir si c'est un changement de clé légitime ou bien une attaque de l'Homme du Milieu).
Un sujet qui fait l'objet de nombreuses discussions dès qu'on parle de vie privée et de surveillance est celui des métadonnées (section 5.6). Chiffrer protège en effet très bien le contenu. Malgré quelques rumeurs, il est peu probable que même les plus puissants attaquants arrivent aujourd'hui à craquer le chiffrement bien fait (attention : bien chiffrer est beaucoup plus dur que ce n'en a l'air). Pour un attaquant rationnel, voler les clés, acheter ou menacer un destinataire légitime, ou encore corrompre le logiciel de chiffrement est bien plus aisé que de casser le chiffrement lui-même (c'est d'ailleurs pour cela que les discussions de détail sur la longueur des clés sont assez ridicules). Mais ce chiffrement n'aide pas si les métadonnées sont, elles accessibles. Pour prendre un exemple classique, imaginons deux personnes qui se téléphonent et chiffrent la communication. Le fait qu'ils se téléphonent est lui-même une information, qui peut être suffisante pour un espion, même s'il n'a pas accès au contenu des communications. C'est encore plus vrai si on a accès à plusieurs communications : si, à chaque fois que A appelle B au téléphone, B, immédiatement après avoir raccroché, appelle C, D et E, on en déduira facilement qu'on a identifié une chaîne de commandement, même si on n'a pas le contenu de leurs conversations. Cet exemple illustre bien le danger des métadonnées. Parfois, même la taille des messages donne des indications (si vingt fichiers de taille différente sont sur un serveur, l'observation du trafic, même chiffré, permet de savoir quel fichier a été récupéré).
Or, ces métadonnées sont partout, soit qu'elle soient absolument indispensables au fonctionnement des protocoles (comme l'adresse IP de destination dans les paquets IP), soit que leur potentiel d'indiscrétion n'ait pas été perçu tout de suite. Les supprimer n'est pas évident : un routeur a bien besoin de l'adresse de destination pour router !
Il y a trois techniques pour lutter contre l'espionnage par les
métadonnées : l'agrégation, le détour
(contraflow), et la dispersion
(multipath). L'agrégation consiste à regrouper
des conversations différentes dans un même flux de données. Par
exemple, si votre résolution DNS passe par
un gros résolveur partagé, les serveurs qu'interroge ce résolveur
auront du mal à identifier vos requêtes, toutes passant par le
résolveur. Idem en HTTP si on utilise un
relais partagé, sauf
évidemment si celui-ci laisse passer, ou, pire, ajoute, des
informations discriminantes comme le
User-Agent:
. Même chose côté serveur : si vos
pages « sensibles » sont hébergées sur un serveur mutualisé, un
observateur aura du mal à dire ce qui était demandé (là
encore, tout est dans les détails : par exemple,
SNI peut trahir la communication).
Le détour consiste à passer délibérement par des chemins supplémentaires. C'est ce que fait un VPN ou, en encore mieux, Tor. Un espion qui voudrait identifier votre trafic devrait observer l'Internet en de nombreux points, et corréler ce qu'il voit.
Quant à la dispersion, elle consiste à envoyer les données par des moyens différents. Si vous commencez une conversation XMPP via de la 4G et que vous continuez en Wifi, l'attaquant aura davantage de mal que si toute la communication passe par un seul canal.
L'analyse de trafic donne souvent des résultats surprenants d'efficacité, dont les concepteurs de protocole ne se rendent pas compte. (Voir la bibliographie de FreeHaven, par exemple.) Il existe des méthodes pour la contrarier, comme d'ajouter des messages vides (padding, voir par exemple le RFC 7540, sections 6.1 et 10.7) mais elles ont un coût (par exemple en terme de débit) et ne sont pas faciles à utiliser.
Notez que les protections de bas niveau (couche 3) ne sont pas très utiles si les applications elle-même font fuiter des données. Un navigateur Web est particulièrement terrible sur ce point, voir le Panopticlick. C'est pour cela que Tor recommande l'usage du Tor Browser qui ne se contente pas de router les données via Tor, mais qui s'assure aussi que le navigateur ne vous trahit pas, et n'envoie qu'un minimum de données.
Un problème fréquent pour tous les systèmes de sécurité est celui des middleboxes, ces équipements intermédiaires qui se permettent de filtrer les messages, voire de les modifier. Beaucoup de protocoles de sécurité de l'Internet sont conçus pour une connexion de bout en bout : c'est le cas de TLS, par exemple. La middlebox viole cette supposition. On voit, par exemple, des middleboxes qui terminent la session TLS, analysent le trafic, puis re-chiffrent de l'autre côté. Pour passer l'authentification TLS, elles imposent en général de mettre le certificat d'une AC complice sur les ordinateurs clients. À noter que, dans la configuration TLS typique, le client authentifie le serveur mais pas le contraire. Ce qui veut dire qu'un serveur, même ultra-paranoïaque, n'a aucun moyen, contrairement au client, de détecter qu'une middlebox est présente.
Un autre exemple typique de middlebox courante est le portail captif (cf. RFC 6585 mais aussi le RFC 7710, issu des réflexions de cet atelier). Certains systèmes d'exploitation utilisent diverses heuristiques pour détecter la présence d'un portail captif afin, par exemple, de permettre une connexion automatisée. Mais ces heuristiques ne marchent évidemment pas toujours. (D'autant plus qu'il semble que certains points d'accès font tout pour empêcher ces heuristiques de marcher, afin d'empêcher les connexions automatisées.)
Idéalement, il faudrait un protocole nouveau permettant aux portails captifs de se signaler, sans avoir à jouer les Hommes du Milieu. Mais, même si un tel protocole était nnormalisé demain, il faut se rappeler que la plupart des points d'accès ne sont jamais mis à jour... (Un hôtel, par exemple, se moque pas mal de si son portail captif marche bien ou pas.)
L'atelier STRINT a ensuite vu les participants se répartir en petits groupes (break-outs) pour discuter en profondeur certains sujets. Par exemple, l'un de ces groupes s'attaquait à l'analyse des clients. Si certains ignorants ne considèrent que les navigateurs Web, les participants à l'atelier savaient bien, eux, qu'il existe une grande variété de logiciels clients. L'un des problèmes de ces clients est « que faire lorsqu'un certificat pose un problème ? » Certains administrateurs système disent simplement aux utilisateurs « continuez, ne vous inquiétez pas de cet avertissement », conseil qu'il sera difficile de faire désapprendre aux utilisateurs ensuite. Peut-être faudrait-il que les logiciels clients ne fournissent plus d'option pour passer outre un problème de certificat. Mais un tel changement devrait être fait plus ou moins simultanément par tous les auteurs de logiciels de cette catégorie. Autrement, il y a un risque que l'utilisateur croit que les logiciels les plus sûrs sont en tort, en l'empêchant de se connecter à son serveur.
Autre problème d'interaction entre la sécurité informatique et les facteurs humains, le cas des certificats auto-signés. Si un tel certificat est évidemment inacceptable pour une banque ou pour GitHub, pour un site personnel, il peut être tout à fait valable et en tout cas meilleur qu'une communication en clair. Un des aspects délirants de l'usage de HTTPS aujourd'hui est que bien des gérants de serveurs personnels n'activent pas HTTPS car obtenir un certificat est cher et compliqué, et utiliser un certificat auto-signé provoquerait des avertissements de sécurité injustifiés. Résultat : on reste en clair...
Un autre groupe travaillait sur l'activation par défaut des meilleurs choix de sécurité. Quant l'IETF dit que tous les programmes DOIVENT (MUST, cf. RFC 2119) mettre en œuvre tel protocole ou tel algorithme, cela veut dire qu'il doit être présent dans le code (MTI ou Mandatory To Implement, cf. RFC 3365). Mais cela ne signifie pas qu'il sera utilisé, s'il faut une action explicite de l'utilisateur ou de l'administrateur système pour l'activer. La très grande majorité des utilisateurs, et la plupart des administrateurs système, ne changent pas les réglages par défaut. Si on veut vraiment combattre la surveillance généralisée, il ne suffit pas d'avoir 2 ou 3 % des utilisateurs qui sont protégés. Il faut que presque tous le soient, donc passer du MTI au MTU (Mandatory To Use).
Enfin, un autre groupe break-out a planché sur la notion de « sécurité opportuniste » (opportunistic security). Le terme est très utilisé dans les milieux de la sécurité informatique mais n'a pas de définition précise. Plusieurs auteurs ont essayé d'en donner une définition (voir par exemple le RFC 4322) mais ces définitions sont très différentes les unes des autres. Depuis, l'IETF a publié la sienne, dans le RFC 7435.
On l'a dit, ce RFC arrive bien tard après l'atelier. Depuis, du travail a été fait. Juste après l'atelier, la réunion IETF de Londres a logiquement beaucoup couvert ces questions de protection contre l'espionnage. Ce fut par exemple la « DNSE BoF », première réunion physique du projet « DNS et vie privée », qui a depuis débouché sur le RFC 7626.
La totalité des articles présentés est en ligne.
Date de publication du RFC : Décembre 2015
Auteur(s) du RFC : W. Kumari (Google), O. Gudmundsson
(CloudFlare), P. Ebersman
(Comcast), S. Sheng (ICANN)
Chemin des normes
Première rédaction de cet article le 14 décembre 2015
Les portails captifs sont une des plaies de l'accès à l'Internet. À défaut de pouvoir les supprimer, ce nouveau RFC propose des options aux protocoles DHCP et RA pour permettre de signaler la présence d'un portail captif, au lieu que la malheureuse machine doive le détecter elle-même. depuis, il a été remplacé par le RFC 8910.
On trouve de tels portails captifs en de nombreux endroits où de l'accès Internet est fourni, par exemple dans des hôtels ou des cafés. Tant que l'utilisateur ne s'est pas authentifié auprès du portail captif, ses capacités d'accès à l'Internet sont très limitées. Quels sont les problèmes que pose un portail captif ?
Pourquoi est-ce que ces hôtels et cafés s'obstinent à imposer le passage par un portail captif ? On lit parfois que c'est pour authentifier l'utilisateur mais c'est faux. D'abord, certains portails captifs ne demandent pas d'authentification, juste une acceptation des conditions d'utilisation. Ensuite, il existe une bien meilleure solution pour authentifier, qui n'a pas les défauts indiqués plus haut. C'est 802.1X, utilisé entre autres dans eduroam (voir RFC 7593). La vraie raison est plutôt une combinaison d'ignorance (les autres possibilités comme 802.1X ne sont pas connues) et de désir de contrôle (« je veux qu'ils voient mes publicités et mes CGU »).
L'IETF travaille à développer un jour un protocole complet d'interaction avec les portails captifs, pour limiter leurs conséquences. En attendant, ce RFC propose une option qui permet au moins au réseau local de signaler « attention, un portail captif est là, ne lance pas de tâches - comme Windows Update - avant l'authentification ». Cette option peut être annoncée par le serveur DHCP (RFC 2131 et RFC 8415) ou par le routeur qui envoie des RA (RFC 4861).
Cette option (section 2 du RFC) annonce au client qu'il est derrière un portail captif et lui fournit l'URI de la page d'authentification (ce qui évite d'être détourné, ce qui est grave quand on utilise HTTPS). Dans cet URI, le serveur HTTP doit être désigné par son adresse IP, pour éviter d'avoir à faire du mensonge DNS.
Les sections 2.1, 2.2 et 2.3 de notre RFC donnent le format de l'option en DHCP v4, DHCP v6 et en RA. Le code DHCP v4 est 160 (qui était malheureusement squatté, ce qui a nécessité son changement dans le RFC 8910), le DHCP v6 est 103 et le type RA est 37.
La section 4 de notre RFC étudie les conséquences de cette option pour la sécurité. Elle rappelle que DHCP et RA ne sont pas sécurisés, de toute façon. Donc, un méchant peut envoyer une fausse option « il y a un portail captif, allez à cet URI pour vous authentifier » mais le même méchant peut aussi bien annoncer un faux routeur...
Il est même possible que cette option nouvelle améliore la sécurité, en n'encourageant pas les utilisateurs à couper les mécanismes de validation comme la vérification des certificats, contrairement à ce que font les portails captifs actuels.
Pour DHCP, la plupart des serveurs permettent de servir une option quelconque, en mettant ses valeurs manuellement et une future mise à jour ne servira donc qu'à rendre l'usage de cette option plus simple. Autrement, il n'existe pas encore de mise en œuvre côté clients DHCP ou RA. (Pour des nouvelles plus récentes, voir le RFC 8910.)
Date de publication du RFC : Décembre 2015
Auteur(s) du RFC : D. McPherson (Verisign), S. Amante
(Apple), E. Osterweil
(Verisign), L. Blunk (Merit
Network), D. Mitchell (Singularity
Networks)
Pour information
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 13 décembre 2015
On le sait, il n'y a pas de
chef de l'Internet. Personne ne
reste dans un bureau toute la journée avec pour mission l'envoi de
règles qui seront immédiatement appliquées par tous les acteurs de
l'Internet. C'est même le cas des fonctions les plus essentielles
de l'Internet comme l'échange des tables de
routage. Tout l'Internet ne tient que parce
que les opérateurs sont d'accord entre eux pour s'échanger
l'information qui se retrouvera dans ces tables « pour joindre le
préfixe 2001:db8:fe2::/48
, passez par moi, je
connais un chemin que j'ai appris des AS
64499 puis 429496613 ». Cet accord de principe se double d'un
accord technique sur le protocole à utiliser :
BGP, normalisé dans le RFC 4271. Et au-delà, rien, aucun accord : chaque opérateur
est libre de sa politique et notament de ce qu'il accepte ou
refuse. Un opérateur peut refuser les préfixes plus spécifiques
que /32, par exemple. Chacun est maître chez soi. En pratique,
bien des opérateurs refusent les préfixes qui ne sont pas dans un
IRR. C'est quoi, un IRR ? Qui les gère ?
Qui décide de ce
qu'on met dans un IRR ?. Ce nouveau RFC
explore la question.
Un IRR (Internet Routing Registry) est une base de données stockant des préfixes d'adresses IP et des informations de politique associées comme, par exemple, le ou les AS qui sont autorisés à annoncer ce préfixe en BGP ou bien les communautés BGP (RFC 1997) utilisées. Le RFC 1787, dans sa section 7, décrit l'importance de partager l'information entre les opérateurs. Certes, chacun est maître chez lui, mais tout serait plus simple si chacun partageait avec les autres, pour limiter le risque de décisions malencontreuses.
Mais les IRR ont des problèmes et des limites (introduction en section 3). Première catégorie de problèmes, l'exactitude et l'intégrité des données stockées (section 4). Comme tous les registres utilisés sur l'Internet, les IRR sont plein de données fausses ou dépassées. Les personnes qui mettent ces données dans les registres n'ont guère de motivations pour mettre des données correctes et encore moins pour les mettre à jour. Les données sont donc souvent erronées.
En outre, il n'existe pas de moyen largement déployé de vérifier ces données dès le départ. Si Pakistan Telecom met dans un IRR qu'ils sont autorisés à annoncer le préfixe de YouTube, comment vérifier qu'ils ont le droit de le faire ? Le langage utilisé pour les IRR, RPSL (normalisé dans le RFC 2622) le permet techniquement mais en l'absence d'un mécanisme de signature cryptographique entre le préfixe et l'AS, cela ne permet pas de s'assurer de l'authenticité du contenu de l'IRR. Le RFC note à juste titre que cette absence de mécanisme de signature vient en partie d'un manque d'intérêt de la communauté des opérateurs : tout le monde se plaint des détournements BGP mais personne n'est prêt à faire les considérables efforts qu'il faudrait pour tout certifier.
Bien sûr, certains IRR ont des mesures de sécurité (par exemple, dans la base RIPE, seul le titulaire d'un préfixe peut ajouter des routes pour ce préfixe, cf. RFC 2725 et c'est une obligation contractuelle, cf. ripe-637) mais cela ne s'étend pas aux autres IRR, qui ne peuvent pas vérifier que cette sécurité a été respectée. Difficile donc de savoir quelle politique de sécurité a été utilisée par un IRR donné.
Même quand les données sont correctes, en l'absence de mécanismes de vérification fondés sur la cryptographie, on peut parfois se retrouver avec des données fausses alors qu'elles étaient justes au départ.
Il existe de nombreuses propositions pour créer de tels systèmes de vérification et de certification (TASRS, HotNets-X et bien sûr la RPKI) mais aucune n'a encore un déploiement suffisant.
Comme indiqué plus haut, une partie du problème est le manque
de motivation : le titulaire d'une ressource Internet (un préfixe
IP, par exemple) peut avoir un intérêt direct à ajouter une
information dans un IRR (par exemple parce que son
transitaire est strict, et lui impose cet ajout, avant d'accepter
l'annonce BGP du titulaire) mais il a rarement de raison objective
de le maintenir à jour ou, surtout, de le détruire quand il n'est
plus utilisé. Certains acteurs bâtissent leurs filtres d'annonces
BGP à partir des IRR, ce qui fait qu'une information manquante se
paie d'un manque de visibilité BGP. Mais il n'y a aucune pénalité à
avoir de l'information en trop. Si un client, titulaire d'un
préfixe IP, passe d'un transitaire strict, qui lui imposait une
entrée dans un IRR (par exemple un objet
route
dans la base
RIPE-NCC) vers un transitaire laxiste qui
n'impose rien, le client n'a aucune motivation (à part la pureté
de l'IRR, qui n'intéresse qu'une poignée de barbus fanatiques
utilisant OpenBSD) à changer l'ancienne entrée. Il la laissera probablement
telle quelle. Le nouveau transitaire, qui ignore l'IRR, n'en
tiendra pas compte.
Une des rares motivations concrètes qui pourrait mener à un nettoyage des IRR est le manque de mémoire dans les routeurs : les filtres pourraient devenir trop gros, si personne ne nettoie jamais. Heureusement pour les utilisateurs des routeurs, mais malheureusement pour la pureté de l'IRR, les routeurs PE modernes ont en général assez de mémoire dans leur module de routage (control plane) pour que cela ne soit plus un problème.
Autre problème avec les IRR, le fait que leur modèle de
sécurité soit en général basé sur « le titulaire peut tout, les
autres ne peuvent rien ». Si une information est dépassée, un
tiers qui s'en aperçoit ne peut rien faire, seul le titulaire est
autorisé à la modifier. Pas moyen de nettoyer pour compenser la
négligence d'un titulaire. C'est pour cela que le RFC 2725 avait prévu le mécanisme
auth-override
, qui semble n'avoir jamais été
mis en œuvre.
Pour accéder aux données des IRR, on utilise souvent whois. Un exemple (une liste des IRR existe en ligne) :
% whois -h whois.radb.net 192.134.5.10 route: 192.134.5.0/24 descr: NIC-FR-SITE-TH3 origin: AS2485 mnt-by: FR-NIC-MNT mnt-lower: FR-NIC-MNT mnt-routes: FR-NIC-MNT changed: jean-philippe.pick@nic.fr 20110214 remarks: Peering: peering@nic.fr remarks: NOC: noc@nic.fr remarks: Info: http://www.nic.fr/ source: RIPE remarks: **************************** remarks: * THIS OBJECT IS MODIFIED remarks: * Please note that all data that is generally regarded as personal remarks: * data has been removed from this object. remarks: * To view the original object, please query the RIPE Database at: remarks: * http://www.ripe.net/whois remarks: ****************************
On y voit que seul l'AS 2485 est autorisé à être l'origine d'une
annonce pour le préfixe 192.134.5.0/24
.
Un plaisir des IRR existants est qu'on n'a pas de moyen
simple, étant donné une ressource Internet (par exemple un préfixe
IP), de savoir quel IRR utiliser. Les clients logiciels existants
doivent utiliser diverses heuristiques. Par exemple GNU whois utilise un
fichier de configuration local - /etc/whois.conf
, des règles incluses dans
le client - fichier ip_del_list
dans le
source, et compte sur le serveur whois de
l'ARIN pour le rediriger, pour les
ressources inconnues (cette fonction de redirection étant une
extension absente du protocole officiel whois, normalisé dans le
RFC 3912).
À noter que whois ne fournit aucune confidentialité : le protocole est du simple TCP en clair sur le port 43. (Le protocole RDAP, lui, fournit un mécanisme de chiffrement via TLS.)
La section 5 de notre RFC se penche sur le fonctionnement interne des IRR et notamment sur leur synchronisation. Il est fréquent en effet que les IRR copient les données gérées par d'autres IRR. Cela se fait en général avec le protocole NRTM (protocole ressemblant à whois, et qui est peu ou pas documenté). Ce protocole n'a aucun mécanisme de sécurité (en pratique, la seule protection est la limitation d'accès à certaines adresses IP) et est peu robuste (des erreurs de synchronisation ont déjà eu lieu). Il fonctionne en mode pull et il n'y a pas de mécanisme de notification pour indiquer la présence de données récentes. Une autre façon de synchroniser des IRR est de télécharger un fichier plat, par exemple en FTP, qu'on applique ensuite à la copie locale (ce qui facilite l'application de modifications locales). Ce téléchargement et cette synchronisation sont typiquement faits toutes les 24 heures (une période qui date de l'époque où les réseaux étaient plus lents qu'aujourd'hui, et qui n'a pas toujours été réévaluée depuis), ce qui fait que les données ne sont pas forcément de la première fraicheur. On notera que le logiciel irrd synchronise toutes les dix minutes, par défaut.
Un standard existe pour cette réplication d'IRR, le RFC 2769, mais il ne semble pas avoir jamais eu le moindre succès, peut-être parce qu'il dépend du standard de sécurité RFC 2725, également peu ou pas répandu.
Les filtres effectivement utilisés par les routeurs de l'opérateur sont créés à partir d'un IRR, et cette création implique une autre étape (et les délais associés). Typiquement, l'opérateur utilise un logiciel comme IRRtoolset, qui va traduire les objets trouvés dans l'IRR en règles pour un type de routeur donné. Ce logiciel ne tourne pas en permanence. Conséquence pratique : un changement dans l'IRR a intérêt à ne pas être urgent ! Il n'y a aucun moyen de forcer les opérateurs à télécharger tout de suite les nouvelles données, et à faire tourner la « moulinette » qui va produire les règles pour les routeurs. Si on est un client payant de l'opérateur, on peut parfois les appeler et obtenir que cette opération soit faite de suite, mais ce n'est pas toujours le cas.
Idéalement, lorsqu'une politique change (par exemple un AS
annonce un nouveau préfixe), il « suffit » de changer l'IRR,
d'attendre les copies dans les autres IRR, puis l'exportation des
données depuis les IRR vers les routeurs. Mais le protocole BGP ne
permettait pas forcément de changer les caractéristiques d'une
session en vol (section 6 de notre
RFC) et exigeait une opération de réinitialisation, pour que le
routeur accepte les nouvelles routes. Pendant cette opération,
tout ou partie du travail normal du routeur était mis en
attente... Résultat, cette opération (clear ip
bgp neighbor...
sur les Cisco...) ne
pouvait se faire que pendant les périodes de maintenance. C'est un
bon exemple d'un cas où les « bonnes pratiques » (n'accepter que
les préfixes décrits dans les IRR) sont irréalisables dans un
environnement de production (cf. section 8). Le yakafokon ne marche pas bien dans
le monde des réseaux.
Heureusement, ce problème spécifique appartient largement au passé : les extensions à BGP des RFC 2918 et RFC 7313 ont largement supprimé ces obligations.
Il y a aussi les limites inhérentes à certaines mises en œuvre de BGP (section 7 du RFC). Par exemple, au milieu des années 1990, la plupart des routeurs ne permettaient pas de modifier les listes de préfixes acceptés de manière incrémentale : il fallait effacer la liste, puis installer une nouvelle liste, créant ainsi une fenêtre de vulnérabilité pendant laquelle des routes pouvaient fuir. Là aussi, ce problème a largement disparu avec les progrès des routeurs (voir aussi les sections 1 et 8, qui expliquent bien que certains problèmes historiques d'utilisation des IRR sont désormais du passé).
Rien n'est gratuit en informatique : le stockage des listes de préfixes IP acceptés nécessite de la mémoire et, pendant longtemps, les routeurs disposaient de trop peu de mémoire (une NVRAM bien limitée, et très lente en écriture). Les routeurs modernes ont des mémoires flash ou SSD, voire des disques durs et ont donc une bien meilleure capacité. D'un autre côté, les exigences ont crû et la taille de certaines configurations peut toujours poser des défis aux mémoires des routeurs (voir « NTT BGP Configuration Size and Scope »).
Dernier problème, l'envoi aux routeurs des changements. Autrefois, il n'y avait aucun standard en ce sens. Chaque routeur avait son CLI et il fallait générer depuis l'IRR les quelques lignes de commandes qui allaient changer la configuration du routeur, lui faisant accepter de nouveaux préfixes, ou bien refuser ceux qui étaient acceptés. Le routeur recevait ensuite en telnet, puis SSH, l'ordre de charger ces quelques lignes en TFTP ou FTP, puis, plus tard, en SCP. On pouvait alors activer la nouvelle configuration.
De nos jours, il existe une norme pour cela, NETCONF (RFC 6241). On génère toujours des données depuis l'IRR, puis on utilise NETCONF pour les charger. Les données issues de la RPKI peuvent, elles, être envoyées en RTR (RFC 6810) mais cela ne concerne pas tout le reste de la configuration du routeur.
Un petit mot de sécurité pour finir (section 9 du RFC). Le but des IRR étant d'influencer le routage à distance, ces IRR sont donc des ressources sensibles : si quelqu'un peut pirater un IRR et y injecter de fausses données, il peut perturber le routage Internet. Si ce problème est trop fréquent, les opérateurs pourraient en arriver à ne plus utiliser les IRR. Une gestion rigoureuse de leur sécurité est donc cruciale.
Voilà, si vous voulez en savoir davantage sur les IRR, il y a
bien sûr l'incontournable site http://www.irr.net/
.
Date de publication du RFC : Décembre 2015
Auteur(s) du RFC : M. Blanchet (Viagenie), L-J. Liman (Netnod)
Première rédaction de cet article le 13 décembre 2015
L'Internet repose en grande partie sur
le DNS (si ce
dernier est en panne, presque plus rien ne fonctionne) et le DNS
doit à sa nature arborescente de dépendre de sa racine ou plus
exactement de ses serveurs
racine. La gestion de ces derniers est donc une
question cruciale, même si les débats sur la gouvernance de
l'Internet se focalisent plutôt sur des sujets moins
concrets comme la création (ou non) du TLD .vin
. Ce très
court RFC
précise les obligations des serveurs racine en terme de protocoles réseau à
suivre. D'autres documents décrivent les exigences
opérationnelles. (Voir notamment le RSSAC
001: Service Expectation of Root Servers.)
Avant, ces obligations étaient dans un seul RFC, le RFC 2870. Il contenait des recommandations concernant les protocoles, donc plutôt du ressort de l'IETF, et d'autres concernant les règles quotidiennes des opérations d'un serveur racine, considérées aujourd'hui comme relevant plutôt du RSSAC (Root Server System Advisory Committee, qui publie ses propres recommandations dans le document nommé RSSAC-001). Ce RFC est donc encore plus court que son prédécesseur, désormais document historique.
À noter que les serveurs racine ne servent pas que la racine, mais aussi
root-servers.net
, domaine dans lequel ils
sont nommés. Certains d'entre eux servent également .arpa
.
Le cœur de notre RFC est la section 2 qui exige que les serveurs racine :
La plupart de ces règles vont de soi mais, en 2015, on rencontre hélas encore des serveurs DNS qui n'ont pas EDNS ou bien qui n'ont pas TCP (sans même parler d'IPv6...)
Moins liées aux protocoles, il y a deux autres exigences dans la section 3 :
Merci à Lancelot et Atlal (et Opale), qui savent pourquoi...
Date de publication du RFC : Novembre 2015
Auteur(s) du RFC : D. Crocker (Brandenburg InternetWorking), N. Clark (Pavonis Consulting)
Pour information
Première rédaction de cet article le 12 décembre 2015
La question de la diversité dans les organisations qui contribuent d'une manière ou d'une autre au bon fonctionnement de l'Internet a souvent été discutée. Un simple coup d'œil à une réunion IETF permet de voir de nets déséquilibres (peu de femmes, peu de gens originaires d'Afrique ou d'Amérique Latine...). Comme le dit le résumé de ce nouveau RFC : « a small group of well-funded, American, white, male technicians ». Même si ce résumé est exagéré, et si le mécanisme ouvert de l'IETF a largement prouvé son efficacité, il n'est pas interdit de creuser la question « comment accroitre la diversité ? », dans l'espoir d'augmenter encore cette efficacité. (Un tel document suscitera forcément des controverses. Par exemple, personnellement, il me semble que la diversité est plutôt une question de justice - faire sauter les éventuelles discriminations - que d'une supposée meilleure efficacité.)
L'état actuel d'une organisation dépend évidemment de son histoire (section 1 du RFC). L'IETF est née d'un effort commencé à la fin des années 1960, et financé par l'ARPA. Au début, il n'y avait donc que des États-Uniens. La participation s'est ensuite étendue à d'autres milieux aux États-Unis, comme ceux financés par la NSF et non plus l'ARPA. À la création formelle de l'IETF, à la fin des années 1980, le projet a été complètement ouvert. Tout le monde peut participer, sans distinction de genre, de nationalité ou de couleur de peau, au moins en théorie.
L'IETF est à juste titre fière du résultat : le processus ouvert s'est avéré particulièrement efficace, permettant aux protocoles TCP/IP d'être très largement déployés, à la place des protocoles conçus par des SDO traditionnelles et fermées. Mais rien n'est éternel et on ne peut évidemment pas garantir que l'IETF gardera éternellement cette ouverture. Une « vigilance citoyenne » permanente est donc nécessaire.
La culture spécifique de l'IETF est née. Elle se caractérise par une grande franchise dans les discussions, loin de l'hypocrisie de beaucoup d'organisations, où on n'affiche jamais ouvertement les désaccords. Comme toute chose peut être vue de deux façons différentes, le RFC parle non pas de franchise mais de « singularly aggressive behavior, including singularly hostile tone and content ». Il ajoute que ce style n'est pas « professionnel », un terme très curieux, comme si l'aggressivité était le privilège des amateurs... Ce qui est sûr, c'est que ce style, qui allait bien aux participants du début, peut être un problème pour la diversité. Un comportement qui serait considéré « un peu trop direct » aux Pays-Bas peut être vu comme « très impoli » au Japon. (Le RFC parle de « more polite cultures », qui peuvent se sentir mal à l'aise face au style franc et direct de l'IETF.)
La section 2 du RFC décrit ensuite pourquoi le manque de diversité est un problème. D'abord, précisons que tous les attributs sont concernés, le genre, la nationalité, la religion, l'orientation sexuelle, etc. Cette section reprend l'idée que des groupes divers prennent des meilleures décisions (en citant, c'est amusant, uniquement des études états-uniennes, et presque toutes limitées au monde du management capitaliste, comme « Better Decisions Through Diversity: Heterogeneity can boost group performance »).
La question de la diversité étant ancienne, il n'est pas étonnant que le débat sur les solutions le soit aussi, et que de nombreuses techniques aient déjà été proposées, et expérimentées. Par exemple, le RFC note que des mesures purement statistiques, comme des quotas, peuvent être difficile à mettre en œuvre dans des groupes restreints. S'il y a deux Area Directors pour la Routing Area de l'IETF, ils ou elles ne peuvent pas représenter à eux deux toute la diversité souhaitée. En outre, le but est la diversité, pas juste des nombres appliqués aveuglément (avoir X % de membres de tel groupe ne sert à rien si ces X % sont silencieux et ne participent pas).
Quels sont les mécanismes qui peuvent, en pratique, limiter la diversité dans l'IETF (puisque, en théorie, tout le monde peut participer) ? Il y a plein d'exemples :
Mais il y a aussi des comportements anti-diversité plus directs et plus actifs comme le harcèlement ou l'intimidation. Ils peuvent être dirigés contre toutes les personnes appartenant (ou supposées appartenir) à tel ou tel groupe (comme « les femmes » ou « les homosexuels ») ou bien dirigés contre des individus spécifiques (comme l'abominable GamerGate). Aucun cas précis n'a été dénoncé à l'IETF, contrairement à ce qui arrive dans d'autres organisations, mais cela ne veut pas dire que cela n'arrivera jamais, ni même que cela n'est pas déjà arrivé : tous les cas ne sont pas publics, par exemple parce que les victimes peuvent hésiter à se plaindre, en raison du risque de représailles. Un futur RFC décrira la politique de l'IETF au sujet du harcèlement.
Malheureusement, ce RFC 7704 continue à décrire un environnement sans harcèlement comme « professional » comme si des actions aussi graves que celles du GamerGate étaient juste un manque de professionnalisme !
La section 3 du RFC s'occupe plutôt de propositions constructives : comment faire pour que tout le monde se sente bienvenu, de manière à augmenter la diversité ? Par exemple, le RFC recommande aux anglophones (la langue de travail de l'IETF est l'anglais) de parler lentement et clairement, et d'éviter les idiosyncrasies locales, ou les références culturelles trop locales (ah, ces allusions agaçantes à des émissions télé US que les non-États-Uniens n'ont pas vu...) Ainsi, la participation des non-anglophones pourra augmenter. Je note personnellement que, lorsqu'une réunion de l'IETF se tient aux États-Unis, les participants parlent bien plus vite et font moins attention à la diversité linguistique.
On peut aussi :
Tout cela n'est pas facile car il faut aussi tenir compte des exigences du travail : le but n'est pas juste d'être gentil mais surtout de créer les nouvelles normes techniques. Un exemple où il est difficile d'atteindre un bon équilibre est celui des réunions physiques des groupes de travail. L'IETF privilégie normalement l'efficacité : on saute directement dans le sujet, on ne passe pas son temps à expliquer, de toute façon, tout le monde est censé avoir travaillé avant, lisant les drafts et les discussions sur la liste de diffusion. Mais cette excellente façon de faire peut décourager les nouveaux, qui n'ont pas compris tous les tenants et aboutissants de la discussion.
Enfin, que faut-il faire contre les gens qui se comportent d'une manière qui peut faire fuir certain·e·s (section 4 du RFC) ? On peut les ignorer si ce n'est pas trop grave mais, au-delà d'un certain niveau de perturbation, il faut faire appel aux autorités (présidents du groupe de travail, ombudsperson, et président de l'IETF si nécessaire).
Quelques ressources supplémentaires sur l'activité de l'IETF à ce sujet :
Date de publication du RFC : Novembre 2015
Auteur(s) du RFC : W. Kumari (Google), P. Hoffman (ICANN)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 26 novembre 2015
Toute résolution DNS commence par la racine (de l'arbre des noms de domaine). Bien sûr, la mémorisation (la mise en cache) des réponses fait qu'on n'a pas besoin tout le temps de contacter un serveur racine. Mais c'est quand même fréquent et les performances de la racine sont donc cruciales. L'idée documentée dans ce RFC est donc d'avoir en local un serveur esclave de la racine, copiant celle-ci et permettant donc de répondre localement aux requêtes. Notez que ce RFC a depuis été remplacé par le RFC 8806.
Le problème est particulièrement important pour les noms qui
n'existent pas. Si les
TLD existants comme
.com
ou
.fr
vont vite se
retrouver dans la mémoire (le cache) du résolveur DNS, les fautes
de frappe ou autres cas où un TLD n'existe pas vont nécessiter la
plupart du temps un aller-retour jusqu'au serveur racine le plus
proche. Les réponses négatives seront également mémorisées mais 1)
il y a davantage de noms non existants que de noms existants 2) le
TTL est plus court (actuellement deux fois
plus court). Ces noms non existants représentent ainsi la majorité du
trafic de la racine.
Bien qu'il existe aujourd'hui des centaines de sites dans le monde où se trouve une instance d'un serveur racine, ce nombre reste faible par rapport au nombre total de réseaux connectés à l'Internet. Dans certains endroits de la planète, le serveur racine le plus proche est assez lointain. Voici les RTT en millisecondes avec les serveurs racine observés depuis un réseau tunisien (notez les deux serveurs qui répondent bien plus vite que les autres, car ils ont une instance à Tunis) :
% check-soa -4 -i . a.root-servers.net. 198.41.0.4: OK: 2015112501 (54 ms) b.root-servers.net. 192.228.79.201: OK: 2015112501 (236 ms) c.root-servers.net. 192.33.4.12: OK: 2015112501 (62 ms) d.root-servers.net. 199.7.91.13: OK: 2015112501 (23 ms) e.root-servers.net. 192.203.230.10: OK: 2015112501 (18 ms) f.root-servers.net. 192.5.5.241: OK: 2015112501 (69 ms) g.root-servers.net. 192.112.36.4: OK: 2015112501 (62 ms) h.root-servers.net. 128.63.2.53: OK: 2015112501 (153 ms) i.root-servers.net. 192.36.148.17: OK: 2015112501 (67 ms) j.root-servers.net. 192.58.128.30: OK: 2015112501 (55 ms) k.root-servers.net. 193.0.14.129: OK: 2015112501 (72 ms) l.root-servers.net. 199.7.83.42: ERROR: Timeout m.root-servers.net. 202.12.27.33: OK: 2015112501 (79 ms)
Ces délais peuvent sembler courts mais ils ne forment qu'une partie du travail de résolution, il est donc légitime de vouloir les réduire encore.
En outre, ces requêtes à la racine peuvent être observées, que ce soit par les opérateurs de serveurs racine, ou par des tiers sur le projet, ce qui n'est pas forcément souhaitable, question vie privée (cf. RFC 7626).
Donc, l'idée de base de ce RFC est de :
Cette idée est documentée dans ce RFC mais n'est pas encouragée (c'est un très vieux débat, dont j'avais déjà parlé). En effet, cela ajoute un composant à la résolution (le serveur local faisant autorité pour la racine), composant peu ou pas géré et qui peut défaillir, entrainant ainsi des problèmes graves et difficiles à déboguer. Mais pourquoi documenter une idée qui n'est pas une bonne idée ? Parce que des gens le font déjà et qu'il vaut mieux documenter cette pratique, et en limiter les plus mauvais effets. C'est pour cela, par exemple, que notre RFC demande que le serveur local n'écoute que sur les adresses locales, pour limiter les conséquences d'une éventuelle défaillance à une seule machine.
Dans tous les cas, le RFC recommande que la configuration décrite ici ne soit pas celle par défaut : l'utilisateur doit l'activer explicitement (et en supporter les conséquences).
Pas découragé ? Vous voulez encore le faire ? Alors, les
détails pratiques. D'abord (section 2 du RFC), les
pré-requis. DNSSEC est indispensable (pour
éviter de se faire refiler un faux fichier de zone par de faux
serveurs racine). Ensuite (section 3), vous mettez un serveur
faisant autorité (par exemple NSD ou
Knot) qui écoute sur une des adresses
locales (en 127.0.0.0/8
,
IPv6 est moins pratique car il ne fournit
paradoxalement qu'une seule adresse locale à la machine) et qui
est esclave des serveurs racine. À noter que votre serveur,
n'étant pas connu des serveurs racine, ne recevra pas les
notifications (RFC 1996) et sera donc
parfois un peu en retard sur la vraie racine (ce qui n'est pas
très grave, elle bouge peu).
Il est important de lister plusieurs serveurs maîtres dans sa configuration. En effet, si la mise à jour de la racine dans votre serveur esclave échoue, ce sera catastrophique (signatures DNSSEC expirées, etc) et cette configuration locale, contrairement à la « vraie » racine, n'a aucune redondance. (Une autre raison pour laquelle ce n'est pas une idée géniale.) Quels serveurs maîtres indiquer ? Certains serveurs racine permettent le transfert de zone (RFC 5936) mais ce n'est jamais officiel, ils peuvent cesser à tout moment (l'annexe A du RFC donne une liste et discute de ce choix). Une raison de plus de se méfier.
Il est donc important d'avoir un mécanisme de supervision, pour être prévenu si quelque chose échoue. On peut par exemple interroger le numéro de série dans l'enregistrement SOA de la racine et vérifier qu'il change.
Ensuite, une fois ce serveur faisant autorité configuré, il ne reste qu'à indiquer à un résolveur (comme Unbound) de l'utiliser (section 4 du RFC).
Voici un exemple, pris dans l'annexe B du RFC et testé. J'ai
choisi l'exemple avec NSD et
Unbound mais il y en a d'autres dans le
RFC. D'abord, la configuration de NSD (notez la longue liste de
maîtres, pour maximiser les chances que l'un d'eux fonctionne ;
notez aussi l'adresse loopback choisie, 127.12.12.12
) :
# RFC 7706 server: ip-address: 127.12.12.12 zone: name: "." request-xfr: 192.228.79.201 NOKEY # b.root-servers.net request-xfr: 192.33.4.12 NOKEY # c.root-servers.net request-xfr: 192.5.5.241 NOKEY # f.root-servers.net request-xfr: 192.112.36.4 NOKEY # g.root-servers.net request-xfr: 193.0.14.129 NOKEY # k.root-servers.net request-xfr: 192.0.47.132 NOKEY # xfr.cjr.dns.icann.org request-xfr: 192.0.32.132 NOKEY # xfr.lax.dns.icann.org request-xfr: 2001:500:84::b NOKEY # b.root-servers.net request-xfr: 2001:500:2f::f NOKEY # f.root-servers.net request-xfr: 2001:7fd::1 NOKEY # k.root-servers.net request-xfr: 2620:0:2830:202::132 NOKEY # xfr.cjr.dns.icann.org request-xfr: 2620:0:2d0:202::132 NOKEY # xfr.lax.dns.icann.org
Le démarrage de NSD (notez qu'il faut patienter un peu la première fois, le temps que le premier transfert de zone se passe) :
Nov 25 19:50:43 machine-locale nsd[2154]: [2015-11-25 19:50:43.791] nsd[2175]: notice: nsd started (NSD 4.1.2), pid 2154 Nov 25 19:50:56 machine-locale nsd[2154]: zone . serial 0 is updated to 2015112501. Nov 25 19:50:56 machine-locale nsd[2154]: [2015-11-25 19:50:56.166] nsd[2154]: info: zone . serial 0 is updated to 2015112501.
C'est bon, on a transféré la zone. Testons (notez le bit AA - Authoritative Answer - dans la réponse) :
% dig @127.12.12.12 SOA . ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61984 ;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 14, ADDITIONAL: 25 ... ;; ANSWER SECTION: . 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. ( 2015112501 ; serial ...
C'est bon.
Maintenant, la configuration d'Unbound (prise dans le RFC) :
server: # RFC 7706 do-not-query-localhost: no # RFC 7706 # Requires a slave auth. running (normally, nsd) stub-zone: name: "." stub-prime: no stub-addr: 127.12.12.12
Et le test :
% dig www.cnam.fr ... ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23562 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 3 ... ;; ANSWER SECTION: www.cnam.fr. 0 IN CNAME sarek.cnam.fr. sarek.cnam.fr. 86400 IN A 163.173.128.52
Ça a marché. Avec tcpdump, on voit le trafic (faible, en raison du cache) vers le serveur racine local :
08:37:24.869569 IP (tos 0x0, ttl 64, id 7734, offset 0, flags [none], proto UDP (17), length 76) 127.0.0.1.10908 > 127.12.12.12.53: 42633% [1au] A? www.tunisair.com.tn. (48) 08:37:24.869671 IP (tos 0x0, ttl 64, id 12657, offset 0, flags [none], proto UDP (17), length 685) 127.12.12.12.53 > 127.0.0.1.10908: 42633- 0/8/13 (657) 08:38:04.734565 IP (tos 0x0, ttl 64, id 12887, offset 0, flags [none], proto UDP (17), length 71) 127.0.0.1.45221 > 127.12.12.12.53: 25787% [1au] A? www.edreams.es. (43) 08:38:04.734645 IP (tos 0x0, ttl 64, id 19270, offset 0, flags [none], proto UDP (17), length 749) 127.12.12.12.53 > 127.0.0.1.45221: 25787- 0/10/14 (721) 08:38:04.734867 IP (tos 0x0, ttl 64, id 12888, offset 0, flags [none], proto UDP (17), length 70) 127.0.0.1.40575 > 127.12.12.12.53: 61589% [1au] AAAA? ns-ext.nic.cl. (42) 08:38:04.734932 IP (tos 0x0, ttl 64, id 19271, offset 0, flags [none], proto UDP (17), length 622) 127.12.12.12.53 > 127.0.0.1.40575: 61589- 0/8/11 (594) 08:44:00.366698 IP (tos 0x0, ttl 64, id 27563, offset 0, flags [none], proto UDP (17), length 62) 127.0.0.1.22009 > 127.12.12.12.53: 30565% [1au] A? po.st. (34) 08:44:00.389126 IP (tos 0x0, ttl 64, id 34039, offset 0, flags [none], proto UDP (17), length 404) 127.12.12.12.53 > 127.0.0.1.22009: 30565- 0/6/5 (376) 08:44:01.229635 IP (tos 0x0, ttl 64, id 27693, offset 0, flags [none], proto UDP (17), length 69) 127.0.0.1.65173 > 127.12.12.12.53: 32911% [1au] AAAA? ns3.perf1.eu. (41) 08:44:01.229705 IP (tos 0x0, ttl 64, id 34207, offset 0, flags [none], proto UDP (17), length 560) 127.12.12.12.53 > 127.0.0.1.65173: 32911- 0/8/10 (532)
Pour BIND on peut suivre le ticket #33.
À noter qu'il existe un brevet futile (comme tous les brevets...) de Verisign sur cette technique : déclaration #2539 à l'IETF.
Date de publication du RFC : Novembre 2015
Auteur(s) du RFC : P. Pfister, B. Paterson (Cisco Systems), J. Arkko (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF homenet
Première rédaction de cet article le 25 novembre 2015
Le projet Homenet, qui vise à relier en un réseau local autonome tous les objets électroniques de la maison, avance (cf. RFC 7368). Parmi les briques indispensables à l'édification de ce réseau de la maison, il fallait un mécanisme d'allocation des adresses IP. Un réseau Homenet devant fonctionner sans administration système, ce mécanisme devait être entièrement automatique. C'est ce que propose ce RFC.
Contrairement au traditionnel réseau domotique actuel, le réseau Homenet peut être constitué de plusieurs réseaux (au sens IP du terme), avec chacun son préfixe IPv6. Si la maison a un préfixe IPv6 délégué, il faut le découper et affecter les sous-préfixes à chaque réseau de la maison. Normalement, c'est le travail de l'administrateur réseaux, qui centralise l'information puis la distribue. Mais, à la maison, il n'y a personne qui puisse ou veuille faire ce travail, il faut donc l'automatiser. Et ce doit être un algorithme réparti car un réseau Homenet n'a pas de machine « chef ».
Cet algorithme prend en entrée une liste de préfixes (le ou les préfixes délégués à la maison), et répartit les sous-préfixes à chaque lien de façon à ce que chaque lien reçoive au plus un sous-préfixe de chacun des préfixes délégués, qu'il n'y ait pas de recouvrement entre les préfixes, et que le tout soit stable, tant que la topologie du réseau ne change pas (cf. section 3 sur les conditions d'usage de cet algorithme).
Le principe (section 4) est que chaque routeur (je simplifie : ce n'est pas forcément un routeur qui choisit le préfixe) va, pour chaque lien, tirer au hasard (pour minimiser le risque de collision), un préfixe plus spécifique que le préfixe délégué et le transmettre ensuite à tout le réseau, via un algorithme d'inondation. Notez bien que c'est une présentation simplifiée : par exemple, le préfixe initial n'est pas forcément tiré au hasard (cf. section 5).
Cet algorithme dépend donc de l'existence d'un algorithme d'inondation, qui n'est pas spécifié dans ce RFC, plusieurs sont envisageables (comme ceux de OSPF - cf. RFC 7503 - ou de HNCP - Home Networking Control Protocol). Il dépend aussi de l'existence d'un identificateur unique par nœud (rappelez-vous que ce RFC n'est qu'une seule des briques d'Homenet, il n'est pas utilisable seul, par exemple il ne dit pas comment cet identificateur est attribué), et que ces identificateurs ont un ordre. Cela servira au cas où plusieurs routeurs veulent le même préfixe, avec la même priorité (celui qui a l'identificateur le plus grand gagne).
Parmi les nombreuses options de l'algorithme, notez qu'il gère également le cas où le lien a déjà eu un préfixe alloué et souhaite le réutiliser. (Une telle stabilité est souhaitable.)
Enfin, la section 8, sur la sécurité, rappelle que ce protocole n'a pas de protection contre un acteur malveillant. Par exemple, un routeur gourmand qui se prend le préfixe entier pour l'un de ses liens empêche les autres de le réclamer. Un méchant peut aussi annoncer quelque chose tout le temps pour empêcher la convergence, réalisant ainsi une attaque par déni de service. En outre, cet algorithme dépend de la sécurité de l'algorithme d'inondation et de celle du mécanisme de sélection de l'identificateur.
Une mise en œuvre de HNCP en logiciel
libre existe, hnetd. Elle contient
cet algorithme (cf. fichiers src/pa_core*
,
« pa » signifiant prefix assignment).
Première rédaction de cet article le 24 novembre 2015
Un cas intéressant cité par Phil Mayers sur la liste des utilisateurs de BIND va me permettre, cher lecteur, de t'instruire sur la différence entre nom de domaine et nom de machine.
La question originale était de savoir pourquoi on pouvait faire
une résolution DNS (par exemple avec
dig) de
nexistesurementpas.um.outlook.com
alors que les
commandes comme ping ne pouvaient pas
utiliser ce nom :
% dig +short nexistesurementpas.um.outlook.com *.um.outlook.com.glbdns2.microsoft.com. wildcard-emeasouth.um.outlook.com. 157.55.9.252
On récupère bien une adresse IP (c'est pareil avec d'autres outils DNS comme host) mais :
% ping nexistesurementpas.um.outlook.com ping: unknown host nexistesurementpas.um.outlook.com
Mais, alors, pourquoi est-ce que ping prétend que ce nom n'existe pas ? (Le problème n'est pas spécifique à ping, d'autres commandes comme telnet font le même diagnostic.)
L'explication est qu'il existe une différence entre les
noms de domaine (domain
names) et les noms de machines (host
names). Les premiers permettent à peu près tous les
caractères possibles (cf. RFC 2181, section
11, et regardez le nom
&-funny-%-syntax-$.bortzmeyer.org
pour
s'en convaincre). Les seconds obéissent à une syntaxe bien plus
restrictive, documentée dans le RFC 1123,
section 2.1. En gros, un nom de machine est restreint à LDH
(Letters, Digits and Hyphen). C'est pour cela
que je peux résoudre le nom rigolo indiqué plus haut :
% dig +short +nodnssec '&-funny-%-syntax-$.bortzmeyer.org' www.bortzmeyer.org. 204.62.14.153
Mais que je ne peux pas l'utiliser :
% ping '&-funny-%-syntax-$.bortzmeyer.org' ping: unknown host &-funny-%-syntax-$.bortzmeyer.org
(Notez qu'il a fallu l'encadrer d'apostrophes car certains caractères sont spéciaux pour le shell Unix.)
Arrivé à ce stade, mes lecteurs et lectrices, qui sont très
malins, se grattent la tête « OK dans l'exemple avec
&-funny-%-syntax-$.bortzmeyer.org
mais le
nom au début,
nexistesurementpas.um.outlook.com
, est
parfaitement conforme au RFC 1123, lui ! »
Il faut examiner de plus près le processus de résolution DNS :
% dig nexistesurementpas.um.outlook.com ... ;; ANSWER SECTION: nexistesurementpas.um.outlook.com. 0 IN CNAME *.um.outlook.com.glbdns2.microsoft.com. *.um.outlook.com.glbdns2.microsoft.com. 0 IN CNAME wildcard-emeasouth.um.outlook.com. wildcard-emeasouth.um.outlook.com. 300 IN A 157.55.9.252
Le nom est en fait un pointeur (enregistrement DNS de type
CNAME
) vers un nom canonique,
*.um.outlook.com.glbdns2.microsoft.com
(qui,
à son tour, pointe vers un autre nom canonique,
wildcard-emeasouth.um.outlook.com
, mais ce
n'est pas important ici).
Or, le sous-programme
getaddrinfo()
, qu'appellent les
applications pour résoudre un nom en adresse IP, teste la validité
de ces noms. Sur les systèmes utilisant la GNU
libc (ce qui est le cas de
l'Ubuntu sur laquelle j'ai fait les tests),
getaddrinfo
est encore plus violent, il teste
tous les noms de la chaîne. Arrivant au
*.um.outlook.com.glbdns2.microsoft.com
, il le
rejette car contenant un caractère invalide,
l'astérisque. Ainsi, la résolution échoue
et le nom est considéré comme inconnu. (Les fanas du DNS noteront
que, dans un fichier de zone, l'astérisque a un sens spécial,
faisant du nom un joker. Mais ça n'a pas
d'importance ici : c'est un caractère illégal, point.)
À noter que le résultat dépend du système
d'exploitation utilisé car toutes les mises en œuvre
de getaddrinfo
ne sont pas aussi
sévères. Apparemment, FreeBSD refuse ces
noms, mais pas Mac OS ou
Windows. Ainsi,
sur Mac OS, même le nom le plus bizarre est accepté :
$ ping -c 1 '&-funny-%-syntax-$.bortzmeyer.org' PING www.bortzmeyer.org (204.62.14.153): 56 data bytes 64 bytes from 204.62.14.153: icmp_seq=0 ttl=51 time=73.471 ms --- www.bortzmeyer.org ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 73.471/73.471/73.471/0.000 ms
Windows, lui, accepte le premier nom (la machine ne répond pas aux requêtes ICMP mais peu importe) :
E:\Users\moi>ping -n 1 nexistesurementpas.um.outlook.com Envoi d'une requête 'ping' sur wildcard-emeacenter.um.outlook.com [157.55.9.252] avec 32 octets de données : Délai d'attente de la demande dépassé. Statistiques Ping pour 157.55.9.252: Paquets : envoyés = 1, reçus = 0, perdus = 1 (perte 100%),
Les programmeurs n'ont qu'à jeter un œil au code source de la
GNU libc, dans resolv/res_comp.c
:
#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ || ((c) >= 0x61 && (c) <= 0x7a)) #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) #define borderchar(c) (alphachar(c) || digitchar(c)) #define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c)) #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) int res_hnok(const char *dn) { int pch = PERIOD, ch = *dn++; while (ch != '\0') { int nch = *dn++; if (periodchar(ch)) { (void)NULL; } else if (periodchar(pch)) { if (!borderchar(ch)) return (0); } else if (periodchar(nch) || nch == '\0') { if (!borderchar(ch)) return (0); } else { if (!middlechar(ch)) return (0); } pch = ch, ch = nch; } return (1); }
Ce code teste que le nom de machine suit l'expression
rationnelle [a-z0-9\.\-]+
(pas
tout à fait : il autorise aussi le trait
bas à certains endroits, ce qui est une erreur). Le
code équivalent pour FreeBSD est gethostbydns.c
.
À noter qu'on a testé que le cas où le nom illégal est au milieu de la chaîne des pointeurs. Il serait intéressant de refaire le test avec tous ces systèmes d'exploitation pour les cas où le nom illégal est au début ou à la fin de cette chaîne.
Un post-scriptum pour mes lecteurs juristes : les définitions de domaine et de machine utilisées ici sont évidemment celles des RFC. Mais le gouvernement se moque bien de la terminologie existante et, dans sa hâte de contrôler l'Internet, il invente un vocabulaire bizarre. C'est ainsi que le décret français n° 2015-125 du 5 février 2015, qui institue la censure administrative en France a cette définition pittoresque « Les adresses électroniques figurant sur la liste comportent soit un nom de domaine (DNS), soit un nom d'hôte caractérisé par un nom de domaine précédé d'un nom de serveur. »
Merci à Kim-Minh Kaplan pour la discussion et à Vincent Archer et Pascal Courtois pour avoir prêté des machines à la science.
Date de publication du RFC : Novembre 2015
Auteur(s) du RFC : R. Housley (Vigil Security)
Première rédaction de cet article le 22 novembre 2015
Bien des protocoles de l'IETF utilisent la cryptographie. Ils s'en servent pour la confidentialité, pour l'authentification, pour la signature. L'utilisation pour la confidentialité a évidemment crû en importance depuis les révélations d'Edward Snowden, malgré la guerre contre le chiffrement que mènent de nombreux gouvernements, qui voudraient pouvoir continuer à espionner tranquillement leurs citoyens. Or, un problème de la cryptographie est que les algorithmes ne sont pas éternels : la cryptanalyse trouve parfois, au bout d'un temps plus ou moins long, des moyens de casser un algorithme, qui doit alors être abandonné. Ce fut le cas, par exemple, de RC4, rejeté dans le RFC 7465. Il est donc indispensable que les protocoles utilisant la cryptographie aient la propriété d'agilité. Cette propriété désigne le fait qu'on puisse changer d'algorithme sans changer le protocole.
Pour des raisons d'interopérabilité, l'IETF désigne toujours un algorithme cryptographique comme obligatoire : ainsi, deux mises en œuvre d'un protocole donné auront toujours au moins un algorithme en commun, l'algorithme obligatoire, et pourront donc interopérer. Mais l'algorithme obligatoire peut lui aussi céder un jour face à la cryptanalyse, et il faut donc également prévoir le moyen de le remplacer.
[Au passage, la plupart des protocoles IETF utilisent non pas un algorithme unique mais une liste d'algorithmes, la cipher suite. Par exemple, pour TLS, cette liste comprend un algorithme de chiffrement asymétrique (comme RSA), un de chiffrement symétrique (comme AES) et un de condensation (comme SHA-2).]
Revenons à la cryptanalyse. Les algorithmes « vieillissent » donc avec le temps, au fur et à mesure que les cryptanalystes découvrent de nouvelles méthodes pour casser l'algorithme. Ce vieillissement n'est pas régulier et n'est pas prévisible. Certains algorithmes sont cassés dans les années qui suivent immédiatement leur publication, d'autres résistent encore (plus ou moins bien) des dizaines d'années après. Ce qui est sûr, c'est que les attaques, au pire stagnent, au mieux se perfectionnent avec le temps : un algorithme ne peut donc pas « rajeunir ». C'est ce vieillissement inéluctable (quoique de durée très variable) qui justifie le principe d'agilité cryptographique.
Le principe est simple et semble excellent. Mais l'expérience de la communauté Internet est qu'il est difficile de changer les vieux algorithmes vulnérables par des nouveaux. Même une fois le nouvel algorithme normalisé par l'IETF, et une fois qu'il est mis en œuvre dans les logiciels les plus répandus, on constate souvent que la mise à jour des logiciels est lente et que, des années après l'abandon officiel d'un algorithme, il est toujours disponible et activé dans des millions de machines (et parfois, il est même le seul disponible). Il est donc difficile de supprimer un vieil algorithme vulnérable (comme MD5, cf. RFC 6151), ne serait-ce que pour des raisons d'interopérabilité : si une machine ne sait condenser qu'avec MD5, les machines équipées d'un logiciel plus récent, qui gère SHA-2 et d'autres, devront bien accepter de parler avec MD5 ou, sinon, plus de communication. Bref, les algorithmes morts continuent à hanter l'Internet pendant très longtemps. Pensons par exemple aux administrateurs système qui hésitent encore à supprimer le protocole SSLv3 (cf. RFC 7568) de leurs serveurs HTTPS, de peur de ne plus pouvoir accepter les clients MSIE 6. Il faut souvent recourir à des méthodes de name and shame comme le test de SSLlabs (qui fait aussi de la gamification, avec ses notes) pour TLS : « cette banque est nulle, leur serveur HTTPS accepte encore 3DES » (ce que le RFC nomme pudiquement « social pressure »).
Passons au concret avec la section 2 de notre RFC. Il s'agit de
règles internes à l'IETF qu'il est fortement recommandé de suivre
lors du développement de nouveaux protocoles, pour permettre
l'agilité cryptographique. D'abord, évidemment, les protocoles
IETF ne doivent pas être liés à un algorithme
unique, puisque le cassage de celui-ci entrainerait la fin du
protocole. Pour permettre le choix d'un algorithme, il faut que
chaque algorithme (ou chaque liste d'algorithmes) ait un
identificateur, un nombre ou une chaîne de
caractères qui désigne un algorithme donné. Ainsi, pour
DNSSEC, ces identificateurs (8 pour la liste RSA avec
SHA-256, 13 pour la liste
ECDSA avec la courbe
P-256 et SHA-256,
etc) sont stockés dans un registre
IANA. TLS, lui, utilise des chaînes
de caractères comme TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
qui veut dire
« échange de clés Diffie-Hellman avec
courbes elliptiques, authentification avec
RSA, chiffrement symétrique en
AES
mode GCM,
condensation avec SHA-256 ». Cet identificateur est donc la première étape indispensable
vers l'agilité cryptographique.
Faut-il un identificateur par algorithme, identificateurs que l'on combine ensuite pour obtenir la liste utilisée, comme le fait IKE (RFC 7296) ou bien un identificateur par liste, comme c'est le cas pour TLS (RFC 5246) ? La question n'est pas évidente. La première méthode permet d'avoir moins d'enregistrements. Mais toutes les combinaisons possibles n'ont pas forcément un sens donc enregistrer les listes (les combinaisons) peut être préférable. Notre RFC ne tranche pas là-dessus.
Dans tous les cas, pour que nos amis Alice et Bob puissent communiquer, il faut qu'ils aient un jeu d'algorithmes en commun (RFC 3365). D'une manière générale, l'IETF prête une grande attention à cette interopérabilité, d'où la notion d'algorithme obligatoire, ou plutôt « obligatoire à implémenter » (à mettre dans les programmes). Sans ces algorithmes obligatoires, on pourrait avoir deux implémentations parfaitement correctes du protocole, mais qui seraient dans l'impossibilité de dialoguer, puisqu'elles n'auraient aucun algorithme en commun. C'est pour cela que chaque protocole doit avoir un ou plusieurs algorithmes (ou listes, si on enregistre les listes) qui soient obligatoires. Pour DNSSEC, par exemple, c'est RSA-SHA1.
Et comme les algorithmes obligatoires peuvent eux aussi être cassés un jour, il est recommandé, pour faciliter leur changement, que le RFC spécifiant le protocole n'indique pas quels sont les algorithmes obligatoires, mais se réfère à un RFC plus court, sur ce sujet. On pourra ainsi modifier le RFC « Algorithmes » sans toucher au protocole. DNSSEC n'utilise pas cette méthode (l'algorithme obligatoire est défini dans le RFC 4034) mais JOSE (cryptographie pour JSON) le fait (les algorithmes sont définis dans le RFC 7518).
Pour la taille des clés utilisées pour ces algorithmes, notre RFC renvoie au RFC 3766 pour la cryptographie asymétrique et au RFC 7525 pour la symétrique.
En général, la mort d'un algorithme cryptographique n'est pas instantanée. Si, en théorie, il est possible qu'un mathématicien génial fasse une percée théorique inattendue qui rende tout à coup le cassage de tel algorithme trivial, en pratique, cela n'arrive que très rarement : on voit plutôt des attaques de plus en plus perfectionnées, un algorithme de plus en plus déconseillé jusqu'à son abandon officiel. C'est un domaine où il y a peu de « coups de tonnerre dans un ciel bleu ». Le passage de DES à AES s'est ainsi étalé sur des dizaines d'années, et celui de RSA vers les courbes elliptiques prendra sans doute autant de temps.
Pour prévenir les programmeurs des changements qu'on peut sans doute attendre, notre RFC recommande, dans l'esprit du RFC 4307, d'augmenter les termes normatifs définis dans le RFC 2119. Ce RFC définissait l'usage de MUST, SHOULD et MAY (en majuscules) dans les RFC. Notre nouveau RFC recommande d'utiliser également SHOULD+, SHOULD- et MUST-. Un SHOULD+ est la même chose qu'un SHOULD aujourd'hui (« cet algorithme devrait être implémenté, sauf si on a une très bonne raison et qu'on sait ce qu'on fait »). Mais, dans le futur, il est probable qu'il deviendra un MUST (algorithme obligatoire). Un SHOULD- est un SHOULD qui sera probablement dégradé en un simple MAY dans le futur. Quant au MUST-, il indique que l'algorithme est aujourd'hui obligatoire mais ne le restera sans doute pas.
Passer d'un algorithme à l'autre, on l'a vu, n'est pas trivial. Intuitivement, on se dit que l'IETF normalise le nouvel (et meilleur algorithme), que les programmeurs le programment dans les logiciels et que, au bout d'un moment, les nouveaux logiciels sont assez répandus pour qu'on puisse abandonner officiellement l'ancien algorithme.
Cela suppose qu'on sache mesurer l'état du déploiement et, pour beaucoup de protocoles, il n'y a pas de mécanisme de centralisation des statistiques. On ne sait donc pas si on peut « couper le cordon » et abandonner l'ancien algorithme.
C'est pour cela que la tendance est à mettre dans les nouveaux protocoles un mécanisme de signalisation, permettant de voir le déploiement du nouvel algorithme (par exemple le RFC 6975 pour DNSSEC).
Comme le déploiement est toujours trop long, on peut potentiellement se retrouver dans des situations ennuyeuses où l'ancien algorithme, désormais facilement cassé, est encore largement utilisé. Faut-il alors le supprimer des implémentations, remettant ainsi en cause l'interopérabilité, ou bien le laisser alors qu'on sait que cela met en cause la sécurité ? Débat cornélien qui agite régulièrement le monde TLS, par exemple. Il y a quelques années, la tendance était plutôt à laisser les algorithmes mourir tranquillement, de nos jours, elle est plutôt à éliminer rapidement les « canards boiteux », quitte à renoncer à la communication avec les vieux logiciels. C'est ainsi que l'abandon progressif de SHA-1, désormais largement attaqué, a été souvent fait de manière brutale (par exemple Google Chrome décidant soudainement de marquer les certificats utilisant SHA-1 comme étant dangereux).
L'agilité cryptographique n'a pas que des avantages. On a vu qu'elle était indispensable, pour tenir compte des progrès de la cryptanalyse. Mais, si un protocole accepte plusieurs algorithmes, comment s'assurer que les deux pairs qui négocient utilisent bien le plus fort ? Imaginons un protocole de chiffrement où le serveur indique à la connexion les algorithmes qu'il sait gérer et où le client en choisit un dans la liste, a priori le plus solide, et où le chiffrement démarre ensuite, avec l'algorithme choisi. Un attaquant actif, par exemple un Homme du Milieu, peut modifier la liste d'algorithmes pour mettre l'algorithme le plus faible, qu'il pourra ensuite casser. C'est ce qu'on nomme une attaque par repli (downgrade attack) et c'est la plaie des protocoles qui offrent l'agilité cryptographique. Il faut donc trouver un mécanisme de protection et ne pas garder éternellement les algorithmes trop vieux.
Un problème du même ordre se pose avec les protocoles qui permettent, non seulement de négocier les algorithmes de cryptographie, mais également le mécanisme d'échange initial des clés. C'est le cas d'EAP, par exemple (RFC 3748). Les concepteurs de protocole doivent se souvenir que la complexité est souvent la principale ennemie de la sécurité.
Compte tenu des problèmes que peut entrainer l'agilité cryptographique, notamment la complexité accrue du code, certains pourraient être tentés de concevoir des protocoles à un seul algorithme. Le protocole serait plus simple, et n'offrirait pas de possibilités d'attaques par repli. Un exemple de ce choix avait été WEP. Lié à un seul algorithme, ne pouvant pas évoluer, WEP avait été très long et compliqué à remplacer par un nouveau protocole, qu'il avait fallu concevoir, implémenter puis déployer. WEP est donc un bon exemple de l'importance de l'agilité cryptographique.
La section 3 de notre RFC examine sur quels critères choisir les algorithmes et notamment ceux qui seront obligatoires, et qui doivent donc être de haute qualité cryptographique. Évidemment, le choix ne doit pas être laissé à l'utilisateur final, qui n'a pas les éléments pour le faire. Il vaut mieux aussi qu'il ne soit pas laissé à l'administrateur système, qui n'est typiquement pas un expert en cryptographie. (Regardez la difficulté qu'il y a aujourd'hui à gérer un serveur HTTPS, avec tous ces choix pointus à faire en matière d'algorithmes. TLS est probablement un bon exemple du syndrome « trop de choix ».)
D'abord, les algorithmes obligatoires doivent évidemment faire l'objet d'une spécification publique (pendant longtemps, RC4 était secret). Il doivent avoir fait l'objet d'examens attentifs et de tentatives de cassage par des experts. De préférence, ils ne doivent pas faire l'objet de brevets. Ils doivent évidemment aussi répondre à des exigences plus techniques : ils doivent être rapides, implémentables dans un code de taille réduite, résister aux attaques par canal auxiliaire, etc.
Il existe des algorithmes de cryptographie dits « nationaux » parce que normalisés par une organisation de normalisation nationale officielle et parfois rendus obligatoires par une loi locale (si l'organisation de normalisation est le NIST, on ne les appelle pas « nationaux », le terme est réservé à ceux normalisés en dehors des États-Unis). Ils n'ont pas forcément fait l'objet d'une étude sérieuse et leur but est souvent de simple protectionnisme de l'industrie de sécurité nationale. Auquel cas ils ne doivent pas être choisis dans les protocoles IETF et en tout cas pas activés par défaut. (La section 3.4 du RFC fait pas mal de FUD : il existe d'excellents algorithmes « nationaux » comme ceux du GOST.)
Enfin, la section 4 du RFC, qui examine les questions de sécurité restantes, note que la force de l'algorithme n'est pas tout. Des faiblesses peuvent apparaitre, par exemple en raison de l'ordre des opérations de cryptographie (cf. RFC 7366)
Première rédaction de cet article le 25 octobre 2015
Les FAI ne manquent pas d'imagination lorsqu'il s'agit de violer la neutralité du réseau. Un exemple récent est décrit dans l'article de Narseo Vallina-Rodriguez, Srikanth Sundaresan, Christian Kreibich et Vern Paxson, « Header Enrichment or ISP Enrichment? Emerging Privacy Threats in Mobile Networks », qui consiste à modifier les flux HTTP automatiquement pour ajouter, à l'insu de l'utilisateur, des informations personnelles qui seront utiles aux publicitaires qui gèrent les sites Web. Et cela se nomme cyniquement l'« enrichissement des en-têtes ».
Un exemple de fournisseur de matériel et logiciel qui propose cette technique est Juniper mais il y en a plein d'autres qui fournissent aux FAI sans scrupules des moyens de modifier les flux HTTP (HTTPS, pour l'instant, protège contre ces manipulations).
Est-ce que cette pratique est répandue ? On sait que, dans le monde de l'accès Internet par mobile, la neutralité du réseau est violée bien plus souvent (ce qui explique les campagnes marketing répétant en boucle que bientôt, X % des accès Internet seront par un mobile : il est important de convaincre les utilisateurs de passer à des technologies où la triche est plus fréquente). Avec quelle ampleur ? Les auteurs de l'article ont utilisé l'application Netalyzr pour récolter des données à ce sujet. Sur les 300 opérateurs mobile identifiés, 5 ajoutent des en-têtes qui compromettent la vie privée de l'utilisateur, 6 ajoutent des en-têtes qui permettent de suivre un utilisateur à la trace (remplaçant les cookies désormais trop bien connus des utilisateurs), 24 mettent des informations techniques dans ces en-têtes, informations qui peuvent mener également à des problèmes de vie privée (cf. RFC 7239).
Inutile de dire que la majorité des opérateurs en question sont
situés dans les pays du Sud, où la vigilance des citoyens et leurs
connaissances techniques sont plus faibles : nettement moins de
chances de se faire prendre en Jordanie
qu'en Californie !
Orange Jordanie fait partie des
« enrichisseurs d'en-têtes » et ajoute le numéro de téléphone du
client aux en-têtes HTTP qui seront récupérables par les
publicitaires sur le site Web visité ! L'en-tête utilisé est
msisdn:
. (Notez que la documentation
de Juniper citée plus haut utilisait
exactement cela comme exemple, avec juste le préfixe
x-
qui indique traditionnellement qu'il
s'agit d'un en-tête non standard.)
Le record appartient apparemment à Vodafone Afrique du Sud pour publier dans les en-têtes ajoutés le numéro de téléphone et l'IMEI (depuis la parution de l'article, ils semblent avoir arrêté).
Si la signification de l'en-tête ajouté subrepticement est
parfois évidente (comme msidn:
,
Mobile Subscriber ISDN, cité plus
haut), ce n'est pas toujours le cas. Par exemple,
Verizon met un en-tête
x-uidh:
qui semble dédié au traçage : il est
unique par abonné.
Enfin, il y a les en-têtes techniques, indiquant les logiciels
utilisés pour cette opération. En France,
SFR ajoute ainsi des
x-bluecoat-via:
(cf. la page Wikipédia sur cette sympathique
entreprise), et des
x-nokia-gateway-id:
. Très souvent,
l'opérateur (par exemple Bouygues et
SFR en France) ajoute un x-forwarded-for:
(en-tête depuis remplacé par un en-tête standard, cf. RFC 7239) qui indique l'adresse
IP privée et peut aider au traçage d'un
utilisateur. Sans compter les en-têtes mystérieux comme le
x-vfstatus:
chez SFR.
Bref, cet excellent travail de recherche montre que la neutralité de l'Internet n'est pas un problème abstrait : elle est violée tous les jours, et il est donc crucial qu'elle soit défendue.
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : J. Levine (Taughannock Networks)
Pour information
Première rédaction de cet article le 25 octobre 2015
Depuis mai 2015, tous les RFC ont un DOI. C'est quoi et à quoi ça sert ? C'est ce qu'explique ce RFC avec lequel, je vous préviens, je ne suis pas du tout d'accord.
Les DOI sont un mécanisme
d'identification formel de documents numériques. Par exemple, le
RFC 7626 a désormais le DOI
10.17487/RFC7626
. Les DOI sont désormais
attribués à tous les RFC (et c'est rétroactif : le RFC 1 a le DOI 10.17487/RFC0001
). Ils
étaient prévus à l'origine pour être utilisé avec le système de
résolution Handle
(RFC 3650). Celui-ci s'étant complètement
cassé la figure (et à juste titre), les DOI sont aujourd'hui
résolus via un URI (par exemple, pour le
RFC 7676, l'URI est
).https://dx.doi.org/10.17487/rfc7676
Ce RFC explique que les DOI sont largement utilisés (y compris, désormais, par les RFC) mais oublie de dire que c'est souvent par obligation, par exemple parce que certaines bibliothèques numériques anglo-saxonnes refusent les documents qui n'ont pas de DOI.
Les DOI sont techniquement décrits par une norme ISO, la ISO 26324:2012. Comme presque toutes les normes du dinosaure ISO, elle n'est pas en accès libre. Si vous tenez à la lire, il vous en coûtera 88 francs suisses, et vous n'aurez pas le droit de la distribuer ensuite aux copains. (On note l'incohérence de l'IETF, qui avait signé une grandiose déclaration en faveur des SDO ouvertes.) Les DOI sont ensuite attribués de manière hiérarchique, l'IDF accréditant des agences qui attribuent ensuite des DOI.
Pourquoi des DOI et pas un autre type d'identificateurs ? La section 1 du RFC cite un passage du « Report on best practices for citability of data and on evolving roles in scholarly communication » qui tape sur les URI en montrant une grande incompréhension du sujet. Le document en question reproche aux URI leur manque de permanence, en oubliant la règle numéro 1 de la permanence des identificateurs : la permanence est une fonction de l'organisation, pas de la technique. Autrement dit, un URI peut être stable, s'il est géré par une organisation sérieuse. C'est exactement pareil pour un DOI. Si l'IDF, organisation purement privée, disparait, que deviendront les DOI ?
Notez aussi une particularité des RFC, qui peut être très
intéressante pour leur trouver des identificateurs : les RFC sont
immuables. Une fois publiés, ils ne sont jamais changés, même pas
d'une virgule (le seul moyen de faire un changement est de publier
un nouveau RFC). Résultat, on pourrait parfaitement désigner les
RFC par un identificateur très stable, leur
condensat, comme avec les NI du RFC 6920 (au passage, ce RFC 7669 a le
NI ni:///sha256;NAuLJduQ-wP7LBI5nYQw0-Ubxh8DsQdVVaxooj4oYB4
).
Un autre argument tout aussi erroné figure dans la section 1 : que les DOI permettent de trouver plus facilement la version gratuite des RFC en ligne. Il est vrai que des gens peu honnêtes ont vendu des versions payantes des RFC (ce qui est légal, les RFC sont libres d'utilisation) sans prévenir leurs acheteurs qu'ils pouvaient les obtenir gratuitement en ligne (ce qui est assez inéthique). Mais croire que les gens ont besoin des DOI pour trouver un RFC en ligne est assez fort de café ! (Cet argument est pourtant repris dans la section 3.)
La section 2 du RFC explique comment sont formés les DOI des
RFC. Notez bien qu'un DOI est normalement opaque pour
l'utilisateur : contrairement à un URI, il ne faut pas l'analyser
pour en chercher des composantes. Néanmoins, si vous aimez savoir
comment les choses sont faites, un DOI pour un RFC commence avec
le préfixe 10.17487
(les DOI commencent
toujours par 10, d'autres utilisations avaient été prévues avec
d'autres nombres, mais n'ont jamais décollé), préfixe attribué aux RFC, et est
suivi du texte rfc
et du numéro du RFC. Le
texte est apparemment insensible à la casse
(en tout cas, les exemples du RFC sont tantôt en minuscules,
tantôt en majuscules) mais, la norme n'étant pas librement
accessible, je n'ai pas pu vérifier. Comme le DOI est opaque, il
ne faut pas chercher à deviner un DOI pour un RFC donné. Par
exemple, le numéro est actuellement formaté avec quatre chiffres
mais cela pourra changer après le RFC 9999...
Comme indiqué plus haut, les vendeurs de DOI, après avoir
répandu plein de FUD contre les URI, on
finalement renoncé à leurs grandioses projets de déploiement de
nouveaux protocoles et utilisent le même
HTTP que tout le monde, avec les mêmes URI
que tout le monde. Pour accéder à un DOI, on le préfixe par
https://dx.doi.org/
. On accède alors à une
page Web fournie par l'entité qui a publié le document (et dont
rien ne garantit donc la stabilité...) Cette page peut être le
document recherché lui-même, une page de métadonnées avec un
accès au document (c'est le cas des RFC) ou bien une page de
métadonnées sans le document (cas des documents privés, non
accessibles publiquement). Voir à ce sujet le « DOI
Handbook »
Le processus d'attribution d'un DOI pour un RFC est décrit dans la section 4. Comme on l'a vu, il existe plusieurs agences d'attribution de DOI, dont plusieurs sont spécialisées dans un secteur très particulier. Le RFC Editor a choisi CrossRef, émanation des éditeurs. (Et qui n'est pas l'unique agence, contrairement à ce que dit le Wikipédia francophone.) Le coût d'adhésion à Crossref est de 660 dollars et chaque DOI attribué à un document coûte un dollar de plus.
Le DOI du RFC est maintenant inclus dans les bases distribuées
par le RFC Editor. Tous les RFC qui citent un autre RFC doivent maintenant inclure
le DOI (une obligation imposée par l'IDF, cf. la section 4.4 du RFC.) C'est fait
automatiquement quand on utilise les outils comme xml2rfc (faut juste penser à vider le cache, en
~/.cache/xml2rfc
d'abord, sinon certains RFC
auront des DOI et pas d'autres).
L'attribution de DOI aux RFC parus précédemment a nécessité un peu de développement logiciel, utilisant l'API de Crossref pour solliciter les sept mille et quelques DOI des RFC existants.
Notez que tout cela s'est fait sans aucune concertation, ce qui est en contradiction avec les valeurs de l'IETF. Lorsque ce RFC a été soumis, la décision était déjà prise et mise en œuvre (l'annonce officielle date de mai 2015, avant, il fallait prêter attention à des appels d'offre du RFC Editor comme celui-ci).
D'autres solutions auraient pourtant été possibles. D'abord, l'IETF elle-même a plein de mécanismes d'identificateurs, à commencer évidemment par les URI du RFC 3986. Au sein des URI, des plans particulier (comme NI, cité plus haut) étaient possibles. En dehors de l'IETF, des identificateurs plus ouverts comme ARK auraient été un choix mais il semble que les éditeurs scientifiques anglo-saxons ont décidé d'imposer le DOI partout.
Concevoir un système d'identificateurs est moins simple qu'il n'y parait et les DOI ont été conçus par des gens qui n'avaient pas de compétences particulières en ce domaine. Ici, le but était clairement de respectabilité plus que d'améliorer la vie des utilisateurs (comme cela avait été le cas pour l'ISSN).
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : J. Appelbaum (The Tor
Project,), A. Muffett (Facebook)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 24 octobre 2015
Le TLD
.onion
est utilisé par
Tor pour nommer des serveurs Internet dont
la localisation exacte est cachée. Tor est surtout connu pour
permettre aux clients de demeurer relativement
intraçables pendant leurs activités sur l'Internet, et
.onion
étend cette possibilité aux
serveurs. Ce TLD n'avait aucune forme
d'existence officielle avant, il avait juste été choisi comme cela
et était reconnu par les logiciels Tor. Désormais, il est stocké
dans le registre des noms de domaine
spéciaux créé par le RFC 6761.
C'est politiquement une certaine forme de reconnaissance de la
part de l'IETF pour ces services
cachés de Tor (que TF1 et les
ministres nomment le Dark Web). Mais cela ne
changera pas grand'chose en pratique, .onion
était utilisé depuis des années, illustrant d'ailleurs la
déconnexion entre la réalité et certains professionnels de la
gouvernance Internet, qui croient que
l'ICANN est le « régulateur de
l'Internet ».
Techniquement, cet enregistrement de .onion
dans le registre des noms de
domaine spéciaux mènera peut-être certains logiciels à
intégrer une connaissance de ce TLD, pour ne
pas faire de requêtes
.onion
dans le DNS
(requêtes involontaires et qui peuvent « trahir » un utilisateur de
Tor).
La section 1 de notre RFC rappelle le
principe de Tor et des .onion
. Tor est
spécifié dans « Tor: the
second-generation onion router ». Ses
services cachés (dont la localisation du
serveur est caché : le service lui-même est parfaitement visible,
c'est le but) sont identifiés par un nom de domaine en
.onion
. Par
exemple, celui de Facebook, société dont un
employé est co-auteur du RFC, est facebookcorewwwi.onion
. Comme
c'est un nom de domaine, il peut s'utiliser partout où on utilise
un nom de domaine, par exemple dans les
URI. Ainsi, le blog d'Amaelle Guiton est
accessible en
. Comme ce nom
est spécial, on n'utilise pas le
DNS pour trouver des données comme l'adresse
IP. Un nom en http://ozawuyxtechnopol.onion/
.onion
est un identificateur
cryptographique (c'est
le condensat de la clé
publique du serveur). Il est « auto-authentifiant » ce
qui veut dire que le client peut s'assurer qu'il parle au bon
serveur, via la signature de la communication par la clé du serveur, sans avoir besoin, par exemple, d'un
certificat, et ceci que le réseau
sous-jacent soit de confiance ou pas. Comme l'identificateur est un
condensat cryptographique, il n'est normalement pas compréhensible
par un humain (voir la section 4 pour une nuance à cette
affirmation, comme dans le cas du nom de Facebook ci-dessus).
Les noms en .onion
sont générés localement,
sans utiliser une autorité distincte (voir les explications pour mon blog). Aucun
registre n'est utilisé (lors de la chaude
discussion à l'IETF sur ce RFC, une minorité
avait protesté contre le fait que cet enregistrement du TLD privait
l'ICANN d'une source de revenus). On
n'enregistre pas un nom en .onion
, on ne le
vend pas, on n'en est « propriétaire » que parce qu'on connait la
clé privée correspondante (au passage, comme avec tous les
identificateurs cryptographiques, de Namecoin à BitMessage, attention à vos
clés privées ! Si elles sont perdues, vous n'avez
aucun recours).
On a vu que .onion
n'utilise pas le
DNS. Pour éviter les collisions entre un nom extérieur au monde du
DNS et un nom identique qui serait dans le DNS, le RFC 6761 avait introduit le concept de « noms de domaine
spéciaux ». Ces noms ont la syntaxe et une partie de la sémantique
des noms utilisés dans le DNS mais ne sont jamais supposés
apparaitre dans le DNS. Dans le registre des noms spéciaux, on
précise ce que doivent faire les différents composants du
DNS (bibliothèques, résolveurs, registres,
etc) s'ils rencontrent ces noms. À part les noms du RFC 2606, devenus « spéciaux » par la suite, le premier nom
spécial enregistré était le
.local
d'Apple, via le RFC 6762. Comme pour .local
, notre
nouveau RFC demande que .onion
soit traité
spécialement par les logiciels DNS. En pratique, évidemment, cette
demande ne sera pas honorée par tous et il y aura donc pendant
encore longtemps des « fuites », des requêtes DNS pour
.onion
qui arrivent aux serveurs
racine. Au moment de la publication
de notre RFC, .local
était le troisième
TLD le plus demandé à la racine (derrière les
indéboulonnables .com
et
.net
, cf. les statistiques du serveur
racine L) et le premier, de très loin, des TLD inexistants. Par
comparaison, les fuites pour .onion
sont
négligeables.
La section 2 du RFC décrit quelles sont ces règles que devraient
suivre les logiciels DNS (cette section est obligatoire pour mettre
un nom dans le registre des noms spéciaux, cf. RFC 6761, section 5). Donc, voici les différents composants
du DNS qui devraient (idéalement) traiter les
.onion
à part :
.onion
ont des propriétés de sécurité
particulières, et qu'ils ne sont accessibles qu'avec un logiciel
spécial (comme le Tor
Browser)..onion
et les passer à Tor. Les autres
devraient générer une erreur tout de suite et ne pas tenter ces
noms dans le DNS..onion
...
Le RFC précise explicitement que l'IANA est
autorisée à mettre dans la zone racine un mécanisme pour réserver
le nom (comme, je suppose, celui du RFC 7535). Et que les opérateurs non-DNS (par exemple les
AC, voir la
déclaration du CAB sur les .onion) peuvent évidemment
stocker des noms en .onion
.
Pourquoi ces demandes répétées de ne pas tenter de résoudre les noms dans le DNS ? Car cela ferait connaitre à l'extérieur, en clair, les services Tor cachés auquel vous tentez d'accéder, ce qui annulerait l'effet anonymisant de Tor. Par exemple, ici j'utilise par erreur un logiciel non-Tor pour accéder au blog d'Aeris :
% curl http://blog.aeriszyr4wbpvuo2.onion/ curl: (6) Could not resolve host: blog.aeriszyr4wbpvuo2.onion
Et si quelqu'un d'indiscret, sur un serveur racine, regardait le trafic, il a vu (ici, avec tcpdump) :
18:36:10.252749 IP6 2001:db8:8bd9:8bb0:21e:8cff:fe76:29b6.33562 > 2001:1608:10:167:32e::53.53: \ 65162% [1au] A? blog.aeriszyr4wbpvuo2.onion. (56) 18:36:10.284260 IP6 2001:1608:10:167:32e::53.53 > 2001:db8:8bd9:8bb0:21e:8cff:fe76:29b6.33562: \ 65162 NXDomain*- 0/9/1 (1129)
que non seulement je suis un mauvais citoyen qui utilise Tor malgré les injonctions d'un gouvernement bienveillant qui explique qu'il ne faut utiliser que la « cryptographie légale », mais en plus l'indiscret a le nom du site qui m'intéressait (RFC 7626).
En parlant du risque de fuite, la section 4 de notre RFC est
consacrée à la sécurité. Outre ce problème de logiciels trop
bavards qui en révèlent trop à l'extérieur via
les requêtes DNS, elle mentionne le risque de se tromper de
nom .onion
.
En effet, les noms en .onion
sont certes
auto-vérifiables, via la cryptographie, mais cela suppose
d'utiliser le bon nom. Si un utilisateur se trompe, ou bien fait
trop confiance à un nom indiqué sur un canal
IRC de numéristes radicalisés, il peut
atterrir sur le mauvais site .onion
. Le risque
est d'autant plus élevé que les noms en .onion
sont typiquement illisibles par un humain (des techniques,
coûteuses en temps de calcul, permettent de générer des noms plus
jolis, comme celui de Facebook cité plus haut).
Les utilisateurs pourraient aussi se faire avoir par ignorance
de la syntaxe des noms de domaine. Par exemple, un utilisateur
ordinaire pourrait être trompé en croyant que
www.onion.example
est protégé par Tor ce qui
n'est pas du tout le cas.
Il y a aussi des attaques plus techniques. Un nom en
.onion
est le condensat d'une clé
cryptographique. Casser cette clé (trouver la partie privée en n'ayant
que la partie publique) nécessite des ressources de calcul
colossales mais trouver une clé ayant le même condensat (et donc le
même nom .onion
) est moins coûteux (tout est
relatif : il faudra quand même de la puissance de calcul et du
temps), et cela pourrait permettre de créer un faux service caché
indistinguable du vrai.
Si vous voulez en savoir plus sur comment fonctionnent ces noms
en .onion
(je trouve personnellement que la
documentation disponible est insuffisante), voyez les guides
officiels « Special Hostnames in
Tor » et « Tor Rendezvous
Specification ».
L'enregistrement de .onion
dans les noms de
domain spéciaux a été l'occasion d'un long et houleux débat à
l'IETF, tournant parfois au psychodrame,
comme toujours quand on parle des TLD. En
gros, il opposait les « conservateurs », méfiants vis-à-vis de ces
nouveaux services pair à pair et soucieux de
rester « respectable » aux yeux de l'ICANN, aux « pairàpairistes »
qui ne se soucient pas de l'ICANN et ne sont pas satisfaits du
système de nommage actuel. Le
RFC 6761, qui fournit la base de cet
enregistrement, a été très contesté (bien plus que lorsqu'il a
servi à enregistrer le TLD d'Apple
.local
...). L'IETF a finalement pris la
décision d'enregistrer .onion
mais de fermer la
porte juste après aux autres demandes en attente (comme
.gnu
ou .bit
) en
attendant une éventuelle révision du RFC 6761. Voici l'article qui annonce
cette décision. Ce sera un des points chauds de la prochaine
réunion de l'IETF à Yokohama.
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : C. Pignataro (Cisco Systems), R. Bonica (Juniper Networks), S. Krishnan (Ericsson)
Chemin des normes
Première rédaction de cet article le 23 octobre 2015
Le protocole GRE est le plus simple mécanisme de tunnel normalisé. Il est mis en œuvre sur d'innombrables systèmes, et très largement répandu. Pour reprendre la formule de James Raftery, GRE est « The AK-47 of guerrilla networking. Cheap, simple, gets all sorts of dirty jobs done. ». Il ne fonctionnait traditionnellement qu'avec IPv4 mais bien des mises en œuvre de GRE avaient été adaptées à IPv6 depuis longtemps. Ce RFC décrit cette adaptation.
GRE, spécifié dans les RFC 2784 et RFC 2890, permet de transporter n'importe quoi sur n'importe quoi. On peut faire de l'IPv4 dans IPv4, de l'IPv6 dans l'IPv6, de l'IPv4 dans IPv6 ou le contraire. En termes GRE, IPv6 peut être la charge utile (payload, IPv6 sur autre chose) ou bien le support (delivery, quelque chose sur IPv6).
Le format des en-têtes GRE (RFC 2784, section 2) ne change pas avec ce RFC. Il y a juste la forte recommandation de ne pas utiliser la somme de contrôle GRE. Cela diminue la charge de calcul pour les machines aux extrémités du tunnel GRE, charge qui était peu utile car cette somme de contrôle GRE est largement redondante avec celle que fournissent IP (pour IPv4 seulement), TCP ou UDP. Néanmoins, on a toujours le droit de mettre une somme de contrôle, en cas d'environnement très hostile. (Cf. RFC 6935 à propos des sommes de contrôle et des tunnels.)
D'abord, le cas où IPv6 est la charge utile (section 3 de notre RFC), encapsulé dans... ce qu'on veut, IPv4 ou IPv6. Dans l'en-tête GRE, le champ Protocol Type (RFC 2784, section 2.4) doit être mis à 0x86DD (c'est la même valeur que lorsque IPv6 est porté sur Ethernet, cf. RFC 7042).
Qui dit tunnel dit problèmes de MTU. Pour limiter les dégâts, notre RFC impose que tout tunnel GRE qui transporte de l'IPv6 ait une MTU d'au moins 1 280 octets, ce qui est la valeur minimum requise par IPv6. (Plus précisement, notre RFC demande que le tunnel puisse transporter des paquets de 1 280 octets sans utiliser la fragmentation IP. Cela peut se faire en ayant une MTU >= 1 280 octets ou bien en ayant un système de fragmentation et réassemblage sous IP.) Avec cette règle, on est au moins sûrs que les paquets IPv6 prudents (ceux limités à 1 280 octets) passeront.
En théorie, une mise en œuvre standard de GRE doit tester cette possibilité, avant d'envoyer des paquets IPv6. (Celles d'aujourd'hui ne le font apparemment pas souvent, cf. RFC 7588.)
Et si le point d'entrée du tunnel GRE reçoit un paquet qui est plus grand que la MTU du tunnel ? Rappelez-vous qu'une des principales différences entre IPv4 et IPv6 est que, en IPv6, les routeurs sur le trajet n'ont pas le droit de fragmenter : si c'est nécessaire, cela doit être fait à la source. (Notez aussi que les machines d'entrée et de sortie du tunnel font un travail proche de celui d'un routeur mais que ce ne sont pas exactement des routeurs.) Donc, si le paquet trop gros arrive, le point d'entrée du tunnel doit faire ce que fait un routeur IPv6 : jeter le paquet et envoyer un message ICMP Packet Too Big.
Et le contraire, IPv6 comme réseau sous-jacent, pour transporter n'importe quoi, de l'IPv4 ou de l'IPv6 (section 4 de notre RFC) ? Le paquet IPv6 va comporter l'en-tête IPv6, zéro, un ou davantage en-têtes d'extensions, puis la charge utile, faite d'un en-tête GRE et des données (un paquet IPv4 ou IPv6). S'il n'y a pas d'en-têtes d'extension IPv6, le champ Next Header d'IPv6 vaut 47 (la valeur enregistrée pour GRE). S'il y a un ou plusieurs en-têtes d'extension, le dernier doit avoir, dans son champ Next Header, cette même valeur 47.
Comme l'en-tête IPv6 n'a pas de somme de contrôle, une distribution du paquet à la mauvaise machine est toujours possible. Le comportement normal de cette machine qui reçoit un paquet inattendu est de le jeter silencieusement. Si elle parle GRE elle-même, elle peut faire la décapsulation et faire suivre le paquet (cela me semble très dangereux, permettant de faire relayer les paquets par des machines « ouvertes »).
Enfin, la section 6 de notre RFC se penche sur la sécurité de GRE. Cela va vite car elle est à peu près nulle (cf. RFC 6169). Notamment, contrairement à beaucoup de tunnels modernes, GRE ne chiffre pas. Si on veut de la confidentialité pour les données transportées, il ne faut pas utiliser GRE. GRE reste très utile quand on veut simplement contourner le routage IP normal et établir une forme de routage manuellement contrôlée (j'ai décrit un exemple réel d'un tel cas).
Comme indiqué plus haut, il existe déjà plusieurs mises en œuvre de GRE IPv6. Faisons quelques essais avec des machines Linux. D'abord, IPv6 dans IPv4 (oui, il existe d'autres protocoles que GRE pour tunneler IPv6 dans IPv4, je suis au courant, cf. RFC 7059 pour une comparaison des tunnels), donc en mode « IPv6 payload ».
% sudo ip tunnel add tun0 mode gre remote 10.254.112.180 \ local 192.168.43.49 ttl 255 % sudo ip link set tun0 up
On a ici créé un tunnel GRE entre la machine locale,
192.168.43.49
et l'autre extrémité du tunnel,
10.254.112.180
. On attribue maintenant des
adresses IPv6 à l'interface tun0
:
% sudo ip -6 addr add fda1:1a36:de6d::2 dev tun0 % sudo ip -6 route add fda1:1a36:de6d::/48 dev tun0
On fait pareil de l'autre côté du tunnel (en inversant évidemment
remote
et local
). On peut
maintenant se pinguer en IPv6 même si le
FAI ne le fournissait pas (c'est le cas
ici, avec un VPS OVH) :
% ping6 fda1:1a36:de6d::2 PING fda1:1a36:de6d::2(fda1:1a36:de6d::2) 56 data bytes 64 bytes from fda1:1a36:de6d::2: icmp_seq=1 ttl=64 time=1.22 ms 64 bytes from fda1:1a36:de6d::2: icmp_seq=2 ttl=64 time=0.761 ms 64 bytes from fda1:1a36:de6d::2: icmp_seq=3 ttl=64 time=0.689 ms ^C --- fda1:1a36:de6d::2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 0.689/0.893/1.229/0.239 ms
Plus amusant, tcpdump sait décoder le GRE et affiche donc bien ce qui s'est passé dans le tunnel :
16:46:02.240707 IP 10.254.112.180 > 192.168.43.49: GREv0, length 108: \ IP6 fda1:1a36:de6d::1 > fda1:1a36:de6d::2: ICMP6, echo request, seq 1, length 64 16:46:02.240957 IP 192.168.43.49 > 10.254.112.180: GREv0, length 108: \ IP6 fda1:1a36:de6d::2 > fda1:1a36:de6d::1: ICMP6, echo reply, seq 1, length 64
tcpdump a décapsulé le GRE, trouvé les paquets ICMP d'IPv6 et les a affichés.
Essayons maintenant l'inverse, « IPv6
delivery », c'est-à-dire de l'IPv4 encapsulé dans IPv6
(cela pourra servir lorsqu'on verra apparaître des FAI uniquement
IPv6). Créons le tunnel (notez que le mode est
ip6gre
et plus gre
) :
% sudo ip -6 tunnel add tun0 mode ip6gre remote 2001:db8:2:245b::42 \ local 2001:db8:8bd9:8bb0:666:6c7c:9bed:b390 ttl 255 % sudo ip -6 link set tun0 up
Donnons des adresses IPv4 :
% sudo ip addr add 172.17.0.2 dev tun0 % sudo ip route add 172.17.0.0/24 dev tun0
Et on peut désormais pinguer en IPv4. tcpdump, là encore, sait décapsuler et afficher ce qui se passe dans le tunnel :
21:19:17.158171 IP6 2001:db8:2:245b::42 > 2001:db8:8bd9:8bb0:666:6c7c:9bed:b390: GREv0, length 88: \ IP 172.17.0.1 > 172.17.0.2: ICMP echo request, id 32762, seq 1, length 64 21:19:17.238950 IP6 2001:db8:8bd9:8bb0:666:6c7c:9bed:b390 > 2001:db8:2:245b::42: GREv0, length 88: \ IP 172.17.0.2 > 172.17.0.1: ICMP echo reply, id 32762, seq 1, length 64
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : S. Morris (ISC), J. Ihren
(Netnod), J. Dickinson
(Sinodun), W. Mekking (NLnet Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 22 octobre 2015
Contrairement au DNS classique, le système de sécurité DNSSEC est très dynamique : il faut changer les signatures régulièrement et il est souvent recommandé de remplacer (changer) les clés. Compte-tenu du fait que le DNS n'est pas synchrone (les changements n'apparaissent pas instantanément partout dans l'Internet), ce changement, ce remplacement (rollover, dans la langue d'Alan Turing) est une opération délicate et qui nécessite le strict respect d'un certain nombre de durées. Ce RFC donne des conseils sur la temporalité des opérations DNSSEC.
Pourquoi faut-il changer les clés cryptographiques utilisées ? Il y a plusieurs écoles à ce sujet. Les minimalistes considèrent qu'on ne change les clés que quand c'est nécessaire, par exemple pour passer à des clés plus longues et donc moins vulnérables à la cryptanalyse, ou évidemment quand les clés privées ont été copiées par un méchant. Les maximalistes estiment qu'il faut changer de clé régulièrement, pour être mieux préparé en cas de changement d'urgence, ou pour priver un méchant discret qui aurait réussi à copier une clé privée sans qu'on s'en aperçoive du fruit de son forfait, ou tout simplement parce que l'utilisation d'une clé fournit du matériau, qui peut être utile à un éventuel cryptanalyste. Changer de clé est une opération délicate et, à mon avis, devrait être automatisé : autrement, le risque d'erreur est trop important, comme l'avait montré mon article à la conférence SATIN.
En effet, les facteurs qui rendent l'opération compliquée sont :
Une description de ce processus de remplacement de clés (key rollover) figure dans le RFC 6781. Un exemple avec OpenDNSSEC est raconté dans un de mes articles. Notre nouveau RFC détaille la description du RFC 6781, notamment sur les aspects temporels. Deux points à garder en tête avant de le lire :
Rappelez-vous en outre qu'une requête DNS d'un type donné (par exemple, A, NS, DNSKEY) récupère toujours tous les enregistrements de ce type. Si l'ensemble des enregistrements (RRset pour Resource Record Set) a changé entre temps, mais qu'un ensemble plus ancien est dans le cache, il y restera jusqu'à l'expiration du TTL.
Après ces rappels, les méthodes pour faire un remplacement de clé (section 2 de notre RFC). D'abord, les ZSK (Zone-Signing Keys). Il faut que tout résolveur validant qui a accès à une signature ait également accès à la ZSK correspondante, et ce à tout moment, que l'information soit dans le cache ou pas. Pas question donc de se contenter de publier la nouvelle ZSK et de l'utiliser immédiatement pour signer (les résolveurs ayant l'ancien enregistrement DNSKEY dans leur cache ne pourraient pas valider les nouvelles signatures, et idem si c'est la signature qui est dans le cache mais pas la clé). Il y a trois techniques pour un remplacement qui marche :
La double-signature est probablement la plus facile à comprendre : à tout moment, durant la transition, on aura à la fois l'ancienne et la nouvelle clé, les anciennes et les nouvelles signatures. Elle n'a que deux étapes (introduire la nouvelle clé et les nouvelles signatures, puis retirer l'ancienne clé et les anciennes signatures). Son principal inconvénient est d'augmenter la taille des réponses puisqu'il faut transmettre deux fois plus de signatures. La pré-publication est plus compliquée (trois étapes) mais maintient la taille des réponses au minimum nécessaire. Notez que « plus compliqué » est surtout un problème si vous voulez tout comprendre, ou bien si vous êtes le programmeur qui va devoir automatiser l'opération. Mais, si vous utilisez un logiciel déjà fait, comme OpenDNSSEC, vous ne verrez pas cette complexité. La double-RRSIG a les inconvénients des deux autres techniques sans leurs avantages. C'est pour cela qu'elle ne figure pas dans le RFC 6781 et qu'elle n'est pas davantage mentionnée ici.
Et pour un remplacement de KSK ? Le problème est plus simple car la KSK n'est utilisée que pour signer le DNSKEY et clé et signatures voyagent donc ensemble (mais n'ont pas forcément le même TTL, ce que le RFC oublie de dire, donc l'une peut expirer du cache avant l'autre). Mais il est aussi plus compliqué car la KSK est pointée par un lien de confiance (trust anchor), typiquement un enregistrement DS dans la zone parente. Il faut donc coordonner le remplacement de KSK avec celui de ces liens. Et, comme le sait tout administrateur réseau, tout est plus compliqué quand on doit se coordonner avec le monde extérieur. Contrairement au remplacement d'une ZSK, où tout peut être automatisé car le passage d'une phase à l'autre ne dépend que de l'écoulement du temps, le remplacement d'une KSK nécessite une observation manuelle du parent, dont le délai de réaction est imprévisible.
Si le lien de confiance est un enregistrement DS (cas le plus fréquent), il faudra une interaction avec le gestionnaire de la zone parente. Si ce lien a été configuré manuellement (c'est rare, sauf pour la zone racine, qui n'a pas de parente), il faudra faire le changement dans tous les résolveurs qui ont configuré ce lien (une tâche difficile), ou bien utiliser le RFC 5011 (cf. section 3.3.4). C'est en raison des incertitudes à ce sujet qu'il n'y a jamais eu de remplacement de la KSK de la racine.
Comme pour le changement de ZSK, il y a trois techniques :
Le double-KSK est le plus simple à comprendre, mais cette technique augmente la taille de l'ensemble DNSKEY. Le double-DS n'a pas ce défaut mais nécessite deux interactions avec le parent (certaines zones parentes, comme la racine, sont très lentes à réagir). Le double-RRset a les inconvénients des deux autres techniques mais est aussi la technique qui minimise le temps total de remplacement.
La section 3 du RFC présente les frises chronologiques (timeline) détaillées. Elle s'appuie sur une liste d'états des clés (états qu'affiche un logiciel comme OpenDNSSEC) :
Les sections 3.2 et 3.3 présentent les frises
chronologiques (timelines) des différentes techniques de remplacement
d'une ZSK et d'une KSK (en art ASCII...) Les
frises sont un peu complexes car,
à chaque fois, on voit deux introductions d'une nouvelle clé, la N et la N+1.
L'annexe A détaille les abréviations utilisées. Je n'ai pas reproduit
ici les frises du RFC mais juste une version très simplifiée. Quelques points sont dignes d'être notés. D'abord, il peut
être prudent, lorsqu'on met en œuvre ces frises, d'ajouter une marge à
chaque opération (les éléments
<PublishSafety>
et
<RetireSafety>
dans
la configuration d'OpenDNSSEC). Si une clé est publiée à l'instant T, et que le TTL
est de N secondes, on peut compter que cette clé soit accessible à
tous les caches à T + N mais il est plus prudent d'utiliser T + N + M
où M est une marge qui permet de faire face à certains imprévus (un
retard dans la mise à jour de certains serveurs faisant autorité, par exemple).
On peut améliorer la technique de pré-publication en
introduisant des clés en attente
(standby keys, section 4). Ces clés sont
pré-publiées mais ne sont pas utilisées même lorsque le TTL de DNSKEY
est passé. Elles attendent simplement. En général, elles sont là pour
des cas d'urgence. Un exemple est celui d'une clé normale, stockée sur
la machine qui fait les signatures DNSSEC, et une clé en attente,
stockée sur une clé USB dans un
coffre-fort. On pré-publie la clé en
attente. Si, un matin, on découvre que la machine de signature a été
piratée, on peut basculer tout de suite vers la clé en attente,
puisqu'elle est dans les caches (la clé en attente est en permanence
dans l'état Ready). À noter que, pour une KSK et
pour la technique du Double-DS, ce n'est pas la clé qu'on publie mais
le DS correspondant. On a donc un standby DS (c'est
le cas aujourd'hui sur
.fr
, si vous
regardez). Notez aussi un point de sécurité : une clé en attente n'a
de sens que si elle se trouve stockée dans un endroit différent des
autres clés. Autrement, elle sera piratée avec les autres.
Donc, en résumé (section 6) :
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : J. Halpern (Ericsson), C. Pignataro (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF sfc
Première rédaction de cet article le 22 octobre 2015
Aujourd'hui, des flots de paquets IP qui voyagent d'un point à un autre de l'Internet ont peu de chances de le faire sans passer par divers traitements, des plus honorables (statistiques, lutte contre une attaque par déni de service) aux moins avouables (étranglement du trafic pour pousser un fournisseur de contenu à payer, censure). Actuellement, ces traitements sont rigidement liés à la topologie du réseau sous-jacent et manquent donc de souplesse. Dès qu'on veut chaîner plusieurs traitements, le résultat de la configuration devient difficile à lire et à maintenir (le problème est décrit plus en détail dans le RFC 7498). L'idée de base du projet SFC (Service Function Chaining) est de spécifier une architecture (ce RFC) et peut-être plus tard des protocoles pour organiser ces traitements de manière plus souple.
Le RFC 7498 avait très bien décrit le problème qu'on essaye de résoudre. Ce nouveau RFC 7665 est plus concret, décrivant l'architecture des SFC mais je trouve personnellement qu'il reste encore très abstrait et qu'il ne fait pas beaucoup avancer la compréhension, par rapport à son prédécesseur.
Donc, l'architecture des SFC (Service Function Chaining). On veut avoir des chaînes ordonnées des traitements appliqués aux flux réseau, et on veut pouvoir les créer, les modifier et les détruire facilement, avec bien plus de souplesse que le système actuel (section 1 du RFC).
Les paquets entrent et sont classés, les traitements étant ensuite appliqués en fonction du classement. Ces traitements sont appliqués dans l'ordre de la chaîne et, attention, il peut y avoir une re-classification dans un des ces traitements, menant à une autre chaîne.
Pour définir l'architecture, on suppose que :
Chaque traitement (on le nomme un SF pour Service Function) est identifié de manière unique dans le domaine (dans les exemples du RFC, l'identificateur est un simple nombre). Une suite de SF est une SFC (Service Function Chain). Une SFC peut être unidirectionnelle (par exemple des paquets qui sont d'abord comptés, puis filtrés, puis modifiés) ou bidirectionnelle.
Un SFF (Service Function Forwarder) est responsable d'acheminer le trafic d'une SF à une autre. Un SFP (Service Function Path) est la réalisation concrète d'une SFC et un RSP (Rendered Service Path) est la suite des SF effectivement visités. Prenons comme exemple une SFC qui dit que le trafic doit passer par deux SF, un pare-feu et un cache. Le SFP, plus concret, va indiquer quelle instance des deux DF, et dans quel centre de données, on va utiliser. Et le RSP indiquera où le trafic est réellement passé (il peut différer du SFP si ce dernier laissait une certaine latitude, ou bien si quelque chose ne s'est pas passé comme prévu).
La section 3 du RFC liste les grands principes, notamment :
La section 4 de notre RFC détaille les composants du système vus plus haut (SF, SFF, etc). Ces composants sont reliés par l'encapsulation SFC, qui définit comment on va encapsuler le trafic pour l'acheminer d'un composant à l'autre. Attention, ce n'est pas un remplaçant d'IP : lorsque les SF sont sur des machines séparées, il faudra toujours un réseau sous-jacent pour transmettre les paquets. Le plan de contrôle (comment trouver où acheminer le trafic) n'est pas décrit, il est hors-sujet pour ce projet, qui reposera sur des protocoles déjà existants.
D'ailleurs, en parlant de réseau, la section 5, qui couvre divers problèmes de réalisation, note entre autres que qui dit encapsulation dit problèmes de MTU, suite aux octets d'en-tête de l'encapsulation. Il n'y a pas de solution idéale pour les futurs protocoles concrets qui instancieront cette vision abstraite des Service Function Chains mais il faut au moins garder ce problème en tête.
Autre problème pratique dans la même section 5, la fiabilité. Si on met des services supplémentaires dans le réseau, cela ne doit pas trop diminuer sa résilience. Par exemple, prenons une SFC qui ne comporte qu'un seul SF, chargé de mesurer le trafic. La panne de l'équipement qui porte ce SF ne doit pas arrêter tout le trafic. Ici, c'est relativement facile car le SF « compteur » n'a pas besoin d'être en série sur le trajet, il peut être placé en dérivation. Mais d'autres SF ont besoin de modifier le trafic et donc doivent être placés en série. Il faut alors prévoir des solutions de secours, par exemple à base de VRRP (RFC 5798).
Le déploiement des SFC peut aussi avoir des conséquences sur la sécurité. On passe d'un réseau assez statique avec peu de fonctions à un réseau très dynamique pouvant assurer plein de fonctions (section 6 de notre RFC).
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : B. Trammell, M. Kuehlewind (ETH Zurich)
Pour information
Première rédaction de cet article le 22 octobre 2015
Une caractéristique importante de l'Internet d'aujourdhui, et qui le distingue considérablement de l'architecture initialement prévue, est la prévalence de middleboxes un peu partout sur le trajet. Alice et Bob ne peuvent plus, dans la plupart des cas, se parler directement, ils doivent passer par des middleboxes, dont les intérêts ne sont pas ceux des utilisateurs, et qui sont en outre fréquemment boguées et/ou limitées dans leurs fonctions. Un des effets est l'ossification de l'Internet : innover devient de plus en plus difficile, car il y aura toujours une middlebox sur le trajet qui ne sera pas d'accord. Quelles sont les conséquences de cette middleboxation de l'Internet ? Comment peut-on résoudre les problèmes qu'elle posent ? C'est le but du programme IP Stack Evolution de l'IAB que de trouver des réponses à ces questions. C'est dans ce cadre qu'un atelier a été organisé en janvier 2015 à Zurich pour explorer la question. Ce RFC est le compte-rendu de l'atelier SEMI (Stack Evolution in a Middlebox Internet).
On comprend mieux le problème en revenant à l'architecture prévue pour l'Internet (très bien décrite dans le RFC 1958), et qui a assuré son succès, le principe de bout en bout, formalisé dans l'article de J.H. Saltzer, D.P. Reed et David Clark, « End-To-End Arguments in System Design » (ACM TOCS, Vol 2, Number 4, November 1984). Ce principe dit en gros que deux machines connectées à l'Internet doivent décider elles-mêmes de ce qui est bon pour elles, les équipements intermédiaires qui forment le réseau ne sont pas bien placés pour prendre des décisions. Ce principe a pour conséquence un réseau « bête », où les routeurs transmettent les paquets sans chercher à comprendre. Des décisions comme le contrôle de congestion sont faites aux extrémités du réseau, dans les machines terminales. Par exemple, un protocole de transport, dont l'une des fonctions est de réagir en cas de congestion, sera mis en œuvre uniquement dans ces machines. Conséquence de ce principe, l'innovation ne nécessite pas de changement dans l'infrastructure. Si on trouve que le protocole de transport TCP n'est pas terrible, on en invente un autre (comme SCTP) et du jour au lendemain, tout couple de machines Internet peut l'utiliser, sans qu'on ait eu à modifier les routeurs de l'Internet.
Mais l'Internet a bien dégénéré depuis le RFC 1958. D'innombrables équipements supplémentaires, les middleboxes ont été installés et leur but n'est pas de fournir des services aux utilisateurs mais au contraire de les contrôler et de limiter ce qu'ils peuvent faire. C'est ainsi que boitiers NAT, pare-feux, et autres middleboxes se permettent désormais de regarder le trafic et de dire, par exemple « ah, non, SCTP, je ne connais pas, je ne laisse pas passer ». C'est ce qu'on nomme l'ossification : déployer un nouveau protocole de transport, voire un nouveau protocole d'application (« un seul autorisé, HTTP », est un principe fréquent sur les middleboxes), devient de plus en plus difficile. Peut-on encore désossifier l'Internet ? Le problème a été identifié il y a longtemps (cf. l'exposé de S. Deering, « Watching the Waist of the Protocol Hourglass »), il reste à travailler sur les solutions.
L'atelier SEMI avait donc invité les experts à soumettre des articles autour de questions comme « quels chemins dans l'Internet acceptent encore tous les transports ? », « quels chemins sont ouverts à toutes les applications ? », « comment les applications peuvent-elle faire pour contourner les blocages ? », « comment revenir à une situation plus saine ? ». Des tas de pistes étaient possibles :
Les articles acceptés sont tous disponibles sur le site Web de l'atelier SEMI. Ce RFC est très court et n'en fait qu'un résumé (et moi, dans cet article, un résumé du résumé).
À l'époque de l'exposé de Deering cité plus haut, le principal type de middlebox repéré était le routeur NAT. Aujourd'hui, les problèmes causés par le NAT, sans avoir été supprimés, sont bien compris et il existe des solutions de contournement (imparfaites, contrairement à ce que laisse entendre l'optimisme du RFC, qui parle d'un problème « largement résolu »). Plusieurs groupes de travail de l'IETF ont travaillé pour cela, notamment BEHAVE. Mais les middleboxes sont devenues plus variées et plus intrusives, au fur et à mesure que leurs possibilités techniques augmentaient (section 2 de notre RFC). Aujourd'hui, le problème qu'elles posent devient d'autant plus intolérable que les préoccupations de sécurité, et notamment de protection de la vie privée, poussent au développement de la cryptographie. Celle-ci permet de préserver l'intégrité des communications de bout en bout et s'oppose donc directement aux middleboxes. (C'était le coeur de l'exposé de Huitema à SEMI.)
Qu'est-ce qui fait que des middleboxes sont déployées ? La section 3 du RFC se penche sur les motivations ; après tout, il y a peu de chances de pouvoir revenir sur ce déploiement si on ne comprend pas pourquoi il a lieu. Parmi les causes, il y a la loi de Moore, qui fait qu'il est de plus en plus réaliste de mettre des traitements importants sur le chemin des communications, malgré la concentration de trafic. Il y a le désir des opérateurs réseau de ne pas être « uniquement un tuyau » (ce que voudraient les utilisateurs) mais d'imposer des traitements (qu'on baptise « valeur ajoutée ») qui justifieront des augmentations de tarif, ou des violations de la neutralité. Il y a des services informatiques qui trouvent qu'il est plus facile de déployer une politique dans le réseau que dans les machines terminales, d'autant plus qu'ils ne contrôlent pas forcément celles-ci (cas du BYOD). Et il y a bien sûr le marketing des vendeurs de middleboxes qui insiste lourdement pour qu'on achète ces boitiers, dotés de vertus miraculeuses (en sécurité ou en performances). C'est vrai qu'acheter est un acte simple, et il est tentant de se procurer un service juste en faisant un chèque. Toutes ces motivations contribuent à l'ossification du réseau.
Les organisateurs de SEMI se placent dans le cadre d'un système capitaliste pur (rebaptisé, car c'est plus joli, « libre marché »), vu comme incontournable. Dans ce cadre, les désaccords ne sont adressables que par le jeu du marché et il faut donc fournir des motivations business pour tout changement. Cela mène à la question « comment vendre les alternatives aux middleboxes ? »
La section 4 explore ce que font exactement les middleboxes. Car il y en a de plein de sortes différentes et, pour résoudre les problèmes qu'elles posent, il faut les étudier et les classer (c'était le papier de Edeline et Donnet).
Cette étude est notamment nécessaire pour savoir si les applications pourront coopérer avec les middleboxes ou bien s'il faudra envisager des mesures plus « ninja » comme de tout tunneler (la contribution de Raiciu et Olteanu).
Et sur les protocoles de transport ? La section 5 discute de comment faire évoluer la couche 4 dans un Internet gelé par les middleboxes. S'inspirant d'un épisode du film « La vie de Brian », le RFC classe les propositions en deux camps :
Ajoutez la crypto à cela et la solution UDP se traduira peut-être dans le futur par « tout sur DTLS »... Des tas de solutions ont été imaginées par les « transporteurs », les gens de la couche 4. Par exemple, la contribution de Briscoe propose de mettre les options et extensions nouvelles de TCP dans la charge utile et non pas dans l'en-tête TCP, les mettant ainsi à l'abri des middleboxes (jusqu'à ce qu'elles se mettent à faire du DPI lourd...)
À noter que tous les chemins sur l'Internet ne sont pas forcément affligés de middleboxes. Quelles que soient les solutions de contournement adoptées, il serait dommagee qu'elles soient imposées à tous, avec leurs coûts en octets gaspillés et en complexité, alors qu'on peut s'en passer dans beaucoup de cas. Welzl, Fairhurst et Ros avaient ainsi proposé de consacrer des efforts à la détection des middleboxes. On teste le chemin et, s'il est propre, on se dispense des horreurs nécessitées par le contournement des middleboxes. Comme ce test va prendre du temps, il faudra sans doute le faire en parallèle des tentatives de connexion, comme dans le cas du RFC 6555.
Bon, maintenant, place à l'action. Qu'est-ce qui doit être fait pour avancer ? La section 6 de notre RFC liste les points à traiter. D'abord, est-ce qu'on ne pourrait pas envisager de signaler au réseau certaines informations sémantiques (du genre « ce paquet est le début d'un nouveau flot »), dispensant les middleboxes d'essayer de (mal) trouver cette information elles-mêmes ? Cela serait d'autant plus utile que cette information est masquée en cas de chiffrement. Cette idée est à la base du projet SPUD (Substrate Protocol for User Datagrams, « un traité de paix entre machines et réseau »). Ce projet a suscité des controverses lors de sa présentation à l'IETF 92 à Dallas (si on chiffre, ce n'est pas ensuite pour donner des informations à un réseau en qui on n'a pas confiance) et aucun groupe de travail n'a encore été créé. Les objections à SPUD portent notamment sur le fait que la publication des informations devrait être volontaire, et le résultat d'un choix délibéré.
Autre sujet sur lequel il faudrait travailler, la mesure. Cela ne vaudrait pas la peine de développer des hacks d'enfer dans les couches 4 ou 7 pour contourner une perturbation qui est rare. Or, à l'heure actuelle, on manque de données sur les différents types de problèmes causés par les middleboxes. Par exemple, combien de chemins dans l'Internet ne laissent pas passer un protocole de transport inconnu ? (Avant de crier « aucun, tout le monde est derrière un routeur NAT », pensez aux réseaux d'entreprise ou d'organisation, aux réseaux IPv6, etc.) Ces mesures sont le travail de la liste de diffusion hops (How Ossified is the Protocol Stack?) qui discute des meilleurs moyens de collecter cette information, par exemple à partir des journaux des applications qui tentent d'utiliser tel ou tel protocole mais se replient ensuite sur une autre solution. Le pourcentage de repli serait une information utile.
Le RFC n'en parle pas mais un des problèmes posés par les middleboxes est typiquement que leurs programmeurs sont inconnus, et ne participent pas aux forums comme le RIPE ou l'IETF, où se discutent les problèmes de l'Internet. Même si on rédige des bonnes pratiques à suivre pour les auteurs de logiciel de middlebox, il y a peu de chances qu'ils les lisent, ou même apprennent leur existence. (Les middleboxes actuelles ont manifestement été programmées sans lire les RFC ou en tout cas sans lire tous les RFC pertinents, cf. RFC 5625 pour des exemples).
Mais l'IETF est optimiste et croit que l'humanité peut s'améliorer : d'où des documents comme le RFC 3234. Un travail est en cours pour le compléter avec des conseils pratiques.
Bref, la lutte entre les machines terminales, qui veulent un tuyau bête et neutre, et le réseau qui cherche à imposer ses propres vues, n'est pas terminée, loin de là.
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : V. Dukhovni (Unaffiliated), W. Hardaker (Parsons)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dane
Première rédaction de cet article le 21 octobre 2015
Le protocole DANE (RFC 6698) de sécurisation des communications utilisant TLS est encore très peu déployé. Donc, il n'y a pas vraiment de retours d'expériences mais les premiers essais ont quand même permis de se faire des idées, et, pour aider ceux et celles qui vont déployer DANE dans les années à venir, ce nouveau RFC rassemble quelques conseils pratiques.
Donc, DANE permet d'améliorer l'authentification des sessions TLS en publiant dans le DNS, sécurisés par DNSSEC, des enregistrements nommés TLSA (non, ce n'est pas un acronyme, ce nom est à utiliser sans comprendre son étymologie). Ces enregistrements indiquent le certificat utilisé pour la connexion TLS. Ainsi, un gérant d'un serveur TLS n'est plus obligé de dépendre d'une tierce partie, genre AC.
J'ai simplifié car il y en a fait beaucoup de choix : DANE permet de publier des clés brutes, pas seulement des certificats, il permet de publier un certificat d'AC, pas seulement le certificat final, etc. Le RFC 6698 normalise trois champs dans l'enregistrement TLSA (cf. section 2 de notre RFC), « Utilisation du certificat » (quatre valeurs possibles), « Sélecteur » (deux valeurs possibles) et « Méthode de correspondance » (trois valeurs possibles). En tout, il existe vingt-quatre combinaisons, ce qui est probablement trop (combien de clients DANE ont-ils vraiment été testés avec les vingt-quatre combinaisons différentes ?). Notre RFC réduit ce choix par ses conseils.
Voici un exemple d'un enregistrement DANE à peu près conforme aux recommandations du RFC, celui de mon blog :
% dig TLSA _443._tcp.www.bortzmeyer.org ;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 60895 ;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 8; ADDITIONAL: 6 ;; QUESTION SECTION: ;; _443._tcp.www.bortzmeyer.org. IN TLSA ;; ANSWER SECTION: _443._tcp.www.bortzmeyer.org. 86400 IN TLSA 2 0 2 EB0AD84F11B4B08BF76C7866EF32842292BBB2862FB6FC49C0A3F807629CA8F5DD28A0DE7B0C04D566020AC4FF2BA44E2F612AA58A1AE4CCACE486D244952FC2
L'« utilisation du certificat » est DANE-TA (valeur 2, mais le RFC 7218 a introduit de jolis noms pour ces codes), le « sélecteur » est CERT (valeur : 0, on testera tout le certificat, pas juste la clé publique) et la « méthode de correspondance » 2, ce qui veut dire qu'on publie un condensat en SHA-512 de ce certificat.
Notre RFC 7671 ne fait pas qu'ajouter des conseils opérationnels au RFC 6698, il le modifie légèrement sur certains points (section 3 de notre RFC), par exemple en ajoutant qu'un client DANE doit utiliser l'extension TLS nommée SNI (Server Name Indication, cf. RFC 6066).
Que mettre dans le champ « utilisation du certificat » de l'enregistrement TLSA ? La section 4 de notre RFC s'attaque à ce problème. Les quatre valeurs possibles sont PKIX-TA (le certificat utilisé pour TLS doit être vérifié par les mécanismes X.509 classiques et le certificat publié dans le TLSA doit être celui de l'AC), PKIX-EE (le certificat utilisé pour TLS doit être vérifié par les mécanismes X.509 classiques et le certificat publié dans le TLSA doit être celui du serveur TLS), DANE-TA (le certificat publié dans le TLSA est celui d'une AC à partir de laquelle on vérifie le certificat du serveur TLS) et enfin DANE-EE (le certificat publié dans le TLSA est celui du serveur TLS). Pour DANE-TA et DANE-EE, il n'y a pas besoin d'un magasin de certificats pré-existant sur le client TLS.
Il n'y a pas forcément besoin, pour un client DANE, de gérer les quatre utilisations. S'il le fait, un attaquant qui arrive à modifier les enregistrements DNS peut remplacer un PKIK-EE par un DANE-EE et la sécurité supplémentaire de la vérification X.509 qu'impose X.509 est donc assez illusoire. Un client paranoïaque et traditionnaliste qui veut imposer des vérifications X.509 doit donc ignorer purement et simplement les enregistrements avec DANE-EE ou DANE-TA.
Mais notre RFC donne le conseil contraire : ne gérer que DANE-EE et DANE-TA, en raison du manque de confiance qu'on peut avoir dans les centaines d'AC existantes, dont beaucoup ont déjà fait la preuve qu'on ne pouvait pas leur faire confiance. La vérification X.509 de ces AC n'apporte pas grand'chose en sécurité. En outre, il n'existe aucune liste standard d'AC reconnues, ce qui rend PKIX-TA et PKIX-EE très fragiles : le magasin du client doit être un sur-ensemble du magasin de tous les serveurs possibles ce qui mène à des listes d'AC délirantes (regardez celle de votre navigateur Web).
Depuis la publication de DANE, d'autres techniques visant à boucher les trous de X.509 sont apparues, comme les certificats au grand jour du RFC 6962. Comme la liste publique décrite dans ce RFC ne stocke que des certificats émis par des AC connues de la liste, les vérifications du RFC 6962 ne doivent pas être faites pour les utilisations DANE-TA et DANE-EE.
La section 5 rassemble ensuite des conseils spécifiques à chaque usage particulier du certificat publié avec DANE. D'abord, l'usage DANE-EE (valeur : 3). Dans cet usage, le certificat du serveur est publié dans l'enregistrement TLSA et les vérifications X.509 (RFC 5280) ne doivent pas être faites. Le RFC 6698, qui normalisait DANE, ne disait apparemment pas ce qu'il fallait faire des autres informations contenues dans le certificat comme la date d'expiration. Notre RFC 7671 précise (et c'est un des points où il met à jour le RFC 6698, ne se contentant pas d'ajouter des conseils, cf. section 12 pour les autres cas) que les autres informations doivent être ignorées. Si le certificat est dans un enregistrement TLSA, il est bon, quelle que soit la date d'expiration. Idem pour le nom de serveur dans le certificat.
Le sélecteur recommandé, pour cet usage, est SPKI (valeur : 1) qui indique qu'on ne trouve pas dans l'enregistrement TLSA tout le certificat mais juste la clé publique. Raisons de cette recommandation :
Il n'est pas recommandé d'envoyer le certificat entier (méthode de correspondance Full, valeur 0), notamment en raison des problèmes du DNS avec des enregistrements de grande taille (ce qui est souvent le cas des certificats). Il faut plutôt utiliser un condensat du certificat. En cas de doute, notre RFC recommande donc DANE-EE + SPKI + SHA-256 (notez que l'enregistrement TLSA de mon serveur HTTP, cité plus haut, ne suit pas cette recommandation mais ce que le RFC présente comme un second choix).
Mais ce n'est pas impératif. L'usage DANE-TA, où on publie dans l'enregistrement TLSA le certificat de l'AC et pas celui du serveur, est tout à fait légitime (c'est celui que j'utilise). Attention, il impose d'envoyer toute la chaîne de certificats dans la réponse TLS. (Avec OpenSSL et GnuTLS, il suffit de concaténer tous ces certificats, dans le bon ordre - du plus spécifique au plus général, cf. RFC 5246, section 7.4.2 - dans un seul fichier PEM, qui sera celui indiqué au serveur.) Cette nouvelle obligation a été ajoutée pour le cas où l'AC choisie par le gérant du serveur DANE ne soit pas dans le magasin du client (pour CAcert, c'est fréquent).
Contrairement à l'usage DANE-EE, il est recommandé, avec cet usage DANE-TA, d'utiliser le sélecteur Cert (valeur : 0), car, cette fois, il faut tenir compte du contenu complet du certificat (comme les limites de longueur, par exemple, ou bien les restrictions sur les noms que l'AC peut approuver, cf. RFC 5280, section 4.2.1.10).
Un rappel de sécurité pour finir la section sur DANE-TA : cet usage vous protège contre les autres AC, malhonnêtes ou piratées, mais pas contre les autres utilisateurs de la même AC. Choisissez donc bien votre Autorité de Certification !
Deux autres usages possibles de l'enregistrement TLSA maintiennent des validations X.509 classiques. Ce sont les usages PKIK-EE (valeur : 1) et PKIX-TA (valeur : 0).
Un risque important de l'utilisation de DANE est la désynchronisation entre le ou les certificat(s) envoyés en TLS et ceux publiés dans le DNS, dans l'enregistrement TLSA (section 6 de notre RFC). Il faut absolument maintenir ces informations en cohérence, ce qui est d'autant plus difficile que les outils de supervision actuels n'offrent en général pas grand'chose pour DANE. Ainsi, si on utilise DANE-EE ou PKIX-EE, quand on change de clé publique sur le serveur TLS, il faut penser à mettre à jour l'enregistrement TLSA. Compte-tenu de l'importance de la mise en cache des données dans le DNS, cela nécessite de publier le nouveau certificat dans le DNS à l'avance (cf. section 8.4). Bref, notre RFC fait remarquer à juste titre qu'il est très recommandé que le DNS et le TLS soient gérés par la même organisation, autrement, le risque de cafouillage est trop élevé. (DANE est encore d'utilisation récente et on n'a pas encore vu beaucoup de cas de changement de certificat. Quand ça arrivera, il est à craindre qu'il y ait quelques malheurs, lorsque l'administrateur système oubliera qu'il avait publié un enregistrement TLSA.)
La section 8 met en garde les gérants de serveurs utilisant DANE contre le fait qu'on ne peut pas espérer que tous les clients DANE comprennent tous vos enregistrements TLSA. Ceux-ci peuvent spécifier un algorithme de condensation récent que tout le monde ne gère pas encore. Ou bien ils peuvent utiliser les clés nues du RFC 7250, que tout le monde n'accepte pas, loin de là. Attention donc, surtout lorsque vous décidez des paramètres.
La même section traite du difficile problème du remplacement : en raison des caches du DNS, les changements de clé ou de paramètres ne sont pas vus immédiatement partout. Il faut donc suivre quelques précautions quand on est hébergeur DNS d'un domaine qui utilise DANE :
À noter que le problème des clients DANE ne gérant pas toutes les valeurs possibles des paramètres est d'autant plus agaçant qu'il n'y a pas forcément de règles précises sur le choix d'un enregistrement TLSA, si plusieurs conviennent. Imaginons que vous ayez deux enregistrements TLSA, identiques sauf la méthode de correspondance qui vaut SHA-256 pour l'un et SHA-512 pour l'autre. Lequel sera utilisé par le client DANE ? Il faudrait évidemment que ce soit le plus fort (SHA-512) mais le RFC 6698 ne dit pas comment. Notre nouveau RFC demande au contraire que tout client DANE ait un classement des algorithmes de condensation, idéalement configurable par l'utilisateur, et qui soit par défaut l'ordre des valeurs (SHA-256 : 1, SHA-512 : 2, etc). Le client DANE, lorsqu'il a le choix, doit prendre le mieux classé (ou la méthode Full - valeur : 0 - qui n'utilise pas d'algorithme de condensation cryptographique, si un enregistrement TLSA l'utilise).
La section 10 de notre RFC rassemble des conseils divers pour la conception de protocoles utilisant DANE. D'abord, la taille des enregistrements, importante car le DNS a souvent des limites de taille. Par exemple, la plupart des serveurs faisant autorité ont une taille maximale de 4 096 octets pour les réponses se faisant en UDP. Même si la réponse est inférieure à cette valeur, une taille plus grande que 1 500 octets a de grandes chances de mener à une fragmentation de la réponse UDP, avec des conséquences négatives sur les performances voire, pire, sur la fiabilité de l'acheminement de la réponse (pas mal de pare-feux bogués bloquent stupidement les fragments). En théorie, on peut alors utiliser TCP pour transmettre les données mais lui aussi est souvent bloqué par des logiciels configurés par des incompétents.
Avec les grands certificats qu'on trouve souvent dans le monde X.509, le risque de paquets trop grands est bien plus élevé qu'avec les données de petite taille qu'on trouve habituellement dans le DNS. D'où les conseils de notre RFC : n'utilisez pas ensemble le sélecteur CERT (valeur : 0, il indique qu'il faut comparer tout le certificat, pas juste la clé publique) et la méthode de correspondance FULL (valeur : 0, elle indique que l'enregistrement TLSA contient les données complètes, pas juste un condensat). En effet, cette combinaison oblige à mettre un certificat entier dans l'enregistrement TLSA, ce qui dépasse en général la taille raisonnable. (D'autant plus qu'en cas de remplacement, il faudra publier simultanément deux enregistrements TLSA.) Avec un sélecteur SPKI (valeur : 1, on ne vérifie que la clé publique), le problème est moins grave, néanmoins autant ne jamais utiliser la méthode de correspondance FULL.
Notre RFC contient aussi des conseils pour le certificat envoyé par TLS. Il y a normalement des règles précises sur le nom (subject, en terminologie X.509) qui doit être mis dans le certificat, afin de permettre l'authentification. Néanmoins, ces règles sont complexes (donc pas toujours bien comprises) et ont changé dans le temps. Il peut être prudent de rajouter des noms « au cas où ». Ainsi, pour un service auquel on accès via un enregistrement SRV, le RFC 7673 prescrit de vérifier le nom en partie droite du SRV. Mais comme on ne peut pas être sûr de ce que feront tous les clients DANE, autant essayer de mettre aussi dans le certificat le nom qui est en partie gauche du SRV.
La section 11 se penche, elle, sur DNSSEC. DANE est complètement dépendant de DNSSEC : sans lui, plus aucun enregistrement TLSA n'est accepté. La sécurité de DNSSEC est donc cruciale pour DANE. Avec X.509, la sécurité de l'AC que vous choisissez a peu d'importance, puisque n'importe quelle AC peut émettre un certificat pour votre serveur. (Les « Name constraints » - section 4.2.1.10 du RFC 5280 - sont très peu utilisées.) Avec DNSSEC, au contraire, vous ne dépendez que d'acteurs que vous choisissez : votre hébergeur DNS, votre BE (souvent le même que l'hébergeur), votre registre...
DNSSEC dépendant du DNS, il va donc falloir sécuriser votre configuration DNS (cf. le bon guide de l'ANSSI). Par exemple, il est recommandé de placer un verrou (registry lock) pour limiter les risques de détournement de votre domaine, ou de modification non autorisée.
Certaines opérations dans le DNS sont délicates à faire lorsqu'un domaine est signé : le passage d'un BE à l'autre lorsque chacun est également l'hébergeur DNS. Une technique parfois recommandée est de dé-signer la zone temporairement. On retire le DS, on attend l'expiration dans les caches, on migre, on met un nouveau DS. Cette méthode est sûre et simple mais elle laisse une fenêtre d'insécurité, où la zone n'est pas signée. Sans DANE, c'est un inconvénient supportable (il faut juste espérer que l'attaquant ne frappe pas à ce moment), avec DANE, c'est impossible car les enregistrements DANE seront ignorés pendant cette période d'insécurité. S'ils sont d'usage PKIK-EE ou PKIK-TA, ce n'est pas trop grave, le certificat sera toujours validé par X.509 mais s'ils sont d'usage DANE-TA ou surtout DANE-EE, on ne pourra plus se connecter au serveur. Voilà pourquoi il faut étudier les conditions de migration du domaine avant de déployer DANE.
DNSSEC n'a pas de notion de révocation (là encore, sauf si on utilise les usages PKIX-EE ou PKIK-TA, où les vérifications de la révocation du certificat peuvent être faites). Attention donc de ne pas mettre des TTL trop longs à vos enregistrements TLSA (section 13 du RFC, au début) et surtout pas des périodes de validité des signatures trop longues pour éviter des attaques par rejeu. Pour ces périodes de validité, le RFC recommande quelques jours pour des clés importantes et quelques semaines pour les autres. Regardez par exemple l'enregistrement TLSA de mon serveur de courrier :
_25._tcp.mail.bortzmeyer.org. 86400 IN TLSA 2 0 1 ( FF2A65CFF1149C7430101E0F65A07EC19183A3B633EF 4A6510890DAD18316B3A ) _25._tcp.mail.bortzmeyer.org. 86400 IN RRSIG TLSA 8 5 86400 ( 20151101223339 20151012192513 53605 bortzmeyer.org. BEiYRQh4i4Z3RH0h3yZqDjltCmv...
Le TTL est d'une journée (ce qui fait qu'un changement d'urgence
du certificat pourrait casser la vérification pendant une journée,
dans le pire des cas). La durée de validité de la signature est de 20 jours
(<Validity><Default>P20D</Default></Validity>
dans la configuration OpenDNSSEC). Avec des courtes validités, on ne peut pas
se permettre d'avoir un serveur DNS maître en panne très
longtemps, et des périodes de quelques jours ne doivent donc être
utilisées que si on dispose d'une équipe professionnelle et réactive.
Enfin, il est évidemment crucial de superviser sa configuration DNSSEC.
Enfin, dernier conseil, section 14 (mais on l'a déjà dit plus haut), attention au fait que certains enregistrement TLSA seront considérés comme inutilisables par certains clients DANE. En TLS « opportuniste » (RFC 7435), cela se traduira par une absence de vérification du certificat par le client. Mais en mode plus sécurisé (très rare à l'heure actuelle), cela peut se traduire par une impossibilité de se connecter en TLS.
Terminons avec un peu de ligne de commande Unix. Comment on génère
un enregistrement TLSA ? Par exemple, pour le mien, d'usage DANE-TA
(valeur : 2), je prends le certificat de mon
AC, CAcert (wget https://www.cacert.org/certs/root.crt
) et voici
deux méthodes possibles, avec OpenSSL, puis
avec hash-slinger. D'abord,
avec OpenSSL (voir cet article) :
% openssl x509 -in root.crt -outform DER | openssl sha256 (stdin)= ff2a65cff1149c7430101e0f65a07ec19183a3b633ef4a6510890dad18316b3a
Et on n'a plus qu'à mettre :
_25._tcp.MXSERVER.DOMAIN. IN TLSA 2 0 1 ff2a65cff1149c7430101e0f65a07ec19183a3b633ef4a6510890dad18316b3a
dans sa configuration DNS. Avec hash-slinger :
% tlsa --create --port 25 --certificat root.crt --usage 2 --selector 0 --mtype 1 \ mail.bortzmeyer.org _25._tcp.mail.bortzmeyer.org. IN TLSA 2 0 1 ff2a65cff1149c7430101e0f65a07ec19183a3b633ef4a6510890dad18316b3a
Troisième possibilité, le faire en ligne.
Et si je voulais un enregistrement TLSA d'usage DANE-EE (valeur : 3) ? Avec OpenSSL, ce serait :
printf '_25._tcp.%s. IN TLSA 3 1 1 %s\n' \ $(uname -n) \ $(openssl x509 -in server.pem -noout -pubkey | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | hexdump -ve '/1 "%02x"') _25._tcp.www.foobar.example. IN TLSA 3 1 1 755b35d2c34c54729d92f97e25d8a8be020235d5b1c6b7751bfefc896b8e5164
Avec hash-slinger, il suffit de modifier les paramètres de la ligne de commande.
Si vous voulez tester vos enregistrements TLSA, ce qui est très recommandé :
https://check.sidnlabs.nl/dane/
.https://www.tlsa.info
.Et pour lire davantage, vous pouvez voir le dossier thématique de l'AFNIC sur DANE.
Première rédaction de cet article le 19 octobre 2015
Le lancement raté d'un site Web gouvernemental (détails plus loin, analyse technique détaillée à la fin) est l'occasion de revenir sur un phénomène qui arrive assez souvent lorsqu'une partie de l'Internet est en panne : le coupable désigné sur les réseaux sociaux n'est pas toujours le bon (enfin, le méchant). Notamment, en cas de mauvaise configuration des techniques de sécurité, ceux qui appliquent ces techniques peuvent être « accusés » de la panne, puisque ça continue à marcher chez les « laxistes ».
Le dernier exemple que j'ai en tête s'est produit il y a
quelques jours lors du lancement de
http://www.images-art.fr/
, un site Web
gouvernemental de distribution d'images. Ce site est un
scandale mais ce n'est pas le problème ici. Le problème est
que les gérants du site Web avaient fait une erreur de
configuration, et que ce site n'était donc pas visible depuis une
partie de l'Internet, notamment depuis
Free. La réaction de beaucoup
d'utilisateurs avait été de reprocher ce problème à Free puisque
« ça marche chez les autres ». Mais c'était injuste. En effet,
Free est un des rares FAI français à
déployer DNSSEC, une technique de sécurité
qui vise à protéger les utilisateurs contre certaines attaques sur
le réseau. Malheureusement, la plupart des autres FAI ne se
soucient pas de sécurité et n'ont pas déployé cette technique. (Si
vous préférez des exemples états-uniens, un incident similaire
s'était produit lorsque la NASA avait
cafouillé dans sa configuration, et que
Comcast, principal FAI à utiliser DNSSEC,
avait été accusé, bien à tort, de bloquer la NASA.)
Or, le nom de domaine
images-art.fr
avait un problème de
configuration. Cela le rendait invisible depuis les opérateurs qui
mettaient en œuvre DNSSEC (Free mais aussi Google
Public DNS). En effet, ce problème de configuration
était indistinguable d'une attaque.
Et c'est là un paradoxe fréquent de la sécurité : la sécurité gêne les utilisateurs. Imaginons un petit village qui n'a jamais connu de cambriolage. Les habitants ne ferment pas la porte à clé ou, quand ils le font, ils laissent la clé sous le pot de fleurs près de l'entrée. Maintenant, si la situation change et qu'il commence à y avoir quelques cambriolages, certains habitants vont commencer à faire plus attention. Et les ennuis commenceront parce que, pour un cambriolage évité grâce à une porte fermée, il y aura dix ou vingt incidents dus à la sécurité : une personne claque la porte en laissant la clé dedans, une autre a oublié qu'un membre de sa famille devait passer et n'avait pas la clé, un troisième perd la clé dans la journée... Tous réagiront probablement au début en disant « la sécurité, c'est pénible » (ce qui est parfaitement exact).
Quittons notre histoire et revenons à
l'Internet. images-art.fr
a cafouillé (voir
l'analyse technique détaillée plus loin). Mais ce cafouillage n'a
eu aucune conséquence chez les FAI qui ne vérifient pas. Ils n'ont
pas de quoi s'en vanter. Bien au contraire, ils laissent leurs
utilisateurs vulnérables. Et ce sont donc Free ou Google qui
avaient raison : les mesures de sécurité déployées étaient bonnes,
la responsabilité de la panne n'était pas chez eux. Notons que ce
problème n'a rien de spécifique à DNSSEC et que, par exemple,
HTTPS (le petit cadenas et la barre
verte...) connait largement autant de semblables « bavures ».
Pour les techniciens, voici maintenant quelques informations
concrètes. La panne était due au fait que
images-art.fr
n'était pas
signé par DNSSEC mais qu'il y avait dans la
zone parente (.fr
) un
enregistrement DS (Delegation Signer, un
pointeur de la zone parente vers la clé de la zone fille, celui-ci
pointait vers la clé 60840). Cet
enregistrement DS est interprété par les résolveurs DNSSEC comme
voulant dire « la zone est signée ». Si le résolveur découvre
qu'elle ne l'est pas, il interprète cela comme une
attaque. Pourquoi cette erreur ? On peut supposer plein de choses
mais je note en examinant DNSDB que le
DS n'a jamais changé alors que les clés dans la zone (et les
signatures) ne sont apparues que le 19 octobre dans
l'après-midi. Il est donc probable que la zone était prévue pour
être signée, mais que c'est la zone non signée qui a été publiée,
sans que cela n'empêche l'administrateur système de publier le DS,
sans avoir vérifié (la plupart des professionnels ne testent jamais
la configuration qu'ils déploient). Une hypothèse proche était que
le processus (signature + envoi du DS au registre) était automatisé
mais que le programme avait une bogue : l'échec de la signature n'a
pas suspendu la publication du DS.
Voici ce que montraient deux logiciels de débogage DNSSEC au moment de la panne : ZoneMaster (« Server at 46.105.206.200 sent 2 DNSKEY records, and 0 RRSIG records ») et DNSviz. Voici ce que voyait l'outil dig, d'abord avec Google Public DNS :
% dig @8.8.8.8 www.images-art.fr ; <<>> DiG 9.9.5-12-Debian <<>> @8.8.8.8 www.images-art.fr ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 11922 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ;; QUESTION SECTION: ;www.images-art.fr. IN A ;; Query time: 24 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Mon Oct 19 15:30:06 CEST 2015 ;; MSG SIZE rcvd: 46
Le code SERVFAIL
signifie Server
Failure. Si on demande à Google de ne
pas valider avec DNSSEC (CD = Checking
Disabled) :
% dig +cd @8.8.8.8 www.images-art.fr ; <<>> DiG 9.9.5-12-Debian <<>> +cd @8.8.8.8 www.images-art.fr ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4472 ;; flags: qr rd ra cd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ;; QUESTION SECTION: ;www.images-art.fr. IN A ;; ANSWER SECTION: www.images-art.fr. 3599 IN A 213.186.33.5 ;; Query time: 15 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Mon Oct 19 15:30:09 CEST 2015 ;; MSG SIZE rcvd: 62
C'était une autre preuve que le problème avait un lien avec DNSSEC. Essayons ensuite chez Free avec le résolveur de la Freebox :
% dig www.images-art.fr ; <<>> DiG 9.10.2-P2 <<>> www.images-art.fr ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 52045 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;www.images-art.fr. IN A ;; Query time: 51 msec ;; SERVER: 192.168.2.254#53(192.168.2.254) ;; WHEN: Mon Oct 19 15:34:37 CEST 2015 ;; MSG SIZE rcvd: 46 % dig +cd www.images-art.fr ; <<>> DiG 9.10.2-P2 <<>> +cd www.images-art.fr ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50409 ;; flags: qr rd ra cd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;www.images-art.fr. IN A ;; ANSWER SECTION: www.images-art.fr. 3361 IN A 213.186.33.5 ;; Query time: 8 msec ;; SERVER: 192.168.2.254#53(192.168.2.254) ;; WHEN: Mon Oct 19 15:34:40 CEST 2015 ;; MSG SIZE rcvd: 62
À noter que ce problème de « fausse alerte » ou de « faux positif » avec DNSSEC a été identifié il y a longtemps. Une des solutions possibles est le Negative Trust Anchor décrit dans le RFC 7646.
Merci à Kanor pour avoir attiré mon attention sur ce problème.
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : V. Dukhovni (Two Sigma), W. Hardaker
(Parsons)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dane
Première rédaction de cet article le 18 octobre 2015
L'état actuel de la sécurisation de SMTP par TLS n'est pas très satisfaisant : la grande majorité des certificats est auto-signée (pour éviter les prix et les délais des Autorités de certification) et, souvent, expirée. Conséquence logique, les serveurs SMTP ne vérifient pas les certificats : s'ils le faisaient, ils ne pourraient plus envoyer de courrier, ou bien ils se rabattraient sur du SMTP en clair, sans TLS, ce qui serait pire que d'accepter un certificat pourri. Comment améliorer la situation ? Ce nouveau RFC propose d'utiliser DANE en publiant dans le DNS, sécurisé par DNSSEC, le certificat du serveur. DANE était déjà normalisé pour HTTP, voici comment l'utiliser pour le courrier, où il y a un petit piège supplémentaire : le nom du serveur est indiqué via les enregistrements MX.
Le courrier a des spécificités qui font qu'on ne peut pas
appliquer directement DANE de la même façon qu'avec
HTTP (section 1 du RFC). Outre l'indirection entre nom du
service (ce qui est à droite du @ dans une
adresse) et nom de serveur (la partie droite de
l'enregistrement MX), il y a le fait que
rien n'indique si un service ou un serveur donné a
TLS. Résultat, un attaquant actif peut
supprimer la requête STARTTLS
(RFC 3207), forçant ainsi un repli vers l'envoi de
courrier en clair (c'est une des plus grosses vulnérabilités de
SMTP-sur-TLS).
Généraliser TLS pour SMTP va prendre du temps (en France, il faut apparemment une charte signée avec le ministre juste pour activer TLS sur son Postfix). La sécurité de SMTP va donc forcément être « opportuniste » (RFC 7435), c'est-à-dire « on chiffre quand on peut » (au passage, attention en lisant les textes sur la sécurité en anglais : « opportunistic security » est un terme flou, qui désigne des choses très différentes selon les auteurs. Ce n'est pas du vocabulaire standardisé de la sécurité).
Notre nouveau RFC 7672 propose de résoudre ce problème
avec des enregistrements DANE. Cela permet
notamment de résister aux attaques par
repli telles que celle où un attaquant actif retire
STARTTLS
de la liste des extensions SMTP d'un
serveur. De même, DANE permet de se protéger contre un
Homme du Milieu, en authentifiant le
serveur (ce qui est théoriquement possible avec TLS aujourd'hui
mais, comme on l'a vu, n'est quasiment jamais fait). À noter qu'un
attaquant actif, avec le courrier d'aujourd'hui, n'a même pas
besoin de supprimer STARTTLS
: s'il n'y a pas
de DNSSEC, il peut se contenter d'un
empoisonnement DNS pour changer le MX, vers un serveur qui
collabore davantage avec lui.
DANE, normalisé dans le RFC 6698, doit sa création à la constatation des faiblesses de X.509. La principale est le nombre excessif d'autorités de certification à qui il faut faire confiance (regardez le magasin de certificats dans votre navigateur Web...) Qu'une seule d'entre elles trahisse ou soit piratée et tout est fichu, même pour les gens qui ne sont pas clients de cette AC.
Bon, mais HTTPS utilise TLS et les AC de X.509 depuis des années et, plus ou moins, ça marche. Pourquoi SMTP serait-il différent ? La section 1.3 de notre RFC explique les différences (lisez bien cette partie si vous voulez comprendre en détail le problème qu'on essaie de résoudre) :
https://...
indique clairement la volonté
de protéger la session avec TLS. Au contraire, rien dans une
adresse de courrier électronique ne permet d'indiquer cette
volonté. Cela serait d'ailleurs difficile : SMTP-sur-TLS
fonctionne étape par étape alors que l'adresse est de bout en
bout. La seule solution est donc d'opportunité : si le serveur
SMTP à l'autre bout annonce STARTTLS
(RFC 3207) dans
sa bannière, tenter sa chance en TLS. Cela permet évidemment des
attaques par repli (un attaquant actif peut supprimer le
STARTTLS
de la bannière), qui sont la plaie
de SMTP-sur-TLS.dnsviz.net
) et un nom de serveur assurant
ce service (par exemple
www1.dnsviz.net
). Cela a des tas de
conséquences négatives pour HTTP (difficulté de faire de la
répartition de charge côté client,
obligation de « squatter » l'apex du domaine avec des
enregistrements A ou AAAA, etc). Si HTTP était à refaire, il
faudrait absolument lui faire utiliser les
enregistrements SRV. Mais l'indirection,
que ce soit par les enregistrements SRV ou bien par la forme
simplifiée, les enregistrements MX,
qu'utilise SMTP, a un défaut : il faut sécuriser la liaison
entre nom de service (la partie gauche du MX, celle qui apparait
dans l'adresse de courrier) et nom de serveur (la partie droite
du MX). Imaginons un domaine
internautique.fr
dont le courrier est servi
par mail1.provider.example
. Même si ce
dernier utilise TLS, si l'enregistrement MX n'est pas sécurisé
(typiquement via DNSSEC), un attaquant
pourrait tout simplement rediriger le courrier vers un autre
serveur que mail1.provider.example
, plus
favorable à ses noirs desseins. Une solution à ce problème
serait que le certificat de
mail1.provider.example
contienne également
(subject alternative name ou un truc de ce
genre) le nom du service (ici
internautique.fr
). Ce n'est pas du tout
réaliste pour un gros hébergeur ayant des dizaines ou des
centaines de milliers de clients.https://www.bortzmeyer.org/
n'est pas signé par une autorité reconnue, voulez-vous
continuer ? » D'innombrables études auprès des utilisateurs ont
montré que cela ne marchait pas : l'utilisateur ne connait pas
assez X.509 et la sécurité pour pouvoir prendre une décision
informée. Mais, de toute façon, cette méthode n'a pas de sens pour
SMTP, qui n'est pas interactif : le MTA
n'a pas d'utilisateur humain à qui demander.
Ça, c'était le problème. Le reste du RFC est consacré à la solution, « DANE pour SMTP ». L'idée est que le MTA émetteur fasse une requête DNS pour le type TLSA (le type utilisé par DANE : ce n'est pas un acronyme, ne cherchez pas sa signification). Une fois les enregistrements TLSA récupérés et validés (par DNSSEC), l'émetteur se connecte au récepteur en SMTP et lance TLS. Il récupère alors le certificat et le compare à ce qu'il a trouvé dans l'enregistrement TLSA. Si c'est bon, il continue, si non il avorte. Un tel système protège contre les attaques par repli : si on trouve un enregistrement TLSA, c'est que le récepteur sait faire du TLS et veut le faire.
Donc, première étape de cette méthode, trouver les TLSA (section
2) du RFC. Si on en trouve, ils indiquent clairement la volonté du
pair SMTP de faire du TLS (contrairement à l'indication
STARTTLS
dans la bannière, qui est parfois
envoyée par des serveurs qui ne savent pas faire de TLS). C'est donc
l'équivalent du HSTS de HTTP (RFC 6797), une promesse. Administrateurs système, ne mettez pas
un TLSA dans le DNS si vous ne savez pas ce que vous faites !
En résultat de la requête DNS pour trouver les TLSA, il y a quatre possibilités :
En fait, j'ai un peu exagéré, la première étape n'est pas de trouver les enregistrements TLSA mais de trouver les enregistrements MX. Naturellement, on ne doit utiliser DANE que si le MX est signé par DNSSEC. S'il y a plusieurs enregistrements MX, certains peuvent pointer vers des serveurs qui n'ont pas DANE, voire pas TLS. Il est important de se rappeler que l'algorithme de choix parmi ces enregistrements MX (RFC 5321, section 5.1) ne tient pas compte de TLS : le premier serveur peut ne pas avoir TLS alors que les suivants l'ont. DANE ne modifie pas les algorithmes de SMTP et le choix d'un relais de courrier ne dépend donc pas de leur sécurité. Si on veut imposer TLS, il faut donc mettre TLS sur tous ses serveurs annoncés par les enregistrements MX. (Si SMTP avait été conçu plus récemment, il utiliserait les enregistrements SRV et on devrait donc lire le RFC 7673 à la place de celui-ci.)
Ah, et où trouver l'enregistrement TLSA ? Le nom de domaine à
utiliser avec DANE est
_port._protocole.nom.du.serveur
. Pour SMTP, le
port est normalement 25. Donc, en général, on
cherchera l'enregistrement TLSA en
_25._tcp...
. Voyons un cas réel avec le domaine
sources.org
. On cherche d'abord le MX (je fais
ici avec dig ce qu'un
MTA DANE ferait automatiquement) :
% dig MX sources.org ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 5, ADDITIONAL: 1 ... ;; ANSWER SECTION: sources.org. 86400 IN MX 10 uucp.bortzmeyer.org.
On trouve un MX, sécurisé par DNSSEC (le flag AD - Authentic Data - dans la réponse ; notez au passage qu'il faut un résolveur DNSSEC validant pour faire du DANE). Cherchons maintenant le TLSA :
% dig TLSA _25._tcp.uucp.bortzmeyer.org ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 9, ADDITIONAL: 9 ... ;; ANSWER SECTION: _25._tcp.uucp.bortzmeyer.org. 86400 IN TLSA 2 0 1 ( FF2A65CFF1149C7430101E0F65A07EC19183A3B633EF 4A6510890DAD18316B3A )
On a un TLSA utilisable, donc on va faire du TLS et vérifier que le certificat obtenu en TLS correspond bien au contenu de l'enregistrement TLSA.
Et quels enregistrements TLSA suggérer pour les serveurs SMTP, parmi les nombreuses combinaisons possibles ? Notre RFC recommande DANE-EE (usage 3) + SPKI (sélecteur 1) + SHA-256 (méthode de correspondance 1). Pourquoi ces recommandations (vous noterez, sur mon domaine personnel, que je ne les ai pas suivies, utilisant le « second choix » du RFC...) ? DANE-EE (c'est-à-dire qu'on ne fait pas de vérifications X.509 à partir des autorités de certification dans le magasin et que le certificat dans l'enregistrement TLSA est celui du serveur) est recommandé parce que les trois autres possibilités ont des défauts gênants. Avec DANE-TA (usage 2, que j'utilise personnellement), le certificat est celui de l'AC, pas celui du serveur. Comme tous les clients DANE n'ont pas forcément « mon » AC dans leur magasin, il faut envoyer le certificat de l'AC en sus de celui du serveur (ce que je fais sur mon serveur SMTP : cela ne me semble pas si difficile que ça). PKIX-TA et PKIX-EE (où on continue à faire les vérifications X.509 classiques) ont le même problème (la variété des AC présentes dans les différents magasins, qui interdit de compter sur une AC de référence). Mettre ces deux usages est donc dangereux, bien des MTA ne pourront plus vous authentifier.
Pour l'usage DANE-EE, qui est recommandé, le sélecteur suggéré est SPKI (l'enregistrement TLSA contient juste la clé, pas tout le certificat) car les autres informations du certificat (comme la date d'expiration ou le nom du serveur) sont inutiles (toute l'information utile est dans le DNS).
Pour l'usage DANE-TA, en revanche, il est recommandé de mettre un sélecteur CERT, qui indique que le client DANE doit vérifier tout le certificat, pas juste la clé.
Quant aux méthodes de correspondance (le troisième champ de l'enregistrement TLSA), la valeur 0 (on met le certificat entier, au lieu de juste un condensat) est déconseillée, en raison de la difficulté du DNS à faire passer des données de trop grande taille.
Au fait, on a surtout ici parlé de DANE pour sécuriser la communication entre deux serveurs SMTP, deux MTA. Mais entre un MUA et un MTA ? Pour les protocoles comme IMAP (RFC 6186), on utilise DANE+SRV (RFC 7673). Pour SMTP (soumission d'un message par le MUA), qui utilise rarement le RFC 6186 pour l'instant, les configurations statiques traditionnelles marchent encore.
Les administrateurs système seront intéressés par la section 9 du RFC, consacrée aux problèmes opérationnels. Par exemple, un administrateur peut hésiter à activer DANE sur le serveur SMTP dont il a la responsabilité : et si, se dit-il, mon courrier n'est plus transmis, par exemple parce que trop d'informaticiens font des erreurs et publient des configuration DANE cassées ? Cet administrateur prudent peut envisager d'utiliser DANE seulement pour certaines destinations, « pour voir », ou bien utiliser DANE en mode « on regarde et on journalise » mais on ne vérifie pas.
Autre problème opérationnel important, un changement de certificat : il faut bien penser à publier le nouveau TLSA à l'avance, pour que l'ancien ensemble TLSA ait disparu de tous les caches DNS avant que le serveur SMTP n'utilise le nouveau certificat.
Et pour faire du DANE avec SMTP en pratique ? Un MTA qui gère DANE existe, Postfix, depuis la version 2.11 (cf. la documentation officielle). Vous vérifiez bien que votre serveur SMTP utilise un résolveur DNSSEC validant, vous mettez dans la configuration :
smtp_dns_support_level = dnssec smtp_tls_security_level = dane
Et c'est parti. Essayons d'envoyer un message à DENIC qui a annoncé avoir déployé DANE (certificat auto-signé donc normalement pas validable) :
Oct 18 21:58:08 aetius postfix/smtp[26542]: Verified TLS connection established \ to mx2.denic.de[81.91.161.38]:25: \ TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)
Et voilà, on se connecte en TLS après avoir vérifié que tout allait bien. En effet, DENIC a un enregistrement TLSA :
% dig TLSA _25._tcp.mx1.denic.de ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5 ... ;; ANSWER SECTION: _25._tcp.mx1.denic.de. 3600 IN TLSA 3 0 1 ( 17CBD8A164851E86C94A534438D02A4202CC71FCAE6C 24E1F98214BD586F67A1 )
Ça, c'était la configuration en émetteur. Et en réception ? Il faut
avoir déjà activé TLS sur son serveur
(ce qui a été fait il y a pas mal d'années sur tous les serveurs SMTP
sérieux). Il faut avoir une zone
(correctement) signée avec DNSSEC. Il faut ensuite publier un
enregistrement TLSA. Ici, j'ai choisi, comme expliqué plus haut, de
publier le certificat de mon AC, CAcert. J'utilise la commande
tlsa
dans l'outil hash-slinger :
% tlsa --usage 2 --selector 0 --mtype 1 --output rfc --certificate ~/tmp/cacert.pem \ --port 25 mail.bortzmeyer.org _25._tcp.mail.bortzmeyer.org. IN TLSA 2 0 1 ff2a65cff1149c7430101e0f65a07ec19183a3b633ef4a6510890dad18316b3a
Et je mets cet enregistrement dans ma zone DNS :
% dig TLSA _25._tcp.mail.bortzmeyer.org ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 8, ADDITIONAL: 7 ... ;; ANSWER SECTION: _25._tcp.mail.bortzmeyer.org. 86400 IN TLSA 2 0 1 ( FF2A65CFF1149C7430101E0F65A07EC19183A3B633EF 4A6510890DAD18316B3A )
Pour tester, on peut faire appel aux copains en leur demandant
d'envoyer des messages, ou bien on peut se servir de https://www.tlsa.info/
, qui teste tout (DNSSEC, DANE et TLS en
se connectant au serveur SMTP). Il n'essaie pas uniquement le DNS mais aussi
le fait que le certificat corresponde bien à l'enregistrement TLSA. Si je publie un
mauvais enregistrement, il proteste :
bortzmeyer.fr The domain lists the following MX entries: 0 uucp.bortzmeyer.org All TLSA RRs failed. (See details.) Usable TLSA Records 2, 0, 1 ff2a65cff1149c74[...]10890dad18316b3b - application verification failure: (50)
Un autre outil de test est https://arp.simson.net/dane_check.cgi
.
Date de publication du RFC : Octobre 2015
Auteur(s) du RFC : T. Finch (University of Cambridge), M. Miller (Cisco Systems), P. Saint-Andre (&yet)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dane
Première rédaction de cet article le 15 octobre 2015
Le protocole DANE, normalisé dans le RFC 6698, permet d'associer au nom d'un serveur un certificat qu'on peut comparer avec celui qui est présenté par le serveur lors d'une session TLS, authentifiant ainsi directement ou indirectement le serveur. Cela permet de boucher certaines failles de X.509. Mais DANE ne marche qu'avec un nom de serveur, tel que l'utilise HTTP. La quasi-totalité des protocoles ont, au contraire, une indirection supplémentaire entre nom de service et nom de serveur, typiquement via un enregistrement SRV (RFC 2782). Dans un tel cas, où trouver les enregistrements TLSA, ceux utilisés par DANE ? Le choix est de vérifier le domaine pointé (nom du serveur, celui du prestataire) et pas le pointeur (nom de service, celui de l'utilisateur).
Voici un exemple d'un enregistrement TLSA (au passage, ne
cherchez pas à quels mots correspondent les lettres de TLSA : ce
n'est officiellement pas un acronyme) classique, pour un
serveur HTTP, en l'occurrence pour https://www.freebsd.org
:
% dig TLSA _443._tcp.www.freebsd.org ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 13 ... ;; ANSWER SECTION: _443._tcp.www.freebsd.org. 600 IN TLSA 3 0 1 ( A9F16D689F5AEE122E86A8468A8586DDA4440A7298C6 4AD4EED1AAE8BEB2A892 ) ...
Mais, à part HTTP (dont c'est l'une des principales faiblesses, menant à un mélange entre nom de service et nom de serveur), les protocoles utilisent en général un nom de service (vu par l'utilisateur) et un nom de serveur (récupéré automatiquement dans le DNS via les enregistrements SRV ou, dans le cas du courrier, des enregistrements MX). Il fallait donc étendre la définition originelle de DANE, celle du RFC 6698, pour ces protocoles. Pour SMTP et ses MX, c'est le RFC 7672. Pour les protocoles à SRV, comme XMPP, c'est ce RFC 7673.
Le choix principal qui se posait lors de la rédaction de ce
RFC était « l'enregistrement TLSA doit-il
être associé au service (l'origine, en partie gauche de
l'enregistrement SRV) ou bien au serveur (la cible, en partie
droite) ? » Le choix a été fait d'accrocher le TLSA,
l'enregistrement DNS contenant le
certificat au
serveur. Ainsi, si on a cet enregistrement
SRV pour XMPP à example.com
:
_xmpp-client._tcp.example.com. SRV 1 0 5222 im.example.net.
L'enregistrement TLSA sera en im.example.net
, pas en
example.com
. Les raisons de ce choix sont expliquées
dans l'annexe B du RFC et résumées plus loin.
Pour la sécurité du lien entre service et serveur, on compte sur DNSSEC, qui signera l'enregistrement SRV (ainsi que, bien sûr, le TLSA). Maintenant, place aux détails concrets.
La section 3 du RFC commence par les tests DNS. Si
l'utilisateur veut se connecter à un service
foobar
dans
example.com
, il va demander le SRV de
_foobar._tcp.example.com
. Supposons qu'il existe un alias
(enregistrement CNAME) vers
foobar.example.net
et qu'ensuite on trouve le
SRV qui liste un seul serveur,
foobar1.example.org
. Pour pouvoir utiliser
DANE, il faut que toute la chaîne DNS soit sécurisée par
DNSSEC. Dans cet exemple, les deux
enregistrements qui forment la chaîne (le CNAME puis le SRV)
doivent donc tous les deux être signés et validés. Sinon, si l'un
de ces enregistrements n'est pas signé, pas question de lancer
DANE puisqu'on ne peut pas avoir confiance dans leur contenu.
On n'en a pas fini avec le DNS : il faut maintenant trouver
l'adresse IP des serveurs (ici, un seul),
ce qui doit être également validé avec DNSSEC. Enfin, on fait les
requêtes pour les enregistrements TLSA, en utilisant comme nom (le
QNAME ou Query Name) le nom du serveur, préfixé
du numéro de port. Si l'application foobar
fonctionne sur le port 5634 (il est indiqué dans l'enregistrement SRV), on demandera ici le ou les TLSA de
_5634._tcp.foobar1.example.org
(et non pas
d'example.com
). Autre exemple, emprunté au
RFC, avec IMAP, le SRV pour
example.com
valait :
_imap._tcp.example.com. 86400 IN SRV 10 0 9143 imap.example.net.
On demandera donc un enregistrement TLSA pour
_9143._tcp.imap.example.net.
Évidemment, on
vérifie la validité de cet enregistrement avec DNSSEC (ignorer les
enregistrements non signés et donc non validés est un principe de
base de DANE, cf. RFC 6698, section 4.1).
Le client se connecte en TLS au serveur. Quelles vérifications doit-il faire (section 4) ? S'il n'a trouvé aucun enregistrement TLSA utilisable (par exemple parce qu'il n'y en avait pas, ou bien parce qu'ils n'étaient pas signés avec DNSSEC), il doit faire la validation habituelle d'un certificat X.509 (à partir des AC que le client a dans son magasin), décrite dans le RFC 5280. Il peut être nécessaire d'utiliser quelques règles spécifiques à l'application, cf. RFC 6125. Au passage, notons que la terminologie est variable : ce que notre RFC 7673 nomme service et serveur est appelé dans la RFC 6125 « domaine source » et « domaine dérivé ».
Par contre, s'il y a des enregistrements TLSA et qu'ils sont utilisables (ce qui implique notamment qu'ils soient signés et validés), alors le client doit valider le certificat obtenu dans le dialogue TLS avec DANE (RFC 6698, section 2.1). Notamment, si l'enregistrement TLSA indique un usage « DANE-EE » (DANE End Entity), alors le client ne doit pas faire de vérification X.509 du tout et donc ignorer les RFC 5280 et RFC 6125.
Si vous êtes l'auteur d'un protocole qui utilise des enregistrements SRV, lisez la section 5 de notre RFC : elle écrit les détails auxquels vous devez penser pour votre protocole. Ce sont notamment :
<to>
de son flux XML).Si vous êtes opérateur d'un service sécurisé avec TLS, voyez la section 6. Elle rappelle la nécessité de signer les enregistrements DNS SRV et TLSA avec DNSSEC. D'autre part, en créant le certificat qui sera servi en TLS, il faut suivre certaines règles :
L'extension SNI du RFC 6066, déjà citée, permet d'envoyer au client le bon certificat, si le serveur en a plusieurs. Un exemple d'un usage de TLSA où il faut vérifier le nom est l'usage DANE-TA où le certificat dans l'enregistrement TLSA autorise l'AC, pas le certificat du serveur. Cet usage empêche les attaques par une autre AC mais pas celles par un autre utilisateur de la même AC. Il faut donc vérifier que le(s) nom(s) dans le certificat est(sont) bien celui attendu (cf. section 9.2).
Après les auteurs de protocoles et les administrateurs système, place aux développeurs (section 7). Pour limiter le temps d'attente pour les utilisateurs, le RFC leur recommande de faire les différentes résolutions aussi en parallèle que possible. Par exemple, une fois obtenu un SRV, on peut faire les résolutions d'adresse (enregistrements A et AAAA) en même temps que le TLSA.
La section 9 du RFC revient sur quelques pièges de sécurité. D'abord, un ensemble d'enregistrements SRV pouvant contenir plusieurs noms de serveurs, il ne faut pas croire que tous auront le même niveau de sécurité, surtout si l'un d'eux est sous-traité à un opérateur ne servant qu'en cas de problème avec les serveurs « principaux ». Par exemple, certains peuvent accepter TLS et d'autres pas. Il sera donc inutile de chercher des enregistrements TLSA pour les seconds. Ce point est d'autant plus important que le traitement des enregistrements SRV ne donne aucune priorité aux serveurs ayant TLS.
L'annexe B de notre RFC est cruciale et doit absolument être lue. Elle revient sur un choix qui a été délicat et très discuté à l'IETF : l'enregistrement TLSA doit-il se situer sur le nom de service (domaine originellement indiqué par l'utilisateur et donc a priori le domaine important qu'on veut vérifier) ou bien sur le nom de serveur (obtenu après une requête SRV et information normalement purement technique) ? Le choix de notre RFC 7673 est clair : le TLSA pertinent est situé sur le nom du serveur, essentiellement parce que c'est la seule méthode réaliste pour les services hébergés chez un gros opérateur qui a des milliers, voire des millions, de client hébergés.
Des raisons diverses viennent à l'appui de ce choix :
https://www.republique-numerique.fr/
partage son certificat avec un site porno chinois, https://renxxx.com/
).RCPT TO
vers des domaines différents.Bien sûr, il y a des cas où le TLSA sur le nom du service (du domaine source) serait préférable. L'IETF avait envisagé de permettre cette possibilité, en plus de la « normale » mais y a renoncé pour garder le protocole simple. Dans certains cas (clients non-DNSSEC, par exemple, qui ne peuvent donc pas valider le SRV et doivent donc vérifier le domaine d'origine), cela compliquera les choses (SNI aidera parfois).
Allez, un exemple réel d'un enregistrement SRV avec DANE au bout :
% dig +nodnssec +short SRV _xmpp-server._tcp.mailbox.org 0 5 5269 xmpp.mailbox.org. % dig +nodnssec +short TLSA _5269._tcp.xmpp.mailbox.org 3 1 1 4758AF6F02DFB5DC8795FA402E77A8A0486AF5E85D2CA60C294476AA DC40B220
Et je vous recommande de lire cet excellent article sur la sécurisation de XMPP avec DNSSEC et DANE.
Première rédaction de cet article le 9 octobre 2015
Quelques mois après le problème
juralib.noblogs.org
, les rézosocios ont
bruissé de clameurs sur le domaine
ladiscordia.noblogs.org
, invisible depuis
Free. Censure ou bavure ?
Beaucoup de gens ont crié à la censure, ce qui est raisonnable dans le contexte politique actuel, vu que le site Web derrière ce domaine sert en général des contenus politiquement radicaux. (Voir par exemple une discussion très foutraque sur Reddit.) Mais, si la censure existe, les bogues existent aussi, et il existe davantage de maladroits que de méchants. Étudions donc la question.
D'abord, plaçons nous sur une machine connectée par Free et utilisant les résolveurs DNS de Free (ce n'est pas obligatoire). On constate qu'on ne peut pas visiter la page Web citée plus haut. Des tests techniques montrent que le problème est dans la résolution DNS. Pas moyen de trouver l'adresse IP associée au nom. Testons avec dig :
% dig ladiscordia.noblogs.org ... ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 937 ^^^^^^^^ Server Failure
Ah, Houston, nous avons un problème. Le domaine noblogs.org
étant signé avec DNSSEC (une excellente idée),
regardons avec l'option +cd
(Checking
Disabled) qui coupe la validation DNSSEC :
% dig +dnssec +cd ladiscordia.noblogs.org ; <<>> DiG 9.10.2-P2 <<>> +cd ladiscordia.noblogs.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16475 ;; flags: qr rd ra cd; QUERY: 1, ANSWER: 15, AUTHORITY: 5, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;ladiscordia.noblogs.org. IN A ;; ANSWER SECTION: ladiscordia.noblogs.org. 2284 IN CNAME www.l.autistici.org. ladiscordia.noblogs.org. 2284 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im MphTYlJRGvwTzZTPwbbbkZjSuCtt5P7l3/iMx50ZEZ/B x3q0PDD3Yo4ckrfcIzMQ9V+HeosW+W78UBTC0LyQIxSq eRdlhsNZKSELmR8k9sVpJ5mrQPTQ3HzGzUr4z1w= ) ladiscordia.noblogs.org. 2284 IN CNAME www.l.autistici.org. ladiscordia.noblogs.org. 2284 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im MphTYlJRGvwTzZTPwbbbkZjSuCtt5P7l3/iMx50ZEZ/B x3q0PDD3Yo4ckrfcIzMQ9V+HeosW+W78UBTC0LyQIxSq eRdlhsNZKSELmR8k9sVpJ5mrQPTQ3HzGzUr4z1w= ) ladiscordia.noblogs.org. 2284 IN CNAME www.l.autistici.org. ladiscordia.noblogs.org. 2284 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im MphTYlJRGvwTzZTPwbbbkZjSuCtt5P7l3/iMx50ZEZ/B x3q0PDD3Yo4ckrfcIzMQ9V+HeosW+W78UBTC0LyQIxSq eRdlhsNZKSELmR8k9sVpJ5mrQPTQ3HzGzUr4z1w= ) ladiscordia.noblogs.org. 2284 IN CNAME www.l.autistici.org. ladiscordia.noblogs.org. 2284 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im MphTYlJRGvwTzZTPwbbbkZjSuCtt5P7l3/iMx50ZEZ/B x3q0PDD3Yo4ckrfcIzMQ9V+HeosW+W78UBTC0LyQIxSq eRdlhsNZKSELmR8k9sVpJ5mrQPTQ3HzGzUr4z1w= ) ladiscordia.noblogs.org. 2284 IN CNAME www.l.autistici.org. ladiscordia.noblogs.org. 2284 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im MphTYlJRGvwTzZTPwbbbkZjSuCtt5P7l3/iMx50ZEZ/B x3q0PDD3Yo4ckrfcIzMQ9V+HeosW+W78UBTC0LyQIxSq eRdlhsNZKSELmR8k9sVpJ5mrQPTQ3HzGzUr4z1w= ) ladiscordia.noblogs.org. 2284 IN CNAME www.l.autistici.org. ladiscordia.noblogs.org. 2284 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im MphTYlJRGvwTzZTPwbbbkZjSuCtt5P7l3/iMx50ZEZ/B x3q0PDD3Yo4ckrfcIzMQ9V+HeosW+W78UBTC0LyQIxSq eRdlhsNZKSELmR8k9sVpJ5mrQPTQ3HzGzUr4z1w= ) www.l.autistici.org. 1800 IN A 94.23.50.208 www.l.autistici.org. 1800 IN A 82.94.249.234 www.l.autistici.org. 1800 IN RRSIG A 7 4 30 ( 20151105063002 20151006063002 2207 l.autistici.org. HDkkzb8afOIlk5P0HRmiVal7KmAu4bevmkAPpHuAMruS 9Pj2OkWjeWwJiLm7zX5MjqIcfUBvJ6gbODvRGr7dDJHn 7qqLNA3IXMvxm5trBWz2/YZsTs/2XEgIBDVgxRel+OBp HD+riKX0ZylmTGXG7/fyRfcYLquwphS4gNTMWbk= ) ;; AUTHORITY SECTION: l.autistici.org. 1800 IN NS ns1.investici.org. l.autistici.org. 1800 IN NS ns2.investici.org. l.autistici.org. 1800 IN NS ns2-v6.investici.org. l.autistici.org. 1800 IN NS ns1-v6.investici.org. l.autistici.org. 1800 IN RRSIG NS 7 3 30 ( 20151105063002 20151006063002 2207 l.autistici.org. bA28B6AP9NQzyavLXFZoxDCsV1kDpZwid+QyPcR2qhrj c3wfuB6P2PM7WBHzlbZevt1C3+z/FMqvXRr/TrhbseDy ScKCai/LPD68z0bqUucz0uuFbDpTxvJNDf+0zJrMQTsw +zse/UsiopBVrqCjOXRWte2DvDxyCPtN3WnEYJc= ) ;; Query time: 26 msec ;; SERVER: 192.168.2.254#53(192.168.2.254) ;; WHEN: Fri Oct 09 11:09:32 CEST 2015 ;; MSG SIZE rcvd: 1648
Ouh là, là, c'est long. Bien trop long, la répétition de
l'enregistrement CNAME
et de sa signature est
tout à fait anormale. Est-ce de la faute du résolveur DNS Free ou bien
du domaine noblogs.org
? Allons sur une autre
machine qui utilise son propre résolveur, un
Unbound :
% dig +dnssec ladiscordia.noblogs.org ; <<>> DiG 9.9.5-9+deb8u3-Debian <<>> +dnssec ladiscordia.noblogs.org ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62823 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 5, AUTHORITY: 7, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;ladiscordia.noblogs.org. IN A ;; ANSWER SECTION: ladiscordia.noblogs.org. 6082 IN CNAME www.l.autistici.org. ladiscordia.noblogs.org. 6082 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im MphTYlJRGvwTzZTPwbbbkZjSuCtt5P7l3/iMx50ZEZ/B x3q0PDD3Yo4ckrfcIzMQ9V+HeosW+W78UBTC0LyQIxSq eRdlhsNZKSELmR8k9sVpJ5mrQPTQ3HzGzUr4z1w= ) www.l.autistici.org. 30 IN A 94.23.50.208 www.l.autistici.org. 30 IN A 82.94.249.234 www.l.autistici.org. 30 IN RRSIG A 7 4 30 ( 20151105063002 20151006063002 2207 l.autistici.org. HDkkzb8afOIlk5P0HRmiVal7KmAu4bevmkAPpHuAMruS 9Pj2OkWjeWwJiLm7zX5MjqIcfUBvJ6gbODvRGr7dDJHn 7qqLNA3IXMvxm5trBWz2/YZsTs/2XEgIBDVgxRel+OBp HD+riKX0ZylmTGXG7/fyRfcYLquwphS4gNTMWbk= ) ;; AUTHORITY SECTION: EDG28OM0KF8LV6JVVTUAE9R7GLNTNKMD.noblogs.org. 82 IN NSEC3 1 0 10 5CA1AB1E ( K1C26GO8L9TJ398E8MKH7QLSP4LB88UO CNAME RRSIG ) EDG28OM0KF8LV6JVVTUAE9R7GLNTNKMD.noblogs.org. 82 IN RRSIG NSEC3 7 3 3600 ( 20151101063004 20151002063004 64367 noblogs.org. juTchEjZZFdj5WkhyKh/2qZxffIjahcjtWrC7aiM78QT nuBLP6AqRatIwpbIauM9ZbBwXD1ZXwRhpZrLTDKqS8bK qU5dsUCKsB3vIYba84I12t1bAg0YKv0HP8bkEMp9ftO+ bZNLtY+TXyaZ5FULNI26gMen2YYsqPovY0YnH0M= ) l.autistici.org. 30 IN NS ns2-v6.investici.org. l.autistici.org. 30 IN NS ns2.investici.org. l.autistici.org. 30 IN NS ns1.investici.org. l.autistici.org. 30 IN NS ns1-v6.investici.org. l.autistici.org. 30 IN RRSIG NS 7 3 30 ( 20151105063002 20151006063002 2207 l.autistici.org. bA28B6AP9NQzyavLXFZoxDCsV1kDpZwid+QyPcR2qhrj c3wfuB6P2PM7WBHzlbZevt1C3+z/FMqvXRr/TrhbseDy ScKCai/LPD68z0bqUucz0uuFbDpTxvJNDf+0zJrMQTsw +zse/UsiopBVrqCjOXRWte2DvDxyCPtN3WnEYJc= ) ;; Query time: 239 msec ;; SERVER: ::1#53(::1) ;; WHEN: Fri Oct 09 11:12:01 CEST 2015 ;; MSG SIZE rcvd: 977
On n'a pas cette fois la répétition des CNAME
,
c'est plus normal (et valide : le bit AD Authentic
Data dans la réponse nous l'indique). Autre façon de
vérifier qu'il y a bien un problème spécifique à Free, demander aux
sondes RIPE Atlas
françaises (avec ce programme) ce qu'elles voient :
% python resolve-name.py -r 500 -c FR -t A ladiscordia.noblogs.org Measurement #2490878 for ladiscordia.noblogs.org/A uses 500 probes [ERROR: REFUSED] : 3 occurrences [ERROR: SERVFAIL] : 116 occurrences [82.94.249.234 94.23.50.208] : 338 occurrences Test done at 2015-10-08T08:58:30Z
La plupart voient la bonne réponse (deux adresses IP), 116 d'entre elles reçoivent le
SERVFAIL
. Ce sont celles situées sur ce réseau de
Free. Limitons la requête à l'AS de Free :
% python resolve-name.py -r 500 --as 12322 -t A ladiscordia.noblogs.org Measurement #2495118 for ladiscordia.noblogs.org/A uses 233 probes [ERROR: REFUSED] : 1 occurrences [ERROR: SERVFAIL] : 161 occurrences [82.94.249.234 94.23.50.208] : 62 occurrences Test done at 2015-10-09T09:18:07Z
La majorité des sondes Atlas chez Free ont le problème (certains clients de Free ont leur propre résolveur et ne voient donc pas le problème).
Donc, c'est chez Free ? Il n'y a pas de problème dans la zone
noblogs.org
? Je dois confesser que j'avais
stupidement mis en cause cette zone sur
Twitter, en confondant avec un autre cas. Comme
les gens qui criaient à la censure, j'avais réagi trop vite en sens
inverse. Toutes mes excuses au mainteneur de
noblogs.org
, cette zone ne semble pas avoir de
problème DNSSEC grave, comme le montrent très bien DNSviz
ou ZoneMaster
(il y a des erreurs mais pas graves et sans lien avec DNSSEC).
Mais, alors, qu'est-ce qui se passe ? Y aurait-il bien censure
délibérée par Free ? Sans doute pas. En effet, en comparant le
résultat des commandes dig avec le résolveur
DNS de Free et un autre résolveur, on voit le problème :
l'enregistrement NSEC3 est manquant. Ça veut dire
quoi ? NSEC3, normalisé dans le RFC 5155, sert à
prouver qu'un nom n'existe pas. Ici, comme la zone
noblogs.org
utilise des jokers (tout nom, même
gfcgf565FsdZE523SEDvgGFSS.noblogs.org
va
marcher, cf. RFC 1034, section 4.3.3), le NSEC3 doit être envoyé pour prouver que le nom demandé,
ladiscordia.noblogs.org
, n'existait pas
réellement mais été synthétisé via le joker. Dans la réponse du
résolveur correct, on a le NSEC3 :
EDG28OM0KF8LV6JVVTUAE9R7GLNTNKMD.noblogs.org. 82 IN NSEC3 1 0 10 5CA1AB1E ( K1C26GO8L9TJ398E8MKH7QLSP4LB88UO CNAME RRSIG )
Mais on ne l'a pas dans la réponse du résolveur de Free. Si on teste avec DNSviz en local, en passant à travers le résolveur de Free, le rapport (en JSON) nous dit la même chose :
"errors": [ { "description": "No NSEC RR(s) were returned to validate the wildcard response.", "code": "MISSING_NSEC_FOR_WILDCARD", "servers": [ "192.168.2.254" ], "tags": [ "UDP_272_EDNS0_32768_4096" ] } ...
(Au passage, notez que Free force un TTL minimum, ce qui fait également couiner DNSviz, car DNSSEC ne permet pas ce genre de manips :
"errors": [ { "description": "The TTL of the RRset (1665) exceeds the value of the Original TTL field of the RRSIG RR covering it (900).", "code": "ORIGINAL_TTL_EXCEEDED" } ...
)
Comment un résolveur ayant ces données voit qu'il y a un problème DNSSEC
(et va donc renvoyer SERVFAIL
) ? Grâce au champ
Number of labels de la signature (RFC 4034, section 3.1.3). Lorsque le nom
existe, ce champ indique le nombre de composants dans le nom demandé :
www.noblogs.org. 9600 IN RRSIG CNAME 7 3 9600 ( 20151101063004 20151002063004 64367 noblogs.org. k7l/nfVCejZ+pO7BPIPEPaQs7w09CE/4SJL7rjItAEqf ...
Le champ est le troisième après le type
RRSIG
. Ici, il vaut trois, ce qui est bien le
nombre de composants du nom de domaine demandé. Mais lorsque le nom a
été synthétisé grâce au joker :
ladiscordia.noblogs.org. 5073 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im ...
Alors, le champ ne vaut que deux, indiquant qu'il y a un joker dans le
deuxième composant (la zone noblogs.org
; après
tout, le joker pourrait être dans une zone parente ou
grand-parente). Le résolveur DNSSEC voit donc que la signature couvre
en fait le joker :
*.noblogs.org. 9600 IN RRSIG CNAME 7 2 9600 ( 20151101063004 20151002063004 64367 noblogs.org. LuRSXa97Yjr+wYVGjq8yFxIOTXeufRMNaL6L31jqq3im ...
(Regardez la signature, c'est la même que pour
ladiscordia
mais pas la même que pour
www
.) Le résolveur validant va donc chercher un
NSEC3 prouvant que le nom n'existe pas (un nom existant masque le
joker), ne le trouve pas, et paf, SERVFAIL
.
Pourquoi le résolveur de Free a-t-il omis le NSEC3, qui est bien
envoyé par les serveurs faisant autorité pour
noblogs.org
? L'investigation doit s'arrêter là,
je n'ai pas accès à l'intérieur de ces résolveurs. Je soupçonne que la
duplication anormale des CNAME
a mené à une
réponse trop grosse et que l'enregistrement NSEC3 a été abandonné.
Donc, ma conclusion est que les résolveurs de Free sont en
tort, mais qu'il s'agit très probablement d'une bogue et pas d'une
attaque délibérée. Quant à la zone noblogs.org
, elle n'avait d'autres torts
que de combiner des techniques compliquées (jokers et NSEC3).
Notez que, six mois plus tard, la bogue n'était pas réparée, et se déclenche même sans NSEC3.
Première rédaction de cet article le 8 octobre 2015
On a beaucoup parlé des attaques DoS par réflexion + amplification en les présentant souvent comme spécifiques à UDP. Mais un article récent (mais passé curieusement inaperçu) montre qu'on peut en faire également avec TCP.
Petit rappel du principe de cette attaque : il y a trois parties, l'attaquant A, la victime V et le réflecteur R. Ce dernier est innocent (il n'a rien contre la victime) mais souvent négligent (il a laissé un réflecteur ouvert alors qu'il n'aurait pas dû). A envoie un paquet IP dont l'adresse source est usurpée : il met l'adresse de V (cela implique que le FAI de A ait ignoré le RFC 2827). L'adresse de destination est celle de R. Celui-ci répond à celui qu'il croit être l'expéditeur, donc à V. Ainsi, R va bombarder V.
Sans amplification, les attaques par réflexion n'ont que peu d'intérêt. Mais ce qui est rigolo, c'est que certains protocoles envoient une réponse plus grande (en nombre de paquets ou bien en nombre d'octets) que la question. On a ainsi une amplification, A obtient plus de paquets ou d'octets qu'il n'en a envoyé. L'efficacité d'un réflecteur se mesure à son PAF (Packet Amplification Factor) ou à son BAF (Bandwidth Amplification Fcator).
Usurper une adresse IP en TCP est très difficile et c'est pour
cela que ces attaques, dans la nature, étaient typiquement faites
en UDP (en utilisant par exemple NTP). Le seul cas que je connaissais
personnellement où on pouvait avoir une amplification avec TCP
était la suivante : A envoie un paquet SYN
, R
transmet le SYN/ACK
à V, puis, n'ayant pas de
nouvelles de V, réémet le SYN/ACK
,
typiquement cinq fois. Cela donne donc un PAF de 5 et un BAF ayant
la même valeur (le SYN/ACK
ayant la même
taille que le SYN
). Comme toutes les
attaques, la pratique est plus compliquée que cela (si V émet un
RST
en recevant ce
SYN/ACK
inattendu, cela stoppe la réémission)
mais l'attaquant astucieux peut s'en tirer quand même. Ceci dit,
un PAF et un BAF de 5 ne font pas une attaque bien
terrifiante.
C'est là qu'arrive l'article de Kührer, Hupperich, Rossow et Holz, « Hell of a handshake: Abusing TCP for reflective amplification DDoS attacks » publié à USENIX en août 2014 et apparemment passé relativement inaperçu (merci à Paul Vixie pour me l'avoir signalé).
Les auteurs ont montré qu'il existait d'autres voies
d'amplification avec TCP que le SYN/ACK
indiqué plus haut et, pire, qu'il existait des machines dans
l'Internet qui répondaient et qui étaient disponibles comme
réflecteurs. Par exemple, certains systèmes répondent au
SYN
initial par des paquets de données,
souvent de très grande taille, avant
même que la triple poignée de mains (l'établissement de la
connexion TCP) soit terminée ! (Ce qui justifie ma loi « si une
connerie d'implémentation de TCP/IP est possible, alors il existe
au moins une machine dans l'Internet qui la fait ».)
Les mesures décrites dans l'article sur un échantillon de vingt millions de machines montrent ainsi plus de 600 000 machines qui répondent sur le port de MySQL dont 8 sont des amplificateurs, avec un BAF moyen de 84 000 (oui, une réponse 84 000 fois plus grosse que la requête). Extrapolé à tout l'Internet IPv4, cela ferait 1 700 amplificateurs MySQL.
Le BAF est plus faible sur les ports FTP ou telnet (de l'ordre de 50) mais il y a beaucoup plus d'amplificateurs (des millions, en extrapolant à tout l'Internet IPv4).
Les analyses des réflecteurs semblent indiquer qu'il s'agit de machines très variées et qu'il n'y a donc pas un vendeur dont l'implémentation particulièrement boguée serait responsable. Par exemple, les machines avec un port telnet ouvert semblent être surtout des routeurs, mais de marques très variées. Les fanas de sécurité noteront toutefois que de nombreuses caméras de vidéosurveillance IP semblent être des réflecteurs. Joie de l'Internet des objets.
Les auteurs discutent aussi des solutions, pour l'instant peu
convaincantes. Le mieux, pour la victime, est d'envoyer des
RST
ou, surtout, des
ICMP port unreachable
aux réflecteurs : souvent, cela les calme. Mais le problème de
fond, surgi de la combinaison entre la possibilité de tricher sur
son adresse IP et la disponibilité de nombreux réflecteurs
amplificateurs, reste.
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : R. Shekh-Yusef (Avaya), D. Ahrens
(Independent), S. Bremer
(Netzkonform)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF httpauth
Première rédaction de cet article le 8 octobre 2015
Dans les techniques d'authentification normalisées pour un client HTTP, la plus connue et la plus simple est le mécanisme Basic du RFC 7617. Mais elle a plusieurs failles de sécurité, comme le transmission explicite du mot de passe (et qui se fait en clair si on n'utilise pas HTTPS). D'où cette technique alternative, que je crois peu répandue, car plus complexe (et pas forcément plus sûre) : le mécanisme Digest. Dans ce cas, le serveur HTTP envoie un défi au client, défi auquel le client répondra sans divulguer au serveur aucun secret.
Avec les RFC 7615 et RFC 7617, ce nouveau RFC remplace le très ancien RFC 2617 (qui normalisait tous les mécanismes d'authentification de HTTP). Désormais, l'authentification HTTP comporte un cadre général (le RFC 7235) et un RFC spécifique par mécanisme d'authentification. Celui de notre nouveau RFC, le Digest, a assez peu changé depuis le RFC 2617.
L'essentiel du RFC actuel est dans la section 3. Le client s'authentifie avec un nom et un mot de passe mais le mot de passe n'est pas envoyé tel quel au serveur (quant au nom, ça dépend). Comme son nom l'indique (digest = condensation), les données sont condensées avant d'être envoyées au serveur, empêchant le serveur (ou un indiscret qui écoute) d'accéder à la valeur initiale.
Lorsque le client HTTP tente d'accéder à une ressource
protégée, le serveur lui répond avec un code HTTP 401 et un
en-tête WWW-Authenticate:
, indiquant le
mécanisme Digest. Cet en-tête contient
le royaume (realm, un identificateur
caractérisant le groupe d'utilisateurs attendus, cf. RFC 7235, section 2.2), le
domaine (une liste
d'URI pour qui cette protection s'applique),
un numnique, une chaîne de caractères
opaque, que le client renverra telle quelle, une indication de
l'algorithme de condensation utilisé et
quelques autres détails. Le numnique doit être différent à chaque
réponse du serveur et de son mécanisme de génération dépend
largement la sécurité de ce mécanisme d'authentification. Un
attaquant ne doit pas pouvoir deviner le numnique qui sera
utilisé. À part cela, le mécanisme de génération des numniques n'est
pas spécifié, c'est une décision locale. Une
méthode suggérée par le RFC est que le numnique soit la
concaténation d'une estampille temporelle et de la
condensation de la concaténation de l'estampille temporelle, de
l'ETag
de la ressource et d'un secret connu
du seul serveur. L'estampille temporelle sert à éviter les
attaques par rejeu. Elle est en clair au
début du numnique, pour faciliter les comparaisons floues
(estampille « pas trop ancienne »). Notez que le RFC ne
conseille pas d'inclure l'adresse IP du
client dans son calcul, cela défavoriserait trop les clients qui
changent d'adresse IP, par exemple parce qu'ils passent par
plusieurs relais de sortie possibles. (Alors que la section 5.5 du
même RFC donne le conseil opposé...)
Le client HTTP doit répondre à ce défi en envoyant un en-tête
Authorization:
qui inclut la réponse
condensée, le nom de l'utilisateur
(qui peut être condensé ou pas, selon la valeur du paramètre
userhash
, cf. section 3.4.4 pour les détails), un numnique du
client, et un compteur du nombre
de tentatives d'authentification, qui permet de repérer les
rejeux.
La réponse condensée est calculée (section 3.4.1) en condensant la concaténation de plusieurs valeurs, comprenant notamment une condensation de la concaténation du nom de l'utilisateur, de son mot de passe et du royaume, le numnique du serveur et celui du client. Un attaquant ne peut donc pas savoir à l'avance quelle sera la réponse, puisqu'il ne connait pas le numnique.
En recevant cette réponse à son défi, le serveur doit récupérer le mot de passe de l'utilisateur dans sa base de données, et refaire les mêmes opérations de concaténation et de condensation que le client, puis vérifier qu'il trouve le même résultat. (Notez qu'il n'y a pas besoin de stocker le mot de passe en clair, et que c'est même déconseillé, il suffit d'avoir accès à son condensat.) Par exemple, avec Apache, l'outil htdigest gère tout cela.
Le même mécanisme peut s'utiliser pour s'authentifier auprès
d'un relais, mais dans ce cas les en-têtes
se nomment Proxy-Authenticate:
et
Proxy-Authorization:
.
Bon, c'est bien compliqué tout cela, place aux exemples. Un
client veut accéder à
http://www.example.org/dir/index.html
(section 3.9.1 du RFC). Le
royaume est http-auth@example.org
, le nom
d'utilisateur Mufasa et
le mot de passe Circle of Life (n'oubliez pas
les deux espaces entre les mots). Le serveur envoie le défi :
HTTP/1.1 401 Unauthorized WWW-Authenticate: Digest realm="http-auth@example.org", qop="auth, auth-int", algorithm=SHA-256, nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
Le serveur demande qu'on condense avec SHA-256. Le client répond au défi :
Authorization: Digest username="Mufasa", realm="http-auth@example.org", uri="/dir/index.html", algorithm=SHA-256, nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", nc=00000001, cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ", qop=auth, response="753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1", opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
Le nom de l'utilisateur était en clair (non condensé). Le numnique et la chaîne opaque sont renvoyés tels quels. La réponse a été calculée en suivant l'algorithme de la section 3.4.1. Si vous voulez toutes les étapes (condensat calculé avec la commande Unix sha256sum) :
Parmi les points qui peuvent compliquer ce mécanisme (qui est
ennuyeux mais simple à mettre en œuvre), l'internationalisation
(section 4). Si le nom ou le mot de passe ne se limitent pas à
ASCII, le serveur a intérêt à utiliser le
paramètre charset
pour indiquer le jeu
de caractères dont le client devra se servir. La seule
valeur légale de ce caractère est UTF-8, et les
chaînes de caractères doivent être normalisées en
NFC (cf. RFC 5198,
notamment la section 3). Un exemple se trouve dans la section 3.9.2.
Maintenant que ce mécanisme est décrit, analysons sa sécurité
(section 5 du RFC). D'abord, les mots de passe utilisés peuvent être
trop faibles. Ce mécanisme Digest permet les
attaques par dictionnaire (on essaie tous les mots d'un dictionnaire
comme mots de passe) et, si le mot de passe figure dans les
dictionnaires habituels (c'est le cas de
azertyuipop
et de
123456789
), il finira par être trouvé. Cette
attaque marche quelles que soient les qualités de l'algorithme de
condensation employé. Il faut donc essayer de s'assurer qu'on
n'utilise que des mots de passe forts. (Si la communication n'utilise
pas HTTPS, et qu'un attaquant écoute passivement
les défis
et les réponses, il peut également les tester contre un dictionnaire,
sans avoir besoin de faire des essais qui peuvent donner l'alarme.)
Ces mots de passe doivent être stockés sur le serveur. Bien sûr, on
peut stocker uniquement leur forme condensée mais, comme c'est elle
qui sert d'entrée à l'algorithme de calcul de la réponse, un attaquant
qui met la main sur cette base a un accès complet aux ressources du
serveur, sans étape de décryptage (comme cela serait le cas avec un
attaquant mettant la main sur un /etc/passwd
ou
/etc/shadow
Unix). Notez que le mécanisme
Digest ne permet pas de
saler les mots de passe. (À titre personnel,
c'est pour cela que je ne trouve pas forcément ce mécanisme forcément plus sûr
que Basic, contrairement à ce que dit le
RFC en 5.13. Aujourd'hui, les piratages de bases des serveurs sont
fréquents. La documentation d'Apache est
sceptique aussi, disant « this [Digest authentication] does
not lead to a significant security advantage over basic
authentication » et « the password storage on the server is much less secure with digest authentication than with basic authentication »).
C'est en raison de cette faiblesse que le royaume est inclus dans la
condensation qu'on stocke dans la base : au moins l'attaquant ne
pourra pas attaquer les autres sites, même si on a le même nom
d'utilisateur et mot de passe.
Notez au passage que, comme le mécanisme Basic du RFC 7617, ce Digest permet au serveur d'authentifier le client, mais pas le contraire. Si on veut plus fort, il va falloir utiliser l'authentification permise par TLS (avec des certificats).
Et les attaques par rejeu ? La principale protection est fournie par le numnique. S'il est stupidement généré (par exemple, un simple compteur incrémental, trivial à deviner), les attaques par rejeu deviennent possibles. Avec l'algorithme conseillé, les attaques par rejeu sont plus difficiles mais pas impossibles : comme on peut réutiliser le numnique pendant un certain temps, un attaquant rapide peut faire plusieurs essais. Si c'est intolérable, la seule solution est d'avoir des numniques qui ne sont absolument pas réutilisables (par exemple, des numniques aléatoires, en prenant les précautions du RFC 4086). L'inconvénient est qu'il faut que le serveur les mémorise, au lieu de simplement les recalculer.
Il y a aussi les attaques classiques de l'Homme du Milieu (par exemple dans un relais Web). Un tel attaquant peut, par exemple, remplacer l'algorithme dans le défi par un algorithme plus faible, voir remplacer le défi de Digest par un appel à utiliser un mécanisme plus faible, tel que Basic. Le client HTTP peut prendre quelques mesures (se souvenir de l'authentification utilisée et avertir l'utilisateur si un site qui utilisait Digest passe à Basic) mais aucune n'est parfaite.
Le RFC recommande aussi de n'utiliser l'authentification qu'au-dessus de TLS. Même si le mot de passe n'est pas transmis, l'observation de l'authentification peut donner des informations (et donner accès au contenu des pages Web alors que, si on authentifie, cela peut être parce qu'il est confidentiel). Et TLS avec authentification du serveur protège contre les attaques de l'Homme du Milieu.
Le mécanisme Digest est dans le registre IANA des mécanismes d'authentification. Un nouveau registre est créé pour stocker les algorithmes de condensation.
Les changements depuis le RFC 2617 sont décrits dans l'annexe A. Les principaux ? SHA-256 et SHA-512 sont ajoutés aux algorithmes de condensation. MD5 est conservé, pour des raisons de compatibilité mais très déconseillé (RFC 6151). La possibilité de condenser le nom de l'utilisateur est ajoutée. L'internationalisation est ajoutée.
Si vous utilisez curl pour vous
connecter au serveur HTTP, l'option
--digest
vous permettra d'utiliser le
mécanisme de ce RFC (ou bien vous mettez l'option
--anyauth
et vous laissez curl se
débrouiller pour trouver). Côté serveur, pour
Apache, c'est bien
documenté. Notez la directive Apache
AuthDigestDomain
pour spécifier le domaine,
c'est-à-dire la liste des URI
protégés. Pour Nginx, il n'y a apparement
pas de solution standard, il faut utiliser un module
supplémentaire (ou utiliser le mécanisme
Basic + TLS, ce qui est probablement meilleur).
Deux bons textes à lire si vous voulez creuser la question, avec des exemples, un chez Microsoft, et sur le blog perso de Chua Hock-Chuan.
Première rédaction de cet article le 6 octobre 2015
Le 5 octobre, à Brest, j'ai eu le plaisir de parler du DNS, pas comme technique ou comme protocole réseau, mais comme bien commun.
Cette causerie s'inscrivait dans le cadre du festival « Brest en Biens Communs » qui comptait bien d'autres activités au cours de la semaine. Par exemple, j'y ai suivi un atelier de formation au sous-titrage, organisé par les Chats Cosmiques, avec le logiciel Aegisub.
La vidéo de ma conférence sera disponible, restez connectés. En attendant, voici :
Merci à la ville de Brest qui a payé mon voyage, à l'Université de Bretagne occidentale pour les locaux, à la Cantine numérique de Brest pour l'accueil et l'organisation, et à la Maison du Libre. Et merci aussi à Jessica et Nicolas.
Également, sur cette conf', l'article de la Cantine et les notes détaillées de Guigui.
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : K. Wierenga (Cisco
Systems), S. Winter
(RESTENA), T. Wolniewicz (Nicolaus Copernicus
University)
Pour information
Première rédaction de cet article le 6 octobre 2015
Le service eduroam permet aux étudiants et employés des universités et centres de recherche européens de se connecter en Wi-Fi même quand ils ne sont pas dans leur université habituelle. Ce RFC décrit le fonctionnement d'eduroam et les choix effectués lors de sa conception (notamment l'absence de ces abominables portails captifs). La taille d'eduroam et ses années de fonctionnement indiquent que ces choix étaient bons et qu'eduroam peut être un modèle pour bien d'autres déploiements de Wi-Fi.
Le projet d'un accès pour le monde académique européen a démarré en 2002 (cf. la proposition initiale, par un des auteurs du RFC). Aujourd'hui, eduroam couvre 10 000 sites (dont un en Papouasie Nouvelle-Guinée) et des millions d'utilisateurs.
Les buts d'eduroam étaient (section 1 du RFC) :
Avec un tel cahier des charges (section 1), plutôt ambitieux, les solutions qui avaient été envisagées et testées étaient :
Désormais, eduroam repose sur trois piliers :
L'utilisation d'EAP dans RADIUS est décrite dans le RFC 3579.
L'architecture d'eduroam est décrite en section 2 de notre RFC. Qui dit authentification dit confiance : d'où vient la confiance dans eduroam ? Il y a une relation de confiance entre l'utilisateur et l'IdP, son établissement d'origine, vérifiée par une authentification mutuelle. Et il y a une relation de confiance entre l'IdP et le SP (l'établissement d'accueil), fondée sur RADIUS.
Si une université, ou établissement analogue, participe au
service eduroam, ses bornes Wi-Fi vont publier le
SSID eduroam
. C'est
celui que choisit l'utilisateur la première fois, la connexion
sera typiquement faite automatiquement les fois suivantes. Notez
qu'il est toujours possible qu'un point d'accès méchant diffuse un
faux eduroam
: l'utilisateur ne doit pas
considérer que tout SSID eduroam
est sûr !
Notez aussi, mais c'est moins grave, qu'un utilisateur qui est
dans son université habituelle peut se connecter via eduroam, avec
les éventuelles limitations que cela implique, plutôt qu'au réseau
local de son université. Pour s'accrocher au point
d'accès Wi-Fi du SP, la machine de l'utilisateur
utilise, on l'a vu, 802.1X. Les
transmissions radio sont sécurisées par
WPA2 avec AES. Il
n'y a pas d'accès anonyme à eduroam, tout utilisateur doit avoir
un compte sur un des IdP.
Et EAP, il sert à quoi ? Il permet une
protection de bout en bout des informations
d'authentification. Même si l'utilisateur s'est connecté à un faux
réseau prétendant être eduroam, celui-ci ne pourra pas
intercepter, par exemple les mots de passe. Seul l'IdP,
l'institution d'origine de l'utilisateur, verra son mot de passe. EAP n'est pas
directement un mécanisme d'authentification mais un protocole qui
permet de négocier et transporter plusieurs mécanismes
d'authentification (du « simple » mot de passe - RFC 4746 - aux
certificats - RFC 5216). EAP est de bout en bout, entre l'utilisateur
et son IdP, son fournisseur d'identité. Si l'université de
rattachement de l'utilisateur déploie une technique
d'authentification nouvelle et très rare, pas de problème : les
SP, et les serveurs RADIUS n'ont pas à la gérer, seul EAP sera au
courant. L'utilisateur s'identifie avec un
NAI (RFC 7542),
comportant un nom local à l'IdP, un @ et un
domaine (ou royaume, realm) unique. Pour
des raisons de protection de la vie privée, on peut utiliser un
NAI ne comportant que le domaine (par exemple
@ma-fac.example
), le NAI complet n'étant
transporté que dans EAP (pensez à un
tunnel), et donc chiffré et inaccessible
aux intermédiaires.
Le point d'accès Wi-Fi va ensuite être un client RADIUS pour transmettre les informations permettant l'authentification. (Du point de vue sécurité, notez que cette communication entre le client RADIUS et le premier serveur RADIUS est entièrement chez le SP, et sécurisée par lui, typiquement via les secrets partagés de RADIUS.)
Une fois qu'on est arrivé au serveur RADIUS du SP, que se
passe-t-il ? Il faut relayer jusqu'au serveur RADIUS de l'IdP. Les
serveurs RADIUS de eduroam sont organisés de manière arborescente,
en suivant à peu près l'arbre du DNS. Si un
professeur à soton.ac.uk
visite
l'Université de l'Utah, sa requête va
d'abord passer par le serveur RADIUS de cette université. Ce
serveur de l'université utah.edu
ne connait
que le serveur RADIUS et edu
. Il lui transmet
donc la requête, le serveur de edu
passe à la
racine (notez que, contrairement au DNS, on ne part pas de la racine)
et la requête redescend ensuite vers le serveur de l'IdP (serveurs
de ac.uk
puis de
soton.ac.uk
).
Donc, pour détailler le processus, les étapes étaient :
anonymous@soton.ac.uk
,soton.ac.uk
n'est pas le sien), il
fait suivre au serveur RADIUS de .edu
,.edu
), il transmet donc à la racine (au
passage, notez que la racine est évidemment composée de
plusieurs serveurs, pour des raisons de redondance),ac.uk
(notez que la racine est généralement
configurée avec des TLD mais
ac.uk
est une exception),soton.ac.uk
,Access-Accept
ou
Access-Reject
) est renvoyée dans l'Utah en
suivant la hiérarchie RADIUS d'eduroam en sens inverse,On voit qu'il faut en faire bouger des électrons, et très vite et de manière très fiable. eduroam a logiquement connu quelques malheurs (section 3 du RFC). Par exemple, les serveurs RADIUS à utiliser pour router la requête sont statiquement configurés (une grosse différence avec le DNS). Le RFC 2865 ne dit pas ce qu'il faut faire en cas de panne. RADIUS fonctionne sur UDP et la panne n'est donc pas indiquée explicitement, on a juste une absence de réponse. Pour l'utilisateur final, cela peut se traduire par un long délai, suivi d'un refus d'accès inexplicable. En prime, comme il y a plusieurs relais RADIUS successifs, l'administrateur d'une université, en cas de non-réponse, ne sait pas quel relais a défailli. Son RADIUS ne peut pas distinguer une panne du premier relais d'une panne de la racine, sauf en constatant que les éventuelles requêtes pour des domaines du même TLD marchent. Un processus de débogage pénible (cf. l'article « Dead-realm marking feature for Radiator RADIUS servers »). Et il n'y avait pas non plus dans RADIUS de message de retour indiquant la fin de la panne (ce point a toutefois été résolu avec le RFC 5997).
RADIUS est nettement faiblard en terme de signalisation des erreurs mais le protocole 802.1X ne permet pas non plus de transmettre à l'utilisateur final un message très détaillé. Un serveur RADIUS qui dépend d'un serveur dorsal extérieur (LDAP ou SGBD par exemple) a donc un choix cornélien si ce serveur extérieur est défaillant : le serveur RADIUS peut ne pas répondre du tout, mais cela va être interprété comme une panne par les relais RADIUS, qui risquent de ne plus envoyer de requêtes. Et le logiciel de l'utilisateur ne va pas transmettre de message utile, voire il donnera des avis erronés (« vérifiez votre mot de passe »), en raison du manque d'informations. Soit, autre solution, le serveur RADIUS répond par un refus (RFC 2865, section 4.3), ce qui serait mieux pour les autres relais RADIUS (ils verront que leur camarade répond toujours) mais très déroutant pour l'utilisateur final, qui verra des messages trompeurs et effrayants, par exemple « votre mot de passe est incorrect ou votre compte est fermé ». Ainsi, Windows, dans un tel cas, efface les informations d'authentification qui étaient enregistrées et oblige l'utilisateur à tout recommencer. Ce problème a suscité de nombreux appels à l'assistance utilisateur, car les gens avaient évidemment oublié le mot de passe qu'ils avaient configuré des semaines ou des mois auparavant...
Les innombrables discussions dans la communauté eduroam ou dans le groupe de travail RADEXT de l'IETF n'ont pas permis d'arriver à un consensus. Si RADIUS sur TCP, introduit depuis, résout une partie des problèmes, il ne solutionne pas celui du dorsal (LDAP ou SGBP) planté. Il faudrait un mécanisme analogue au code d'erreur 500 de HTTP mais RADIUS n'en a pas.
Autre problème, la complexité du routage entre les relais
RADIUS. Le faire sur la base du TLD marche
bien pour les ccTLD (le serveur RADIUS national est administré par l'association
eduroam du pays) mais pas du tout pour
.com
. Il a fallu
mettre des exceptions manuelles comme kit.edu
routé vers le serveur allemand car le
KIT est en Allemagne, ce qui n'était pas évident vu
son TLD... Cela pose un problème de passage à l'échelle : s'il n'y a
qu'environ 200 ccTLD (dont 50 sont aujourd'hui dans eduroam), il
peut y avoir potentiellement des milliers d'établissements dans
les gTLD, chacun avec son exception à
mettre dans les tables de routage, et à propager vers tous les
serveurs (pour des raisons de fiabilité, il y a plusieurs serveurs
racines).
Je l'ai dit, RADIUS fonctionne sur UDP. Ce choix était raisonnable dans les configurations simples du début (un client RADIUS, le point d'accès, et un serveur RADIUS, sans relais), mais il a des conséquences désagréables pour la configuration bien plus complexe d'eduroam. EAP est un protocole bavard et il n'est pas rare d'avoir 8 à 10 aller-retours entre le serveur RADIUS du SP et celui de l'IdP. La perte d'un seul paquet nécessitera de tout recommencer, UDP n'ayant pas de retransmission. Dans certains cas, les données EAP sont de taille importante (c'est surtout le cas avec EAP-TLS, où il faut transmettre de gros certificats) et on peut voir des paquets RADIUS dépasser la MTU et être fragmentés. Si, en théorie, la fragmentation n'est pas un problème, en pratique, on sait qu'elle marche mal sur l'Internet, notamment en raison des nombreux pare-feux bogués ou mal configurés. Ces problèmes sont très difficiles à déboguer car, si Alice et Bob constatent que les paquets entre eux ne passent pas, la cause peut être un réseau tiers, situé sur le chemin, et qu'ils ne contrôlent pas. (RADIUS sur TCP, RFC 6613, résout ce problème. Le RFC 6613 discute plus en détail ce problème.)
Autre limite de RADIUS tel qu'il était au début d'eduroam : la
protection de la vie privée. Le protocole
permettait de chiffrer les mots de passe mais pas le reste du
trafic. C'est donc à EAP de contourner ce problème, par exemple
avec son authentification TLS. Mais cela ne
suffit pas car il y a toujours des attributs « privés » transmis
en clair par RADIUS comme Calling-Station-ID
qui peut permettre de trouver le terminal de l'utilisateur, ou
comme NAS-IP-Address
qui permet de trouver le
point d'accès. (Le problème se pose aussi dans la réponse : si le
message d'acceptation est trop bavard, par exemple en indiquant le
département de l'utilisateur à l'université, cela laisse fuiter
des informations en clair.) Cela permet donc à un attaquant puissant, en
surveillant tous les flux RADIUS (ce qui est largement dans les
moyens de la NSA), de suivre à la trace bien des
gens. À noter que une telle récolte d'informations n'a pas encore
été documentée (on ne trouve pas RADIUS ou eduroam dans les
documents Snowden) mais cela ne veut pas
dire qu'elle n'a pas eu lieu. La seule solution est de chiffrer
toute la session RADIUS, ce qui n'était pas possible dans le
RADIUS original (mais le devient avec le RFC 6614).
EAP protège également en permettant l'utilisation d'identificateurs « anonymes », le vrai identificateur n'étant transmis que dans la session EAP chiffrée. Encore faut-il que l'utilisateur configure son logiciel pour cela, et tous les logiciels ne le permettent pas.
Ces sécurités fournies par EAP ne marchent que si on se connecte au bon serveur EAP. Si on se connecte à la place au terrible Homme du Milieu, plus aucune sécurité ne joue. Est-ce que les utilisateurs ont tous configuré leur logiciel pour tester la validité du certificat du serveur EAP, et la tester contre une liste d'AC sérieuses ? On peut en douter et il est donc sans doute possible de capturer des sessions Wi-Fi en présentant un faux serveur EAP.
Ces problèmes de configuration d'EAP sont d'autant plus pénibles que beaucoup des mises en œuvres d'EAP ne permettent pas aux administrateurs système de diffuser facilement des configurations pré-remplies (et, lorsqu'il y en a, elles sont spécifiques à un vendeur), où tous les paramètres de sécurité ont été fixés aux bonnes valeurs, et où l'utilisateur n'a plus qu'à taper nom et mot de passe (ou bien indiquer le certificat client).
Les difficultés pratiques rencontrées avec l'architecture d'eduroam ont mené à certains changements, décrits dans la section 4 du RFC. Certains changements ont nécessité une action normalisatrice à l'IETF. Ces changements peuvent cohabiter avec l'infrastructure actuelle (pas question de tout raser pour recommencer de zéro) et sont donc déployés progressivement. Les deux grands changements sont le remplacement progressif d'UDP par TCP, et l'utilisation de TLS pour sécuriser la session RADIUS (l'ancien système était un secret partagé entre les deux pairs RADIUS).
Au passage, pourquoi ne pas avoir remplacé RADIUS par Diameter (RFC 6733) ? Cela avait été envisagé puisque, sur le papier, le protocole Diameter, bien plus complexe et « enterprise-grade » (c'est-à-dire apprécié des DSI, et n'ayant pas de mise en œuvre en logiciel libre), disposait déjà des services voulus. Mais l'examen de l'offre Diameter existante, par rapport aux exigences d'eduroam (logiciels gratuits ou bon marché, gestion des authentifications EAP les plus courantes, accès à des dorsaux courants comme MySQL, etc) a été décevante. En prime, les points d'accès Wi-Fi existants n'avaient pas de client Diameter (et n'en ont toujours pas).
D'où le choix de travailler à l'IETF pour développer les nouveaux services (RFC 6613, RFC 6614), et avec les développeurs de logiciel libre pour les mettre en œuvre.
Déployer TCP et TLS dans l'infrastructure de serveurs RADIUS a permis de détecter les serveurs en panne (avec les keepalive de TCP, cf. RFC 6613, section 2.6) et de protéger le contenu échangé contre les écoutes. Les certificats X.509 d'eduroam, qui servent à authentifier les pairs RADIUS, sont fournis par un ensemble d'AC accréditées.
TCP et TLS laissent un problème, celui du routage statique des
requêtes, dans la hiérarchie des serveurs eduroam. La solution se
nomme « découverte dynamique ». Il y a deux problèmes à résoudre :
trouver le serveur RADIUS responsable d'un domaine donné, et
s'assurer de son authenticité. Pour le premier problème, eduroam
utilise des enregistrements S-NAPTR (RFC 3958) avec le service privé
x-eduroam:radius.tls
, donnant accès à des
enregistrements SRV indiquant le serveur à
contacter. Par exemple, un cas réel chez RESTENA :
% dig NAPTR restena.lu ... restena.lu. 21600 IN NAPTR 100 10 "s" "x-eduroam:radius.tls" "" _radsec._tcp.eduroam.lu. ... % dig SRV _radsec._tcp.eduroam.lu ... _radsec._tcp.eduroam.lu. 43198 IN SRV 0 0 2083 tld1.eduroam.lu. _radsec._tcp.eduroam.lu. 43198 IN SRV 10 0 2083 tld2.eduroam.lu.
Ces deux enregistrements nous disent que le domaine
restena.lu
a un serveur RADIUS joignable via
le nom _radsec._tcp.eduroam.lu
et que ce nom
correspond à deux serveurs, tld1.eduroam.lu
et tld2.eduroam.lu
, tous les deux opérant sur
le port 2083. (Ce système est décrit dans
le RFC 7585.) Le RFC note aussi que le nouveau système de découverte
dynamique rendra le système plus souple mais peut-être aussi plus
fragile, par suite de la complexité ajoutée.
Le second problème est la vérification de l'authenticité d'un serveur. Après tout, n'importe qui peut mettre des enregistrements NAPTR et SRV dans son domaine et prétendre avoir un serveur RADIUS d'eduroam. La solution a été de réutiliser les AC qui émettent les certificats nécessaires pour RADIUS-sur-TLS. Le serveur RADIUS doit donc vérifier que le pair en face :
/DC=org/DC=edupki/CN=eduPKI
),openssl
s_client -connect $RADIUS_SERVER:$RADIUS_PORT |openssl x509
-text
sur le serveur RADIUS doit montrer « Policy:
1.3.6.1.4.1.27262.1.13.1.1.1.3 » (je trouve des serveurs qui ont
plutôt une vieille version de la politique, comme 1.3.6.1.4.1.27262.1.13.1.1.1.0).
Une dizaine de pays et une centaine de domaines utilisent ce nouveau système de découverte dynamique. Les principaux problèmes sont les problèmes classiques de X.509, gestion des CRL, par exemple.
Le progrès ne va évidemment pas s'arrêter là. eduroam considère aussi deux alternatives :
draft-ietf-abfab-arch
), prometteur mais encore loin
d'être complètement spécifié.Vu le très grand nombre d'utilisateurs d'eduroam, il ne faut pas s'étonner qu'il y ait des incidents, des abus, etc. La section 5 du RFC décrit les mécanismes techniques permettant de gérer ces contrariétés. D'abord, la comptabilité : dans eduroam, c'est une affaire à gérer localement dans le SP (l'université d'accueil). L'IdP (l'université d'origine) n'est pas informée (cf. le « eduroam Compliance Statement »). Mesurer l'activité d'un utilisateur est un pré-requis pour la lutte contre certains abus. D'un autre côté, le SP ne voit pas forcément l'identité du visiteur, juste son domaine (si le visiteur a configuré les identificateurs « anonymes ») ce qui rend difficile la comptabilité. Le RFC 4372 fournit un mécanisme de comptabilité par utilisateur, chargeable user identity (qui envoie un pseudonyme, pas le « vrai » nom), mais il est très peu implémenté.
En dix ans de fonctionnement, eduroam n'a pas eu d'incident de sécurité sérieux. Cela peut indiquer que l'architecture de sécurité est bonne : il n'y a pas d'accès anonyme, chaque utilisateur est identifié, ce qui peut expliquer leur retenue. Le RFC note que cela veut peut-être dire plutôt que les réseaux utilisés par eduroam ne sont pas assez supervisés et que certains abus passent peut-être inaperçus.
Quoiqu'il en soit, la partie politique de la sécurité est
traitée dans « eduroam
Policy Service Definition », notre RFC ne décrivant
que les moyens techniques. D'abord, le SP est évidemment libre de
bloquer un utilisateur qui abuse. Comment ? Si l'utilisateur a
activé les identifiants « anonymes », le SP ne possède que le nom
de domaine et l'adresse MAC (sauf
coopération avec l'IdP, forcément lente et complexe et donc pas
utilisable en urgence). Le SP peut donc, si ses
équipements le permettent, bloquer la requête EAP sur la base de
ces deux éléments. Mais changer l'adresse MAC est trop facile, et
un attaquant déterminé peut donc contourner cette
protection. Autre solution, le SP peut attendre la réponse du
serveur RADIUS de l'IdP et regarder si elle contient l'attribut
Chargeable-User-Identity
du RFC 4372, qui contient un identifiant unique de
l'utilisateur (unique par SP : le SP envoie son
Operator-Name
- RFC 5580, et l'IdP
calcule un identifiant qui dépend du SP, pour les raisons décrites
en section 6.1). C'est la meilleure solution car le SP peut alors
bloquer cet utilisateur, et uniquement lui, soit en ne répondant
pas à ses requêtes, soit en fabriquant des
Access-Reject
RADIUS. S'il n'y a pas de
Chargeable-User-Identity
dans la réponse ? La
seule solution restant, et elle est violente, est de bloquer le
domaine entier, ce qui aura l'effet de bord de bloquer les
visiteurs qui ont le malheur d'avoir un compte au même endroit que
l'abuseur.
Et bloquer au niveau de l'IdP, alors ? Lui peut facilement
fermer un compte, empêchant ainsi l'utilisateur d'accèder à tout
site eduroam. Si le SP envoie son nom dans la requête (avec
l'attribut RADIUS Operator-Name
du RFC 5580), on peut même ne bloquer un compte que pour certains
SP, par exemple ceux qui se sont plaints de cet utilisateur. Cela
permet des politiques plus fines. Par exemple, imaginons un SP qui
interdise le partage d'œuvres culturelles. Un visiteur utilise
BitTorrent et le SP demande à l'IdP de le
bloquer, alors même que l'utilisation de BitTorrent n'est pas
interdite sur le réseau de l'IdP. Bloquer l'utilisateur seulement
s'il est sur le réseau du SP râleur permet de satisfaire les
politiques du SP et de l'IdP. Sans cette finesse, que permet
l'attribut Operator-Name
, l'IdP risquerait
de bloquer complètement un utilisateur, qui n'était peut-être même
pas au courant des politiques restrictives du SP.
Passons maintenant à la protection de la vie
privée, un des gros morceaux d'eduroam (section 6 du
RFC). Si eduroam avait été conçu par
Cazeneuve ou Facebook, tout aurait été enregistré tout
le temps mais eduroam a au contraire été prévu avec des fortes
préoccupations de vie privée. D'abord, on l'a vu, la possibilité
de NAI « anonymes » n'indiquant que le domaine (outer
identities). Ce système empêche, par exemple, deux SP de
déterminer si deux visiteurs de leurs campus, ayant le même IdP,
sont une seule et même personne. Excellent pour la vie privée,
mais cela rend compliqué l'attribution d'une éventuelle mauvaise
action. D'où l'ajout de l'attribut
Chargeable-User-Identity
dans eduroam. Étant
calculé par l'IdP et différent pour chaque SP, il empêche les
collusions de SP entre eux, mais permet de remonter les traces
d'un éventuel abuseur.
À noter que le domaine, lui, est visible du SP, des différents serveurs RADIUS qui relaient (ils en ont besoin pour le routage) et, si on n'utilise pas TLS, de tous les indiscrets sur le trajet. Si l'IdP est une très grosse université, cela peut frustrer l'observateur mais, dans le cas de petits établissements, cela peut l'aider. Il serait difficile de résoudre ce problème sans refaire tout eduroam.
Par défaut, l'IdP ne sait pas où se trouvent ses utilisateurs, puisque son serveur RADIUS ne voit que les requêtes du serveur RADIUS supérieur (typiquement, celui du pays). Cet enchaînement de serveurs RADIUS, peut sembler lourd, et difficile à déboguer (le point discuté en section 3). Mais il est avantageux, question vie privée.
Par contre, cette protection de l'utilisateur contre son propre
IdP peut être affaiblie si on utilise la découverte dynamique
(l'IdP voit les requêtes DNS, cf. RFC 7626), et évidemment si le SP envoie son nom
dans la requête RADIUS (attribut Operator-Name
).
Et la sécurité, à part cette question de vie privée ? Il faut bien sûr relire les sections Sécurité des normes RADIUS, EAP et 802.1X, plus la section 7 de notre RFC, qui discute les problèmes plus spécifiques à eduroam. D'abord, la sécurité de bout en bout repose complètement sur EAP. Si un Homme du Milieu réussit à se faire passer pour le serveur EAP de l'IdP, il a table ouverte. Le client EAP doit donc exiger une authentification du serveur, et le serveur doit faire ce qu'il faut pour être authentifié (par exemple, publier le nom qui doit apparaitre dans le certificat).
En théorie, cette authentification du serveur résout complètement le problème. En pratique, il reste des pièges. Par exemple, certains clients EAP ne permettent de vérifier que l'AC, pas le nom (le sujet du certificat). Tout attaquant qui peut obtenir un certificat quelconque de la même AC peut donc se faire passer pour le serveur EAP. Il vaut donc mieux ne se fier qu'à des AC spécifiques à eduroam. D'autres clients EAP pratiquent le TOFU : ils se fient au premier certificat et le mémorisent pour la suite. Si un utilisateur était chez un point d'accès pirate la première fois, c'est le certificat de l'attaquant qui sera cru. Les utilisateurs doivent donc veiller à configurer leurs clients eduroam proprement (un outil existe pour cela). Pire, certains logiciels permettent à l'utilisateur de complètement sauter la vérification (« No CA certificate is required » sur NetworkManager, par exemple). L'utilisateur qui sélectionnerait cette option pour se faciliter la vie se rendrait très vulnérable aux attaques de l'Homme du Milieu. Dernier piège d'authentification : en utilisant les identités « anonymes » (NAI ne comportant que le nom du domaine), rien n'empêche un utilisateur malveillant de placer dans la session EAP un NAI indiquant un autre domaine. Si le serveur RADIUS de l'IdP indiqué dans le NAI « anonyme » accepte de relayer les requêtes, l'utilisateur pourra se faire authentifier, et le SP ne connaitra alors pas le vrai domaine d'origine. Cela diminue sérieusement la responsabilité de l'utilisateur et lui permet de brouiller ses traces. Voilà pourquoi les serveurs RADIUS d'eduroam ne doivent pas relayer ces requêtes.
Comme tout service sur l'Internet, eduroam est évidemment susceptible de recevoir des attaques par déni de service. Sur les points d'accès Wi-Fi, on peut voir des serveurs DHCP pirates (cf. RFC 7610), des émetteurs de RAcailles (cf. RFC 6105), etc. eduroam est moins vulnérable que le point d'accès Wi-Fi typique avec portail captif, car l'authentification préalable est nécessaire (ce qui limite les attaques par un client tentant d'épuiser la réserve d'adresses IP en faisant des requêtes DHCP répétées) et le Wi-Fi est chiffré (par WPA2), ce qui limite l'usurpation ARP.
Certaines attaques par déni de service spécifiques à eduroam existent. Par exemple, un attaquant situé physiquement à portée d'un point d'accès Wi-Fi eduroam peut envoyer de manière répétée des demandes d'accès en indiquant un domaine situé dans un TLD différent : cela obligera plusieurs serveurs RADIUS, y compris ceux de la racine, à traiter sa demande, et une négociation EAP à se lancer. Heureusement pour eduroam, EAP est synchrone, donc un attaquant donné ne peut lancer qu'une requête à la fois, pour un domaine donné. eduroam reçoit aujourd'hui des centaines de milliers de requêtes d'authentification réussies par jour (et bien plus qui échouent) et un attaquant qui voudrait tuer eduroam avec un afflux de requêtes devrait donc y consacrer de gros moyens. En tout cas, de telles attaques n'ont pas encore été vues.
À noter qu'il existe aussi des attaques involontaires. La plupart des demandes d'authentification qui échouent concernent des comptes qui étaient valides mais ne le sont plus (étudiant qui a terminé ses études, par exemple). Il est donc probable que les gens dont les comptes sont expirés aient oublié de déconfigurer leur logiciel et que celui-ci envoie toujours des demandes dès qu'il passe près d'un point d'accès eduroam. Il y a donc un « botnet de fait » composé de toutes ces machines d'ex-utilisateurs. Le changement de machine par l'utilisateur, lorsque l'ancienne est trop vieille, ne résout pas le problème : aujourd'hui, surtout sur les ordiphones, les données d'authentification sont sauvegardées dans le cloud (pour que Google et la NSA y aient plus facilement accès) et sont remises sur le nouveau jouet lorsque l'ancien est remplacé. Le botnet des anciens d'eduroam ne fait donc que grossir. Il n'y a pas encore de solution propre à ce problème, peut-être améliorer les logiciels client pour qu'ils arrêtent d'envoyer automatiquement des requêtes après N échecs sur une période de X jours.
Un point sur lequel le RFC passe assez rapidement est le problème d'interopérabilité qui peut se poser quand deux auteurs de logiciel n'ont pas compris de la même façon ces normes complexes qu'il faut programmer correctement. Un exemple d'alerte est « RADIUS Attribute Issues regarding RFC5580 (Operator-Name and others) with several RADIUS servers (including Microsoft IAS and NPS) », un amusant problème de normalisation avec le RFC 5580, RFC qui a été souvent cité précédemment.
Si vous êtes intéressé par ce système, je vous recommande la lecture du site Web d'eduroam.
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : J. Reschke (greenbytes)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF httpbis
Première rédaction de cet article le 5 octobre 2015
Un très court RFC, probablement un des
derniers du groupe de travail IETF
qui a fait la réécriture de la norme
HTTP 1.1. Il normalise l'en-tête
HTTP
Authentication-Info:
, qui était précédemment
dans le RFC 2617, et qui, depuis, est dans
le RFC 9110.
Cet en-tête, et son équivalent pour les relais,
Proxy-Authentication-Info:
, sert au serveur
HTTP à communiquer des informations après
une authentification réussie.
Dans la nouvelle rédaction de la
norme HTTP 1.1, l'authentification
est décrite par le RFC 7235. L'ancien RFC
sur les méthodes d'authentification, le RFC 2617, est désormais abandonné et plusieurs RFC ont
repris ses spécifications, comme notre RFC 7615 pour les
deux en-têtes d'information
Authentication-Info:
et
Proxy-Authentication-Info:
.
La section 3 de notre RFC décrit en détail le premier
en-tête. Envoyé par le serveur après une authentification réussie,
il contient une liste de paires {nom, valeur}. Les noms possibles
dépendent du mécanisme d'authentification utilisé. Par exemple, le
mécanisme Digest du RFC 7617 utilise Authentication-Info:
pour des informations techniques nécessaires pour la prochaine
authentification. Notre
RFC 7615 ne normalise donc que la syntaxe, pas la
sémantique. Voici un exemple :
Authentication-Info: rspauth="670ff3158cec20b73d7342932f8c40a1", cnonce="1672b410efa182c061c2f0a58acaa17d", nc=00000001, qop=auth
L'en-tête Proxy-Authentication-Info:
,
décrit en section 4, est exactement le même, sauf qu'il est
utilisé lors de l'authentification avec un relais intermédiaire et non pas avec le serveur
HTTP final.
Les deux en-têtes peuvent être indiscrets, par les informations qu'ils donnent sur l'authentification (ne serait-ce que le simple fait qu'il y a eu authentification). La section 5 de notre RFC, consacrée à la sécurité, recommande donc l'utilisation de HTTPS.
Ces deux en-têtes HTTP sont enregistrés à l'IANA, dans le registre des en-têtes.
Apparemment aucun changement significatif dans ces en-têtes n'est apparu depuis l'ancienne norme, le RFC 2617.
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : J. Reschke (greenbytes)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF httpauth
Première rédaction de cet article le 5 octobre 2015
Ce court RFC (re-)définit le mécanisme d'authentification « de base » (basic authentication scheme) de HTTP : un mécanisme trivial, où un nom d'utilisateur et un mot de passe sont transmis en Base64 au serveur HTTP. Ce RFC (et ses copains) annule et remplace l'ancien RFC 2617.
Depuis la réécriture générale des RFC sur HTTP, le cadre de l'authentification est décrit dans le RFC 7235. Chaque mécanisme spécifique fait ensuite l'objet de son propre RFC. L'authentification de base est le plus ancien et ce RFC 7617 n'apporte donc rien de bien nouveau, il se contente de toiletter une norme existante.
Le principe est simple : le serveur HTTP gère un ou plusieurs « royaumes » (realm). Dans chaque royaume, il connait une liste d'utilisateurs, identifiés par leur nom, et authentifiés par un mot de passe. Le client, à qui le serveur indique le royaume dont dépend la page Web convoitée, transmet cet identificateur et ce mot de passe, et, si cela correspond à ce qui est dans la base, le serveur lui donne accès. Et lui renvoie une code 403 (accès interdit) autrement.
Voici un exemple de dialogue. Le client a tenté d'accéder à la
ressource /rapport.html
qui est protégée. Le
serveur répond par le code 401 (authentification nécessaire, cf. RFC 7235, section 3.1) et un défi : « essaie de t'authentifier dans le
royaume Corporate », dans l'en-tête
WWW-Authenticate:
(RFC 7235, section 4.1).
HTTP/1.1 401 Unauthorized Date: Mon, 04 Feb 2014 16:50:53 GMT WWW-Authenticate: Basic realm="Corporate"
Le client doit lui répondre avec un nom et un mot de passe. S'il est un navigateur Web, il demandera probablement interactivement à l'utilisateur
Si le client HTTP est un programme autonome, il
cherchera dans sa configuration (par exemple, avec
curl, ce sera dans le fichier
~/.netrc
ou bien dans l'option
--user
de la ligne de commande). Une fois que le
client HTTP aura nom et mot de passe, il les concatène (avec un
deux-points comme séparateur) et les encode en
Base64 (RFC 4648).
Si le nom d'utilisateur est Aladdin
et le mot de
passe open sesame
, voici un moyen simple, avec le
shell Unix, de calculer la chaîne de caractères
à envoyer :
% echo -n "Aladdin:open sesame" | base64 QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Le client HTTP enverra donc sa requête avec l'en-tête :
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
À noter que l'ancienne norme ne spécifiait pas quel
encodage utiliser pour représenter nom et mot
de passe avant de les passer à Base64. Certains utilisaient
Latin-1, d'autres
UTF-8. C'est déplorable mais il est trop tard
pour changer cela (l'annexe B.3 explique
ce choix), donc notre nouveau RFC ne spécifie pas non plus
d'encodage, c'est un arrangement privé avec le serveur HTTP, sauf si
un encodage a été spécifié dans le défi, avec le paramètre
charset
. Au passage, signalons que la syntaxe
possible pour les noms d'utilisateur est désormais celle du RFC 8265.
Ce paramètre charset
(qui aurait dû se nommer plutôt
accept-charset
car il indique ce que le serveur
attend, pas ce qu'il envoie), n'a qu'une seule valeur autorisée,
UTF-8
. Cette valeur indique que le serveur
s'attend à ce qu'identificateur et mot de passe soient normalisés en
NFC (règles du RFC 5198),
puis encodés en UTF-8.
Prenons un exemple, le nom est test
et le mot
de passe 123£
(le dernier caractère est U+00A3,
qui devient C2 A3 en UTF-8, le terminal utilisé pour l'exemple
ci-dessous est en UTF-8, ce qui tombe bien). On encode la chaîne
test:123£
en Base64 :
% echo -n test:123£ | base64 dGVzdDoxMjPCow==
Et on a donc la valeur à utiliser dans le champ Authorization:
.
Et le royaume, on peut le mettre en Unicode ? Eh bien, ce point est obscur (section 3 de notre RFC) et il faudra attendre une nouvelle mise à jour pour l'éclaircir.
La section 4 de notre RFC parle de sécurité. Elle rappelle que le mot de passe est transmis en clair (Base64 ne protège évidemment pas du tout) et qu'il est donc impératif de transporter la session HTTP dans du TLS (RFC 2818). La solution du RFC 7616 n'a pas ce défaut.
Ce mécanisme « de base » souffre également des faiblesses habituelles des mots de passe. Par exemple, si les utilisateurs peuvent les choisir, ils risquent de prendre des mots faibles (prénom, date de naissance...) ou bien de réutiliser le même mot de passe pour plusieurs services. S'ils ne peuvent pas les choisir, ils auront du mal à les mémoriser et seront donc tentés de les écrire... pas forcément dans un endroit protégé.
Dans tous les cas, que les mots de passe soient choisis par les utilisateurs ou pas, le serveur qui les stocke doit prendre des précautions. Ils ne doivent jamais être stockés en clair sur le serveur, car, si le serveur est piraté, le pirate aurait alors accès à tous les mots de passe, donc beaucoup pourront être utilisables avec d'autres serveurs. Les mots de passe doivent être stockés condensés et salés.
Le mode Basic a été enregistré à l'IANA (section 5 du RFC) dans le registre des mécanismes d'authentification.
Quels sont les changements concrets depuis RFC 2617,
section 2, qui normalisait ce mécanisme avant ? L'annexe A les
décrit : il y a la compatibilité avec le nouveau cadre
d'authentification du RFC 7235, et une meilleure internationalisation avec le
nouveau paramètre charset
.
Première rédaction de cet article le 27 septembre 2015
La consultation gouvernementale sur le « Projet de loi pour une République numérique » est désormais en ligne. Quelques observations personnelles.
La plus importante est évidemment que le gouvernement organise une consultation sur le numérique après que toutes les lois importantes sur le numérique soient passées (et qu'il n'est pas question de les remettre en cause) : LCEN (qui posait le principe de la responsabilité de l'hébergeur, contrairement à ce que prétend son exposé des motifs, et qui imposait la conservation des données sur les activités des internautes), HADOPI (qui organise la défense des intérêts des ayant-trop-de-droits), le décret n° 2015-125 du 5 février 2015 mettant en place la censure administrative, la Loi Renseignement (le Patriot Act hexagonal) qui légalise notamment les fameuses boîtes noires, dispositifs d'espionnage installés dans le réseau... On note qu'il n'y a pas eu de consultation pour les lois présentées par des ministres importants (Cazeneuve ou Macron) mais qu'on en fait une lorsqu'il s'agit d'une loi essentiellement symbolique, portée par une ministre secondaire (Lemaire). On a fortement l'impression qu'une fois tous les grands sujets bouclés, quelqu'un au gouvernement s'est dit « il faudrait quand même laisser quelque chose à Lemaire, quelqu'un a une idée ? »
La provocation la plus claire est l'article sur le secret des correspondances, proposé quelques mois après avoir fait voter, en profitant cyniquement de l'attaque des intégristes contre Charlie Hebdo, la loi Renseignement, qui légalise justement l'écoute massive. Cet article semble avoir été écrit pour proclamer haut et fort « votre avis n'a aucune importance ». Bref, comme le note Jef Mathiot, cette loi aurait dû être baptisée « Loi Miettes » car c'est tout ce qui reste.
Pour participer à la consultation, il faut s'inscrire en ligne. Le site me propose de m'authentifier avec des fournisseurs d'identité, Facebook ou Google ou avec un compte créé localement sur le site (ce que j'ai fait). Les protocoles d'identification ouverts comme OpenID ne sont pas présents. On est loin de ce qui se fait en République tchèque. On apprécie ici l'hypocrisie qui prétend réguler « les plate-formes » (terme des ministères français pour désigner les GAFA, Google, Amazon, Facebook et Apple) alors qu'on encourage leur usage ! (Sans compter les mouchards Google Analytics dans le site Web.)
Une fois inscrit, je note qu'on peut voter sur tout, sauf sur les modalités de la consultation elle-même. Par exemple, aucun endroit pour discuter du fait que les arguments qu'on écrit doivent forcément être étiquetés Pour ou Contre le texte. Cela interdit, par exemple, de poser une question pour éclaircir un point. Ou tout simplement d'exprimer une position complexe. Cette consultation ressemble en effet pas mal à un plébiscite : soit on met un argument Pour et on est alors classé comme soutenant le gouvernement, soit on met un argument Contre et on risque alors de mettre en péril les progrès très modestes du projet de loi. Par exemple, dans l'article sur l'accès aux publications de la recherche publique, il est proposé de permettre cet accès après douze mois. Si c'est un progrès par rapport aux exigences exorbitantes des ayant-tous-les-droits (comme Elsevier) qui font actuellement la pluie et le beau temps au parlement et au gouvernement, c'est néanmoins très en retrait par rapport au respect de la volonté de l'auteur (qui devrait avoir le droit de rendre publics immédiatement ses propres articles !) et par rapport au bon sens (s'agissant de recherches financées sur fonds publics). Je n'ai donc pas envie de mettre un argument Pour ou Contre. « Progrès mais très insuffisant » serait une étiquette plus adaptée.
Parmi les sujets qui ne coûtent pas cher et sont donc souvent
appréciés des ministres en mal de présence dans les médias, on
trouve la défense de la langue française. Ici, elle a été oubliée
et le nom de domaine est mal orthographié :
republique-numerique.fr
au lieu du correct
république-numérique.fr
qui a, comme
d'habitude été
enregistré par un internaute profitant de cette
négligence. Cela a logiquement mené à des confusions, comme un
article du Parisien qui suggérait aux
internautes d'aller en
, bonne
orthographe mais mauvais site.http://république-numérique.fr/
Dans la série « souveraineté numérique », slogan souvent brandi dans les cercles gouvernementaux, on note que le site est hébergé par l'états-unien CloudFlare (qui a les serveurs DNS et le frontal HTTP, et signe le certificat). Les adresses IP utilisées sont donc celles de CloudFlare, attribuées par LACNIC à la filiale de CloudFlare au Costa Rica... Quant au courrier de confirmation de l'inscription, il est envoyé depuis la Georgie.
Je regrette aussi que certains articles n'aient pas été soigneusement relus. Par exemple, celui sur le domaine public affirme « [il existe] des pratiques abusives [qui] consistent à revendiquer des droits sur des choses qui appartiennent au domaine public. Par exemple : dans le domaine logiciel, certains codes sources libres sont réappropriés par des entreprises sans être repartagés avec la communauté. », confondant ainsi domaine public et logiciels libres (certaines licences libres permettent tout à fait de ne pas repartager). Cette confusion est classique, mais gênante dans un texte gouvernemental. Même chose pour l'affirmation incroyable comme quoi téléphone et SMS ne sont pas écoutés (dans l'article 22), affirmation qui sent très fort son protectionnisme franco-français (nos techniques à nous sont sûres, contrairement à l'Internet des méchants américains).
Pour finir, voici la liste des amendements sérieux proposés qui me paraissent mériter qu'on les soutienne (et n'ont donc aucune chance d'être repris par Lemaire et Valls) :
Ne vous émeuvez pas du message « Une erreur est survenue, veuillez réessayer », ce message est apparemment une erreur et n'empêche pas le vote d'être pris en compte.
Mon article a été repris sur Rue89. Parmi les nombreux articles publiés sur cette consultation, je vous recommande celui d'Antoine Amarilli.
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : P. Saint-Andre (&yet), D. York (Internet Society)
Pour information
Première rédaction de cet article le 27 septembre 2015
Pendant les réunions physiques de l'IETF, il y a divers moyens de suivre la réunion en n'étant pas présent sur les lieux. Entre autres, il y a une pièce XMPP (protocole autrefois nommé Jabber, ce dernier nom restant très répandu) qui permet de poser des questions et de discuter. Une personne dont le rôle est important est le scribe : il ou elle est sur place et son travail est de relayer les remarques et commentaires dans les deux sens, par exemple en allant au micro lire les questions des participants distants.
Ce RFC décrit le travail de ce scribe, qu'on nomme en général en anglais le « Jabber scribe ». Le protocole XMPP (ex-Jabber) est décrit dans le RFC 6120 et le concept de pièces où peuvent être présents plusieurs utilisateurs est dans le XEP-0045. Le rôle du scribe nécessite surtout des compétences humaines (nul besoin d'être un expert XMPP, d'ailleurs l'IETF pourrait utiliser d'autres technologies de messagerie instantanée, cela ne changerait pas grand'chose à son travail).
Les autres techniques utilisées pour permettre aux participants éloignés de suivre (comme Meetecho) sont en général unidirectionnelles. La pièce XMPP est souvent le seul endroit où ces participants peuvent être actifs et pas seulement regarder et écouter. D'où l'importance du rôle du « scribe Jabber ». Il est présent dans les différentes sessions d'une réunion IETF, notamment lors des réunions des groupes de travail, et c'est une ou un volontaire, personne n'est payé et désigné pour être scribe Jabber. Ce RFC décrit cette activité, les qualités nécessaires et comment faire pour être un bon scribe.
Premièrement, le bon scribe doit connaitre son public, les gens pour qui elle ou il travaille (section 2 du RFC). Il y en a trois catégories :
Cette dernière catégorie peut dans certains cas représenter la totalité des gens présents dans la pièce XMPP. Le scribe peut donc demander s'il y a des participants non physiquement présents. Si ce n'est pas le cas, son travail est simplifié puisque tout le monde peut suivre en direct et parler au micro soi-même.
Dans la pièce XMPP, les gens ont uniquement leur identificateur XMPP qui n'est pas forcément leur nom légal. Le scribe qui doit relayer les questions au micro peut leur demander de préciser quel est le nom à annoncer. Si le participant distant veut rester anonyme, il doit le dire explicitement (les présidents du groupe de travail peuvent refuser qu'il y ait des commentaires anonymes, pour des raisons qui sont entre autres liées aux RFC sur la propriété intellectuelle, cf. RFC 8179).
Le scribe Jabber doit aussi se connaitre lui-même (section 3 du RFC). Tout le monde n'est pas un roi de la dactylographie, tout le monde ne parle pas anglais couramment (et on en entend des accents différents dans les réunions IETF) et on n'exige pas du volontaire qu'il soit un professionnel capable de transcrire en temps réel l'intégralité des débats. Si vous êtes volontaire, ajustez donc votre style de scribe à vos capacités.
Les tâches du scribe sont (section 4 du RFC) avant tout de relayer les messages des participants distants. On n'attend pas du scribe qu'il transcrive toute la session sans erreurs sur le canal XMPP. La plupart des scribes se contentent de donner quelques repères (« Joe en est maintenant à la planche 8, sur les problèmes d'implémentation du protocole », « Daneesh demande comment ont été trouvés les paramètres numériques proposés »). Les tâches importantes sont :
Traditionnellement, le scribe a priorité pour l'accès au micro. C'est notamment utile pour éviter d'aggraver le délai avec lequel les participants distants reçoivent le flux audio et tapent leur contribution.
Il y a aussi d'autres tâches du scribe, moins cruciales (section 5) :
Certains scribes vont jusqu'à résumer l'essentiel des exposés et des interventions sur la pièce XMPP mais ce n'est pas obligatoire.
La section 6 fournit un certain nombre de conseils aux scribes
potentiels, pour qu'ils puissent s'améliorer. D'abord, évidemment,
il faut apprendre XMPP et le service XMPP/Jabber de
l'IETF. Il faut ensuite, si ce n'est pas déjà fait,
installer un client XMPP (une bonne liste est en
ligne) et apprendre à s'en servir. Le serveur XMPP de
l'IETF ne permet pas la création de
compte : il faut avoir un compte existant chez un des innombrables
fournisseurs XMPP (comme celui
de la Quadrature du Net mais il en existe plein d'autres, XMPP
n'étant pas un système centralisé). Vous
pouvez tester la connexion aux pièces IETF, même en dehors des
réunions, en se connectant à la pièce de bavardage et de test
hallway@jabber.ietf.org
.
Une fois prêt, le scribe devrait, avant la session, se coordonner avec les présidents de session, apprendre les dernières nouvelles, s'assurer qu'il y a bien une retransmission etc. Il faut aussi vérifier si ces présidents ont des desiderata particuliers pour le scribe, s'ils sont bien d'accord pour que le scribe ne fasse pas la queue pour s'emparer du micro, etc.
Le scribe doit ensuite s'asseoir près du micro. Même si lui ne
s'en sert pas, cela lui permettra de voir les badges des
intervenants et donc de lire leur nom (ce qui limiterait les
innombrables rappels « state your name, please »). Ensuite, il ou elle doit se
connecter en XMPP à
NOM-DE-LA-SESSION@jabber.ietf.org
. Il est
recommandé d'avoir également un navigateur Web ouvert, avec
plusieurs onglets, affichant l'agenda de la session, la liste des
liens vers les documents présentés en session, la page décrivant
la retransmission, etc.
Une fois que la session a démarré, le scribe doit :
MIC
si on
veut les voir relayées au micro,Et, à la fin de la session, le scribe met un message clair dans la pièce, indiquant bien que c'est fini et que cela ne sert plus d'envoyer des commentaires.
Le scribe ultra-pro peut bénéficier des conseils de la section 7, qui donne quelques trucs avancés mais utiles. Par exemple, il est intéressant d'avoir deux clients XMPP, connectés à des comptes sur des services différents, pour faire face à certaines pannes ou délais dans le réseau (expérience vécue par les auteurs du RFC). Si le scribe est fana de métrologie, il peut aussi mesurer le délai en écoutant lui-même le flux audio de retransmission, ou en travaillant avec un participant distant de confiance, de manière à communiquer sur la pièce XMPP une estimation de ce délai.
Tout ça, c'était pour quand tout va bien. Mais, dans le monde réel, il y a parfois des gens qui abusent, surtout dans la chaleur d'une vive discussion (IDN, par exemple...). Comment les gérer (section 8) ? Le scribe n'est pas censé tout relayer. Si un participant distant écrit dans la pièce XMPP « MIC: ce connard ne connait rien à la technique et devrait fermer sa gueule », le scribe n'est nullement obligé de répéter ce commentaire verbatim au micro. La meilleure solution est sans doute de demander à l'excité de refaire son commentaire de manière plus constructive.
Ceci dit, le scribe n'a aucune autorité ou pouvoir particulier. Il ou elle est juste un participant IETF parmi les autres. Cela veut dire qu'il n'est pas obligé de faire la police, c'est le rôle des présidents de session.
Retour aux problèmes techniques dans la section 9, qui rappelle les adresses de courrier électronique à utiliser pour signaler les ennuis (de WiFi, par exemple).
Dans le monde moderne, difficile d'échapper aux problèmes posés par l'appropriation intellectuelle. La section 10, consacrée aux IPR (Intellectual Property Rights) rassure le scribe : il n'est qu'un simple relais et les obligations IETF liées à ces IPR (RFC 5378 et RFC 8179) ne le concernent pas. Ce n'est pas lui le contributeur mais la personne dont il relaie le commentaire.
Enfin, la traditionnelle section sur la sécurité (ici, section 11), clôt ce RFC. À part l'hypothèse, théoriquement possible mais qui semble assez lointaine, d'une attaque DoS contre les serveurs XMPP pour empêcher le scribe de faire son travail, cette section note que l'IETF n'a pas actuellement déployé les mécanismes d'enregistrement des utilisateurs dans ses pièces XMPP et qu'il ne faut donc pas se fier aux noms annoncés. Si quelqu'un se prétend Jari Arkko (l'actuel président de l'IETF), rien ne prouve qu'il dit vrai. « Sur XMPP, personne ne sait que vous êtes un chien. »
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : P. Ebersman
(Comcast), C. Griffiths, W. Kumari
(Google), J. Livingood
(Comcast), R. Weber (Nominum)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 25 septembre 2015
Comme toutes les techniques de sécurité, DNSSEC, qui vise à assurer l'authenticité des réponses DNS, a ses inconvénients. De même qu'une serrure fermée à clé peut avoir pour conséquence de vous empêcher de rentrer chez vous, si vous avez oublié la clé, de même DNSSEC peut empêcher d'accéder à un domaine si le gérant de la zone a commis une erreur technique. Autant le DNS d'avant était très tolérant (il fallait vraiment insister pour « planter » une zone), autant DNSSEC est délicat : les erreurs ne pardonnent pas, puisque le but de DNSSEC est justement d'empêcher l'accès aux données si elles sont suspectes. Mais les outils et les compétences pour gérer DNSSEC ne sont pas encore parfaitement au point et ne sont pas utilisés partout. Il y a donc de temps en temps des plantages, qui ont pour conséquence la panne d'une zone DNS entière. Face à ce problème, les gérants des résolveurs DNS validants aimeraient bien temporairement suspendre les vérifications, après avoir vérifié qu'il s'agissait bien d'un problème et pas d'une attaque. Cette suspension temporaire et limitée se nomme NTA pour Negative Trust Anchor et est décrite dans ce RFC.
DNSSEC est normalisé dans les RFC 4033, RFC 4034 et RFC 4035. Il permet de valider des enregistrements DNS en les signant. Plusieurs points peuvent invalider accidentellement la signature. Par exemple, les signatures ont une durée de validité limitée (pour éviter les attaques par rejeu) : si le dispositif de re-signature périodique a une panne, les signatures expirent et la zone devient invalide. Ce genre de problèmes a été très fréquent au début du déploiement de DNSSEC et n'a pas complètement disparu. Lorsque cela frappe un domaine important, cela se remarque. (Rappel : toutes les techniques de sécurité ont ce genre de problème. Qu'on pense par exemple aux innombrables expirations de certificats X.509.)
Mettez-vous deux secondes à la place du responsable des
serveurs DNS récursifs (les résolveurs) d'un
gros FAI, ayant beaucoup de
clients. Comcast, par exemple, puisque cette
entreprise a beaucoup plaidé en faveur de ce nouveau RFC. L'administrateur d'un
domaine important, mettons nasa.gov
, a cafouillé, la zone est invalide. Mais seuls
les résolveurs validants (ceux qui protègent leurs utilisateurs
avec DNSSEC) voient cela. Les autres, les anciens résolveurs non
sécurisés, ne testent pas DNSSEC et la zone, pour eux, marche
normalement. Les utilisateurs des FAI qui n'ont pas déployé DNSSEC
pourront donc accéder aux ressources de la zone en panne, mais pas
les vôtres. Ils téléphonent au support en masse, et, sur les
réseaux sociaux, disent
« Comcast a bloqué l'accès à
nasa.gov
» (oui, c'est un cas
réel et qui a été souvent
mal présenté dans les forums publics). Le résultat de cette mauvaise interprétation par les
utilisateurs risque d'être un recul de DNSSEC : les gérants de
résolveurs DNS pourraient se dire « si les mesures de sécurité
embêtent les utilisateurs, coupons les mesures de sécurité ».
La « solution » proposée dans ce RFC, la NTA (Negative
Trust Anchor, ou « débrayage explicite de la
validation ») est une option de configuration du résolveur qui dit
« ne valide pas ces domaines, je sais qu'ils sont cassés, ce
n'est pas une attaque ». Chaque gérant de résolveur devra donc
prendre la décision unilatérale de configurer ou pas ces NTA. Il
n'est pas prévu de protocole pour les distribuer. Les NTA sont un
comportement, pas un objet sur le réseau. Il n'y a pas, par
exemple, d'enregistrement DNS NTA
.
Au passage, s'il y a des negative trust anchor, c'est qu'il en existe des positive, non ? Le concept de « point de départ de la confiance » (trust anchor) est décrit dans le RFC 5914. Le résolveur validant vérifie une zone à partir de sa parente, la parente à partir de la grand-parente et... Il faut bien un endroit où ancrer la vérification : c'est la trust anchor, en général la clé de la racine du DNS, qui sert récursivement à valider toutes les autres. Au contraire, la NTA arrête la validation et dit « tout ce qui est en dessous n'est pas vérifié ».
La section 1.2 de notre RFC décrit plus en détail les motivations pour le concept de NTA. En effet, l'idée de base est surprenante : on dépense beaucoup d'efforts et d'argent pour déployer DNSSEC, afin de vérifier les données DNS, puis on fournit un mécanisme qui permet de débrayer la validation. L'idée a en effet suscité beaucoup de remous à l'IETF et de longues discussions. Comme souvent, le débat opposait, non pas tant les pro contre les anti, que ceux qui disaient « cela existe dans la nature, il vaut mieux le documenter » à ceux qui affirmaient « en le documentant, on le légitimise ». Les premiers l'ont finalement emporté, d'où ce RFC 7646. Les raisons sont documentées dans cette section 1.2.
Aujourd'hui, où bien des administrateurs système sont encore débutants en DNSSEC, la majorité des problèmes de validation sont dus à des erreurs de l'administrateur, pas à une vraie attaque (notez que c'est sans doute également le cas en HTTPS...) Bien sûr, les administrateurs en question devraient lire le RFC 6781, et notamment sa section 4.2. Ils éviteraient ainsi bien des malheurs. Mais, en attendant, il est pratique d'avoir un moyen pour ignorer leurs erreurs. C'est l'un des buts des NTA.
Deuxième motivation, le problème de l'utilisateur. Le DNS est
une technologie d'infrastructure. Il n'est pas visible à
l'utilisateur final et les problèmes au niveau DNS ne peuvent donc
pas être analysés par M. Toutlemonde. C'est délibéré : tout le
rôle du DNS est justement d'isoler ce M. Toutlemonde de détails
pratiques, comme le fait que seenthis.net
a
changé d'adresse IP. Il est donc cohérent avec ce rôle que
l'utilisateur final ne soit pas informé qu'il y a un problème
DNSSEC. Il ne peut donc pas savoir ce qui l'empêche d'aller sur
son site Web favori et, dans son ignorance, il risque de ne pas
attribuer les responsabilités correctement. Comme dans l'exemple
plus haut, il pourrait dire « c'est la faute de mon
FAI » au lieu de pointer du doigt, à juste
titre, l'administrateur de la zone mal signée. Comme dans
l'exemple Comcast/NASA cité plus haut, si un domaine
important est signé, et fait une erreur déclenchant un problème
DNSSEC, on risque de voir vite apparaitre des gazouillis désobligeants contre le FAI,
qui n'y est pourtant pour rien. Cela risque de mener la direction
du FAI à ordonner qu'on arrête de valider avec DNSSEC. « Le bruit
de l'alarme dérange les utilisateurs : coupez l'alarme. » Mettre
une NTA pour le domaine critique en question serait certes un recul
de la sécurité, mais qui pourrait éviter des reculs encore
pires. (C'est compliqué, la politique de sécurité.)
Cette décision stupide pourrait aussi être prise par
l'utilisateur, qui passerait d'un résolveur validant à un
résolveur non validant. Sur les réseaux sociaux, les conseils
idiots se propagent plus vite que les bons, surtout en matière de sécurité « zyva, mets
192.0.2.1
comme résolveur et ça va
marcher ». La NTA vise à ralentir cette fuite.
La section 2 de notre RFC décrit la bonne façon d'utiliser les NTA. D'abord, avant d'installer une Negative Trust Anchor, il faut une vérification manuelle, faite par un technicien compétent, de la situation (cf. section 7 sur les tests techniques). Est-ce bien une erreur de la part du gestionnaire de la zone ? On peut s'en assurer en testant la zone depuis différents points (en comptant qu'ils n'ont probablement pas tous été victimes d'une attaque par empoisonnement en même temps) ou tout simplement en prenant connaissance d'une annonce officielle du gestionnaire de la zone, s'il y en a une. Prendre contact avec le gestionnaire de la zone permettra aussi de s'assurer que le problème est bien involontaire (cf. section 6). En tout cas, il ne faut pas installer aveuglément une NTA à chaque fois qu'une validation DNSSEC échoue : cela annulerait complètement l'intérêt de DNSSEC. D'accord, une telle vérification par un humain coûte cher mais il n'y a pas non plus de problème de ce genre tous les mois, ou même tous les trimestres.
Lors de la discussion avec le gérant de la zone,
l'administrateur du résolveur qui hésite à installer une NTA peut
communiquer à son interlocuteur les enregistrements DNS qu'il voit
(obtenus avec dig +cd
, pour ignorer la
validation), afin de pouvoir s'assurer que ces enregistrements
sont bons, qu'il ne s'agit pas d'une attaque. Bien sûr, il faut
être pragmatique : si un gros TLD a planté
son DNSSEC, rendant ainsi de nombreuses zones invalides, et que
ses employés ne répondent pas, il peut être raisonnable de placer
unilatéralement la NTA, compte-tenu de l'urgence.
Les NTA sont censées être une mesure sale et temporaire. Il est donc important de faire en sorte qu'elles ne restent pas éternellement, par exemple en indiquant clairement la date dans le fichier de configuration ou dans le journal.
Comme la NTA est une action « anormale » (on ignore une alerte de sécurité), le RFC recommande d'informer clairement les utilisateurs du résolveur comme l'a fait Comcast. C'est d'autant plus important que les utilisateurs n'ont pas d'autre moyen de savoir qu'une NTA est en place (le protocole DNS ne fournit pas de mécanisme pour cela).
Mettre une NTA, c'est facile. Mais il ne faut pas la laisser
éternellement, sinon cette zone n'est plus protégée par DNSSEC !
Le RFC demande donc (section 4) que les NTA soient, par défaut, supprimées
automatiquement, par exemple au bout d'une semaine (si c'est
vraiment une panne, elle ne dure jamais plus longtemps que
quelques jours). Idéalement, il
faudrait tester régulièrement la validité du domaine, et retirer
la NTA s'il redevient valide. À cause de ces recommandations, une
gestion entièrement manuelle des NTA, comme dans l'exemple
ci-dessous avec la directive domain-insecure:
d'Unbound, n'est pas forcément à recommander.
Et, évidemment, une fois la NTA retirée, il faut vider les caches DNS pour la zone.
La NTA revient à prendre une décision sur la gestion d'une zone alors qu'on n'est pas le gérant de la zone. Cela doit donc rester exceptionnel. Le problème, et la solution décrite dans ce RFC, sont très spécifiques à DNSSEC, ou plus exactement à son état actuel. La section 5 de notre RFC dit clairement qu'il ne faut pas envisager de telles solutions pour d'autres problèmes. Si un gérant de zone maladroit a mis le mauvais MX dans la zone, il ne faut pas « corriger » dans les résolveurs. Le principe du DNS doit rester que le gérant de la zone fait autorité sur le contenu de la zone.
Certaines zones, comme servfail.nl
cité
plus loin dans un exemple, ou comme
dnssec-failed.org
sont cassées exprès. Leur
but est de permettre de tester les outils de diagnostic ou de
mesurer
le nombre de validateurs. Cette mesure se
fait typiquement en incluant dans une page Web un objet (une
image, par exemple) accessible via un nom de domaine ainsi
invalide. Si le chargement de l'objet se fait, c'est que le
navigateur Web n'utilisait pas de résolveur validant.
Il ne faut évidemment pas mettre de NTA sur ces domaines
volontairement invalides (section 6 de notre RFC). J'utilise
servfail.nl
ci-dessous mais c'est juste un
exemple.
On a dit plus haut qu'une NTA ne devait être ajouté qu'après
qu'un technicien DNS ait évalué l'état de la zone et déterminé que
c'était bien un accident. Pour l'aider à faire cette évaluation, il existe
plusieurs outils. Par exemple, l'histoire compte : si
l'enregistrement de type AAAA de
example.net
est invalide, mais qu'il vaut
2001:db8:67::ab
et qu'il a cette valeur
depuis deux ans, on peut être raisonnablement sûr que c'était une
erreur DNSSEC et pas une attaque. Comment sait-on que la valeur
n'a pas changé depuis deux ans ? On peut utiliser une base de
passive DNS comme DNSDB. Un autre outil historique important
est DNSviz, qui stocke le
résultat des tests DNSSEC précédents (un domaine populaire a forcément
été testé plusieurs fois).
Notre RFC liste plusieurs outils de débogage qui permettent d'analyser l'état actuel de la zone :
Les deux premiers sont des logiciels libres et peuvent être installés
localement sur votre machine. (Une analyse du cas de
nasa.gov
a été faite
avec ces outils.)
En effet, dans certains cas, le résultat peut dépendre de
l'endroit où vous vous trouvez. Par exemple, certaines instances
d'un nuage anycast peuvent servir des
signatures expirées et d'autres pas. Il est donc utile d'avoir
accès à des résolveurs DNSSEC distants. On peut utiliser les sondes Atlas, ou se
connecter à des serveurs distants pour y lancer
dig. Si tous les résolveurs validants de la
planète voient SERVFAIL
, il est beaucoup plus
probable qu'on soit confronté à une erreur dans la gestion de la
zone qu'à une attaque par
empoisonnement.
Le RFC liste aussi, dans cette section 7, les causes les plus fréquentes de problème DNSSEC aujourd'hui :
Enfin, la section 8 de notre RFC couvre plusieurs points de sécurité qui n'étaient pas évidents. Politiquement, la NTA est une prise du pouvoir par le résolveur, qui se permet de contrarier les résultats. C'est un mal nécessaire mais, quand même, il faut être conscient de ce décalage des responsabilités. D'où l'importance d'informer le gérant de la zone signée et de discuter avec lui/elle.
Autre problème, la NTA transforme une zone signée en zone non signée. Cela évite les erreurs de validation mais cela pose un problème pour toutes les applications qui vérifient que le contenu des données est valide (par exemple lorsqu'on lit des clés cryptographiques dans le DNS). Cette vérification se fait typiquement en regardant le bit AD (Authentic Data) dans la réponse DNS. S'il est absent, c'est que la zone n'est pas signée, et les applications risquent alors d'ignorer les informations qu'elles ont trouvées dans le DNS, faute de validation positive. C'est par exemple un problème pour DANE (RFC 6698) : si une NTA est placée, les certificats mis par DANE seront tout à coup ignorés, ce qui pourra couper l'accès à certains serveurs TLS. Le RFC estime que les applications feront de plus en plus leur propre validation, ce qui diminuera le problème, mais ce pronostic me parait très contestable.
L'annexe A du RFC contient plein d'exemples de gestion des NTA sur différents logiciels. Je vais commencer par une méthode non décrite dans le RFC, avec Unbound. Voyons d'abord un domaine invalide avec une requête normale :
% dig A www.servfail.nl ; <<>> DiG 9.9.5-9+deb8u3-Debian <<>> A www.servfail.nl ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 26269 ...
On récupère un SERVFAIL
(Server
Failure) ce qui est normal puisque ce domaine est
(délibérement) invalide. Essayons avec l'option
+cd
(Checking Disabled) qui
indique au résolveur de ne pas valider :
% dig +cd A www.servfail.nl ; <<>> DiG 9.9.5-9+deb8u3-Debian <<>> +cd A www.servfail.nl ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53947 ;; flags: qr rd ra cd; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;www.servfail.nl. IN A ;; ANSWER SECTION: www.servfail.nl. 60 IN CNAME www.forfun.net. ...
Maintenant, modifions la configuration d'Unbound en ajoutant dans le
unbound.conf
la Negative Trust Anchor :
# Added on 2015-09-22, after confirmation from <foobar@forfun.net> domain-insecure: "servfail.nl"
Notez l'importance de mettre la date dans le fichier de configuration : les NTA ne doivent pas être permanentes. On recharge la configuration :
% sudo unbound-control reload ok
Et on réessaie :
% dig A www.servfail.nl ; <<>> DiG 9.9.5-9+deb8u3-Debian <<>> A www.servfail.nl ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62157 ;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 4, ADDITIONAL: 13 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;www.servfail.nl. IN A ;; ANSWER SECTION: www.servfail.nl. 60 IN CNAME www.forfun.net.
Notez qu'on a eu la réponse mais que le bit AD (Authentic Data) n'est évidemment pas mis, comme discuté en section 8 du RFC.
Cette méthode a l'inconvénient d'être un peu trop manuelle et de ne pas être automatiquement réversible. À noter que l'annexe A du RFC cite également une méthode qui ne nécessite pas de changer le fichier de configuration, mais utilise l'outil de contrôle à distance d'Unbound (qu'il faut configurer préalablement) :
[Quels NTA sont installées ? ] % sudo unbound-control list_insecure % [Aucun] [On installe une NTA] % sudo unbound-control insecure_add servfail.nl ok % sudo unbound-control list_insecure servfail.nl. % dig A www.servfail.nl ... www.servfail.nl. 60 IN CNAME www.forfun.net. ... [On retire la NTA] % sudo unbound-control insecure_remove servfail.nl ok % sudo unbound-control list_insecure %
BIND n'a pas d'équivalent de la directive
domain-insecure:
. C'est une de ses faiblesses. Mais il permet, à partir des récentes versions
(non encore publiques, apparemment réservées aux clients payants), d'avoir des NTA plus conformes à ce que demande le RFC,
notamment avec retrait automatique au bout d'un temps donné. Je n'ai
pas testé donc voici les commandes que donne le RFC :
[Quels NTA sont installées ? ] % sudo rndc nta -dump [On installe une NTA pour une heure - la valeur par défaut] % sudo rndc nta servfail.nl [On retire explicitement la NTA (sinon, il est retiré automatiquement)] % sudo rndc nta -remove servfail.nl
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : P. Eardley (BT), A. Morton (AT&T Labs), M. Bagnulo (UC3M), T. Burbridge (BT), P. Aitken (Brocade), A. Akhter (Consultant)
Pour information
Réalisé dans le cadre du groupe de travail IETF lmap
Première rédaction de cet article le 21 septembre 2015
Le groupe de travail LMAP de l'IETF travaille sur les mesures des performances des accès Internet « haut débit ». Des mesures comme celles que fait l'ARCEP en France. Ce RFC définit le cadre conceptuel de ces mesures et leur terminologie.
Donc, d'abord, les généralités (section 1 du RFC). On veut mesurer la qualité du réseau depuis un grand nombre de points de mesure. Sur chacun de ces points se trouve un MA (Measurement Agent, au passage, le vocabulaire spécifique de LMAP est en section 3 du RFC) qui peut être matériel (sondes de l'ARCEP, sondes RIPE Atlas, sondes Sam Knows, etc) ou logiciel (Grenouille, etc). Le matériel peut être un boîtier séparé ou bien être un composant dans un engin comme la box. Le but de LMAP est de travailler sur des mesures à grande échelle, avec des milliers, voire des millions de MA. À qui cela va-t-il servir ?
Ces buts sont décrits plus en détail dans le RFC 7536.
Outre les MA (Measurement Agents, installés chez
M. Michu ou dans un point de mesure dédié, et qui exécutent les mesures), le système comprend les
contrôleurs et les
collecteurs. Le contrôleur est celui qui dit aux
MA quelles mesures faire. Dans le cas de RIPE
Atlas, le contrôleur est une machine au
RIPE-NCC qui reçoit les demandes de mesures
faites, par exemple, via l'API, et
les transmet aux Atlas « pingue donc 192.0.2.34 avec un paquet ICMP
ECHO
par
minute pendant dix minutes ». Le collecteur reçoit les résultats de
ces mesures (« premier essai, RTT de 18 ms,
deuxième essai time out, troisième essai, RTT de 23
ms... ») et les analyse et/ou les rend disponibles. Le collecteur doit
donc gérer une belle base de donnéees (big
data) avec un mécanisme d'accès aux données,
comme SQL. Le
protocole de communication entre le contrôleur
et les MA se nomme le protocole de contrôle et celui entre les MA et
le collecteur le protocole de collecte (report
protocol). Certains systèmes (c'est le cas des Atlas) ne
font pas de différence entre contrôleur et collecteur (et donc
n'utilisent qu'un seul protocole pour le contrôle et la collecte).
On souhaite évidemment que l'ensemble du système :
La section 2 du RFC décrit à gros grains à quoi pourrait ressembler le système idéal. Le MA doit faire des mesures. Celles-ci peuvent être passives (le MA observe le trafic existant, sans interférer) ou actives (le MA envoie des paquets et observe leur effet). Notez que la plupart des systèmes existants sont purement actifs (une collecte passive soulève d'intéressants problèmes de vie privée...) mais que LMAP traite les deux cas.
Pour que les mesures soient anaysables et comparables, il vaut mieux qu'elles se réfèrent à des métriques standards et documentées (ce qui est rare, par exemple les mesures de l'ARCEP ne s'appuient pas sur les normes existantes, réinventant ainsi la roue).
Les canaux de communication (entre le MA et le contrôleur, ainsi qu'entre le MA et le collecteur) doivent évidemment être sécurisés, pour se prémunir contre des attaques comme celle d'un faux contrôleur qui essaierait d'utiliser les MA à son profit.
À noter que la configuration initiale du MA (par exemple, le nom de domaine pour contacter le contrôleur) n'est pas normalisée. Le MA peut arriver pré-configuré (c'est le cas des sondes RIPE Atlas) ou bien être configuré par un des protocoles existants comme NETCONF ou CWMP.
La section 4 de notre RFC est consacrée aux limites de LMAP. Le projet est assez ambitieux comme cela, il va donc se donner quelques restrictions (d'autres sont données en section 5.6) :
La section 5 du RFC décrit de manière abstraite le modèle des protocoles à élaborer. On y trouve notamment la liste des fonctions à mettre en œuvre comme par exemple un mécanisme de suppression des données si on découvre que certaines mesures étaient erronées (par exemple parce que l'amer visé n'était pas joignable à ce moment).
Mais les informaticiens préféreront peut-être lire la section 6, plus concrète, qui décrit les questions pratiques de mise en œuvre et de déploiement. Par exemple, que doit faire un MA qui redémarre après un long arrêt ? Les instructions du contrôleur qu'il avait reçues et stockées peuvent être dépassées. Il doit donc tenter de re-contacter le contrôleur avant de se lancer dans les mesures.
Autre exemple de discussion pratique, la section 6.2 étudie les différentes formes de MA, et l'endroit où les placer, chaque forme et chaque endroit ayant ses avantages et ses inconvénients. Ainsi, un MA embarqué dans la box du FAI aurait des avantages (il voit tout le trafic, donc les mesures passives sont triviales à effectuer et toujours exactes, et les mesures actives peuvent être faites uniquement lorsque le trafic utilisateur est faible, alors qu'une sonde séparée risque de faire ses mesures au moment où on utilise la ligne à fond) et des inconvénients (dans le modèle classique des box imposées, les fonctions de la box ne sont accessibles qu'au FAI, pas au régulateur ou à l'utilisateur).
Et si le MA est (malheureusement pour lui) coincé derrière un NAT ? La principale conséquence est que le contrôleur ne pourra pas le joindre à volonté, ce sera au MA de le contacter. Une autre solution est de mettre un client PCP (RFC 6887) dans le MA.
Autre cas intéressant à considérer, celui où le MA se trouve en plein dans le réseau du FAI, et non plus chez M. Michu. (Le cas est cité dans le RFC 7398.) Cela permet au MA d'être indépendant des lubies du réseau local et de son accès et de faire des mesures dans un environnement plus contrôlé, donc plus scientifiques. Évidemment, ces mesures seront alors moins représentatives du vécu de l'utilisateur.
La section 6 discute aussi le cas où on a besoin d'une aide sur le
réseau. Par exemple, si on pingue
un amer situé sur l'Internet, cet amer
ne peut pas être purement passif. Ce doit être une machine allumée et
qui répond aux paquets ICMP
ECHO
. Une telle aide est nommée MP pour
Measurement Peer. Ce rôle n'est pas évident. Par
exemple, un amer peut tout à coup se mettre à limiter le trafic ICMP car il en a assez d'être
pingué en permanence, faussant alors toutes les mesures. C'est encore
plus vrai si on fait des tests lourds, comme de charger en
HTTP un fichier de grande taille. Si on fait
cela sur une machine qui n'était pas au courant de son rôle de MP, on
peut se retrouver dans les ACL
rapidement. S'il y a un protocole de contrôle explicite avec le MP
(comme ceux des RFC 4656 ou RFC 5357), tout est plus simple, le MA négocie avec le MP le bon
déroulement de la mesure. Sinon, il faut s'assurer d'abord que le MP
est d'accord pour être utilisé. Heureusement, il existe des machines qui sont dédiées à ce
rôle de MP, comme les Ancres.
La section 6.4 décrit un certain nombre de déploiements typiques. Ça peut aller de cas simples (le MA fait du HTTP avec un MP qui est juste un serveur HTTP ordinaire), à des choses plus complexes, où le MP déploie un logiciel spécifique comme iperf.
Un peu de sécurité maintenant (section 7 du RFC). La sécurité de LMAP doit protéger aussi bien le système de mesures, que le réseau mesuré (des mesures actives trop agressives pourraient sérieusement ralentir ce réseau, par exemple, voir la section 6 du RFC 4656). Plusieurs points sont donc à sécuriser. Par exemple, la mise à jour du logiciel du MA doit se faire de manière sécurisée. Imaginez des sondes dont le firmware serait mis à jour en HTTP (pas HTTPS avec vérification du certificat) : un méchant pourrait se glisser sur le trajet, leur envoyer du logiciel malveillant et se constituer ainsi un botnet. Par exemple, si les MA peuvent faire des mesures passives, un tel botnet pourrait servir à faire de la surveillance massive (RFC 7258).
De la même façon, le MA ne doit pas obéir aveuglément à toute machine qui prétend être le contrôleur : il doit l'authentifier, tester l'intégrité des requêtes du contrôleur et empêcher les rejeux, qui pourraient facilement être utilisés pour des attaques par déni de service. La communication entre MA et contrôleur doit également être chiffrée : elle peut révéler des choses à un attaquant. Idem pour la communication du MA avec le collecteur : elle doit être authentifiée (imaginez un faux MA envoyant des mesures mensongères pour fausser une étude comparée sur les différents FAI) et confidentielle (les MA peuvent faire des mesures privées). À noter que, lorsque le MA est situé chez un utilisateur, on ne peut jamais être totalement sûr de son intégrité : il a pu être ouvert et modifié par l'utilisateur. (C'est encore plus vrai pour un MA logiciel.)
LMAP est prévu pour des grands systèmes de mesure. En outre, des malveillants pourraient tenter des attaques par déni de service contre le système de mesure. Notre RFC précise donc également que le collecteur doit se protéger en limitant le nombre de MA qui se connectent à lui simultanément, en limitant le débit d'envoi des données, et la taille totale des données.
Reste la question de la vie privée (section 8), qui fut le gros sujet de discussion au sein du groupe de travail à l'IETF. La vie privée de qui ? Eh bien, on cherche à protéger aussi bien les utilisateurs, que les FAI et les régulateurs. En cas de mesures passives, l'information sur le trafic Internet des utilisateurs est certainement très sensible et on ne veut pas qu'elle soit diffusée partout. Tout MA qui observe le trafic va donc accéder à ces informations qui peuvent menacer la vie privée. (Le RFC note qu'IPFIX a le même problème, cf. section 11.8 du RFC 7011.) Ainsi, même si la sonde Sam Knows ne fait que des mesures actives, a priori moins sensibles, sa documentation recommande de brancher la sonde en coupure du réseau local, de manière à voir passer tout le trafic de l'utilisateur. C'est pour pouvoir ne déclencher les mesures actives que lorsque le trafic utilisateur est faible ou nul. Mais brancher un engin dont on n'a pas le source de manière à ce qu'il puisse voir tout le trafic est assez dérangeant. En outre, quelqu'un qui observerait les communications de la Sam Knows avec son contrôleur, même sans les comprendre, pourrait savoir quand l'utilisateur est en train d'utiliser son réseau : le MA n'a rien à communiquer dans ce cas (section 8.5.1 de notre RFC).
Même en l'absence de mesures passives du trafic, les MA peuvent avoir accès à des informations confidentielles : SSID du WiFi local, adresses MAC repérées lors des requêtes ARP, etc. Certaines informations sont rentrées explicitement par l'utilisateur et peuvent être sensibles : le contrôleur des sondes Atlas connait ainsi la longitude et latitude de la sonde donc la position de la maison (la précision est volontairement réduite lors de la saisie, précisément pour cette raison).
Quand aux données du FAI, qui peuvent être révélées indirectement via les systèmes de mesure, elles sont nombreuses : topologie exacte du réseau, trafic effectif dans les tuyaux, informations commerciales (type d'abonnements souscrits), etc.
Et le régulateur ? Oui, lui aussi a de la vie privée à défendre car il possède des infos confidentielles aussi bien sur les utilisateurs que sur les FAI, et n'a typiquement pas le droit de les diffuser.
Parmi les méchants qui seraient intéressés par cette information, on peut trouver les concurrents (le chiffrement est alors la protection minimale), l'organisation qui fait tourner les mesures (il est donc souhaitable de réduire la confiance qu'il faut lui faire, par exemple en mettant le MA derrière le port d'un commutateur, ce qui le rend difficilement capable de faire des mesures passives), ou bien sûr les organes de surveillance (RFC 6973, notamment section 5.1.1).
Outre le chiffrement des communications entre le MA et ses contrôleurs et collecteurs, solution déjà citée, il va être préférable de minimiser les données récoltées et transmises. Le chiffrement n'est pas une solution parfaite (notamment, il ne protège pas contre l'organisation qui fait fonctionner le collecteur), et il doit être complété par la minimisation, composante cruciale de tout projet de protection de la vie privée (RFC 6973, section 6.1, et notre RFC 7594, section 8.6.1). Les données doivent être agrégées, résumées, réduites à ce qui est strictement nécessaire pour la tâche en cours.
Les organisations qui collectent et traitent des grandes quantités de données essaient souvent de rassurer les utilisateurs en promettant que les données sont « anonymisées ». La section 8.6.2 de notre RFC rappelle que l'anonymisation est très difficile à faire correctement et que les techniques modernes d'analyse de données peuvent souvent dé-anonymiser et donc retrouver les individus dans la masse des données (cf. RFC 6235 et l'étude de Burkhart, M., Schatzmann, D., Trammell, B., et E. Boschi, « The Role of Network Trace anonymisation Under Attack » en 2010).
L'anonymat ne doit pas être réduit au simple pseudonymat, (section 6.1.2 du RFC 6973) où il y a un identificateur stable des activités, même s'il n'est pas relié à une identité du monde extérieur. Dans le vrai anonymat (très difficile à obtenir, malgré les promesses des commerciaux du big data), il n'y a pas de traçabilité.
D'ou la conclusion de cette section, qu'un accord explicite d'un utilisateur informé et conscient est nécessaire, si on fait des mesures chez lui. (Cela peut d'ailleurs être un argument pour des points de mesures créés spécialement pour la mesure, comme dans les tests ARCEP. Il n'y a alors pas de problème de vie privée.)
Première rédaction de cet article le 13 septembre 2015
Dernière mise à jour le 9 mars 2016
J'ai déjà parlé d'Ethereum dans un précédent article, avec une description de ses possibilités. Je suis passé plutôt vite sur la notion de contrat alors qu'elle est essentielle dans Ethereum, et qu'elle est sa principale innovation par rapport à Bitcoin et tous ses dérivés. Je comptais me mettre à l'écriture de contrats mais je manque de temps donc, en attendant que j'apprenne sérieusement, je vais décrire un exemple que je n'ai pas réalisé moi-même mais qui a l'avantage pédagogique d'être assez simple à comprendre et assez compliqué pour faire quelque chose de réel : la Pyramide.
Le nom fait référence à une accusation stupide, mais récurrente, faite contre Bitcoin et ses dérivés, qui seraient soi-disant une pyramide de Ponzi. Mais avant de décrire ce que fait la Pyramide Ethereum, revenons aux contrats.
Un contrat est un programme informatique, stocké sous forme de code pour une machine virtuelle, l'EVM (Ethereum Virtual Machine). Il va s'exécuter sur les machines du réseau qui minent, c'est-à-dire qui vérifient les transactions. Le langage de l'EVM (qu'on appelle parfois, lui aussi, EVM) est un langage de Turing, ce qui, en français, veut dire que tout ce qui peut être programmé dans un autre langage de Turing (C, PHP, Haskell, Go...) peut être programmé pour l'EVM. Un contrat est aussi une entité stockée dans le livre des opérations (la blockchain) et a donc une adresse : on peut lui écrire, plus précisement lui envoyer des ethers (l'unité de compte Ethereum) pour lui faire exécuter son code. (Ethereum n'a pas de code tournant en permanence et n'a pas l'équivalent de cron : il faut explicitement appeler le contrat depuis l'extérieur.)
Les contrats sont stockés sous forme de code de bas niveau mais on les écrit en général dans un langage de plus haut niveau, le plus répandu étant Solidity.
Ces préliminaires étant posés, que fait le contrat « Pyramide » ? Eh bien, il mérite son nom, c'est une vraie pyramide de Ponzi. On envoie un ether (environ un euro au cours actuel) au contrat, et on est ajouté à la pyramide. Quand le niveau où on a été ajouté est plein, un niveau inférieur est ajouté (la pyramide grandit) et on reçoit des ethers. Comme tout bon schéma de Ponzi, cela ne marche que lorsque de nouveaux entrants arrivent en permanence. Quand ils cessent d'affluer, le schéma ne marche plus et les derniers arrivés n'ont plus qu'à pleurer.
Le code écrit en Solidity est disponible en ligne. Les programmeurs familiers avec des langages comme C ou comme JavaScript ne devraient pas avoir trop de mal à le lire. Les points importants :
struct Participant { PayoutType payoutType; bytes desc; address etherAddress; bytes bitcoinAddress; } Participant[] public participants;
Cette variable participants
est
l'état de la pyramide. Les transactions Ethereum
peuvent en effet modifier l'état du système. (Ethereum, comme Bitcoin,
est donc aussi un système de stockage.)
function() { enter(msg.data); }
Cette fonction anonyme est celle qui est appelée lorsque des ethers
sont envoyés au contrat, le « réveillant ». La fonction
enter
, qu'elle appelle, fait l'essentiel du
travail (je l'ai un peu simplifiée ici) :
function enter(bytes desc) { if (msg.value < 1 ether) { msg.sender.send(msg.value); return; } if (desc.length > 16) { msg.sender.send(msg.value); return; } if (msg.value > 1 ether) { msg.sender.send(msg.value - 1 ether); }
Ces trois tests vérifient certaines pré-conditions : que le paiement
était bien de un ether pile, et que le message envoyé par
l'utilisateur (msg.data
) fait bien moins de seize
octets. Si un des deux premiers tests échoue, on est remboursé (attention donc en
testant : vous aurez l'impression que rien ne s'est passé, alors qu'en
fait vous avez été silencieusement remboursé). Si vous envoyez plus
d'un ether, vous serez remboursé du surplus mais le contrat continuera.
uint idx = participants.length; participants.length += 1; participants[idx].desc = desc; // for every three new participants we can // pay out to an earlier participant if (idx != 0 && idx % 3 == 0) { // payout is triple, minus 10 % fee uint amount = 3 ether - 300 finney; participants[payoutIdx].etherAddress.send(amount); payoutIdx += 1; }
Ce code paie (avec intérêts) un ancien participant lorsque de nouveaux participants sont arrivés.
J'ai moi-même envoyé mon ether (sous le nom "Stephane B.") ainsi, depuis la console de geth (cf. mon premier article) :
> eth.sendTransaction({from: eth.accounts[0], value: web3.toWei(1, 'ether'), to: '0x7011f3edc7fa43c81440f9f43a6458174113b162', gas: 500000, data: web3.fromAscii('Stephane B.')})
Ethereum étant transparent, on peut voir sur un explorateur public du
livre des transactions tous les paiements reçus par la pyramide, en
donnant son adresse
(0x7011f3edc7fa43c81440f9f43a6458174113b162
) :
. L'argent
envoyé est bien débité du compte utilisé (https://etherchain.org/account/0x7011f3edc7fa43c81440f9f43a6458174113b162#txreceived
eth.accounts[0]
) :
> eth.getBalance(eth.accounts[0]) 2980411500000000000 [Minage de la transaction] > eth.getBalance(eth.accounts[0]) 1975400100000000000
Et hop, je suis ajouté à la pyramide, en attendant un profit
(quand d'autres gogos viennent, suite à cet article). C'est ainsi que,
deux mois après, j'ai bien
touché mes ethers. De l'argent facilement gagné ! Le code
JavaScript de la page Web du projet affiche
alors la pyramide modifiée. (Le programmeur aurait pu interroger
dynamiquement en JSON-RPC un nœud Ethereum pour
récupérer les données mais, apparemment, cette récupération est faite
entièrement côté serveur et ce code n'est pas publié. Mais vous pouvez
faire pareil. Comment
récupère-t-on des données d'un contrat ? On note (dans le source) que le contrat a des
méthodes publiques comme
getNumberOfParticipants
. Il suffit de créer un
objet JavaScript dans la console ayant la bonne
ABI et l'adresse du contrat. On pourrait faire
l'ABI à la main à partir du source mais c'est plus facile de demander
au compilateur Solidity de le faire :
% solc --json-abi file pyramid.sol
Et l'ABI en JSON est dans le fichier
Pyramid.abi
. Plus qu'à y ajouter un peu de code
Javascript au début et à la fin (déclaration au début et adresse du
contrat à la fin) et on a :
var pyramid = eth.contract( [{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"participants","outputs":[{"name":"payoutType","type":"uint8"},{"name":"desc","type":"bytes"},{"name":"etherAddress","type":"address"},{"name":"bitcoinAddress","type":"bytes"}],"type":"function"},{"constant":false,"inputs":[{"name":"_bitcoinBridge","type":"address"}],"name":"setBitcoinBridge","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"desc","type":"bytes"},{"name":"bitcoinAddress","type":"bytes"}],"name":"enter","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"collectedFees","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"}],"name":"collectFees","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"payoutIdx","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"bitcoinBridge","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"getNumberOfParticipants","outputs":[{"name":"n","type":"uint256"}],"type":"function"},{"inputs":[{"name":"_bitcoinBridge","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"idx","type":"uint256"}],"name":"NewParticipant","type":"event"}] ).at('0x7011f3edc7fa43c81440f9f43a6458174113b162');
On demande à geth de charger tout ça :
> loadScript("load-abi.js"); true
Et on a un objet JavaScript dont on peut appeler les méthodes, récupérant ainsi les données du contrat :
> pyramid { address: "0x7011f3edc7fa43c81440f9f43a6458174113b162", ... getNumberOfParticipants: function(), ... } > pyramid.getNumberOfParticipants() 65
On voit dans cet exemple qu'il est très simple d'écrire un contrat, et de faire donc calculer ses programmes par les machines d'Ethereum.
Le code machine du contrat est également public et visible, à
l'adresse du contrat :
.https://etherchain.org/account/0x7011f3edc7fa43c81440f9f43a6458174113b162#codeDisasm
Première rédaction de cet article le 12 septembre 2015
Je viens de me lancer dans Ethereum et j'ai envie de partager avec vous (partager mon expérience, pas mon argent virtuel, faut pas rêver).
Ethereum est souvent présenté par rapport à Bitcoin : « Bitcoin 2.0 », « the next Bitcoin », « Bitcoin on steroids », etc. Il est vrai qu'il s'inspire très fortement de Bitcoin mais, en le présentant ainsi, on peut le confondre avec tous les autres machins qui ont été faits à partir de Bitcoin comme Dogecoin, Litecoin ou encore Namecoin. À part ce dernier, ces comparaisons peuvent amener à conclure qu'Ethereum n'est qu'« une nouvelle monnaie virtuelle et cryptographique (alt coin) ». Alors qu'il est bien plus que cela.
Ceci dit, c'est vrai que, pour expliquer Ethereum, partir de Bitcoin est pratique. Avant Bitcoin, on considérait que, pour établir et exécuter des contrats (oui, une monnaie est une forme de contrat : je te donne des billets en échange de quelque chose), il n'y avait que deux solutions :
Bitcoin a montré qu'il existait une troisième solution : une structure de données publique, le livre des opérations ou blockchain, que tout le monde peut voir et vérifier. Cette structure liste toutes les transactions et est protégée par la magie de la cryptographie, de façon à ce qu'elle soit validable. C'est le grand mérite de Bitcoin, et l'invention géniale de Satoshi Nakamoto : prouver théoriquement et expérimentalement qu'un système complètement pair à pair pouvait fonctionner, ce qui était loin d'être évident (par exemple, j'étais personnellement persuadé que c'était impossible).
Bitcoin est spécialisé : on ne peut s'en servir que pour la monnaie. Si on veut, par exemple, enregistrer des noms et non pas échanger de l'argent, il faut copier le code de Bitcoin (il est libre), faire des modifications et créer sa propre infrastructure (sa blockchain à soi, ses mineurs, ses explorateurs de blockchain, etc). Ce choix n'est pas un oubli ou une erreur des concepteurs de Bitcoin : c'est parce que faire un système équivalent, mais généraliste, est non trivial, notamment du point de vue de la sécurité.
Ethereum reprend plusieurs concepts importants de Bitcoin, notamment la blockchain et la preuve de travail (il n'est donc pas plus écologiste que Bitcoin). Mais le code est radicalement différent, réécrit de zéro (contrairement à la plupart des alt coins). Il existe en outre plusieurs implémentations, avec une spécification commune (contrairement à Bitcoin où le code est la spécification, le papier original de Nakamoto ne descendant pas dans les détails). Mais le gros changement par rapport à Bitcoin est que les transactions stockées dans la blockchain ne sont pas limitées à envoyer et recevoir de l'argent. Ethereum dispose d'un quasi-langage de Turing et est donc un système de calcul réparti : les pairs dans le réseau Ethereum ne se contentent pas de vérifier l'intégrité de la blockchain et d'ajouter de la monnaie, ils exécutent du code arbitraire, celui des applications que vous ou moi développons et envoyons sur le réseau.
Cela permet d'écrire des contrats (appelés, dans le style marketing fréquent dans le monde Ethereum, des smart contracts) qui sont la description, dans un langage de programmation, des règles qui s'imposent aux parties contractantes. Un prêt d'argent, par exemple, peut se programmer dans un contrat et s'exécuter automatiquement, sans intervention humaine, et donc sans possibilité de triche. (Question philosophique : quel est le pourcentage des contrats entre humains qui peuvent s'automatiser, c'est-à-dire ne plus accepter d'arrangement, de cas particuliers, etc ?) Les applications d'Ethereum ne sont donc limitées que par votre imagination.
Ces contrats sont la nouveauté importante d'Ethereum. Comme
leur exécution peut potentiellement consommer des ressources
importantes (imaginez une boucle sans fin dans un contrat...), il
faut payer pour leur exécution, ce qu'Ethereum nomme
l'essence (gas). Cette
essence est payée avec la monnaie de base d'Ethereum,
l'ether. (D'ailleurs, si vous voulez
m'envoyer des ethers, mon adresse actuelle est
0xbe1f2ac71a9703275a4d3ea01a340f378c931740
.)
Si vous tombez à court d'essence, l'application s'arrête. C'est
cette limite qui fait qu'Ethereum n'est pas une vraie
machine de Turing : celle-ci a des
ressources infinies.
Bon, vous trouverez des articles généraux et théoriques sur Ethereum un peu partout. Passons plutôt à la pratique. D'abord, un sérieux avertissement, Ethereum est encore vraiment expérimental. Le premier bloc de la blockchain, la genèse, n'a été générée que fin juillet 2015. Le code ne marche pas toujours, les compétences humaines sont encore rares et, surtout, tout évolue vite et les documentations qu'on trouve en ligne sont presque toujours fausses ou dépassées (ou les deux à la fois). Les interfaces utilisateurs d'accès facile manquent (il n'existe pas encore d'équivalent des nombreux portefeuilles Bitcoin, par exemple). Contrairement à Bitcoin, on n'est donc pas encore en production. Ne vous plaignez pas qu'on ne vous a pas prévenus ! Et, comme avec Bitcoin, vous êtes entièrement responsable de votre sécurité. Un bon exemple d'erreur de sécurité faite par un utilisateur et de ses conséquences a été raconté sur Reddit.
Donc, installons un nœud Ethereum pour commencer. J'ai dit que, contrairement à Bitcoin, Ethereum n'est heureusement pas défini par une seule implémentation. Deux sont souvent citées pour l'usage pratique d'Ethereum, eth (écrit en C++) et geth (écrit en Go). Essayons avec geth (je dirais plus loin pourquoi eth ne m'a pas satisfait). La voie officielle pour installer un exécutable binaire de geth sur une Debian est :
% curl https://install-geth.ethereum.org -L > install-geth.sh % sudo bash install-geth.sh
Cela ne fonctionne pas (rappelez-vous ce que j'ai dit sur le côté
expérimental de la chose). Contrairement à ce que prétend la documentation,
le code ne marche que sur Ubuntu et il
faut, pour Debian, modifier
la liste des sources apt. J'édite donc
/etc/apt/sources.list.d/ethereum-ethereum-jessie.list
et je remplace « jessie » (Debian) par « vivid » (Ubuntu). Après,
cela fonctionne. Si vous n'aimez pas installer du binaire sans
comprendre, le source est disponible en ligne.
Une fois geth installé, on le lance :
% geth console ... I0912 15:05:24.430701 6306 chain_manager.go:237] Last block (#223283) f374ff2948430d05acc4a14684924d78d6ade385116c9541eec6e40994785dd7 TD=899026925409268704 ... I0912 15:05:25.966841 6306 backend.go:557] Server started ... instance: Geth/v1.1.3/linux/go1.5 >
(Le dernier caractère, le >
est l'invite de la
console Ethereum.) La console est, par défaut, très bavarde. Le moyen
le plus simple de travailler tranquillement est de lancer un autre
terminal :
% geth attach
(Vous pouvez avoir toutes les options de geth en tapant geth
--help
ou bien en
ligne.)
Au premier lancement (WARNING: No etherbase set and no
accounts found as default et WARNING: Wrote default
ethereum genesis block), vous en aurez pour plusieurs heures
(en septembre 2015) avant que
votre nœud Ethereum soit synchronisé avec la
blockchain. (eth est bien plus long que geth pour
cette tâche, et il passe en outre du temps à nous prévenir qu'il
construit un énorme DAG, nécessaire pour le
minage.) À noter que la chaîne de blocs ne fait que s'allonger et, en
mars 2016, ce temps était passé à 36 h, sur le même PC... En attendant cette synchronisation, vos transactions ne
seront pas visibles localement, puisque votre nœud sera encore dans le
passé de la blockchain. Pour voir où en est cette
synchronisation :
> eth.blockNumber 223298
Et vous allez voir sur un explorateur public de la blockchain si vous vous en approchez. Par exemple, si EtherChain ou Eth status me disent sur leur page d'accueil qu'on vient de faire le bloc 223299, j'en déduis que je suis quasi-synchronisé (un seul bloc de retard).
La syntaxe de la ligne de commandes de geth peut paraître bizarre
mais elle vient du fait qu'elle s'inspire de
l'API JavaScript
accessible aux programmes Ethereum (et cette API est
documentée, c'est ainsi que vous pouvez apprendre à utiliser la console). Vous pouvez donc, non seulement
taper des commandes, mais aussi écrire du JavaScript dans la
console. Une documentation plus complète (mais pas toujours correcte)
est disponible
sous le nom d'« Ethereum Frontier Guide ». Il y a aussi une
bonne
documentation de la console interactive (pensez juste à
remplacer web3.eth.
par
eth.
).
Bien, maintenant que geth est lancé et a fini par se synchroniser (rappelez-vous, plusieurs heures, la première fois), on peut se créer un compte, pour envoyer et recevoir des ethers :
> personal.newAccount("Tu ne sauras pas mon mot de passe") "0xbe1f2ac71a9703275a4d3ea01a340f378c931740" > eth.getBalance(eth.accounts[0]) 0
Il peut y avoir plusieurs comptes et
eth.accounts[0]
est le premier créé. Son adresse
est
0xbe1f2ac71a9703275a4d3ea01a340f378c931740
. C'est
là où vous pouvez m'envoyer des ethers. Puisqu'Ethereum, comme Bitcoin,
est transparent, vous pouvez regardez sur un explorateur public toute
l'activité de ce compte.
La commande getBalance
indiquait mon niveau de
pauvreté. Aucun ether disponible. Je pourrais en miner en faisant
tourner mon CPU (et donc mes ventilateurs) à
fond mais j'ai préféré en acheter des tout faits, chez Kraken où on peut désormais acheter et
vendre des ethers. Menu Trade / New order, j'ai
acheté deux ethers. Attention, les interfaces Ethereum comptent
parfois en ethers mais parfois aussi dans leurs subdivisions, portant
des noms pittoresque comme « szabo » (un millionième d'ether) ou
« lovelace » (un millionième de milliardième d'ether). Une fois mes
ethers obtenus, je les envoie depuis Kraken vers mon compte, en
indiquant l'adresse de celui-ci (menu Funding /
Withdraw). Attention, si vous utilisez Kraken pour d'autres
monnaies que l'ether, la fonction permettant d'enregistrer une adresse
est par compte Kraken et pas par monnaie. Si vous avez enregistré une
adresse Bitcoin sous le nom « Maison », vous ne pourrez pas nommer
l'adresse Ethereum de la même façon (« duplicate withdrawal
information » est le peu utile message d'erreur de Kraken).
Rapidement, les ethers se retrouvent sur votre compte :
> eth.getBalance(eth.accounts[0]) 1995000000000000000
(Le montant est indiqué en weis, voir plus haut l'avertissement sur les subdivisions de l'ether. Ici, cela fait 1,995 ethers soit même pas deux euros au cours actuel.) Notez bien qu'Ethereum est aussi transparent que Bitcoin : tout le monde peut voir les retraits effectués depuis Kraken (essayez avec un autre explorateur public, Blockchain).
Jusqu'à présent, rien d'extraordinaire, on a fait exactement la même chose qu'avec Bitcoin. Quel intérêt d'utiliser Ethereum ? Le client est plus perfectionné et permet de faire du JavaScript pour automatiser certaines tâches. Par exemple, ce code :
function cab() { var i =0; eth.accounts.forEach(function(e){ console.log(" eth.accounts["+i+"]: " + e + " \tbalance: " + web3.fromWei(eth.getBalance(e), "ether") + " ether"); i++; }) };
va itérer sur tous vos comptes et afficher le nombre d'ethers :
> cab() eth.accounts[0]: 0xbe1f2ac71a9703275a4d3ea01a340f378c931740 balance: 1.9833824 ether undefined
Mais la vraie puissance d'Ethereum n'est pas là. Elle est dans les contrats. Ceux-ci sont des programmes exécutés par la machine Ethereum. Celle-ci exécute un langage machine nommé EVM. Il est de trop bas niveau pour le programmeur normal, qui écrit en général ses contrats dans un langage de plus haut niveau qu'il compilera. Le plus répandu de ces langages est Solidity (qui ressemble à JavaScript) mais on trouve aussi Serpent (inspiré de Python) ou LLL (dont la syntaxe ressemble à Lisp mais qui est en fait un langage de bas niveau, très proche du langage machine, Serpent peut d'ailleurs produire du LLL). Comme je suis paresseux, je vais utiliser un contrat en Solidity que j'ai récupéré chez Ethereum.org. C'est le Hello, World des contrats. Voyons d'abord si on a bien un compilateur Solidity :
> eth.getCompilers() [""]
Non, rien. Installons-le (le script d'installation a mis la bonne source dans ma configuration d'apt) :
% sudo apt-get install solc ... (Retour à geth) > admin.setSolc("/usr/bin/solc") "solc v0.1.1\nSolidity Compiler: /usr/bin/solc\n" > eth.getCompilers() ["Solidity"]
On peut alors rédiger le contrat (je ne le recopie pas ici, il est en ligne) :
... (Appel à greeterContract.new()...) ... Unlock account be1f2ac71a9703275a4d3ea01a340f378c931740 Passphrase: Contract transaction send: TransactionHash: 0x07dc92c133a433ad58946a7acf8a6f3ccf0352f34882158cc4745c17636ee81e waiting to be mined... undefined
La demande de phrase de passe est due au fait que la création du contrat et son exécution nécessitent de l'essence. Cette transaction a nécessité plus de 200 000 unités d'essence et m'a couté en tout 0,0116 ethers, ce que reflète mon portefeuille :
> eth.getBalance(eth.accounts[0]) 1983382400000000000
Une fois validée par les mineurs, le contrat a une adresse :
> Contract mined! Address: 0xf0b64c321e9db6bf9164eae8be44443e1e2834a5 [object Object]
On peut voir le contrat en ligne, récupérer le code compilé :
> greeter.address; "0xf0b64c321e9db6bf9164eae8be44443e1e2834a5" > eth.getCode(greeter.address) "0x60606040526000357c0100000..."
Et, bien sûr, l'exécuter :
> greeter.greet(); "Mon contrat à moi"
La méthode créée par le code est visible dans la définition de l'ABI, ce que les autres utilisateurs devront connaître pour interagir avec « mes » contrats :
> greeterCompiled.greeter.info.abiDefinition; [ ... { constant: true, inputs: [], name: "greet", outputs: [{ name: "", type: "string" }], type: "function" ...
C'est évidemment un tout petit contrat, sans grand intérêt. Au fur et à mesure que je progresse en programmation, j'espère en faire des meilleurs. En attendant, il existe plein d'exemples en ligne, comme le DAO qui prétend outrageusement implémenter... la démocratie en Solidity et clame même « This is exactly how a democracy should work. ». Ce contrat met en œuvre un mécanisme de vote entre « actionnaires » sur l'allocation de ressources. Ce vote est censitaire « The rules of your organization are very simple: anyone with at least one token [la monnaie du DAO] can create proposals to send funds from the country's account. After a week of debate and votes, if it has received votes worth a total of 100 tokens or more and has more approvals than rejections, the funds will be sent. If the quorum hasn't been met or it ends on a tie, then voting is kept until it's resolved. Otherwise, the proposal is locked and kept for historical purposes. ». Cela peut être une façon intéressante de gérer certaines organisations mais appeler ça « démocratie » est franchement fort de café. Inutile de dire que je ne partage pas leur délire libertarien.
Un exemple plus simple de contrat, facile à étudier mais illustrant la plupart des possibilités d'Ethereum, est la Pyramide, décrite dans mon article suivant.
Revenons à l'autre mise en œuvre d'Ethereum, eth, écrite en C++. C'est en fait par celle là que j'avais commencé mais j'ai arrêté car je n'arrivais pas à lui faire accepter mes contrats. L'installation ressemble beaucoup à celle de geth :
% curl https://install-eth.ethereum.org -L > install-eth.txt % sudo bash -x install-eth.txt
On lance eth, par exemple, ainsi :
% eth -j --frontier -i --verbosity 2
Et sa console n'a pas l'air de comprendre le Contrôle-D de fin de
session, il faut faire
web3.admin.eth.exit()
. Pour de l'aide, on peut
faire eth --help
(ou bien voir la
doc en ligne) et juste taper
web3
dans la console.
J'ai créé plusieurs comptes avec eth (l'objet de référence est
web3.eth
, et pas eth
comme
c'était le cas avec geth) :
> web3.eth.accounts ['0x003653c3b972ede82f621ac322c6e430493eeb8c', '0x0007ca35a2680425974312233a59a74c00d3c040', '0x00740378b6046b199f7197fabe21484787648d24'] > web3.eth.getBalance(web3.eth.accounts[1]) 1995000000000000000'
J'avais ensuite essayé de créer un contrat depuis eth mais sans succès. eth a tous les compilateurs :
> web3.eth.getCompilers() ['lll', 'solidity', 'serpent']
J'ai utilisé le même contrat qu'avec geth, une transaction était bien générée (0xffc8450fd29e6dc26b7df84328913df16dad4b29b3fbd1df9df2a5d12dabc251) mais apparemment jamais validée :
20:51:34|eth New transaction ffc8450f…{[CREATE]/788$0+300000@50000000000<-0007ca35… #0} 'Contract transaction send: TransactionHash: 0xffc8450fd29e6dc26b7df84328913df16dad4b29b3fbd1df9df2a5d12dabc251 waiting to be mined...'
Cela illustre bien qu'Ethereum n'est pas encore prêt pour un usage généralisé. C'est une technique expérimentale mais très prometteuse techniquement et très intéressante politiquement.
Quelques lectures supplémentaires :
Date de publication du RFC : Septembre 2015
Auteur(s) du RFC : P. Saint-Andre (&yet)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF xmpp
Première rédaction de cet article le 10 septembre 2015
Ce RFC normalise le format des adresses du protocole de messagerie instantanée XMPP, protocole également connu sous son ancien nom de Jabber. Il remplace l'ancien RFC 6122 avec notamment un changement important sur l'internationalisation de ces adresses, le passage au nouveau système PRECIS (décrit dans le RFC 7564), qui remplace stringprep. Les adresses XMPP peuvent en effet être entièrement en Unicode.
Le protocole XMPP est le standard actuel de
messagerie instantanée de
l'IETF
(il est normalisé dans le RFC 6120). Les utilisateurs sont identifiés par
une adresse également connue, pour des raisons
historiques, sous le nom de JID (Jabber
IDentifier). Ces adresses ont une forme qui ressemble aux
adresses de courrier électronique mais elles
sont en fait complètement différentes. Ainsi, j'ai personnellement
deux adresses XMPP, bortzmeyer@gmail.com
(le
service de messagerie Google Talk utilise en
effet la norme XMPP), qui me sert surtout pour la distraction, et
bortzmeyer@dns-oarc.net
qui me sert pour le
travail (j'utilise aussi le service XMPP de la Quadrature du
Net mais plus rarement). Mais rien ne dit qu'un courrier envoyé à ces adresses
fonctionnera : adresses XMPP et de courrier vivent dans des mondes différents.
Le format des adresses XMPP était spécifié à l'origine dans le document XEP-0029. Puis il a été normalisé dans la section 3 du RFC 3920. La norme XMPP ayant subi une refonte complète, qui a mené entre autres à un nouveau RFC, le RFC 6120, se posait la question du format d'adresses, dont l'internationalisation, compte tenu de la nouvelle norme IDN, suscitait des débats. Ces débats n'étant pas terminés, la décision a été prise de sortir le format d'adresses du RFC principal, et d'en faire le RFC 6122, jusqu'à ce qu'un consensus apparaisse sur le format « définitif ». Ce format final est celui de notre RFC 7622, qui utilise pour Unicode le cadre PRECIS, normalisé dans le RFC 8264.
Donc, quels sont les points essentiels des adresses XMPP (section
3) ? Une adresse (ou JID) identifie une entité (un humain mais peut-être aussi
un programme automatique). Elle comprend trois parties (dont une
seule, le domaine,
est obligatoire), la partie locale, le
domaine et une
ressource. Ainsi, dans
bortzmeyer@gmail.com/Home
,
bortzmeyer
est la partie locale,
gmail.com
le domaine et Home
la ressource. Le @ et le
/ servent de séparateurs. Chacune des trois
parties peut être composée de caractères
Unicode, qui doivent être encodés en
UTF-8. La partie locale doit être canonicalisée
avec PRECIS et son profil UsernameCaseMapped
(voir RFC 8265), le domaine avec les méthodes
IDN des RFC 5890 et RFC 5892. Seul le domaine est obligatoire et
bot.example.org
est donc un JID valide.
Les adresses XMPP (ou JID) sont souvent représentées sous forme
d'un IRI, selon le RFC 5122. En gros, un IRI XMPP est un JID préfixé par
xmpp:
. Mais ces IRI ne sont pas utilisés par le
protocole XMPP. Dans les champs to
et
from
des strophes (stanzas) XMPP, on
ne trouve que des JID (sans le xmpp:
devant). Les
IRI ne servent que dans les liens dans les pages Web, comme xmpp:bortzmeyer@gmail.com
(attention, ce lien ne marchera pas
avec tous les navigateurs).
Le RFC détaille ensuite chaque partie. Le domaine, seule partie
obligatoire, est dans la section 3.2. On peut le voir comme une
identification du service auquel on se connecte
(gmail.com
= Google Talk), et la création de
comptes et l'authentification se font typiquement en fonction de ce
service. En théorie, une adresse IP est
acceptable pour cette partie mais, en pratique, c'est toujours un
FQDN. Ce nom de domaine peut être un
IDN donc
instantanée.nœud.example
est un nom
acceptable pour former un JID. Auquel cas, ce doit être un IDN légal
(ce qui veut dire que toute chaîne de caractères Unicode n'est pas
forcément un nom légal pour la partie domaine d'un JID). À noter que
XMPP n'utilise pas l'encodage en
ASCII des IDN (le Punycode).
Et la partie locale, celle avant le @ ? La
section 3.3 la couvre. Elle est optionnelle et identifie en général
une personne (mais peut aussi indiquer un programme ou bien un salon de
conversation à plusieurs). Si elle est en Unicode, elle doit être
canonicalisée avec le profil UsernameCaseMapped
de PRECIS, profil décrit dans le RFC 8265. Cette partie locale est donc insensible à
la casse. Certains caractères normalement autorisés par ce
profil sont explicitement interdits en XMPP comme les séparateurs
/ ou @ mais aussi comme
" ou <. (Voir XEP-0106 pour un
mécanisme d'échappement permettant de mettre quand même ces caractères.)
Quant à la ressource, troisième partie du JID (après le
/), également optionnelle, elle sert à
distinguer plusieurs sessions par le même utilisateur (par exemple
/Home
et /Office
). La
section 3.4 la décrit en détail. Également en Unicode, elle est
canonicalisée par le profil OpaqueString
de la
classe FreeformClass
de PRECIS (RFC 8264, section 4.3). Elle n'a pas de structure
officielle. Un / dans une ressource (par exemple
example.com/foo/bar
) n'implique donc pas une hiérarchie.
De même, si on y trouve quelque chose ressemblant à une adresse (par
exemple joe@example.net/nic@host
), cette ressource
nic@host
doit être traitée comme un identificateur
opaque (et pas être analysée en « nom (at) machine »).
La section 3.5 contient quelques exemples de JID. Si certains sont
« ordinaires » (le classique juliet@example.com/foobar
,
reprenant la tradition XMPP des noms tirés de Roméo et
Juliette), d'autres sont plus déroutants à première vue
comme juliet@example.com/foo@bar
(le domaine est
example.com
, la ressource
foo@bar
),
foo\20bar@example.com
(avec un échappement pour
l'espace), π@example.com
(partie locale en
Unicode), king@example.com/♚
(ressource en
Unicode), example.com
(juste le nom de
domaine)...
Il y a aussi des exemples de JID illégaux,
qu'il ne faut pas utiliser, comme
"juliet"@example.com
(les guillemets),
foo bar@example.com
(l'espace),
henriⅣ@example.com
(le caractère Unicode à
la fin de la partie locale a un équivalent canonique et n'est donc pas
autorisé), ♚@example.com
(la partie locale
doit obéir aux règles restrictives du RFC 8265,
qui n'autorise pas les symboles dans les identificateurs, seulement
les lettres et chiffres), juliet@
(domaine
absent)...
En parlant d'adresses illégales, qui doit vérifier qu'elles sont légales ? Évidemment, l'émetteur devrait le faire. Mais notre RFC va plus loin en recommandant (section 4) que le récepteur jette les messages XMPP (les strophes, stanzas en anglais) contenant de telles adresses. C'est donc plus strict que le traditionnel principe de robustesse.
Quelles sont les conséquences de sécurité de ces adresses ? Il n'y
en a guère mais, bon, il y a toujours des inquiets donc la section 7
examine en détail tous les risques, même très théoriques. Bien sûr,
les adresses XMPP héritent des questions de sécurité de
PRECIS mais le RFC mentionne surtout les risques de triche
sur les
adresses. Il y en a de deux sortes, les usurpations et les
imitations. Les usurpations (section 7.3.1) sont les cas où un méchant
arrive à envoyer un message XMPP en trichant sur
l'origine, par exemple si jean@example.net
, une
fois authentifié auprès de son propre serveur, arrive
à transmettre un message prétendant venir de
jeanne@jabber.example
. Normalement, le protocole
XMPP empêche cela, par l'authentification mutuelle des serveurs (sauf
attaques un peu sophistiquées, par exemple sur le DNS). Cela
dit, cette authentification n'empêche pas un serveur d'annoncer une
autre partie locale (jeanne@example.net
au lieu
jean@example.net
).
L'autre risque est celui d'imitation (section 7.3.2). Cette fois,
il s'agit d'utiliser des JID légitimes et authentiques mais qui ressemblent à celui de la victime,
par exemple fric@paypa1.com
au lieu de
fric@paypal.com
(si vous ne voyez pas la
différence, regardez mieux). Cette technique est souvent connue sous
le nom de typejacking. Comme le montre l'exemple du RFC ou bien celui cité plus haut,
le problème arrive même en se limitant à ASCII. Si vous voulez un joli
exemple avec Unicode (mais le résultat dépend de l'environnement avec
lequel vous lisez cet article), regardez ᏚᎢᎵᎬᎢᎬᏒ
qui ressemble à
STPETER
mais est écrit en
Cherokee. Comme un JID peut contenir à peu près
n'importe quel caractère Unicode, il n'y a pas vraiment de prévention technique
possible contre ce problème. Il est peu probable que cela ait des conséquences en pratique.
La liste complète des changements par rapport au RFC 6122 figure en annexe A. Rappelons que le RFC 6122 s'appuyait, pour les parties en
Unicode, sur des profils
Stringprep
(RFC 3454) comme Nameprep
. Ce Nameprep
, décrit dans le RFC 3491, ayant été supprimé à l'occasion de la
réforme IDNA bis, le grand changement
dans ce nouveau RFC est l'abandon complet de stringprep et
l'utilisation de PRECIS pour les identificateurs (comme la partie
locale d'un JID) et d'IDN pour le nom de domaine.
Vu les changements entre stringprep et PRECIS, on ne peut pas garantir à 100 % que les JID autrefois valides le seront toujours. Mais, dans la plupart des cas, les anciens JID Unicode resteront légaux et utilisables.
Date de publication du RFC : Août 2015
Auteur(s) du RFC : F. Gont (SI6 Networks / UTN-FRH), W. Liu (Huawei Technologies), G. Van de Velde (Alcatel-Lucent)
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 7 septembre 2015
Un peu de sécurité IPv6 sur le réseau local : comment protéger les pauvres machines IPv6 contre un méchant serveur DHCP, qui répond à la place du serveur légitime, et plus rapidement que lui ? Pas de surprise, la solution est la même qu'en IPv4 (DHCP snooping) et est détaillée dans ce RFC : le commutateur bloque les réponses DHCP qui viennent d'un port où aucun serveur DHCP n'est censé être présent.
Le mécanisme porte le doux nom de DHCP Shield. DHCP, normalisé dans le RFC 8415, est très proche en IPv6 et en IPv4 et, dans les deux cas, n'offre quasiment aucune sécurité. Sur un réseau sans serveur DHCP officiel, une machine peut prétendre être serveur DHCP et tout le monde va la croire et accepter ses annonces. C'est une des plaies des réseaux locaux, d'autant plus qu'authentifier le serveur DHCP est très difficile puisqu'on utilise justement DHCP pour ne rien avoir à configurer sur les machines clientes. Sur un réseau avec serveur DHCP légitime, un faux serveur peut parfois se faire écouter, par exemple s'il répond plus vite. Et, même quand il n'y a qu'un seul serveur DHCP, rien ne garantit que les machines utiliseront uniquement les adresses IP qui leur ont été allouées officiellement.
Pour DHCP Shield, le mode de fonctionnement normal est que l'administrateur réseaux configure le commutateur en lui disant sur quels ports du commutateur se trouve le serveur DHCP légitime. Le commutateur examine alors tous les messages et rejette les réponses DHCP qui viendraient d'un autre port. Le problème d'un serveur DHCP pirate est très proche de celui d'un routeur IPv6 pirate qui envoie des Router Advertisement (RFC 4861, section 4.2) trompeurs et la solution est donc très proche (pour les RAcailles, les RA illégitimes, le problème était exposé dans le RFC 6104 et la solution, RA Guard, dans les RFC 6105 et RFC 7113).
Voilà pour le principe, les détails maintenant. Un commutateur ordinaire ne protège pas contre les serveurs DHCP pirates. Il faut un DHCPv6 Shield Device (section 3 du RFC), commutateur « intelligent » capable de mettre en œuvre la technique décrite dans ce RFC. Demandez à votre vendeur avant d'acheter, s'il y a bien les fonctions de DHCP Shield.
Il faut ensuite le configurer explicitement (le commutateur pourrait apprendre seul, en regardant les réponses mais c'est risqué : si le serveur pirate est déjà en service au moment où le commutateur démarre, ce dernier pourrait prendre le pirate pour le serveur légitime). Cette configuration est faite par l'administrateur réseaux, qui désigne le ou les ports du commutateur qui peuvent légitimement voir arriver des réponses DHCPv6, car un serveur légitime se trouve derrière (section 4 du RFC).
Dit comme cela, ça a l'air simple. Mais, dans les réseaux réels, plein de complications peuvent survenir et la section 5 du RFC, sur les problèmes possibles, est beaucoup plus longue que la section 4 qui décrit l'algorithme. Premier gag possible, les en-têtes d'extension IPv6 qui sont très difficiles à analyser. Notre RFC impose donc aux mises en œuvre de DHCP shield d'analyser tout le paquet, de ne pas se limiter arbitrairement aux N premiers octets, car la liste des en-têtes peut être longue. (La section 6 note que cela peut être difficile sur le fast path - mis en oeuvre dans le matériel - des commutateurs et suggère de jeter le paquet si on ne peut pas l'analyser complètement, mais avec une liste de protocoles de transport qui soit configurable, pour éviter de bloquer les nouveaux protocoles apparus après la vente du commutateur.)
Pour aider un peu les pauvres commutateurs, le RFC 7112 impose que, dans un paquet fragmenté, la totalité des en-têtes soit dans le premier fragment (autrement, un serveur DHCPv6 pirate pourrait « tricher » en « cachant » la réponse IPv6 dans le deuxième fragment et en espérant qu'il ne soit pas analysé). Le commutateur doit donc jeter les paquets fragmentés dont le premier fragment ne contient pas toute la chaîne des en-têtes. (Interdire que les réponses DHCP soient fragmentées aurait été encore plus efficace mais pouvait être gênant dans certains cas, où il y a un besoin légitime d'envoyer de grandes réponses.) Cette politique peut sembler violente mais, de toute façon, un paquet fragmenté n'incluant pas la totalité des en-têtes n'a déjà quasiment aucune chance de passer les pare-feux actuels.
Il faut aussi prêter attenion aux fragments qui se recouvrent (RFC 5722). Ils peuvent permettre d'échapper à la détection par le commutateur.
Plus contestable, la décision en cas d'en-têtes dont le champ Next Header est inconnu. Malheureusement, en IPv6, il n'y a pas de moyen garanti de sauter par dessus un tel en-tête (c'est un peu mieux depuis le RFC 6564). Notre RFC 7610 prend donc une décision radicale : par défaut, les paquets IPv6 ayant un tel en-tête doivent être jetés sans merci. Une option du commutateur doit permettre, si l'administrateur le demande, de les accepter (cf. RFC 7045 pour un point de vue plus général sur la question).
Si le paquet est protégé par IPsec/ESP, le commutateur ne peut évidemment pas savoir si c'est du DHCP ou pas, le but d'ESP (RFC 4303) étant bien d'empêcher les intermédiaires d'être indiscrets. Dans ces conditions, le commutateur doit transmettre le paquet. Les machines clientes qui acceptent des réponses DHCP sur IPsec (ça doit être très rare !) doivent donc les authentifier elles-mêmes, ce qui est dans la logique d'IPsec.
Une fois ces précautions prises, le DHCPv6 Shield Device peut déterminer si le paquet est une réponses DHCPv6 et, si oui, et si elle ne vient pas par le bon port, la jeter, protégeant ainsi les clients DHCP innocents.
La section 6 résume certains problèmes de sécurité du DHCP Shield. Elle rappelle que celui-ci ne protège pas contre les attaques non-DHCP (évidemment) ni même contre certaines attaques DHCP (comme les dénis de service).
Elle rappelle également que DHCP Shield devrait être présent sur tous les commutateurs du réseau : autrement, un attaquant relié à un commutateur bête, qui ne filtre pas, verra ses paquets acceptés s'il y a au moins un serveur légitime sur ce commutateur (puisqu'il aura fallu, en aval, autoriser le port où est relié ce commutateur.)
Notez que notre RFC ne propose pas de solution à l'usurpation d'adresses IP (une machine utilisant une adresse qui ne lui a pas été allouée en DHCP, cas mentionné au début de mon article) mais que ces solutions sont dans le RFC 7513.
À l'heure actuelle, au moins certains commutateurs Cisco ont cette fonction de DHCP Shield.
Date de publication du RFC : Août 2015
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 5 septembre 2015
Il existe désormais plusieurs techniques pour authentifier les courriers
électroniques. Certaines peuvent nécessiter des calculs un
peu compliqués et on voudrait souvent les centraliser sur une machine
de puissance raisonnable, dotée de tous les logiciels
nécessaires. Dans cette hypothèse, le MUA ne
recevra qu'une synthèse (« Ce message vient bien de
example.com
») et pourra alors prendre une
décision, basée sur cette synthèse. C'est le but de l'en-tête
Authentication-Results:
, normalisé originellement dans le RFC 5451 six ans plus tôt, auquel a succédé le RFC 7001, que ce nouveau RFC met légèrement à jour (il y a peu
de changements, le principal étant la correction de l'erreur #4201). Depuis,
notre RFC a lui-même été remplacé par le RFC 8601.
Avec des techniques d'authentification comme
DKIM (RFC 6376) ou
SPF (RFC 7208), les
calculs à faire pour déterminer si un message est authentique peuvent
être complexes (DKIM utilise la cryptographie) et nécessiter la
présence de bibliothèques non-standard. Les installer et
les maintenir à jour sur chaque machine, surtout en présence
d'éventuelles failles de sécurité qu'il faudra boucher en urgence,
peut être trop pénible pour l'administrateur système. L'idée de ce RFC
est donc de séparer l'opération en deux :
l'authentification est faite sur un serveur,
typiquement le premier MTA du site (cf. annexe
C pour une discussion de ce choix), celui-ci
ajoute au message un en-tête indiquant le résultat de ladite
authentification et le MUA (ou bien le MDA,
voir la section 1.5.3 pour un bon rappel sur ces concepts) peut ensuite, par exemple par un langage de
filtrage comme procmail ou
Sieve, agir sur la base de ce résultat.
L'idée n'est donc pas de montrer la valeur de cet en-tête à M. Michu
(voir la section 4.1 pour quelques risques que cela poserait),
mais d'en faire une donnée pour un programme. Cet
en-tête marche pour tous les protocoles d'authentification et surpasse
donc les en-têtes spécifiques comme le
Received-SPF:
de SPF (section
1 du RFC). Le filtrage des messages non
authentifiés n'est
pas obligatoire (section 1.4) : agir - ou pas - sur la base de l'en-tête
Authentication-Results:
est une décision politique locale.
J'ai utilisé le terme de « site » pour désigner un ensemble de
machines gérées par la même organisation mais le RFC a un terme plus
rigoureux, ADMD (ADministrative Management
Domain). La frontière d'un ADMD est la « frontière de confiance » (trust boundary),
définie en section 1.2. Un domaine administratif de gestion est un
groupe de machines entre lesquelles il existe une relation de
confiance, notamment du fait que, à l'intérieur de l'ADMD, l'en-tête
Authentication-Results:
ne sera pas modifié ou
ajouté à tort (section 1.6 : l'en-tête n'est pas protégé, notamment il
n'est pas signé). Il existe de nombreuses variantes organisationnelles
du concept d'ADMD. Un ADMD inclus typiquement une organisation (ou un
département de celle-ci) et d'éventuels sous-traitants. Il a un nom,
l'authserv-id
, défini en section 2.2.
L'en-tête Authentication-Results:
lui-même est formellement défini en section 2. Il
appartient à la catégorie des en-têtes de « trace » (RFC 5322, section 3.6.7 et RFC 5321, section 4.4) comme
Received:
qui doivent être ajoutés en haut des
en-têtes et jamais modifiés. La syntaxe de Authentication-Results:
est en section
2.2. L'en-tête est composé du authserv-id
, le nom
de l'ADMD et d'une série de doublets (méthode, résultat), chacun
indiquant une méthode d'authentification et le résultat
obtenu. L'annexe B fournit une série d'exemples. Elle commence (annexe
B.1) par un message sans Authentication-Results:
(eh oui, il n'est pas obligatoire). Puis
(tiré de l'annexe B.3), une authentification SPF réussie, au
sein de l'ADMD example.com
, donnera :
Authentication-Results: example.com; spf=pass smtp.mailfrom=example.net Received: from dialup-1-2-3-4.example.net (dialup-1-2-3-4.example.net [192.0.2.200]) by mail-router.example.com (8.11.6/8.11.6) with ESMTP id g1G0r1kA003489; Wed, Mar 14 2009 17:19:07 -0800 From: sender@example.net Date: Wed, Mar 14 2009 16:54:30 -0800 To: receiver@example.com
Rappelez-vous qu'il peut y avoir plusieurs authentifications. Voici un cas (annexe B.4) avec SPF et l'authentification SMTP du RFC 4954 :
Authentication-Results: example.com; auth=pass (cram-md5) smtp.auth=sender@example.net; spf=pass smtp.mailfrom=example.net Received: from dialup-1-2-3-4.example.net (8.11.6/8.11.6) (dialup-1-2-3-4.example.net [192.0.2.200]) by mail-router.example.com (8.11.6/8.11.6) with ESMTP id g1G0r1kA003489; Fri, Feb 15 2002 17:19:07 -0800 Date: Fri, Feb 15 2002 16:54:30 -0800 To: receiver@example.com From: sender@example.net
L'une des authentifications peut réussir et l'autre échouer. Un
exemple (annexe B.6) avec deux signatures DKIM, une bonne et une qui
était correcte au départ (regardez le premier Authentication-Results:
) mais plus à
l'arrivée, peut-être parce qu'un gestionnaire de liste de diffusion a
modifié le message :
Authentication-Results: example.com; dkim=pass reason="good signature" header.i=@mail-router.example.net; dkim=fail reason="bad signature" header.i=@newyork.example.com Received: from mail-router.example.net (mail-router.example.net [192.0.2.250]) by chicago.example.com (8.11.6/8.11.6) for <recipient@chicago.example.com> with ESMTP id i7PK0sH7021929; Fri, Feb 15 2002 17:19:22 -0800 DKIM-Signature: v=1; a=rsa-sha256; s=furble; d=mail-router.example.net; t=1188964198; c=relaxed/simple; h=From:Date:To:Message-Id:Subject:Authentication-Results; bh=ftA9J6GtX8OpwUECzHnCkRzKw1uk6FNiLfJl5Nmv49E=; b=oINEO8hgn/gnunsg ... 9n9ODSNFSDij3= Authentication-Results: example.net; dkim=pass (good signature) header.i=@newyork.example.com Received: from smtp.newyork.example.com (smtp.newyork.example.com [192.0.2.220]) by mail-router.example.net (8.11.6/8.11.6) with ESMTP id g1G0r1kA003489; Fri, Feb 15 2002 17:19:07 -0800 DKIM-Signature: v=1; a=rsa-sha256; s=gatsby; d=newyork.example.com; t=1188964191; c=simple/simple; h=From:Date:To:Message-Id:Subject; bh=sEu28nfs9fuZGD/pSr7ANysbY3jtdaQ3Xv9xPQtS0m7=; b=EToRSuvUfQVP3Bkz ... rTB0t0gYnBVCM= From: sender@newyork.example.com Date: Fri, Feb 15 2002 16:54:30 -0800 To: meetings@example.net
La liste complète des méthodes figure dans un registre IANA (section 6). De nouvelles méthodes peuvent être enregistrées en utilisant la procédure « Examen par un expert » du RFC 5226.
La section 2.3 détaille l'authserv-id
. C'est
un texte qui identifie le domaine, l'ADMD. Il doit donc être unique
dans tout l'Internet. En général, c'est un
nom de domaine comme
laposte.net
. (Il est possible d'être plus
spécifique et d'indiquer le nom d'une machine particulière mais cette
même section du RFC explique pourquoi c'est en général une mauvaise
idée : comme les MUA du domaine n'agissent que sur les Authentication-Results:
dont ils
reconnaissent l'authserv-id
, avoir un tel
identificateur qui soit lié au nom d'une machine, et qui change donc
trop souvent, complique l'administration système.)
La section 2.7 explique les résultats possibles pour les méthodes
d'authentification (en rappelant que la liste à jour des méthodes et
des résultats est dans le registre IANA). Ainsi, DKIM (section 2.7.1)
permet des résultats comme pass
(authentification
réussie) ou temperror
(erreur temporaire au cours
de l'authentification, par exemple liée au DNS). Des résultats similaires sont possibles
pour SPF (section 2.7.3).
Notons la normalisation d'une méthode traditionnelle
d'authentification faible, le test DNS du chemin « adresse IP du
serveur -> nom » et retour. Baptisée iprev
, cette
méthode, bien que bâtie sur la pure superstition (cf. section 7.11) est utilisée
couramment. Très injuste (car les arbres des résolutions inverses du DNS,
in-addr.arpa
et ip6.arpa
,
ne sont pas sous le contrôle du domaine qui envoie le courrier), cette
méthode discrimine les petits FAI, ce qui est sans doute un avantage
pour les gros, comme AOL qui
l'utilisent. Attention aux implémenteurs : aussi bien la résolution
inverse d'adresse IP en nom que la résolution droite de nom en adresse
IP peuvent renvoyer plusieurs résultats et il faut donc comparer des
ensembles. (Cette méthode qui, contrairement aux autres, n'avait
jamais été exposée dans un RFC avant le RFC 5451, est décrite en détail dans la section
3, avec ses sérieuses limites.)
Autre méthode mentionnée, auth
(section
2.7.4) qui repose sur l'authentification SMTP
du RFC 4954. Si un MTA (ou plutôt MSA) a
authentifié un utilisateur, il peut le noter ici.
Une fois le code d'authentification exécuté, où mettre le Authentication-Results:
?
La section 4 fournit tous les détails, indiquant notamment que le MTA
doit placer l'en-tête en haut du message, ce qui facilite le repérage
des Authentication-Results:
à qui on peut faire confiance (en examinant les en-têtes
Received:
; en l'absence de signature, un Authentication-Results:
très ancien, situé au début du trajet, donc en bas des en-têtes, ne
signifie pas grand'chose). On se fie a priori aux en-têtes mis par les
MTA de l'ADMD, du domaine de confiance. L'ordre est donc
important. (La section 7 revient en détail sur les en-têtes Authentication-Results:
usurpés.)
Ce n'est pas tout de mettre un Authentication-Results:
, encore faut-il l'utiliser. La
section 4.1 s'attaque à ce problème. Principe essentiel pour le MUA :
ne pas agir sur la base d'un Authentication-Results:
, même si ce n'est que pour
l'afficher, sans l'avoir validé un minimum. Comme le Authentication-Results:
n'est pas
signé, n'importe qui a pu en insérer un sur le trajet. Le RFC précise
donc que les MUA doivent, par défaut, ne rien faire. Et qu'ils doivent ne
regarder les Authentication-Results:
qu'après que cela ait été activé par
l'administrateur de la machine, qui indiquera quel
authserv-id
est acceptable.
Naturellement, le MTA d'entrée du domaine devrait supprimer les
Authentication-Results:
portant son propre authserv-id
qu'il trouve
dans les messages entrants : ils sont forcément frauduleux (section
5). (Le RFC accepte aussi une solution plus simpliste, qui est de
supprimer tous les Authentication-Results:
des messages entrants, quel que soit leur
authserv-id
.)
Arrivé à ce stade de cet article, le lecteur doit normalement se
poser bien des questions sur la valeur du Authentication-Results:
. Quel poids lui
accorder alors que n'importe quel méchant sur le trajet a pu ajouter
des Authentication-Results:
bidons ? La section 7, consacrée à l'analyse générale de la
sécurité, répond à ces inquiétudes. 7.1 détaille le cas des en-têtes
usurpés. Les principales lignes de défense ici sont le fait que le MUA
ne doit faire confiance aux Authentication-Results:
que s'ils portent le
authserv-id
de son ADMD et
le fait que le MTA entrant doit filtrer les Authentication-Results:
avec son
authserv-id
. Comme l'intérieur de l'ADMD, par
définition, est sûr, cela garantit en théorie contre les Authentication-Results:
usurpés. Le RFC liste néanmoins d'autres méthodes possibles comme le
fait de ne faire confiance qu'au premier Authentication-Results:
(le plus récent), si on sait que le MTA en ajoute systématiquement un
(les éventuels Authentication-Results:
usurpés apparaîtront après ; mais certains
serveurs les réordonnent, cf. section 7.3). Pour l'instant, il n'y a
pas de méthode unique et universelle de vérification du Authentication-Results:
, le RFC
propose des pistes mais ne tranche pas.
Comme toujours en sécurité, il faut bien faire la différence entre
authentification et
autorisation. Un spammeur a
pu insérer un Authentication-Results:
légitime pour son
authserv-id
. Même authentifié, il ne doit pas
être considéré comme une autorisation (section 7.2).
Plusieurs mises en œuvre de ce système existent déjà comme
dans MDaemon, sendmail
(via sid-milter),
Courier, OpenDKIM,
etc. Si on veut analyser les en-têtes Authentication-Results:
en
Python, on a le module authres.
Parmi les grosses usines à courrier centralisées,
Gmail met
systématiquement cet en-tête, par exemple :
Authentication-Results: mx.google.com; spf=pass \ (google.com: domain of stephane@sources.org designates 217.70.190.232 \ as permitted sender) smtp.mail=stephane@sources.org
Outre Gmail, à la date de publication du RFC, Yahoo et Hotmail ajoutaient cet en-tête.
Les changements depuis le RFC 7001 sont peu
nombreux (annexe D pour une liste complète). Le RFC 7410, qui créait le registre
des types d'information possibles sur l'authentification a
été intégré et est donc remplacé par notre nouveau RFC.
Autrement, l'un des principaux changements
concerne la bogue #4201.
Le texte du précédent RFC disait que la source de l'authentification
devait être un en-tête du message alors que cela peut être un champ particulier d'un en-tête (le cas
du champ i
dans les signatures DKIM d'exemple
dans cet article, cf. 2.3 et 2.7.1). Autrement, les changements par
rapport au RFC 7001 sont surtout des détails et
les mises en œuvre actuelles devraient continuer sans trop
d'histoires. Je rappelle que ce RFC 7601 n'est plus
d'actualité, ayant été remplacé par le RFC 8601.
Date de publication du RFC : Août 2015
Auteur(s) du RFC : Brad Schoening (Independent
Consultant), Mouli Chandramouli (Cisco
Systems), Bruce Nordman (Lawrence Berkeley National
Laboratory)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF eman
Première rédaction de cet article le 4 septembre 2015
Le but du projet EMAN (Energy MANagement) à l'IETF est de développer un ensemble de normes techniques sur la gestion de l'énergie par les équipements informatiques en réseau. Ce RFC explique le projet et décrit des scénarios d'utilisation. C'est un pas de plus (très modeste encore) vers un Internet plus « vert ».
Le cadre général pour la gestion de l'énergie des équipements Internet figure dans le RFC 7326 (et le cahier des charges dans le RFC 6988). L'idée est de d'abord de pouvoir superviser à distance tout engin connecté à l'Internet, et de connaitre par ce moyen sa consommation d'énergie (le préalable à toute action). Puis, le cadre EMAN (défini par le groupe de travail du même nom) doit permettre l'action sur ces engins, par exemple ralentir le processeur pour diminuer la consommation, ou carrément arrêter certaines machines pour économiser l'énergie. Il existe bien sûr déjà des méthodes pour cela mais elles ne sont pas encore normalisées ou bien utilisent des protocoles pré-Internet. EMAN doit permettre la supervision et l'action sur des engins très différents, et ne sortant pas de chez le même fournisseur. Le but n'est pas seulement d'économiser l'argent (l'électricité coûte cher) mais aussi de tenir compte de la finitude des ressources de la planète (c'est, à ma connaissance, la première fois que ce point est mentionné dans un RFC : bien des acteurs de l'Internet vivaient jusqu'à présent dans l'illusion qu'on trouverait toujours « une autre ressource énergétique »).
Bref, deux tâches pour EMAN, la supervision (mesurer la consommation) et l'action (éteindre si nécessaire). Pour permettre cette supervision et cette action, EMAN (RFC 7326) a défini un modèle de données, et utilisera le protocole SNMP, et des MIB dont certaines sont déjà développées (voir par exemple les RFC 7460 sur la MIB générale, RFC 7461 et le RFC 7577 sur la MIB de gestion des batteries). EMAN n'est donc pas une nouvelle pile protocolaire complète (cf. section 5), il s'appuie sur TCP/IP et sur les protocoles de gestion de réseaux standard (cf. RFC 6632).
Et les scénarios d'usage promis ? Ils figurent en section 2 de notre RFC. Je ne vais pas tous les reprendre ici mais certains sont rigolos. On trouve des routeurs dont on veut mesurer la consommation, des commutateurs qui sont eux-même distributeurs d'énergie (PSE Power Sourcing Equipment, par exemple via PoE, cf. RFC 3621), etc. Dans ce dernier cas, celui où des machines sont alimentées via un équipement réseau, il y a deux sous-cas : soit la machine est elle-même capable de faire du EMAN, donc d'informer sur sa consommation électrique elle-même (elle est un « Energy Object »), soit elle ne l'est pas et le PSE va alors devoir le faire pour elle. Et si la machine tire du courant d'une prise au mur ? Là encore, deux sous-cas, l'alimentation électrique peut être un PDU (Power Distribution Unit) « intelligent », capable de transmettre les informations lui-même, soit ce n'est pas le cas et il faudra alors que la machine alimentée soit capable de transmettre les informations à la gestion de réseau (un PC n'aura pas de mal, un objet plus simple si). Voir aussi la section 2.5 sur cette notion d'intermédiaire de mesure, le Mid-level Manager.
Il y a déjà partout des compteurs électriques, soit intégrés aux PDU, soit autonomes, et qui mesurent la consommation. Un des enjeux d'EMAN est de les rendre interrogeables à distance (section 2.4).
Prenons maintenant le cas d'un immeuble de bureaux ou d'une usine, doté d'une grosse alimentation électrique, gérée par des professionnels. De tels systèmes (BMS, Building Management System) sont évidemment gérés centralement depuis longtemps, bien avant EMAN, mais en général par des mécanismes non-standards. La liaison physique avec les équipements se fait souvent en RS-232 ou RS-485, les protocoles sont BACnet, Modbus ou ZigBee.
Plus modeste, la supervision de la consommation électrique à la maison. On peut vouloir savoir combien son frigo consomme (le fameux frigo connecté, de préférence en IPv6, un grand classique du discours marketing sur l'Internet des Objets). Beaucoup des équipements à superviser seront sans doute bon marché, et n'ayant donc pas toutes les capacités EMAN, et devront donc être interrogés via un relais (le mid-level manager dont j'ai parlé plus haut).
Au contraire, dans un centre de données, on a à la fois un enjeu bien plus important (la facture d'électricité de ces centres est énorme) et davantage de moyens (plein de machines connectés qui ne demandent pas mieux que d'être gérées à distance depuis un gestionnaire central). On veut en général une granularité de mesure très fine (pas juste « ce que consomme cette armoire » mais « ce que consomme ce serveur ») donc on va gérer d'importantes quantités de données.
Il ne faut pas oublier les équipements de stockage de l'énergie eux-mêmes, de la batterie traditionnelle à la pile à hydrogène. Ces équipements sont souvent distants (une batterie dans une tour de télécommunications ou en haut d'un château d'eau).
Et pour terminer cette liste très variée, n'oublions pas les humbles imprimantes. En raison de leur consommation électrique élevée, les imprimantes ont souvent des dispositifs d'économie d'énergie (mode « veille »). La consommation varie donc énormément (pensez au chauffage des éléments thermo-mécaniques comme le cylindre lorsque l'imprimante démarre) et des interrogations périodiques risquent donc de rater les moments de haute consommation. Les imprimantes haut de gamme connaissent déjà la gestion à distance et ont souvent SNMP.
Je l'ai indiqué plus haut, EMAN n'arrive pas dans un vide complet. Il y a de nombreuses années que la consommation électrique des équipements informatiques est mesurée et que les machines sont éteintes à distance pour économiser des joules. La section 4 de notre RFC couvre les normes et spécifications techniques existantes (je ne les reprends pas toutes ici, il y en a beaucoup). Ainsi, la CEI a toute une série de normes sur la gestion de l'électricité, avec notamment un modèle décrit dans IEC 61850. C'est un modèle qui embrasse largement, avec une centaine de classes. La norme IEC 62053 est également importante et ces normes ont déjà été utilisées dans EMAN. Proche de IEC 62053, l'ANSI a sa norme C12 sur les compteurs électriques. DMTF a aussi son modèle, DMTF DSP1027.
Il existe aussi des normes plus spécifiques, par exemple le PWG a des normes pour les imprimantes. À noter que la MIB « imprimante », dans le RFC 3805, ne couvre pas la gestion d'énergie. Il y a onze ans, c'était jugé moins important et peu de travail avait été fait en ce sens à l'IETF.
Parmi les autres spécifications existantes, on peut aussi citer ZigBee, élaboré par une organisation privée et pas une SDO ouverte.
Et, bien sûr, il y a Smart grid (section 4.3.3), le projet coordonné par le NIST. Smart grid est plus vaste qu'EMAN (il inclut la distribution de l'énergie) mais moins normatif car c'est plus un projet de coordination que de normalisation.
Un projet important car souvent vu par le consommateur final est Energy Star, lancé par le gouvernement états-unien. Il ne s'agit pas d'une norme technique ou d'un protocole de communication mais d'un ensemble de bonnes pratiques que devraient suivre les équipements électriques, notamment en terme d'efficacité énergétique. Aujourd'hui, EMAN et EnergyStar sont deux efforts séparés mais, dans le futur, EnergyStar pourrait référencer EMAN pour inciter les fabricants à doter leurs systèmes de capacité de mesure.
La section 5 de notre RFC rappelle quelques limites volontaires d'EMAN : EMAN ne cherche pas à résoudre tous les problèmes de l'électricité. Par exemple, EMAN ne couvre pas la production et le transport de l'électricité, seulement sa consommation chez les utilisateurs finaux.
Enfin, pour terminer ce RFC, n'oublions évidemment pas la sécurité, avec la section 6, qui rappelle notamment que la mesure de la consommation électrique peut poser de sérieux problèmes de protection de la vie privée. (On pourra déterminer à distance vos habitudes à la maison, par exemple. La NSA saura quand vous avez des insomnies et allumez la lumière en pleine nuit.) Le RFC 7460, dans sa section 10, détaille ce risque.
Date de publication du RFC : Août 2015
Auteur(s) du RFC : M. Boucadair, D. Binet, S. Durel, B. Chatras (France Telecom), T. Reddy (Cisco), B. Williams (Akamai), B. Sarikaya, L. Xue (Huawei), R. Wheeldon
Pour information
Première rédaction de cet article le 4 septembre 2015
Un problème intéressant de l'Internet d'aujourd'hui est l'identification d'une machine (Host Identification, ou Host-ID, en anglais). Il s'agit de détecter si une machine A avec qui on communique est la même que la machine B avec qui on échange également. (Rappel : identification n'est pas authentification.) Évidemment, l'adresse IP ne convient plus depuis longtemps : les techniques de partage d'adresses IP, comme le CGN, sont trop répandues. Comment faire, alors ? Ce nouveau RFC ne propose pas de solutions mais il fait le tour d'horizon de ce problème complexe, plus complexe qu'on pouvait croire en lisant les solutions qui avaient été proposées par le RFC 6967.
En effet, TCP/IP n'a pas de notion d'identité d'une machine. Au début, les adresses IP, stables et uniques, pouvaient remplir tant bien que mal ce rôle. Mais c'est fini depuis longtemps, surtout en IPv4. (IPv6 n'est pas forcément la solution : je connais des sites qui font du NAT IPv6 en sortie. Voir la section 3 de notre RFC.) Le RFC 6269 décrit en détail ce partage d'adresses IP et ses conséquences (en général néfastes pour l'identification). Notez que NAT et CGN ne sont pas les seules techniques qui amènent à un tel partage (par exemple, un relais applicatif a les mêmes conséquences : plusieurs machines derrière une seule adresse IP, cf. section 5 du RFC.). Et, en plus du partage d'adresses, les tunnels compliquent également les choses, puisqu'une machine aura une adresse très éloignée de son point d'attachement physique.
Outre les points mentionnés dans le RFC 6269, l'absence d'identification facile rend difficile :
Évidemment, le partage d'adresses a aussi des avantages, comme une certaine dissimulation, utile pour la protection de la vie privée (cf. section 12 du RFC). Les solutions d'identification d'une machine peuvent potentiellement annuler certains efforts de protection de la vie privée. Le RFC qui proposait des solutions, le RFC 6967 avait un principe: ne pas transmettre davantage d'informations que celles qui étaient dans le paquet IP original émis par la machine. Notre nouveau RFC se demande (section 2) si ce principe n'est pas trop strict.
La suite du RFC est constituée d'études de cas pour différents
environnements. Par exemple, la section 3 étudie le classique
CGN (RFC 6888). Certains cas seront résolus par
IPv6 (par exemple le
NAT IPv4 courant aujourd'hui) mais d'autres
vont rester comme la traduction d'adresses IPv6 mentionnée plus
haut (RFC 6296). La section 5 regarde les
relais applicatifs : comme le CGN, ils
« cachent » plusieurs machines derrière une même adresse IP. Comme
pour le CGN, cela empêche certains usages comme une identification
de l'abonné individuel, ou comme l'attribution d'une attaque, par
exemple un commentaire menaçant sur un forum. On peut noter que
des solutions spécifiques à tel ou tel protocole applicatif ont
été développées et que, si le relais les utilise, le problème
disparait. C'est le cas de l'en-tête
Received:
de SMTP
(RFC 5321, sections 3.7.2 et 4.4), largement
déployé. Dans le monde HTTP, il y a
l'en-tête Forwarded:
, du RFC 7239, moins fréquemment rencontré. Ces solutions sont
souvent discutées dans le contexte de la protection de la vie
privée car leur caractère indiscret est assez évident.
Autre étude de cas, en section 7, les overlays. Ils ont beaucoup d'usages comme par exemple dans certaines architectures pair à pair (RFC 5694). Les manipulations qu'ils utilisent peuvent également aboutir à masquer les adresses IP d'origine. Le RFC contient également des études de cas sur d'autres architectures, le tout étant synthétisé dans la section 11 sous forme d'un joli tableau qui indique notamment, pour chaque architecture, si les problèmes qu'elle pose à l'identification d'une machine disparaitront ou pas avec IPv6.
Terminons en revenant sur la question de la protection de la
vie privée car, évidemment, les mécanismes
d'identification de la machine visent à envoyer des informations,
là où la vie privée exigerait qu'on en envoie le moins
possible. La section 12 du RFC expose le problème et renvoie à la
section 3 du RFC 6967. Elle note aussi qu'il existe des « solutions »
non-standard à la question de l'identification et que ces
solutions sont souvent discutables en termes de vie privée (par
exemple les en-têtes HTTP non-standards HTTP_MSISDN
, HTTP_X_MSISDN
, HTTP_X_UP_CALLING_LINE_ID
,
HTTP_X_NOKIA_MSISDN
..)
L'IESG a en outre ajouté
une note au RFC, rappelant que, si on considère en effet les
« problèmes » cités par ce RFC 7620 comme des problèmes à
résoudre, les solutions ont de fortes chances de piétiner d'autres
RFC et d'être contradictoires avec les principes de
confidentialité des RFC 6280 et RFC 7258. Bref,
identifier les machines ou protéger la vie privée des
utilisateurs, il faudra sans doute choisir.
Date de publication du RFC : Août 2015
Auteur(s) du RFC : R. Barnes, B. Schneier, C. Jennings, T. Hardie, B. Trammell, C. Huitema, D. Borkmann
Pour information
Première rédaction de cet article le 3 septembre 2015
La publication, grâce à Edward Snowden, d'affreux PowerPoint® de la NSA montrant l'ampleur de la surveillance permanente et généralisée a suscité une prise de conscience chez tous les acteurs de l'Internet. (D'autant plus que d'autres pays en font autant, comme la France, surtout depuis la Loi Renseignement.) Ces PowerPoint® sont souvent d'interprétation difficile et il est donc nécessaire, lorsqu'on travaille aux contre-mesures, d'avoir un modèle clair de la menace contre laquelle on tente de défendre les citoyens internautes. Ce nouveau RFC est l'une des étapes dans ce travail à l'IETF : décrire clairement les risques de la surveillance généralisée.
Ce RFC est écrit par l'IAB, et on note parmi les auteurs Bruce Schneier. Il ne s'agit pas de revenir sur le problème bien connu de l'espionnage des communications (qui est aussi ancien que les réseaux), mais sur les nouveautés qui résultent de la prise de conscience d'un espionnage illimité et indiscriminé (cf. RFC 7258 pour la décision politique de considérer cet espionnage comme une attaque contre l'Internet). Les programmes de la NSA, avec leurs noms rigolos, n'utilisent pas de vulnérabilités inconnues. Aucune science-fiction derrière PRISM, TEMPORA ou BULLRUN. Ces programmes exploitent uniquement des risques connus, mais de manière massive, avec un budget très élevé et une absence totale de scrupules.
Notre nouveau RFC commence donc logiquement par un peu de terminologie (section 2). Il réutilise d'autre part les précédents RFC analogues notamment celui de terminologie de la sécurité (RFC 4949) et celui d'analyse de la protection de la vie privée (RFC 6973). Notons deux choses importantes : d'abord la distinction entre attaques passives et actives. La différence ne vient pas de l'effort de l'attaquant (monter une attaque passive peut être beaucoup de travail) mais du fait que, dans le premier cas, l'attaquant n'écrit rien sur le réseau, n'envoie aucun paquet, ne stoppe aucune communication et ne modifie aucun bit. Il espionne, c'est tout. Au contraire, dans une attaque active comme QUANTUM, le surveillant se permet d'interférer avec les communications, changeant le contenu d'un paquet, envoyant des paquets (pour de l'ARP spoofing par exemple, ou de l'empoisonnement de cache DNS), bloquant certains paquets (par exemple pour faire une attaque par repli contre TLS).
Et la deuxième chose importante est le terme relativement nouveau d'attaque généralisée (pervasive attack), qui désigne les attaques menées, non pas par le lycéen dans son garage, mais par un organisme puissant, pouvant observer (et peut-être intervenir) en de très nombreux points du réseau, avec des capacités big data.
Commençons par décrire l'attaquant, étape indispensable pour élaborer un modèle de menace (section 3). D'abord, un modèle d'un attaquant purement passif (et donc moins puissant que la NSA). S'il est purement passif, cet attaquant « idéal » (idéal du point de vue du modèle, pas du point de vue légal ou moral) a quand même de grandes possibilités, notamment quantitatives. Il voit tout, partout. Le RFC note à juste titre qu'avant les révélations de Snowden (qu'on ne remerciera jamais assez pour ce qu'il a fait), un tel attaquant aurait été considéré comme le produit d'un esprit à la limite de la paranoïa, à part chez les experts en sécurité (qui se doutaient bien, même avant Snowden, de la réalité de la surveillance massive). Cet attaquant peut notamment :
L'attaquant doit donc se débrouiller avec ce qu'il observe directement, puisqu'il ne peut pas le modifier, et ce qu'il en déduit (inférence, c'est-à-dire dériver des informations de celles qu'on a déjà).
Le chiffrement, même sans authentification, protège largement contre un tel attaquant, en réduisant sérieusement les observations qu'il peut faire. (À condition que ce chiffrement soit bien réalisé, par exemple que les générateurs aléatoires soient de qualité. Cette condition est, en pratique, très difficile à remplir.) Le chiffrement est par contre moins efficace contre l'inférence. Par exemple, les fameuses métadonnées laissées en clair (en-têtes IP et TCP lorsqu'on utilise TLS) peuvent donner plein d'information. Un autre exemple est la taille des paquets (qui permet de savoir si on a envoyé ou reçu un fichier), une information que TLS (ou SSH) ne brouille pas. Même IPsec/ESP, s'il chiffre l'en-tête de couche 4, laisse la couche 3 (IP) en clair.
L'idéal bien sûr pour notre attaquant modèle est quand il n'y a pas de chiffrement. Quand tout est en clair, le contenu des communications est accessible trivialement. Voilà pourquoi le RFC 3365 (en 2002 ! Ça ne nous rajeunit pas.) disait déjà que tout protocole IETF susceptible d'envoyer des données en clair doit avoir une version sécurisée qui chiffre. C'est le cas de presque tous les protocoles aujourd'hui. Le RFC note qu'il y a une exception avec le DNS mais elle est en train d'être comblée par le groupe de travail DPRIVE, (cf. le RFC 7626).
L'inférence peut aussi utiliser des informations qui se trouvent dans des bases de données extérieures à la communication elle-même. Par exemple, comme l'ICANN impose de publier les coordonnées des titulaires des noms de domaine dans les TLD qu'elle contrôle, ces informations peuvent nourrir l'inférence. Même chose avec les bases géoIP ou, encore mieux, avec la quantité d'informations disponibles dans des réseaux sociaux comme Facebook. Ces dernières sources sont très riches, avec de l'information déjà structurée et envoyée « volontairement » par les utilisateurs. Cela met une sérieuse limite à ce que l'IETF peut faire pour améliorer la vie privée sur l'Internet : améliorer les protocoles n'est pas suffisant.
Notre RFC détaille comment inférer à partir des observations
directes. Par exemple, pour corréler des adresses IP avec des
utilisateurs, on a plusieurs outils : une requête DNS « inverse »
(type PTR) suffit parfois. Ces requêtes
marchent bien pour les serveurs, peu nombreux et stables (donc une
copie locale peut être facilement faite, pour accélerer le
processus). Elles sont moins efficaces pour les clients (on
obtient parfois des trucs sans trop d'intérêt comme
ARouen-655-1-102-140.w90-23.abo.wanadoo.fr
). Notez
que le RFC étudie les possibilités de surveillance
massive. La technique (légale dans de
nombreux pays démocratiques) qui consiste pour la police à
demander au FAI le nom de l'utilisateur
correspond à telle adresse IP ne marche pas ici, elle ne
passe pas à l'échelle. C'est un exemple de
la différence entre enquêtes ciblées et surveillance généralisée,
style Big Brother.
Même si le FAI ne coopère pas dans la mission de surveillance,
il existe d'autres moyens de relier une adresse IP à des identités
de l'utilisateur. Par exemple, s'il utilise
IMAP, on a facilement son identificateur,
sauf si la session est chiffrée (ce qui n'est pas encore fait
partout). Le problème n'est pas spécifique à IMAP et se trouve
aussi dans SIP et dans bien d'autres
protocoles. Chiffrer la session n'est donc pas uniquement utile
lorsqu'on a « quelque chose à cacher » mais aussi simplement
lorsqu'on veut éviter d'être suivi à la trace. Un autre exemple
amusant est décrit en section 3.3.4 : l'utilisation des en-têtes
Received:
du courrier. Même si tout le
courrier est chiffré, l'attaquant peut toujours s'abonner à des
listes de discussion publiques comme perpass. Il reçoit alors des messages avec ce
genre d'en-têtes :
Received: from 192-000-002-044.zone13.example.org (HELO ?192.168.1.100?) (xxx.xxx.xxx.xxx) by lvps192-000-002-219.example.net with ESMTPSA (DHE-RSA-AES256-SHA encrypted, authenticated); 27 Oct 2013 21:47:14 +0100 Message-ID: <526D7BD2.7070908@example.org> Date: Sun, 27 Oct 2013 20:47:14 +0000 From: Some One <some.one@example.org>
Collectionner ces en-têtes va lui permettre de compiler une base des
émetteurs et des adresses IP qu'ils utilisent. Au bout d'un moment,
l'attaquant saura que, si un paquet IP vient de
192.0.2.44
, il y a de fortes chances que ce soit
l'utilisateur Some One.
Parmi les techniques d'inférence, il y a aussi celles fondées sur les graphes de relations. Si une adresse IP envoie X % de ses paquets à l'IETF, Y % au MIT et Z % à YouPorn, l'observation ultérieure d'une toute autre adresse IP qui a le même graphe de relations peut permettre de conclure que la même personne est derrière les deux adresses.
Il y a aussi les adresses MAC. Celles-ci sont uniques au niveau mondial et sont en général très stables (peu de gens utilisent macchanger). Si le réseau est publiquement accessible (ce qui est typiquement le cas des hotspots WiFi), l'attaquant peut facilement regarder « qui est là » et mettre à jour sa base de données. Notez que certaines techniques, comme les SSID cachés aggravent le risque : la machine de l'utilisateur va diffuser les SSID qu'elle cherche, donnant ainsi davantage d'informations à l'attaquant. Des bases de données des hotspots existent déjà (constituées, par exemple, par les utilisateurs d'Android, dont le smartphone transmet à Google et à la NSA plein d'informations sur les SSID détectés). C'est évidemment encore plus facile pour l'attaquant si le réseau WiFi n'utilise pas WPA ou équivalent (tapez sur votre fournisseur WiFi si ce n'est pas le cas).
Ce très intéressant exposé des techniques d'espionnage existantes est évidemment incomplet : nul doute que la NSA ou la DGSI ont plein d'autres idées. Et il y a certainement des différences entre la théorie de la section 3 et la réalité de la surveillance massive effectuée par ces organisations. Il est bien sûr impossible de savoir exactement ce que la NSA sait faire. Tout au plus peut-on faire quelques suppositions raisonnables (section 4 de notre RFC). D'abord, les révélations Snowden ne laissent pas de doute sur l'existence de cette surveillance généralisée effectuée par la NSA et le GCHQ (notez que notre RFC ne fait pas dans la fausse pudeur, et cite les noms de ces organisations, alors qu'avant on ne parlait que de « certaines agences gouvernementales »). Ensuite, ces mêmes révélations donnent une première idée des méthodes utilisées. Et il n'y a pas que la NSA et ses collaborateurs : nul doute que les services secrets français, chinois, russes ou israéliens espionnent également massivement, dans la mesure de leurs moyens matériels et de leurs compétences. Mais on n'a pas encore les détails, on attend un héros comme Snowden dans ces pays moins imbibés de culture démocratique.
Donc, reality check, à la lumière des révélations Snowden, que fait effectivement la NSA, par rapport à l'attaquant passif idéalisé de la section 3 ? D'abord, cette organisation d'espionnage a effectivement une activité massive de collecte passive :
Ce n'est pas tout de capturer, il faut aussi décoder, et une partie du trafic est chiffré. La NSA ne renonce pas devant le chiffrement et, par exemple, son programme BULLRUN met en œuvre divers moyens pour affaiblir la protection qu'offre la cryptographie, par exemple par des modifications du code.
Et, surtout, la NSA ne se contente pas d'attaques passives, comme le faisait l'attaquant modélisé en section 3. Elle a aussi des mécanismes actifs :
Si les révélations Snowden ne portent que sur la NSA et le GCHQ, le RFC rappelle que d'autres États n'hésitent certainement pas à recourir aux mêmes méthodes, et le cas évident de la Chine est cité, avec les techniques de modification de données utilisées par le GFW, techniques qui rappellent fortement le QUANTUM états-unien. Par exemple, le réseau chinois n'hésite pas à modifier les réponses DNS. De l'espionnage actif à l'attaque par déni de service, il n'y a qu'un pas, que le gouvernement chinois a franchi avec le Grand Canon et peut-être avec l'attaque « Poivre du Sichuan ».
La section 5 de notre RFC synthétise la menace à laquelle nous devons désormais faire face. Les attaquants comme la NSA ou la DGSE peuvent :
La traditionnelle opposition attaquant passif / attaquant actif des analyses de sécurité est sans doute insuffisante dans le cas de la surveillance systématique. Les trois dernières possibilités citées plus haut (obtention ponctuelle des clés, obtention systématique des clés et accès aux données stockées) étaient ainsi absentes ou très sous-estimées, avant Snowden. En outre, comme ces trois possibilités se situent en dehors des protocoles réseau, l'IETF tendait à les négliger, les considérant comme hors de son domaine.
Autrefois, on considérait que les attaquants actifs étaient forcément situés en bordure du réseau : sur un hotspot WiFi non protégé par WPA, une attaque active est triviale, pour toute personne connectée à ce hotspot. Mais les organisations comme la NSA peuvent également agir au cœur de l'Internet, ce qui augmente sérieusement leurs possibilités. J'avais entendu lors d'une conférence de sécurité un expert affirmer qu'il ne fallait jamais utiliser la WiFi mais toujours la 3G pour des raisons de sécurité. Ce conseil peut avoir un sens face à un attaquant lycéen dans son garage mais certainement pas face à des organisations importantes, pour qui le réseau de l'opérateur 3G est terrain de chasse libre.
La différence quantitative entre le cracker de base dans son garage et une organisation étatique ou para-étatique devient en outre une différence qualitative. Le fait de pouvoir tout observer rend l'inférence beaucoup plus efficace, même en cas de chiffrement. Ainsi, un observateur présent en beaucoup d'endroits peut corréler des flux réseau entre eux, même s'ils sont chiffrés. Un observateur présent en un seul point du réseau n'a pas cette possibilité. Un simple VPN chiffré peut le rendre aveugle, alors que l'observateur présent partout peut trouver les serveurs où on se connecte uniquement en corrélant le trafic du VPN avec le trafic simultané en un autre point de l'Internet (XKEYSCORE fait apparemment cela.)
En prime, les attaquants susceptibles de monter un système de surveillance massive, comme la DGSE, sont également souvent capables de subvertir l'authentification. Chiffrer, en effet, ne sert pas beaucoup si on chiffre, non pas pour le vrai destinataire mais pour l'homme du milieu. La protection habituelle contre ces attaques de l'homme du milieu est l'authentification. Par exemple, on vérifie l'identité du correspondant via un certificat X.509. Mais une organisation puissante peut contraindre les autorités de certification à émettre de vrais/faux certificats. Comme il suffit d'une seule autorité de certification contrainte (ou piratée, ce qui revient au même) pour faire un certificat pour n'importe quel serveur, on voit que la NSA n'a que l'embarras du choix.
Tout cela ne veut pas forcément dire qu'un attaquant puissant comme la NSA ou le FSB a table ouverte. Ces attaques ont des coûts et l'analyse de ces coûts est une branche relativement récente de la sécurité (elle est bien illustrée dans un excellent dessin de XKCD). On ne peut évidemment pas espérer aveugler les agences d'espionnage mais on peut augmenter le prix de leurs activités, jusqu'à les forcer à réduire ces activités. La section 5.2 de notre RFC discute ces coûts.
Tous ne sont pas forcément monétaires. Par exemple, comme les espions, à l'égal des cloportes, n'aiment pas la lumière, le risque d'être pris la main dans le sac, représente un coût. Cela suppose évidemment que l'espion soit détecté et identifié. Si c'est fait, les conséquences peuvent aller de la fermeture d'une voie d'accès aux données, à des poursuites judiciaires, ou à la démission d'un ministre bouc émissaire.
Par exemple, une attaque passive offre à priori moins de chance de se faire attraper puisqu'on ne modifie pas le trafic. Sauf qu'un branchement physique sur des câbles va laisser des traces (les plombiers du Watergate ou du Canard Enchainé en savent quelque chose). Si l'opérateur réseau n'est pas complice de l'attaquant (il semble que, dans le cas de TEMPORA, il l'était), la « bretelle » peut être découverte à l'occasion d'une opération de maintenance, comme ce fut le cas dans l'affaire de Tarnac. Même si l'écoute se faisait de manière purement logicielle, un employé zélé peut la détecter un jour (« mais pourquoi ce port du commutateur est-il en mode miroir ? »). Les techniques sans-fil ne nécessitent pas de branchement physique mais, souvent, la portée utile est faible et l'attaquant doit se rapprocher, ce qui peut mener à sa détection. Bref, la vie d'un espion n'est pas toujours facile. Si l'opérateur collabore, c'est plus facile pour l'espion mais, s'il y a un Snowden parmi les employés de l'opérateur, patatras, la belle opération secrète d'écoute finit en une du Monde ou du New York Times. Si l'attaquant est un État, il peut forcer les employés d'un opérateur national à collaborer mais c'est plus difficile avec les étrangers.
C'est encore pire (du point de vue de l'attaquant) avec les méthodes actives. Elles laissent forcément davantage de traces. Par exemple, un vrai/faux certificat X.509 peut être détecté par des mesures comme les « certificats au grand jour » du RFC 9162.
Les attaques actives représentent aussi souvent un défi technique plus important. Là où les attaques passives nécessitent surtout des gros disques durs, les attaques actives peuvent demander, par exemple, qu'un injecteur de paquets frauduleux gagne la course contre la source légitime afin que ses paquets arrivent avant. À un térabit/s, ce n'est pas évident et cela ne se fait pas avec un PC ordinaire !
Voilà, on a fait un tour partiel des attaquants et de leurs capacités. Les solutions à ces attaques seront développées plus tard (mais cela ne sera pas facile).
Date de publication du RFC : Août 2015
Auteur(s) du RFC : P. Saint-Andre
(&yet), A. Melnikov (Isode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF precis
Première rédaction de cet article le 29 août 2015
Ah, les plaisirs de l'internationalisation du logiciel... Quand l'informatique ne concernait que les États-Unis, tout était simple. Un utilisateur ne pouvait avoir un nom (un login) que composé des lettres de l'alphabet latin (et même chose pour son mot de passe). Mais de nos jours, il n'est pas acceptable de se limiter au RFC 20. Il faut que Пу́тин ou 艾未未 puissent écrire leur nom dans leur écriture et l'informatique doit suivre. La première tentative de normaliser ces noms d'utilisateur en Unicode, dans le RFC 4013 n'avait pas été un immense succès et elle est désormais remplacée par une approche un peu différente, décrite dans ce nouveau RFC, qui a depuis été remplacé par le RFC 8265.
Mais pourquoi faut-il standardiser quelque chose ? Pourquoi ne
pas dire simplement « les noms d'utilisateur sont en
Unicode » et basta ? Parce que les
logiciels qui gèrent noms d'utilisateurs et mots de passe ont
besoin de les manipuler, notamment de les
comparer. Si ПУ́ТИН
essaie de se loguer, et
que la base de données contient un utilisateur пу́тин
, il faut bien déterminer si c'est
le même utilisateur (ici, oui, à part la casse). C'est en général assez simple dans l'alphabet
latin (ou dans le cyrillique utilisé pour
les exemples) mais il y a d'autres cas plus vicieux qui
nécessitent quelques règles supplémentaires.
Le RFC 4013, qui était fondé sur le cadre du RFC 3454 visait à décrire ces règles. Mais l'approche utilisée n'a pas accroché (en partie parce qu'elle était liée à une version d'Unicode particulière) et le défunt stringprep du RFC 3454 a été remplacé par un nouveau cadre, celui du RFC 7564. Notre nouveau RFC 7613 est l'adaptation de ce RFC 7564 au cas spécifique des noms d'utilisateur et des mots de passe.
Ces noms et ces mots de passe (aujourd'hui, il faudrait plutôt
dire phrases de passe) sont largement
utilisés pour l'authentification, soit
directement (SASL
PLAIN
du RFC 4616, authentification
de base de HTTP du RFC 7617), ou
bien comme entrée d'une fonction de condensation
cryptographique (SASL SCRAM
du
RFC 5802 ou bien authentification HTTP
digest du RFC 7616). L'idée est que
les opérations de base sur ces noms (et sur les mots de passe) ne
surprennent pas excessivement l'utilisateur, quel que soit son
pays, sa langue, sa culture. Un Français ou un Belge ne sera probablement pas trop
étonné que Dupont
soit accepté comme synonyme
de dupont
mais il le serait davantage si
dupond
l'était. Évidemment, la tâche est
impossible (les utilisateurs sont tous différents) mais l'idée est
de ne pas faire un système parfait mais un système qui marche la
plupart du temps.
C'est là qu'intervient le cadre PRECIS (PReparation,
Enforcement, and Comparison of Internationalized
Strings) du RFC 7564. Il évite que
chaque développeur d'un système d'authentification doive lire et
comprendre toutes les conséquences d'Unicode, et lui permet de
s'appuyer sur une analyse déjà faite. Un exemple de piège
d'Unicode (et qui montre pourquoi « on va juste dire que les noms
d'utilisateur peuvent être n'importe quel caractère Unicode » est
sans doute une mauvaise politique) est le chiffre 1 en exposant,
U+00B9 (comme ça : « ¹ » Si vous ne voyez rien, c'est parce
que votre logiciel ne sait pas afficher ce caractère. Vous pouvez
toujours regarder le source HTML pour
comprendre l'exemple.). Doit-on l'autoriser ? Le mettre en
correspondance avec le 1 traditionnel de façon à ce que
user¹
et user1
soient le
même nom ? Imaginez un client XMPP qui vous
dise « user¹@example.com
veut être votre
copain. Je l'autorise ? » et que vous acceptiez en croyant que
c'était user1@example.com
. Bien sûr, on ne
peut pas réellement parler d'« attaque » dans ce cas, une telle
erreur permettrait juste de faire quelques farces mais, pour le
logiciel qui vérifie une identité, des confusions seraient plus
gênantes. Si les « attaques » exploitant la similitude de
caractères Unicode sont surtout un fantasme d'informaticien anglophone n'ayant
jamais réellement accepté l'internationalisation (plutôt qu'une
réalité du terrain), il est quand
même plus prudent de supprimer quelques causes de cafouillage le
plus tôt possible.
Je l'ai dit plus haut, ce nouveau RFC met fin au profil SASLprep du RFC 4013 mais les protocoles qui l'utilisaient ne sont pas mis à jour automatiquement, ils devront publier une nouvelle version de leur norme (comme le RFC 7622 pour XMPP).
Notre RFC compte deux sections importantes, décrivant le profil
PRECIS pour les noms d'utilisateur (section 3) et les mots de
passe (section 4). Commençons par les noms d'utilisateur. Un
nom est une chaîne de caractères Unicode
composée de parties séparées par des espaces. Chaque partie doit
être une instance de IdentifierClass
et est
normalisée en NFC. L'encodage doit être
UTF-8. Pourquoi cette notion de « parties
séparées par des espaces » ? Parce que la classe
IdentifierClass
du RFC 7564 ne permet pas les espaces, ce qui est gênant pour
certains identificateurs (« Prénom Nom » par exemple, cf. section
3.5). D'où la grammaire
de la section 3.1 :
username = userpart *(1*SP userpart)
qui dit « un nom d'utilisateur est composé d'au moins une partie,
les parties étant séparées par un nombre quelconque
d'espaces ». Une des conséquences de cette grammaire étant que le
nombre d'espaces n'est pas significatif : Jean
Dupont
et Jean Dupont
sont
le même identificateur.
Chaque partie étant une instance de
l'IdentifierClass
du RFC 7564, les caractères interdits par cette classe sont
donc interdits pour les noms d'utilisateurs. Une application
donnée peut restreindre (mais pas étendre) ce profil. Ces noms
d'utilisateurs sont-ils sensibles à la
casse ? Ce fut l'un des deux gros débats dans le
groupe de travail PRECIS, puisque
certains protocoles ont fait un choix et d'autres le choix opposé
(l'autre gros débat concernait - bien à tort - un
problème subtil et peu important sur les conséquences des
changements dans les nouvelles versions d'Unicode). Eh bien, il y
a désormais deux sous-profils, un sensible et un insensible. Les
protocoles et applications utilisant ce RFC 7613 devront
annoncer clairement lequel ils utilisent. Et les bibliothèques
logicielles manipulant ces utilisateurs auront probablement une
option pour indiquer le sous-profil à utiliser.
Le sous-profil UsernameCaseMapped
rajoute
donc une règle de préparation des chaînes de caractères : tout
passer en minuscules (avant les comparaisons, les condensations
cryptographiques, etc), en utilisant l'algorithme Case
Folding d'Unicode (oui, changer la casse est bien plus
compliqué en Unicode qu'en ASCII). Une fois
la préparation faite, on peut comparer octet par octet
(rappelez-vous que la chaîne doit être en
UTF-8).
L'autre sous-profil,
UsernameCasePreserved
ne change pas la casse,
comme son nom l'indique. ПУ́ТИН
et пу́тин
y
sont donc deux identificateurs différents. C'est la seule
différence entre les deux sous-profils. Notre RFC recommande le
profil insensible à la casse,
UsernameCaseMapped
, pour éviter des surprises
comme celles décrites dans le RFC 6943
(cf. section 8.2 de notre RFC).
Bon, tout ça est bien nébuleux et vous préféreriez des exemples ? Le RFC nous en fournit. D'abord, des identificateurs peut-être surprenants mais légaux (légaux par rapport à PRECIS : certains protocoles peuvent mettre des restrictions supplémentaires). Attention, pour bien les voir, il vous faut un navigateur Unicode, avec toutes les polices nécessaires :
juliet@example.com
: le @ est
autorisé donc un JID (identificateur
XMPP) est légal.fussball
: un nom d'utilisateur
traditionnel, purement ASCII, qui passera
partout, même sur les systèmes les plus antédiluviens.fußball
: presque le même mais
avec un peu d'Unicode. Bien qu'en
allemand, on traite en général ces deux
identificateurs comme identiques, pour PRECIS, ils sont
différents. Si on veut éviter de la confusion aux germanophones,
on peut interdire la création d'un des deux identificateurs si
l'autre existe déjà : PRECIS ne donne que des règles miminales,
on a toujours droit à sa propre politique derrière.π
: entièrement en Unicode, une
lettre.Σ
: une lettre
majuscule.σ
: la même en
minuscule. Cet identificateur et le précédent seront identiques
si on utilise le profil UsernameCaseMapped
et différents si on utilise le profil UsernameCasePreserved
.ς
: la même, lorsqu'elle est en
fin de mot. Le cas de ce sigma final est
compliqué, PRECIS ne tente pas de le résoudre. Comme pour le
eszett plus haut, vous pouvez toujours
ajouter des règles locales.Par contre, ces noms d'utilisateurs ne sont pas valides :
HenriⅣ
: le chiffre romain 4 à
la fin est illégal (car il a ce qu'Unicode appelle « un
équivalent en compatibilité », la chaîne « IV »).♚
: seules les lettres sont
acceptées, pas les symboles (même règle que pour les noms de domaine).Continuons avec les mots de passe (section 4). Comme les noms,
le mot de passe est une chaîne de caractères
Unicode. Il doit
être une instance de FreeformClass
. Cette
classe autorise bien plus de caractères que pour les noms
d'utilisateur, ce qui est logique : un mot de passe doit avoir
beaucoup d'entropie. Peu de caractères sont donc interdits (parmi
eux, les caractères de
contrôle, voir l'exemple plus bas). Les
mots de passe sont sensibles à la casse. L'encodage doit être
UTF-8.
Des exemples ? Légaux, d'abord :
correct horse battery staple
: vous
avez reconnu un fameux dessin de XKCD.Correct Horse Battery Staple
: les
mots de passe sont sensibles à la casse, donc c'est un mot de
passe différent du précédent.πßå
: un mot de passe en Unicode ne pose
pas de problème.Jack of ♦s
: et les symboles sont
acceptés, contrairement à ce qui se passe pour les noms d'utilisateur.foo bar
: le truc qui
ressemble à un trait est
l'espace de l'Ogham, qui doit normalement
être normalisé en un espace ordinaire, donc ce mot de passe est
équivalent à foo bar
.Par contre, ce mot de passe n'est pas valide :
my cat is a by
: les caractères
de contrôle, ici une tabulation, ne sont pas autorisés.Rappelez-vous que ces profils PRECIS ne spécifient que des règles minimales. Un protocole utilisant ce RFC peut ajouter d'autres restrictions (section 5). Par exemple, il peut imposer une longueur minimale à un mot de passe (la grammaire de la section 4.1 n'autorise pas les mots de passe vides mais elle autorise ceux d'un seul caractère, ce qui serait évidemment insuffisant pour la sécurité), une longueur maximale à un nom d'utilisateur, interdire certains caractères qui sont spéciaux pour ce protocole, etc.
Certains profils de PRECIS suggèrent d'être laxiste en acceptant certains caractères ou certaines variantes dans la façon d'écrire un mot (accepter strasse pour straße ? C'est ce qu'on nomme le principe de robustesse.) Mais notre RFC dit que c'est une mauvaise idée pour des mots utilisés dans la sécurité, comme ici (voir RFC 6943).
Comme toutes les fois qu'on change les règles, il faut se préoccuper de la migration depuis l'ancien système (c'est la section 6 du RFC). Si vous aviez déjà des noms d'utilisateur en Unicode en suivant l'ancien système SASLprep, celui du RFC 4013, il va falloir examiner votre base de données et peut-être faire des conversions. Pour les noms, il y a notamment le fait que SASLprep utilisait la normalisation Unicode NFKC alors que PRECIS se sert de NFC. Ce n'est pas forcément si grave que ça car PRECIS interdit les lettres ayant un équivalent de compatibilité, les seules qui sont traitées différemment par NFKC et NFC. Il est donc recommandé d'examiner la base et de repérer des noms ayant un de ces équivalents.
Pour les mots de passe, c'est plus compliqué puisque, si vous êtes sérieux, vous ne les stockez pas en clair, et vous ne pouvez donc pas les examiner. Disons que si un utilisateur qui a utilisé toutes les possibilités rigolotes d'Unicode n'arrive pas à s'authentifier après la migration, il faudra penser à ce problème.
Les profils PRECIS ont été ajoutés au registre IANA (section 7 de notre RFC).
Un petit mot sur la sécurité et on a fini. La section 8 de notre RFC revient sur quelques points difficiles. Notamment, est-ce une bonne idée d'utiliser Unicode pour les mots de passe ? Ça se discute. D'un côté, cela augmente les possibilités (en simplifiant les hypothèses, avec un mot de passe de 8 caractères, on passe de 10^15 à 10^39 possibilités en permettant Unicode et plus seulement ASCII), donc l'entropie. D'un autre, cela rend plus compliqué la saisie du mot de passe, surtout sur un clavier avec lequel l'utilisateur n'est pas familier. Le monde est imparfait et il faut choisir le moindre mal...
Enfin, un résumé des changements depuis l'ancienne technique, celle du RFC 4013, figure dans l'annexe A. Il rappelle que l'ancien stringprep/SASLprep est remplacé par une approche vraiment différente, même si, dans les cas « normaux », le résultat sera le même. Par exemple, stringprep (RFC 3454) autorisait tous les caractères sauf ceux qui étaient interdits alors que PRECIS, comme le fait IDN depuis la nouvelle norme RFC 5891, fait l'inverse (tout ce qui n'est pas autorisé est interdit). Pour résumer les autres principaux changements :
Date de publication du RFC : Août 2015
Auteur(s) du RFC : E. Chen (Cisco Systems), J. Scudder
(Juniper Networks), P. Mohapatra (Sproute
Networks), K. Patel (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 28 août 2015
Que doit faire un routeur
BGP lorsqu'il reçoit un message de type
UPDATE
avec un attribut incorrect ? La norme
était claire : le routeur doit fermer la session BGP en cours (et donc
perdre toutes les routes associées). Cela partait du bon sens (si
l'attribut est corrompu, on ne peut pas se fier au routeur qui l'a
envoyé) mais cela avait des conséquences sérieuses : on supprimait
toutes les routes, pas seulement celle dans l'annonce
UPDATE
. Ce court RFC modifie donc BGP sur un
point : on ne coupe plus forcément toute la session, on
retire uniquement la route qui figurait dans l'annonce incorrecte.
L'ancienne norme figurait dans le RFC 4271, section 6 : « When any of the conditions described here are detected, a NOTIFICATION message, with the indicated Error Code, Error Subcode, and Data fields, is sent, and the BGP connection is closed ». En pratique, cela voulait dire que les routeurs coupaient des sessions simplement à cause d'un attribut mal formé. Cela pose un problème de sécurité : comme certains routeurs ne vérifient pas les attributs des annonces, l'annonce avec l'attribut invalide peut être propagée et planter des sessions situées bien après l'origine de l'annonce, rendant le débogage et l'attribution des responsabilités très difficiles. En outre, l'annonce a pu être dupliquée par ces routeurs qui ne vérifient pas, et une seule annonce peut donc planter plusieurs sessions. Cela s'était produit, par exemple, dans le cas du fameux attribut 99.
Que peut faire un routeur BGP lorsque il reçoit une annonce invalide ? La section 2 du RFC liste les possibilités, de la plus violente à la plus modérée :
L'approche « ignorer l'annonce invalide » n'est pas citée : dans un protocole où les mises à jour sont incrémentales, comme BGP (qui n'envoie pas la table de routage complète, seulement les changements), elle pourrait mener à des routes impossibles à détruire (cf. section 6).
C'est la section 3 qui contient les nouvelles règles exactes, après moultes discussions à l'IETF. Pour résumer : c'est la troisième option (treat-as-withdraw) qui est désormais recommandée dans la plupart des cas.
Le reste du RFC est consacré à des détails pratiques. Par exemple,
en section 5, on trouve des règles d'encodage qui permettront
d'accéder aux routes annoncées (NLRI, Network Layer
Reachability Information) malgré la présence d'attributs mal
formés. En effet, c'est très joli de dire qu'on doit traiter une
annonce invalide comme un retrait mais il faut pour cela savoir
quelles routes retirer (réinitialiser toute la session est bien plus
simple à mettre en œuvre). Quand l'annonce est invalide, l'analyser
n'est pas trivial. Notre RFC demande donc de faciliter la tâche du
routeur de réception de l'annonce, par exemple en encodant les
attributs MP_REACH_NLRI
et
MP_UNREACH_NLRI
au tout début de la liste des
attributs (pour pouvoir les comprendre même si l'annonce est
invalide). Évidemment, les routeurs anciens ne suivent pas forcément ces
règles et les récepteurs doivent donc rester prêts à tout.
Bien sûr, rien n'est parfait. L'ancienne règle de couper toute la session n'était pas due au désir des auteurs de BGP de perturber le plus possible l'Internet. Il y avait de bonnes raisons à cette décision, notamment de garantir la cohérence du routage. Avec la nouvelle règle, ce n'est plus aussi simple et on risque donc des tables de routage incohérentes (un routeur ayant accepté l'annonce et un autre l'ayant traité comme un retrait...), avec leurs conséquences, comme des boucles de routage. Cela explique la très longue gestation de ce RFC, due à de nombreuses discussions à l'IETF. Il faut dire que toucher à BGP est toujours délicat : une erreur peut potentiellement planter tout l'Internet.
La section 7 du RFC décrit en détail ce que veut dire « malformé »
pour un attribut BGP. Par exemple, l'attribut
ORIGIN
(RFC 4271, section
4.3, et qui indique la source de l'information contenue dans
l'annonce) a normalement une longueur de 1 (les attributs BGP sont
encodés en TLV) et toute autre longueur indique
un attribut ORIGIN
mal formé : autrefois, cela
aurait coupé la session, depuis notre RFC, cela doit entrainer un
retrait de la route contenue dans l'annonce. Pour l'attribut
ORIGIN
, même chose si la valeur de l'attribut
n'est pas une des valeurs spécifiées (IGP
,
EGP
ou INCOMPLETE
).
Autre exemple, l'attribut COMMUNITIES
(RFC 1997) doit avoir une longueur qui est un multiple de 4. Si ce
n'est pas le cas => attribut mal formé => annonce traitée comme
étant un retrait de routes.
Conséquence de ce nouveau RFC : tout nouvel attribut spécifié doit indiquer le traitement à appliquer en cas de malformation (section 8). Ce sera en général treat-as-withdraw mais cela doit être marqué explicitement dans la norme décrivant le nouvel attribut.
Un avantage du long délai avant la sortie de ce RFC, est que ce nouveau comportement a déjà été mis en œuvre dans la plupart des routeurs (Alcatel-Lucent SR OS, Cisco IOS, Cisco IOS XR, Juniper JUNOS, Quagga).
Date de publication du RFC : Août 2015
Auteur(s) du RFC : W. Kumari (Google), R. Bush (Internet Initiative Japan), H. Schiller (Verizon), K. Patel (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 28 août 2015
Petit quizz BGP : sans relire le RFC 4271, pouvez-vous dire si 0 est acceptable comme numéro de système autonome dans un message BGP ? Si vous ne pouvez pas, ce n'est pas grave, vous n'êtes pas le seul, ce point n'avait jamais été clairement précisé. Ce très court RFC règle le problème : 0 est désormais officiellement interdit.
Pourtant, cela fait longtemps que l'AS 0
(zéro, pas O) est spécial : il est indiqué dans le registre IANA comme non routable. En outre, les
ROA (Route Origin Authorizations) IANA du RFC 6491 utilisent l'AS 0 pour indiquer
qu'un préfixe IP ne peut
pas être annoncé sur l'Internet. Mais cela veut-il dire qu'un message BGP, par exemple une annonce de route,
n'a pas le droit de contenir l'AS 0 dans son chemin d'AS
(AS_PATH
) ? La plupart des mises en œuvre
de BGP avaient choisi cette voie et rejetaient ces annonces. Ce
comportement est désormais officiel.
Donc, en deux mots, la nouvelle règle : il est défendu d'utiliser
l'AS 0 dans les attributs BGP AS_PATH
,
AS4_PATH
, AGGREGATOR
et
AS4_AGGREGATOR
qu'on émet. Si un pair BGP le
fait, et vous envoie de tels attributs,
ses messages doivent être considérés comme malformés et rejetés selon
les procédures du RFC 7606.
Si jamais un pair ouvre une session en indiquant que son AS est zéro, on doit avorter ladite session avec le message d'erreur n° 2, Bad peer AS (RFC 4271, section 6.2).
Date de publication du RFC : Août 2015
Auteur(s) du RFC : S. Bortzmeyer (AFNIC)
Pour information
Réalisé dans le cadre du groupe de travail IETF dprive
Première rédaction de cet article le 27 août 2015
Les révélations d'Edward Snowden en juin 2013 ont fait comprendre à tous, même aux plus obtus qui s'obstinaient à nier l'ampleur et la gravité de la surveillance généralisée, que les problèmes de vie privée ne sont pas un simple détail. Au contraire, il est maintenant établi que l'Internet, et les technologies numériques en général, sont utilisés comme arme de surveillance massive par le gouvernement des États-Unis et, quasi-certainement, par plusieurs autres, dans la mesure de leurs moyens. Cela a mené l'IETF, qui avait parfois tendance à relativiser l'intensité du problème, à se pencher sérieusement sur la question. Plusieurs travaux ont été lancés. L'un d'eux concerne la protection de la vie privée lors de l'utilisation du DNS et ce nouveau RFC, écrit par votre serviteur, est son premier résultat.
Ce RFC est en fait à la croisée de deux activités. L'une d'elles consiste à documenter les problèmes de vie privée, souvent ignorés jusqu'à présent dans les RFC. Cette activité est symbolisée par le RFC 6973, dont la section 8 contient une excellente analyse de ces problèmes, pour un service particulier (la présence en ligne). L'idée est que, même si on ne peut pas résoudre complètement le problème, on peut au moins le documenter, pour que les utilisateurs soient conscients des risques. Et la seconde activité qui a donné naissance à ce RFC est le projet d'améliorer effectivement la protection de la vie privée des utilisateurs du DNS, en marchant sur deux jambes : minimiser les données envoyées (c'est le sous-projet qname minimization) et les rendre plus résistantes à l'écoute, via le chiffrement. La diminution des données est étudiée dans le groupe de travail IETF dnsop (le principal document est DNS query name minimisation to improve privacy) et le chiffrement dans le groupe de travail IETF dprive (le principal document est TLS for DNS: Initiation and Performance Considerations, qui propose de faire circuler les requêtes DNS sur TLS). Le groupe dprive (le nom, contraction de DNS privacy, suit la tradition des noms de groupes humoristiques, ce qui est fréquent à l'IETF, et est dû à Alexander Mayrhofer) est également l'enceinte où a été développé le RFC 7626, objet principal de cet article.
Donc, pourquoi un RFC sur les questions de vie privée dans le DNS ?
Ce dernier est un très ancien protocole, dont l'une des particularités
est d'être mal spécifié : aux deux RFC originaux, les RFC 1034 et RFC 1035, il faut ajouter dix
ou vingt autres RFC dont la lecture est nécessaire pour tout
comprendre du DNS. Et aucun travail de consolidation n'a jamais été
fait, contrairement à ce qui a eu lieu pour
XMPP, HTTP ou
SMTP. Or, le DNS est crucial, car quasiment
toutes les transactions Internet mettent en jeu au moins une requête
DNS (ne me dites pas des bêtises du genre « moi, je télécharge avec
BitTorrent, je n'utilise pas le DNS » : comment
allez-vous sur thepiratebay.am
?) Mais, alors
que les questions de vie privée liées à HTTP
ont fait l'objet d'innombrables articles et études, celles liées au
DNS étaient largement ignorées (voir la bibliographie du RFC pour un
état de l'art). Pourtant, on peut découvrir bien des choses sur votre
activité Internet uniquement en regardant le trafic DNS.
Une des raisons du manque d'intérêt pour le thème « DNS et vie privée » est le peu de compétences concernant le DNS : le protocole est souvent ignoré ou mal compris. C'est pourquoi le RFC doit commencer par un rappel (section 1) du fonctionnement du DNS.
Je ne vais pas reprendre tout le RFC ici. Juste quelques rappels
des points essentiels du DNS : il existe deux sortes de serveurs DNS,
qui n'ont pratiquement aucun rapport. Il y a les
serveurs faisant autorité et les
résolveurs. Les premiers sont ceux qui
connaissent de première main l'information pour une zone DNS donnée
(comme fr
ou
wikipedia.org
). Ils sont gérés par le titulaire
de la zone ou bien sous-traités à un hébergeur DNS. Les seconds, les
résolveurs, ne connaissent rien (à part l'adresse IP des
serveurs de la racine). Ils interrogent donc
les serveurs faisant autorité, en partant de la racine. Les résolveurs
sont gérés par le FAI ou le service
informatique qui s'occupe du réseau local de l'organisation. Ils
peuvent aussi être individuels, ou bien au contraire être de gros
serveurs publics comme Google Public
DNS, gros fournisseur de la NSA. Pour prendre
un exemple concret (et en simplifiant un peu), si M. Michu veut visiter
le site Web http://thepiratebay.am/
, son
navigateur va utiliser les services du système
d'exploitation sous-jacent pour demander
l'adresse IP de
thepiratebay.am
. Le système d'exploitation va
envoyer une requête DNS au résolveur (sur Unix,
les adresses IP des résolveurs sont dans
/etc/resolv.conf
). Celui-ci va demander aux
serveurs de la racine s'ils connaissent
thepiratebay.am
, il se fera rediriger vers les
serveurs faisant autorité pour am
, puis vers ceux faisant autorité
pour thepiratebay.am
. Le résolveur aura alors une
réponse qu'il pourra transmettre au navigateur de M. Michu.
Principal point où j'ai simplifié : le DNS s'appuie beaucoup sur la
mise en cache des données, c'est-à-dire sur leur
mémorisation pour gagner du temps la fois suivante. Ainsi, si le même
M. Michu, cinq minutes après, veut aller en
http://armenpress.am/
, son résolveur ne demandera rien
aux serveurs de la racine : il sait déjà quels sont les serveurs
faisant autorité pour am
.
Le trafic DNS est un trafic TCP/IP ordinaire, typiquement porté par UDP. Il peut être écouté, et comme il n'est aujourd'hui pas chiffré, un indiscret peut tout suivre. Voici un exemple pris avec tcpdump sur un serveur racine (pas la racine officielle, mais, techniquement, cela ne change rien) :
15:29:24.409283 IP6 2001:67c:1348:8002::7:107.10127 > \ 2001:4b98:dc2:45:216:3eff:fe4b:8c5b.53: 32715+ [1au] \ AAAA? www.armenpress.am. (46)
On y voit que le client 2001:67c:1348:8002::7:107
a demandé l'adresse IPv6 de www.armenpress.am
.
Pour compléter le tableau, on peut aussi noter que les logiciels
génèrent un grand nombre de requêtes DNS, bien supérieur à ce que voit
l'utilisateur. Ainsi, lors de la visite d'une page Web, le résolveur
va envoyer la requête primaire (le nom du site
visité, comme thepiratebay.am
), des requêtes
secondaires dues aux objets contenus dans la page
Web (JavaScript, CSS,
divers traqueurs et autres outils de cyberflicage ou de cyberpub) et
même des requêtes tertiaires, lorsque le
fonctionnement du DNS lui-même nécessitera des requêtes. Par exemple,
si abc.xyz
est hébergé sur des serveurs dans
google.com
, une visite de
http://abc.xyz/
nécessitera de résoudre les noms
comme ns1.google.com
, donc de faire des requêtes
DNS vers les serveurs de google.com
.
Bien sûr, pour un espion qui veut analyser tout cela, le trafic DNS représente beaucoup de données, souvent incomplètes en raison de la mise en cache, et dont l'interprétation peut être difficile (comme dans l'exemple ci-dessus). Mais les organisations qui pratiquent l'espionnage massif, comme la NSA, s'y connaissent en matière de big data et savent trouver les aiguilles dans les bottes de foin.
La section 2 du RFC détaille les risques pour la vie privée dans les différents
composants du DNS. Notez que la confidentialité du contenu du DNS
n'est pas prise en compte (elle l'est dans les RFC 5936 et RFC 5155). Il est important de
noter qu'il y a une énorme différence entre la
confidentialité du contenu et la
confidentialité des requêtes. L'adresse IP de
www.charliehebdo.fr
n'est pas un secret : les
données DNS sont publiques, dès qu'on connait le nom de domaine, et
tout le monde peut faire une requête DNS pour la connaitre. Mais le
fait que vous fassiez une requête pour ce nom ne devrait pas être
public. Vous n'avez pas forcément envie que tout le monde le
sache.
Pour comprendre les risques, il faut aussi revenir un peu au protocole DNS. Les deux informations les plus sensibles dans une requête DNS sont l'adresse IP source et le nom de domaine demandé (qname, pour Query Name, cf. RFC 1034, section 3.7.1). L'adresse IP source est celle de votre machine, lorsque vous parlez au résolveur, et celle du résolveur lorsqu'il parle aux serveurs faisant autorité. Elle peut indiquer d'où vient la demande. Lorsque on utilise un gros résolveur, celui-ci vous masque vis-à-vis des serveurs faisant autorité (par contre, ce gros résolveur va avoir davantage d'informations).
Quant au qname, il peut être très révélateur :
il indique les sites Web que vous visitez, voire, dans certains cas,
les logiciels utilisés. Au moins un client
BitTorrent fait des requêtes DNS pour
_bittorrent-tracker._tcp.domain.example
,
indiquant ainsi à beaucoup de monde que vous utilisez un protocole qui
ne plait pas aux ayant-droits. Et si vous utilisez le RFC 4255, pas mal de serveurs verront à quelles machines vous
vous connectez en SSH...
Donc où un méchant qui veut écouter votre trafic DNS peut-il se placer ? D'abord, évidemment, il suffit qu'il écoute le trafic réseau. On l'a dit, le trafic DNS aujourd'hui est presque toujours en clair donc tout sniffer peut le décoder. Même si vous utilisez HTTPS pour vous connecter à un site Web, le trafic DNS, lui, ne sera pas chiffré. (Les experts pointus de TLS noteront qu'il existe d'autres faiblesses de confidentialité, comme le SNI du RFC 6066.) À noter une particularité du DNS : le trafic DNS peut passer par un autre endroit que le trafic applicatif. Alice peut naïvement croire que, lorsqu'elle se connecte au serveur de Bob, seul un attaquant situé physiquement entre sa machine et celle de Bob représente une menace. Alors que son trafic DNS peut être propagé très loin, et accessible à d'autres acteurs. Si vous utilisez, par exemple, le résolveur DNS public de FDN, toute la portion de l'Internet entre vous et FDN peut facilement lire votre trafic DNS.
Donc, l'éventuel espion peut être près du câble, à écouter. Mais il peut être aussi dans les serveurs. Bercé par la musique du cloud, on oublie souvent cet aspect de la sécurité : les serveurs DNS voient passer le trafic et peuvent le copier. Pour reprendre les termes du RFC 6973, ces serveurs sont des assistants : ils ne sont pas directement entre Alice et Bob mais ils peuvent néanmoins apprendre des choses à propos de leur conversation. Et l'observation est très instructive. Elle est utilisée à de justes fins dans des systèmes comme DNSDB (section 3 du RFC) mais il n'est pas difficile d'imaginer des usages moins sympathiques comme dans le cas du programme NSA MORECOWBELL.
Les résolveurs voient tout le trafic puisqu'il y a peu de mise en cache en amont de ces serveurs. Il faut donc réfléchir à deux fois avant de choisir d'utiliser tel ou tel résolveur ! Il est déplorable qu'à chaque problème DNS (ou supposé tel), des ignorants bondissent sur les réseaux sociaux pour dire « zyva, mets 8.8.8.8 [Google Public DNS] comme serveur DNS et ça ira plus vite » sans penser à toutes les données qu'ils envoient à la NSA ainsi.
Les serveurs faisant autorité voient passer moins de trafic (à cause des caches des résolveurs) mais, contrairement aux résolveurs, ils n'ont pas été choisis délibérement par l'utilisateur. Celui-ci peut ne pas être conscient que ses requêtes DNS seront envoyées à plusieurs acteurs du monde du DNS, à commencer par la racine. Le problème est d'autant plus sérieux que, comme le montre une étude, la concentration dans l'hébergement DNS est élevée : dix gros hébergeurs hébergent le tiers des domaines des 100 000 sites Web les plus fréquentés (listés par Alexa).
Au passage, le lecteur attentif aura noté qu'un résolveur personnel (sur sa machine ou dans son réseau local) a l'avantage de ne pas envoyer vos requêtes à un résolveur peut-être indiscret mais l'inconvénient de vous démasquer vis-à-vis des serveurs faisant autorité, puisque ceux-ci voient alors votre adresse IP. Une bonne solution (qui serait également la plus économe des ressources de l'Internet) serait d'avoir son résolveur local et de faire suivre les requêtes non résolues au résolveur du FAI. Du point de vue de la vie privée, ce serait sans doute la meilleure solution mais cela ne résout hélas pas un autre problème, celui des DNS menteurs, contre lesquels la seule protection est d'utiliser uniquement un résolveur de confiance.
Enfin, il y a aussi les serveurs DNS « pirates » (installés, par
exemple, via un serveur DHCP lui-même pirate) qui détournent le
trafic DNS, par exemple à des fins de surveillance. Voir par exemple l'exposé
de Karrenberg à JCSA 2012
disponible
en ligne
(transparents 27 et 28, Unknown et
Other qui montrent l'existence de clones pirates du
serveur racine K.root-servers.net
).
Pour mes lecteurs français férus de droit, une question intéressante : le trafic DNS est-il une « donnée personnelle » au sens de la loi Informatique & Libertés ? Je vous laisse plancher sur la question, qui a été peu étudiée.
Quelques élements d'histoire de ce RFC pour finir, puisque j'ai vécu tout son cycle de vie (c'est mon premier RFC publié). Sa première version a été entièrement écrite, dans un avion de la KLM entre Amsterdam et Vancouver, où j'allais à une réunion IETF en novembre 2013. Long vol sans connexion Internet, donc sans distractions, sièges de la classe affaires et présence de plusieurs collègues qui vous stimulent et avec qui discuter (merci au passage à Olaf Kolkman pour avoir insisté « il faut que tu publies cela »), cela fait d'excellentes conditions de travail.
Le RFC venant d'être publié, on voit qu'il aura fallu moins de deux ans en tout, alors qu'on raconte souvent que l'IETF est lente (sur le fonctionnement de l'IETF, voir mon exposé à JRES). Pour avoir une idée des changements entre le premier « draft KLM » et l'actuel RFC, vous pouvez voir un calcul automatique des différences.
Quelques autres lectures utiles :
Date de publication du RFC : Août 2015
Auteur(s) du RFC : J. Touch (USC/ISI)
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 8 août 2015
Vous développez une application Internet et vous utilisez des ports enregistrés à l'IANA ? Ou bien aucun port ne convient et vous voulez en enregistrer un nouveau ? Ce RFC est fait pour vous en expliquant, du point de vue du créateur de nouveaux services Internet, comment utiliser les ports ou bien en demander un nouveau.
La procédure complète figure dans le RFC 6335. Ce nouveau RFC 7605 ne le remplace pas mais fournit une vision moins bureaucratique du processus, plus orientée vers le développeur, avec des recommandations concrètes.
Donc, c'est quoi, un port ? C'est un entier de 16 bits qui :
Seule la deuxième utilisation nécessite un registre central.
Pour se connecter à une autre machine, il faut connaître le port de
destination. Le cas le plus connu est celui des
URL. Si l'URL n'indique pas de numéro de port,
le port par défaut est 80 (RFC 7230, section
2.7.1). Donc, avec http://www.example.com/
, le
client HTTP se connectera au port 80 de la machine
www.example.com
. Mais on peut indiquer un port
dans un URL (RFC 3986, section 3.2.3). Si l'URL
est http://www.example.com:9081/
, le client HTTP se connectera au port 9 081 de la machine
www.example.com
.
Bien sûr, rien n'oblige à faire tourner un service sur le port officiellement affecté. On peut mettre un serveur DNS sur le port 80 ou au contraire un serveur HTTP sur le port 53, normalement prévu pour le DNS. C'est ainsi que bien des serveurs SSH écoutent sur le port 443, de manière à ce qu'on puisse se connecter même depuis les points d'accès WiFi les plus pourris qui filtrent tous les ports que leur concepteur ne connait pas. Attention toutefois, si des équipements situés sur le trajet font du DPI, cela peut ne pas leur plaire de voir du trafic non-DNS sur le port 53 et cela peut les amener à couper la communication. Comme le note notre section 5, supposer que le trafic sur le port 53 est forcément du DNS est une erreur : l'interprétation des numéros de ports doit être laissé aux deux machines qui communiquent. Le registre des ports est juste là pour leur faciliter la tâche, pas pour ajouter des contraintes inutiles.
Bien sûr, ce principe n'est pas forcément suivi et des tas de logiciels utilisent le registre des ports en supposant que les services correspondent aux numéros de ports (cf. aussi la section 6.2). C'est fréquent sur les pare-feux, par exemple. On veut couper le DNS, pour forcer l'usage des DNS menteurs, on bloque le port 53, ce qui sera contourné en envoyant le trafic DNS sur un autre port et ainsi de suite. Autre cas où un logiciel utilise le registre des ports pour se faciliter la vie, mais parfois à tort, celui des logiciels d'analyse du trafic réseau, comme tcpdump. Le trafic est avec le port 53, tcpdump l'analyse comme si c'était du DNS. Cela peut mener à des résultats amusants. Ici, tcpdump décode du trafic HTTP en croyant que c'est du DNS :
18:34:03.263985 IP 127.0.0.1.46680 > 127.0.0.1.53: \ Flags [P.], seq 1:111, ack 1, win 342, \ options [nop,nop,TS val 240543975 ecr 240543975], \ length 11021536 update+ [b2&3=0x2f20] \ [21584a] [18516q] [12081n] [11825au][|domain]
Ce qui le mène à des résultats absurdes comme de croire que la section « Question » du message DNS comprend 18 516 questions... À noter que Wireshark, lui, permet de choisir le décodeur, pour ne pas utiliser celui par défaut d'un port donné (menu Analyze/Analyser, puis Decode as/Decoder[sic]).
Aujourd'hui, au moment de la publication de notre RFC 7605, quelle est l'utilisation de l'espace des ports ? Cet espace est divisé (cf. RFC 6335) en trois catégories, « Système » (sur une machine Unix, il faut être root pour écouter sur ces ports), de 0 à 1 023, « Utilisateur », de 1 024 à 49 151, et « Dynamique » (aussi appelé « Privé », les ports locaux, non enregistrés à l'IANA, contrairement aux deux premières catégories), de 49 152 à 65 535.
Donc, un problème à garder en tête avant de réclamer son port, la nécessite de préserver une ressource finie. L'espace des numéros de ports est partagé par tous les utilisateurs de l'Internet et cet espace est petit, moins de 2^16. Sur les 49 151 numéros ouverts à l'enregistrement (à l'exception, donc, de la catégorie « Dynamique »), 5 850 ont été enregistrés pour TCP. Les enregistrements sont en théorie annulables (RFC 6335, section 8.4) mais permanents en pratique (la procédure du RFC 6335 semble parfaitement irréaliste, cf. aussi la section 7.9 de notre RFC). Il faut donc y aller mollo (cette question du conservatisme dans l'allocation a été une des plus disputées au sein du groupe de travail IETF). Par exemple, chaque service ne devrait avoir qu'un seul numéro de port (outre l'économie des numéros de port, cela évite des problèmes de débogages pénibles au cas où certains ports soient bloqués par un pare-feu et pas d'autres). La section 7.2 détaille cette question des ports multiples.
Donc, plutôt que de demander plusieurs ports pour votre service :
Host:
de HTTP, qui évite d'avoir un port
(ou une adresse IP)
par site Web.Les ports sont censés permettre de séparer des services différents, pas juste des variations d'un même service.
La section 7 du RFC couvre toutes les questions qu'il faut se poser avant l'enregistrement d'un nouveau port. D'abord, est-il vraiment nécessaire, compte tenu des exigences de conservation indiquées plus haut ?
OK, on a déterminé qu'on avait vraiment besoin d'un numéro de port, on s'apprête à la demander à l'IANA. Mais quel numéro choisir ? Ce n'est pas une obligation. On peut ne pas indiquer de numéro particulier, et laisser l'IANA en choisir un. En revanche, il faut indiquer si le port doit être dans la plage Système ou dans la plage Utilisateur. La distinction est nettement moins importante aujourd'hui. Autrefois, quand l'Internet ne connectait que des grosses machines gérées professionnellement, la distinction servait à isoler les services critiques des autres. Sur ces grosses machines, l'utilisateur ordinaire ne pouvait pas écouter sur les ports de numéro inférieurs à 1 024 (par exemple, sur Unix, il faut être root pour cela) et cela garantissait que le service sur ces ports était « sérieux ». Aujourd'hui où certains systèmes ne font plus la différence et où, de toute façon, tout le monde est super-utilisateur de son Raspberry Pi, la différence a beaucoup moins de sens. Et cette distinction ne doit pas être utilisé pour la sécurité (cf. section 7.4) comme le faisait malheureusement rlogin. Néanmoins, la différence demeure, au moins comme un marqueur de la criticité du service. La plage Système étant petite et très demandée, les chances d'y obtenir un numéro de port sont plus faibles (il faut un examen par l'IETF ou bien une approbation par l'IESG, RFC 6335, section 8.1, et aussi le RFC 5226, sur la définition des politiques d'enregistrement).
Comme toute ressource limitée dans un espace commun, les numéros de port peuvent susciter des frictions. Une fois le logiciel déployé, il peut être difficile de changer le numéro de port de manière coordonné. D'où les deux règles :
Et c'est quoi, ce risque de squat ? C'est l'utilisation d'un port statique sans l'avoir obtenu par les procédures normales. Cela peut être dû à un développeur pressé ou négligent qui écrit son code sans tenir compte des procédures, et le publie. Cela peut être aussi délibéré de la part de gens qui s'estiment au-dessus des règles et qui se réservent sans vergogne une part de la ressource commune. Dans les deux cas, c'est très gênant car, une fois le code largement déployé sur l'Internet, il sera vraiment difficile de le changer, ou même de savoir si le port est encore utilisé (voir aussi la section 7.9). Le squat est donc nettement condamné. Un exemple fameux de squat est l'enregistrement de CARP.
La section 8 de notre RFC couvre les questions de sécurité liées aux ports. D'abord, il ne faut pas se fier au numéro de port. Rien ne garantit que ce qui circule sur le port 53 soit du DNS, et encore moins que ce soit du DNS correct (voir l'exemple plus haut avec tcpdump). Rien ne garantit qu'un paquet où le port source est inférieur à 1 024 a vraiment été émis par une personne de confiance, et ainsi de suite. Les mesures classique d'authentification sont donc nécessaires si on veut vraiment se protéger.
Ensuite, un mot sur la vie privée. Le système des ports bien connus est l'antithèse de la vie privée puisqu'un simple coup d'œil à l'en-tête de couche 4, sans aller examiner le contenu applicatif, indique quel service on utilise. Bien sûr, ce n'est pas une garantie (paragraphe précédent...) mais cela donne déjà une indication. Autre indiscrétion liée aux ports : en envoyant des demandes de connexion TCP à une machine, vers les différents ports (comme ce que fait nmap), on peut savoir quels services elle offre, sans avoir besoin d'analyser les applications. C'est un problème, mais qui est fondamentalement lié à l'architecture de TCP/IP et qui est difficile à corriger (on peut toujours recourir à des trucs comme le port knocking).
Moins directement utile mais passionnante, l'histoire des ports
était présentée dans la section 3. Le terme est apparu pour la première
fois dans le RFC 33, en 1970 (« We assume here that a
process has several input-output paths which we will call ports. »). À
l'époque, les couches 3 et
4 étaient encore mêlées, dans
le protocole NCP. L'adresse désignant une
machine, le port devait désigner une voie de communication d'un
processus
sur cette machine. (Notez qu'avec des adresses IP suffisamment longues
et abondantes, comme ce que fournit IPv6
aujourd'hui, on pourrait se débarrasser complètement de la distinction
adresse/port, un préfixe IP pourrait désigner une machine et chaque
adresse une prise ou un processus. La séparation adresse/port est le souvenir d'une
époque révolue.) Le RFC 37 et le RFC 38 ont ensuite
précisé et modifié l'idée (« The destintation [sic] socket must be
added to the header of each message on the data link. Presumably this would consist of
32 bits [ce sera finalement 16 bits] immediately after the header and
before the marking. »). Puis le RFC 48, toujours en
1970, introduit l'idée d'« écoute » sur un port, lorsqu'un processus
est en attente d'une requête. Et le RFC 61 est le premier à
se demander comment on est censé connaître le port de destination
d'un message, et à introduire le concept de « port bien connu »
(well-known port) comme le futur port 80 pour
HTTP. Le RFC 76 s'attaque à la
question posée, mais non résolue, par le RFC 61 et propose un
annuaire permettant d'associer des noms de services à des numéros de
port (le /etc/services
de votre machine
Unix en est le lointain
descendant). « most permanently assigned devices and/or
processes are known by standard mnemonic labels such as DSK (disk), LP
(line printer), CR (card reader), TECO (PDP-10 text editor),
etc. »
Une importante étape est ensuite franchie avec le RFC 333 en 1972, qui est le premier à suggérer que les ports de source et de destination servent (avec les adresses IP) à identifier une connexion, ce qui sera le choix final de TCP (RFC 793, en 1981, mais décrit deux ans avant avant dans le document IEN 112). Le RFC 717 est le premier à indiquer des numéros de port officiellement affectés mais c'est le RFC 739, en 1977, qui avait généralisé l'idée (sous le nom de socket number). Dans ce RFC, telnet avait déjà le port 23, qu'il a gardé jusqu'à aujourd'hui, comme bien des protocoles depuis oubliés. Les procédures de l'époque étaient plus simples qu'aujourd'hui (« please contact Jon [Postel] to receive a number assignment »).
Quant au RFC 758, il était le premier à étendre le concept de port à TCP (les RFC précédents ne parlaient que de NCP). Certaines plages de numéros de ports étaient réservées à des usages spécifiques, mais son successeur, le RFC 820, n'a pas retenu cette distinction (en prime, le RFC 820 a étendu l'usage des ports à UDP). Avec le RFC 900 disparait la notation octale, avec le RFC 1340 (en 1992), la liste des « ports bien connus » va désormais de 0 à 1 023 et plus seulement jusq'à 255 (on y note l'apparition de 80, pour HTTP). Cette liste sera encore révisée dans le RFC 1700 puis remplacée en 2002 par un registre en ligne à l'IANA, registre décrit par le RFC 3232. (Le RFC listant les ports était toujours en retard sur l'allocation réelle.)
Première rédaction de cet article le 24 juillet 2015
« On » me demande parfois quels outils utiliser pour analyser un problème BGP quand on n'a pas accès à un routeur de la DFZ (d'ailleurs, certaines techniques ici peuvent servir même dans ce cas). Voici un exemple avec la panne de plus de deux heures de Swift hier 22 juillet.
Point de départ, la machine 204.13.164.192 n'est plus
joignable. Bête panne d'un serveur, comme cela arrive tout le temps
sur l'Internet ? Non, cette fois, c'est plus rigolo, le préfixe IP
204.13.164.0/24
qui l'englobe a disparu de la
table de routage mondiale. De même
que d'autres préfixes du même opérateur, comme
204.8.32.0/24
(qui héberge notamment les serveurs
DNS de swiftco.net
,
rendant ce nom de domaine inutilisable ; on ne
le répétera jamais assez, il faut mettre ses serveurs DNS dans
plusieurs réseaux différents).
Comment voir ce que contient cette table de routage ? Si on a accès
à un routeur qui a une table complète, on peut
le faire soi-même mais, si ce n'est pas le cas, on peut utiliser un
des innombrables looking
glasses qui vous donnent un accès indirect à ces
routeurs. Par exemple, voici ce que donne celui de Hurricane Electric une fois la
panne réparée (on voit les routes pour le
204.8.32.0/24
, pendant la panne, on avait « None of the BGP4 routes match the display condition ») :
Qu'on utilise ce looking glass ou bien qu'on passe par un de ses routeurs à soi, on n'a qu'une vision immédiate. Il serait intéressant de pouvoir regarder le passé, notamment si on a été prévenu trop tard et qu'on veut investiguer a posteriori. C'est ce que permet RIPEstat qui fournit tout un tas d'outils d'analyse (qui ne sont pas toujours d'un abord facile). L'un des plus simples est le BGP Update activity. Voici ce qu'il affichait juste après la réparation :
On y voit une grosse activité BGP vers 0810 UTC au moment où le préfixe, pour une raison inconnue, était retiré. Cette activité comporte des retraits (withdraw) mais aussi des annonces (announce). C'est normal, les routeurs BGP réagissent au retrait en annonçant des routes alternatives pendant une minute ou deux, le temps que tous réalisent que le préfixe est bien retiré, qu'il n'y a pas d'alternative. Puis on voit une autre période d'activité vers 1045 UTC au moment où ça repart. Celle-ci ne comporte que des annonces.
Date de publication du RFC : Juillet 2015
Auteur(s) du RFC : M. Boucadair (France Telecom), A. Petrescu (CEA, LIST), F. Baker (Cisco Systems)
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 23 juillet 2015
Comme IPv4, IPv6 route les paquets en fonction d'un préfixe d'adresses, préfixe qui a une longueur comprise entre 0 (tout l'Internet) et 128 bits (une seule machine). Ce très court RFC a juste pour but de rappeler cette règle : la longueur d'un préfixe est quelconque, les mises en œuvres de IPv6, logicielles ou matérielles, ne doivent pas imposer ou favoriser une longueur de préfixe particulière (même pas 64, souvent considéré, à tort, comme spécial). Le routage se fait exclusivement sur le plus long préfixe, quelle que soit sa longueur.
Il est normal qu'IPv6 et
IPv4 fassent pareil, ce sont après tout deux
versions du même protocole. IPv4 utilisait autrefois un système différent mais,
depuis CIDR, il suit les mêmes règles qu'IPv6 :
le routage se fait sur la base d'un préfixe d'adresses de longueur
quelconque. C'est le préfixe le plus long qui est choisi. Ainsi, pour
prendre un exemple IPv4, si la destination est
203.0.113.51
et qu'il existe deux routes
possibles, une vers le préfixe 203.0.113.0/26
(longueur 26 bits) et l'autre vers le préfixe
203.0.0.0/18
, c'est la première, la plus
spécifique (le préfixe le plus long) qui gagne. En IPv6, si on veut
envoyer un paquet à 2001:db8:440:fe::25a:9ff
et
qu'il existe deux routes possibles,
2001:db8:440:fe::/80
(longueur 80 bits) et
2001:db8:440::/48
, c'est la première qui est
choisie. Le routage sur la base du préfixe le plus long, un concept
fondamental d'IP, c'est juste ça. (Le terme de
CIDR, introduit par le RFC 1380 et décrit dans le RFC 4632, terme très spécifique à IPv4 et aujourd'hui
dépassé techniquement depuis l'abandon de l'ancien système des
classes, n'est pas utilisé pour IPv6.)
Mais pas mal de gens qui ne connaissent pas bien IPv6 ont des idées fausses à ce sujet et croient, par exemple, que les préfixes de longueur 64 bits ont un rôle particulier pour le routage, voire que les préfixes comme le /80 donné en exemple plus haut sont illégaux. Le RFC 4291, qui normalise l'adressage IPv6, dit bien (dans sa section 2.5) que n'importe quelle longueur de préfixe (« arbitrary bit-length ») est possible. Mais c'est vrai que la confusion peut venir du rôle particulier de certaines longueurs, notamment 64, dans d'autres utilisations que le routage. Ainsi, le RFC 7421 note que les préfixes plus longs que 64 bits ont des problèmes pour certaines utilisations, comme le SLAAC. Mais il s'agit là de questions liées à l'adressage : cela ne devrait pas affecter le routage, si on veut que les changements futurs de l'adressage n'empêchent pas les routeurs de fonctionner (deux exemples de changement d'adressage : au début d'IPv6, il était envisagé que ce soit /80 plutôt que /64 qui soit la longueur de préfixe « de référence » et, autre exemple, la recommandation pour les liens point à point a varié de /64 à /127, cf. RFC 6164).
Donc, pour résumer, l'adressage est une chose (et les recommandations du RFC 7421, indiquant les avantages à utiliser du /64 pour un lien local, continuent à s'appliquer), le routage en est une autre : le routage IPv6 doit suivre l'algorithme du préfixe le plus long, et ne doit pas avoir de longueurs de préfixes privilégiées ou spéciales.
Cette exigence est formalisée dans la section 2 de notre RFC :
Ces règles s'appliquent au code des routeurs : l'administrateur d'un routeur donné peut toujours avoir sa propre politique (par exemple, en BGP, ne pas accepter de préfixes plus longs que 48 bits) mais cela ne doit pas se retrouver dans le logiciel, autrement, les futures évolutions seraient sérieusement compliquées.
Première rédaction de cet article le 22 juillet 2015
La sécurité informatique, c'est compliqué. Voilà qu'un utilisateur d'un serveur de messagerie que je gère me signale qu'il ne peut plus lire son courrier avec Thunderbird. Et je découvre que le problème était en fait dû au zèle que mettait Thunderbird à protéger ses utilisateurs de la faille Logjam.
Avant de revenir sur cette faille et sur la solution, voici les symptômes : Thunderbird était configuré pour récupérer le courrier avec POP. Récemment mis à jour automatiquement, il ne récupère plus de courrier. Apparemment pas de messages d'erreurs côté client, mais pas de courrier non plus. Côté serveur (un Courier), on trouve juste dans le journal :
pop3d-ssl: couriertls: accept: error:14094417:SSL routines:SSL3_READ_BYTES:sslv3 alert illegal parameter
Message sybillin, non, d'autant plus que ce serveur refuse évidemment SSLv3, comme le dit le RFC 7568. C'est ça, les messages d'erreur d'OpenSSL...
Bon, je n'ai pas eu trop à chercher, des tas de gens avaient le même problème (par exemple chez CentOS). Deux bogues enregistrées chez Mozilla (la fondation qui développe Thunderbird) donnaient les détails : #1183650 et #1184488. L'explication est simple : la mise à jour de Thunderbird (ou plus exactement celle de la bibliothèque TLS NSS dont il dépend), introduit un refus des paramètres Diffie-Hellman trop faibles.
De quoi s'agit-il encore ? La faille de sécurité Logjam, contre le protocole TLS, concerne les échanges de clés Diffie-Hellman. TLS peut fonctionner sans Diffie-Hellman (et c'est pour cela que certaines utilisateurs n'ont pas eu de problèmes) mais, si on l'utilise, l'échange de clé peut être deviné par un attaquant car les groupes Diffie-Hellman ont pu être pré-calculés, surtout s'ils sont trop petits (768 bits par exemple, taille souvent utilisée par défaut, cf. la bogue Debian #787579). Outre le site officiel de Logjam, on peut consulter sur cette faille une excellente explication chez Cloudflare. Donc, Thunderbird (ou plutôt NSS) refuse désormais les paramètres Diffie-Hellman trop faibles. Testons notre serveur (le problème initial concernait aussi bien POP que IMAP, ici, je teste le serveur IMAP) :
% openssl s_client -connect server.bortzmeyer.org:993 CONNECTED(00000003) ... No client certificate CA names sent Peer signing digest: SHA512 Server Temp Key: DH, 768 bits ... * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998-2011 Double Precision, Inc. See COPYING for distribution information.
En effet, avec ses 768 bits (DH = Diffie-Hellman), le serveur ne suit pas les bonnes pratiques et c'est pour cela que Thunderbird coupe la communication.
Quelle est la solution ? Le site officiel de Logjam a une bonne page d'explications pour
les administrateurs système mais, ici, j'ai simplement utilisé
le
commentaire 13 dans la bogue Mozilla #1184488. Il faut
regénérer des paramètres Diffie-Hellman. Le serveur est une machine
Debian, les paramètres sont en
/etc/courier/dhparams.pem
, et
le script à utiliser, mkdhparams
, est fourni avec
Courier. À noter que sa documentation est
inexacte sur la méthode à utiliser pour augmenter le nombre de bits
(bogue Debian #793184). J'ai choisi une
taille de 3 072 bits (plutôt exagérée aujourd'hui mais c'est ce qui
est recommandé par le RGS) et j'ai donc fait :
server# export DH_BITS=3072 server# mkdhparams 512 semi-random bytes loaded Generating DH parameters, 3072 bit long safe prime, generator 2 This is going to take a long time ................................................+....... ... server# /etc/init.d/courier-imap-ssl restart [ ok ] Restarting courier-imap-ssl (via systemctl): courier-imap-ssl.service. server#
Testons le résultat :
% openssl s_client -connect server.bortzmeyer.org:993 CONNECTED(00000003) ... No client certificate CA names sent Peer signing digest: SHA512 Server Temp Key: DH, 3072 bits ... * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998-2011 Double Precision, Inc. See COPYING for distribution information. closed
Parfait, cette fois, ça marche, et Thunderbird est content, il peut récupérer le courrier de manière sécurisée.
Amusante coïncidence, le lendemain de cet article, à la réunion IETF de Prague, Aaron Zauner faisait un excellent exposé sur des tests de la sécurité des serveurs de courrier (SMTP, POP et IMAP) qu'il avait réalisés dans l'Internet. Beaucoup d'entre eux sont encore vunérables à Logjam.
Date de publication du RFC : Juillet 2015
Auteur(s) du RFC : K. Lynn (Verizon), S. Cheshire
(Apple), M. Blanchet
(Viagenie), D. Migault (Ericsson)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnssd
Première rédaction de cet article le 17 juillet 2015
Pour résoudre des noms de domaine en informations (comme l'adresse IP) sur le réseau local, sans configurer de serveur DNS, nous avons mDNS (RFC 6762). Pour découvrir des services (par exemples les imprimantes) avec ce mDNS, nous avons DNS-SD (RFC 6763). Mais ces deux techniques, mDNS et DNS-SD, ne fonctionnent que sur un seul segment du réseau, à l'intérieur d'un domaine de diffusion. Il serait bien pratique de pouvoir les utiliser dans un réseau étendu (comme l'Internet...). Ce RFC décrit le problème, les souhaits et établit une liste d'exigences pour cette extension de mDNS et DNS-SD « au-delà du lien local ». (À l'heure actuelle, on n'a pas encore de solution satisfaisant ces exigences.)
C'est par conception que mDNS (RFC 6762) ne passe pas les routeurs IP. Ce protocole marche par diffusion. On crie à la cantonade « qui connait iPhone-de-Jean-Bernard ? » et la machine qui se reconnait répond. mDNS s'appuie donc sur un service de couche 2, la diffusion, et ne fonctionne donc pas sur un réseau composé de plusieurs segments L2 reliés par des routeurs.
Or, il y a évidemment des cas où on voudrait des services comme ceux fournis par mDNS et DNS-SD au-delà du lien local. Parce que le campus ou l'entreprise où on travaille a plusieurs segments L2 (par exemple un pour le filaire et un pour le WiFi), ou bien parce qu'on travaille avec une association située à des centaines de kilomètres, mais joignable par l'Internet. Il n'existe pas actuellement de solutions standard pour cela. Et pas encore de consensus sur la façon la plus propre de le faire.
Autre cas où on se retrouve facilement coincé, celui de réseaux ad hoc comme les 6LowPAN (RFC 6568) où chaque machine ou presque peut devenir routeur (RFC 4903).
D'ailleurs, même en l'absence de ce problème multi-segments, la technique de mDNS, la diffusion (globale, ou bien restreinte) n'est pas idéale dans tous les cas. Sur de l'Ethernet filaire, la diffusion consomme relativement peu de ressources. Mais, sur certains segments, la diffusion coûte cher. En WiFi, elle peut vite mener à consommer une bonne partie de la capacité, d'autant plus qu'il faut ralentir au niveau du récepteur le plus lent (cf. section 2.2). Au passage, autre problème de 802.11 : il n'y a pas d'accusé de réception des trames diffusées et donc des pertes peuvent se produire.
La section 2 de notre RFC décrit le problème qu'on veut résoudre. D'abord, on voudrait pouvoir découvrir des ressources distantes (comme des imprimantes ou des serveurs de fichier) même si elles ne sont pas sur le même segment L2. Actuellement, la seule solution standard est le DNS classique. Cela nécessite soit une configuration manuelle par l'administrateur système, ce qui fait du travail, surtout en cas de changement (on modifie l'adresse IP de l'imprimante mais on oublie de changer la base DNS : tous les sites n'ont pas forcément un IPAM intégré qui prend en charge tout cela et tous les réseaux ne sont pas centralement gérés). Autre solution avec le DNS classique, autoriser les mises à jour dynamiques du DNS, ce qui implique qu'on configure les imprimantes pour faire ces mises à jour.
Et la solution à ce problème doit marcher pour des cas où on a des centaines ou des milliers de machines, et à un coût raisonnable (y compris le coût pour le réseau en terme de trafic).
Les réseaux contraints (LLN pour Low power and Lossy Networks, cf. RFC 7102) posent des défis particuliers. Ils sont souvent multi-segments, avec des nœuds devenant routeurs pour prolonger la portée des ondes radio, et ne peuvent donc pas se contenter des actuels mDNS et DNS-SD. Mais ils connectent souvent des machines peu dotées en ressources. Celles-ci sont parfois injoignables (hibernation ou déconnexion) et on ne peut donc pas compter sur leur présence permanente. Ainsi, mDNS assure l'unicité des noms par la vérification, par une nouvelle machine, que le nom n'était pas déjà présent sur le réseau. Si le possesseur de ce nom hiberne, il ne pourra pas « défendre » son nom.
La section 3 du RFC présente ensuite quelques scénarios d'usage concrets, pour qu'on se fasse une meilleure idée de cas où mDNS et DNS-SD ne suffisent pas. D'abord, un cas de base, le PAN (Personal Area Network, qui regroupe les machines d'un seul utilisateur, par exemple, dans un cas trivial, son PC portable et son imprimante). Pas de routeur présent, mDNS et DNS-SD suffisent bien et résolvent tous les problèmes. On passe ensuite à un cas un peu plus riche : une maison, avec un routeur qui connecte à un FAI et un réseau local d'un seul segment (il peut y avor plusieurs segments physiques, par exemple filaire et WiFi, mais le routeur, qui fait également point d'accès WiFi, les présente comme un seul réseau L2. C'est le réseau de M. Michu aujourd'hui et, là encore, mDNS et DNS-SD marchent bien.
On passe ensuite au réseau SOHO ou bien à la maison « avancée ». Cette fois, on introduit plusieurs routeurs (RFC 7368). Un tel réseau peut s'auto-organiser (il n'y a typiquement pas d'administrateur réseaux professionnel) mais la résolution de noms devient difficile, mDNS ne fonctionnant plus (il ne passe pas les routeurs).
Ensuite viennent les réseaux d'« entreprise » (en fait, de n'importe quelle grande organisation, entreprise à but lucratif ou pas). Plusieurs routeurs, des réseaux compliqués mais, cette fois, on a des administrateurs réseaux professionnels pour s'en occuper. À noter que les grands réseaux des conférences (comme le réseau WiFi des réunions IETF) rentrent dans cette catégorie. mDNS ne marche plus mais on peut désormais avoir des serveurs DNS administrés sérieusement.
Le RFC cite un cas encore plus élaboré, avec les NREN, qui mèlent administration centrale du réseau national, avec des équipes qui gèrent des réseaux régionaux ou de campus.
Et les réseaux « mesh » ? Ils sont multi-segments mais en général pas administrés, ils posent donc le plus de problèmes.
Bon, assez de préliminaires, les exigences maintenant, le vrai cahier des charges. Il figure en section 4. Les exigences sont notées REQn où N est un numéro de 1 à 15. REQ1, par exemple, dit qu'il faut un mode d'auto-configuration permettant à la future solution de marcher toute seule, pour le cas des réseaux non administrés. Mais attention, le RFC précise aussi que les objectifs de sécurité, de passage à l'échelle, de facilité et de déployabilité sont souvent contradictoires et qu'il ne faut pas prendre les exigences isolément mais en groupe (il faudra parfois en sacrifier une pour atteindre l'autre).
REQ2, complémentaire de REQ1, dit que pour les réseaux administrés, il faut pouvoir configurer le mécanisme de manière à partitionner le réseau, pour éviter qu'une requête ne voyage partout (voir aussi REQ15). REQ3 demande que cette possibilité de partition ne se fasse pas sur des critères topologiques (si on a deux segments dans un même bâtiment et un troisième dans un autre bâtiment, il faut pouvoir faire une partition regroupant un des segments du bâtiment et le segment de l'autre bâtiment, voir aussi REQ7).
Parmi les autres exigences, le fait (REQ5) de réutiliser les protocoles existants, notamment mDNS (RFC 6762) et DNS-SD (RFC 6763), l'obligation de fonctionner sur des réseaux où la consommation électrique est un facteur crucial (REQ10, qui dit en gros que le protocole ne doit pas réveiller toutes les machines toutes les cinq minutes), la nécessité de marcher correctement sur des réseaux de plusieurs milliers de machines (REQ11), l'importance de fournir aux utilisateurs un vécu identique que les ressources qu'ils cherchent soient locales au lien ou au contraire distantes (REQ12), le souhait que l'information présentée audit utilisateur ne soit pas dépassée (pas question de lui montrer les services tels qu'ils étaient il y a deux heures, ou même simplement deux minutes, REQ13), etc.
Après cette liste d'exigences, la section 5 de notre RFC se penche
sur un problème délicat, la coexistence de plusieurs espaces de
noms. En effet, si on utilise le DNS
« normal », les noms sont uniques, et c'est une des propriétés les
plus essentielles du DNS (RFC 2826). Mais si on
utilise mDNS, chaque segment réseau a ses
propres noms, sous le TLD
.local
. On peut
parfaitement avoir une Imprimante-Couleur.local
dans un bâtiment et voir une toute autre imprimante sous le même nom
dans un autre bâtiment. Les noms ne sont plus mondialement
uniques. Comme beaucoup d'engins seront livrés avec des noms par
défaut identiques, ces « collisions » seront fréquentes. Le problème
reste ouvert (voir aussi la section 6.2).
Enfin, la section 6 du RFC se préoccupe de la sécurité. Bien sûr, l'exigence d'un service automatique et efficace ne va pas forcément dans le sens de la sécurité (difficile d'authentifier sans ennuyer les utilisateurs, par exemple). Mais il y a aussi d'autres pièges. Par exemple, avec le mDNS traditionnel, les requêtes et les réponses ont une portée limitée (au seul segment de réseau local). Si on donne un nom à sa machine, le nom ne sera vu que localement et l'utilisateur peut donc donner un nom ridicule ou grossier sans trop de risques. Avec le projet d'étendre cette résolution de noms plus loin que le réseau local, le nom donné aura davantage de conséquences. Sans même parler du cas de noms à problèmes, une extension de la découverte de services peut faciliter la tâche d'un attaquant (imaginez ce que Shodan ferait d'un tel service) et/ou permettre/faciliter l'accès à des ressources qu'on pensait privées (une imprimante, par exemple). Bien sûr, la découverte d'un service n'implique pas son accessibilité mais le risque est quand même là.
Autre problème, la vie privée. Déjà, aujourd'hui, une technologie comme Bonjour est très bavarde. Un Mac ou un iPhone diffusent à tout le réseau local en donnant le nom de l'utilisateur ("l'iPhone de Jean Durand"). Mais le problème ne peut que s'aggraver si on va plus loin que le réseau local. Ce n'est sans doute pas une bonne idée qu'une machine arrivant dans un réseau inconnu annonce le nom de son propriétaire immédiatement. À noter que, en juillet 2015, une expérience de collecte du trafic diffusé à la réunion IETF de Prague a suscité de nombreuses discussions.
Date de publication du RFC : Juillet 2015
Auteur(s) du RFC : L. Masinter (Adobe)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 15 juillet 2015
Voici la nouvelle définition du type de données Internet
multipart/form-data
, qui est notamment envoyé
par les navigateurs Web
une fois qu'on a rempli un formulaire. Elle
remplace la définition du RFC 2388.
Il y a plusieurs façons de représenter les données d'un formulaire
rempli (cf. annexe B de notre RFC). (Et il faut aussi se rappeler
qu'il n'y a pas que les formulaires en HTML :
le format décrit dans ce RFC peut servir à d'autres types de
formulaires.) Les deux plus fréquentes sont le format par défaut des
formulaires Web,
application/x-www-form-urlencoded
, et le
multipart/form-data
qui fait l'objet de notre
RFC. La sagesse générale des développeurs Web
(citée par exemple dans la
norme HTML 4)
est d'utiliser application/x-www-form-urlencoded
sauf s'il faut transmettre des fichiers ou des
données binaires,
auquel cas on préfère multipart/form-data
. En
HTML, cela se choisit par l'attribut
enctype
. Voici un exemple de formulaire HTML pour
envoyer un fichier :
<form action="http://www.example.com/register" enctype="multipart/form-data" method="post"> <p> What is your name? <input type="text" name="submit-name"/> What files are you sending? <input type="file" name="thefile"/> <input type="submit" value="Send"/> </form>
Si l'utilisateur « Larry » envoie ainsi le fichier
fi1e1.txt
, le navigateur encodera les données du
formulaire ainsi :
Content-Type: multipart/form-data; boundary=---------------------------14768918103265920051546586892 Content-Length: 359 -----------------------------14768918103265920051546586892 Content-Disposition: form-data; name="submit-name" Larry -----------------------------14768918103265920051546586892 Content-Disposition: form-data; name="thefile"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... -----------------------------14768918103265920051546586892--
Alors que l'encodage pour du
application/x-www-form-urlencoded
aurait été
submit-name=Larry&thefile=file1.txt
(ce qui
ne convient pas pour le fichier).
Cette différence entre les formats des données des formulaires est
bien expliquée dans cette réponse sur StackOverflow.
Et si vous voulez expérimenter vous-même avec
netcat, voyez cette autre réponse.
Vu de l'utilisateur, les choses se passent comme cela (section 1 de notre RFC) : on présente à l'utilisateur un formulaire L'utilisateur le remplit, il sélectionne (par exemple en cliquant) le contrôle qui sert à dire « j'ai fini, traite-moi ce formulaire ». Le contenu est envoyé à une application sur le serveur. (Petit souvenir personnel : les formulaires sont apparus avec la version 2 de