Je suis Charlie

Autres trucs


Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »


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.

Checking quickly a DNS zone: a new variant of check-soa

First publication of this article on 26 December 2012
Last update on of 22 November 2014

When you want to assert rapidly whether or not a DNS zone works fine, typical exhaustive tools like Zonemaster may be too slow. There is room for a light-and-fast tool and many people used to rely on the check_soa (with an underscore) program developed by Liu and Albitz and published with their famous book DNS and BIND. This original program no longer seems maintained and, the last time I tested it, did not support IPv6. So, I wrote one more variant of "my very own check-soa".

Like the original one, it queries each name server of a zone for the SOA record of the zone:

% check-soa fr OK: 2222258998
	2001:500:2e::2: OK: 2222258998 OK: 2222258998
	2001:678:c::1: OK: 2222258998 OK: 2222258998
	2a00:d78:0:102:193:176:144:6: OK: 2222258998 OK: 2222258998
	2001:67c:1010:11::53: OK: 2222258998 OK: 2222258997
	2001:678:4c::1: OK: 2222258997

Here, we can see that all name servers of .FR reply properly and their serial number is 2222258998. You have several options (-h to see them all). For instance, -i will display the response time:

% check-soa -i nl OK: 2012122607 (3 ms)
	2001:67c:1010:10::53: OK: 2012122607 (40 ms) OK: 2012122607 (3 ms)
	2001:660:3005:1::1:2: OK: 2012122607 (2 ms) OK: 2012122607 (25 ms)
	2a00:d78:0:102:193:176:144:5: OK: 2012122607 (38 ms)
	2001:7b8:606::85: OK: 2012122607 (15 ms) OK: 2012122607 (36 ms) OK: 2012122607 (24 ms)
	2001:610:0:800d::10: OK: 2012122607 (29 ms) OK: 2012122607 (25 ms)
	2a00:1188:5::212: OK: 2012122607 (34 ms) OK: 2012122607 (24 ms)
	2001:678:2c:0:194:0:28:53: OK: 2012122607 (33 ms)
	2001:500:2e::1: OK: 2012122607 (14 ms) OK: 2012122607 (19 ms)

Sometimes, the name servers of the zone are not synchronized (it can be temporary, the DNS being only loosely consistent, or it can be permanent if there is a problem):

% check-soa                  OK: 2012081301 OK: 2009030502 OK: 2012081301
	2a01:e0b:1:64:240:63ff:fee8:6155: OK: 2012081301 OK: 2012081301
	2a01:4a0:2002:2198:130:185:108:193: OK: 2012081301

Here, lags behind.

Do note that check-soa uses a zone, not just any domain:

% check-soa
No NS records for "". It is probably a domain but not a zone

Of course, when everything works fine, it is boring. What if there is a problem? check-soa will display it and will set the exit code accordingly:

% check-soa OK: 2011112300 OK: 2011112300 OK: 2011112300
	2001:788::88: ERROR: Timeout OK: 2011112300
	2001:788::98: ERROR: Timeout

Here, two name servers failed to reply in time (you can tune the timeout with options -t and -n). The actual problem was with IPv6 connectivity, so you can try with -4:

% check-soa -q
	2001:788::88: ERROR: Timeout
	2001:788::98: ERROR: Timeout
% echo $?               

% check-soa -q -4
% echo $?                  

In this specific case, I tested from several sites. But do note that, quite often, networks problems and the resulting timeout will depend on the site from which you test. check-soa sees the Internet from just one point. Other points may be different (this is specially true with IPv6 today.) A good example is a test from Free (it works for every other operator):

% check-soa -i mil ERROR: Timeout ERROR: Timeout ERROR: Timeout OK: 2012122703 (229 ms) ERROR: Timeout ERROR: Timeout

There are of course many other possible errors. For instance, on the TLD of Cambodia:

% check-soa kh ERROR: REFUSED
	2001:67c:2e8:5:53::6: ERROR: REFUSED OK: 2012030124
	Cannot get the IPv4 address: NXDOMAIN OK: 2012030124 ERROR: Not authoritative OK: 2012030124
	2001:dc0:1:0:4777::140: OK: 2012030124 OK: 2012030124

We see three types of errors, refuses to answer for this TLD (it is called a "lame delegation", the TLD is delegated to a server which does not know or does not want to answer about it, probably because of a misunderstanding between operators), does not exist and replies, but is not authoritative (it is actually an open recursive resolver, something which is frowned upon, see RFC 5358).

By default, check-soa uses EDNS. This can create problems with some very old name servers:

% check-soa ERROR: FORMERR
	2a01:111:2005::1:1: ERROR: FORMERR
	2a01:111:2020::1:1: ERROR: FORMERR
	2a01:111:200f:1::1:1: ERROR: FORMERR

All of Microsoft's name servers reply "FORmat ERRor". The -r option will force back old DNS:

% check-soa -r OK: 2012122401
	2a01:111:2005::1:1: OK: 2012122401
	2a01:111:2006:6::1:1: OK: 2012122401 OK: 2012122401 OK: 2012122401
	2a01:111:2020::1:1: OK: 2012122401
	2404:f800:2003::1:1: OK: 2012122401 OK: 2012122401 OK: 2012122401
	2a01:111:200f:1::1:1: OK: 2012122401

One of the points where my check-soa is an improvment over the original is that it issues DNS requests in parallel. So, the waiting time will depend only on the slowest server, not on the sum of all servers. Let's try it on Sri Lanka TLD:

% time check-soa -i lk OK: 2012122601 (268 ms)
	2405:5400:3:1:203:143:29:3: OK: 2012122601 (274 ms) OK: 2012122601 (133 ms) OK: 2012122601 (189 ms) OK: 2012122601 (290 ms) OK: 2012122601 (179 ms)
	2401:dd00:1::162: OK: 2012122601 (300 ms) OK: 2012122601 (4 ms)
	2001:500:14:6027:ad::1: OK: 2012122601 (5 ms) OK: 2012122601 (142 ms)
	2001:67c:e0::88: OK: 2012122601 (16 ms) OK: 2012122601 (17 ms) OK: 2012122601 (622 ms)
check-soa -i lk  0.02s user 0.00s system 3% cpu 0.637 total

The elapsed time was only 637 ms (a bit more than the slowest server, which was at 622), not the sum of all the delays. Parallelism is specially important when some servers timeout. By default, check-soa tries three times, with a waiting time of 1.5 second (other programs have a default of 5 seconds, which is extremely long: a DNS reply never comes back after 5 seconds!). So:

% time check-soa -i ml ERROR: Timeout OK: 2012122100 (115 ms) OK: 2012122100 (109 ms) ERROR: REFUSED (13 ms)
	2001:67c:e0::95: ERROR: REFUSED (14 ms)
	2001:4f8:0:2::13: OK: 2012122100 (173 ms) OK: 2012122100 (183 ms) OK: 2012122100 (124 ms)
check-soa -i ml  0.01s user 0.00s system 0% cpu 4.518 total

The elapsed time, 4.518 seconds, is mostly because of the timeout (and retries) on

By default, check-soa retrieves the list of name servers to query from the local resolver. If the domain is so broken that it cannot even handle these requests, or simply if you want to test with different name servers (for instance because the zone is not yet delegated), you can use the -ns option to indicate explicitely the name servers:

% check-soa -ns "" com
	2001:503:a83e::2:30: OK: 1416671393 OK: 1416671393
	2001:503:231d::2:30: OK: 1416671393 OK: 1416671393

Are you convinced? Do you want to install it? Then, get the source code and follow the instructions in the file Do note that my check-soa is written in Go so you'll need a Go compiler. Also, it depends on the excellent godns library so you need to install it first.

If you read the source code, there is nothing extraordinary: parallelism is very simple in Go, thanks to the goroutines so there is little extra effort to make a parallel program (one of the great strengths of Go).

I also wrote a Nagios plugin in Go to perform more or less the same tests. But the Nagios plugin does not use parallelism: since it is not an interactive program, it is less important if the elapsed time is longer.

Other versions of check-soa (or check_soa):

A recent alternative to check-soa is the option nssearch of dig:

% dig +nodnssec +nssearch
SOA 2012122602 7200 3600 604800 3600 from server in 1 ms.
SOA 2012122602 7200 3600 604800 3600 from server 2001:67c:2219:3::1:4 in 1 ms.
SOA 2012122602 7200 3600 604800 3600 from server in 2 ms.

It has several limitations: each server is tested only once, even if it has multiple IP addresses (which can belong to different physical machines), if stops immediately for some errors (such as a name server which has no entry in the DNS), it does not react properly to non-EDNS name servers like mentioned above, etc.

Thanks to Miek Gieben for godns and for his debugging of my code. Also, check-soa is available as a package in ArchLinux AUR.

L'article seul

Fiche de lecture : Tubes: A journey to the center of the Internet

Auteur(s) du livre : Andrew Blum
Éditeur : Harper Collins
Publié en 2012
Première rédaction de cet article le 25 décembre 2012

Contrairement à ce qu'on pourrait croire en prêtant attention aux niaiseries comme le discours sur le « virtuel » ou sur le « cloud  », l'Internet n'est pas un concept évaporé. Il s'appuie sur de grosses et lourdes machines, qui sucent beaucoup d'électricité, et qui sont hébergées dans de grands bâtiments industriels. Ceux-ci sont connectés par des liens bien physiques, les ondes radio étant marginales. C'est cet enracinement physique de l'Internet que décrit Andrew Blum. L'auteur vivait autrefois dans l'ignorance de l'endroit où passait son trafic Internet. Il a eu son chemin de Damas lorsqu'un écureuil insolent a eu l'audace de ronger son accès Internet. Blum a alors compris la physicalité du réseau et est parti visiter la planète pour trouver les lieux physiques d'Internet.

(Au passage, ceux qui aiment les écureuils et se demandent pourquoi une si charmante bête est peu aimée des professionnels du réseau doivent lire l'excellent article de Pierre Col.)

Car Blum regrette qu'on ne prête plus attention à cette physicalité : comme le dit Leonard Kleinrock, interrogé par l'auteur sur les lieux des débuts d'Arpanet, « Students no longer take things apart », on ne démonte plus les choses. À défaut de les démonter, Blum les visite. Il se rend dans plusieurs points d'échange et décrit de manière très vivante ces points d'interconnexion où bat le cœur du réseau. Il ne peint pas que l'état physique actuel mais aussi son histoire compliquée et conflictuelle. Le livre contient une passionnante histoire du célèbre MAE-East. Lorsque je travaillais au CNAM, c'était un endroit mythique et lointain où l'Internet, l'interconnexion des réseaux, même entre opérateurs français, se faisait. Dans le livre de Blum, on suit sa difficile naissance, mais aussi celle de son opposé Equinix. (Pendant que je lisais ce chapitre, j'ai appris la naissance d'un des tous derniers points d'échange créés, à Kinshasa, le Kinix.)

Blum visite aussi DE-CIX, AMS-IX, le LINX (contrairement à ce qu'on lit parfois chez des amateurs de sensationnalisme, ces lieux n'ont rien de secret, puisque tout le monde s'y connecte) et suit les réunions de NANOG pour y entendre les mystérieures négociations sur le peering, les exposés des acteurs essayant d'encourager les autres à peerer avec eux, en se vendant et en vendant leurs abonnés comme s'ils étaient une marchandise (« I have eyeballs. If you have content, peer with me. », en utilisant le terme péjoratif de « globes oculaires » pour parler des abonnés, supposés être des consommateurs passifs et bêtes). On croise dans le livre des figures familières de ce genre de réunions comme Sylvie LaPerrière, qui vient de rentrer au Conseil d'Administration d'AMS-IX.

Après les points d'échange, l'auteur se tourne vers les câbles sous-marins, par lesquels passent l'essentiel du trafic international. Ces câbles ne relient pas n'importe quels points. Comme « People go where things are », on s'installe là où il y a déjà quelque chose), la plupart de ces câbles atterrissent aux mêmes endroits où atterrissaient les fils du télégraphe, des lieux comme Porthcurno (un des meilleurs reportages du livre) ou 60 Hudson.

Andrew Blum a même suivi l'atterrissage d'un nouveau câble de Tata, le WACS, au Portugal, encore un passionnant récit.

Ces câbles ne sont pas posés n'importe où : la résilience de l'Internet dépend d'une répartition de ces liens à différents endroits, pour ne pas risquer qu'ils soient victimes du même problème, comme la fameuse panne de Luçon en 2006 où un tremblement de terre avait coupé plusieurs câbles d'un coup.

(Au passage, si vous aimez les histoires de pose de câbles sous-marins, vous pouvez aussi relire l'excellent reportage de Neal Stephenson.)

Après les points d'échange où se connectent les opérateurs, et les câbles qui les relient, où se trouve physiquement l'Internet ? Bien sûr dans les grands data centers où sont hébergées les données. C'est la troisième partie du livre. L'auteur revient sur le scandale de The Dalles, où Google était arrivé en terrain conquis, imposant même au maire de ne pas informer son propre conseil municipal sur les projets en cours. Et, alors que visiter les points d'échange et les stations d'atterrissage des câbles n'avait posé aucun problème au journaliste, il s'est par contre heurté à un mur en tentant de visiter un data center de Google : il n'a pas dépassé la cafétéria, où les officiels lui ont servi un excellent saumon bio et un très indigeste discours corporate comme quoi Google était formidable, « Hein, John, dit au monsieur pourquoi c'est si formidable de travailler pour Google ». Comme le note l'auteur, « Google sait tout de nous, mais nous ne pouvons rien savoir de Google ».

Très peu d'erreurs dans ce livre, qui a été soigneusement étudié et bien vérifié. La plus amusante : ARIN qualifié, p. 121, de Internet governing body. (Le RIPE-NCC, bien plus ancien, n'est guère mentionné.)

L'article seul

RFC 6781: DNSSEC Operational Practices, Version 2

Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : O. Kolkman (NLnet Labs), W. Mekking (NLnet Labs), R. Gieben (SIDN Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 22 décembre 2012

Comme avec toute technique fondée sur la cryptographie, le protocole DNSSEC impose, non seulement des bons algorithmes et une mise en œuvre correcte, mais surtout des procédures rigoureuses et soigneusement exécutées. C'est le but de ce RFC, qui remplace le RFC 4641 et qui explique tout ce à quoi doivent s'attendre les registres et autres administrateurs de zones DNS, grandes ou petites, qui déploieraient DNSSEC. (Le cas des serveurs DNS récursifs, par exemple les résolveurs d'un FAI, n'est pas étudié.)

Notre RFC rappelle donc des concepts de base du DNS (notamment le fait que la réjuvénation des modifications n'est pas instantanée) puis rappelle les différentes clés (cf. section 1.1 pour une définition précise de clé) utilisées par DNSSEC et leurs caractéristiques souhaitables (longueur, période maximale pendant laquelle on les utilise, lieu de stockages, etc). Tout n'est pas encore bien connu dans ce domaine. Certes, la racine est signée depuis juillet 2010, ainsi que plus de 80 TLD mais, au niveau en dessous du TLD, peu de zones sont signées (dans les 1 % de .fr, par exemple) et l'expérience opérationnelle peut donc encore être améliorée.

Il explique ensuite les considérations temporelles (DNSSEC utilise le temps et nécessite des horloges bien synchronisées, par exemple par NTP). Le DNS étant hiérarchique, il faut veiller, lors de toutes les manipulations, à bien rester synchronisé avec le gérant de la zone parente, dont les enregistrements de type DS (delegation signer) pointeront vers notre clé. Le but est, qu'à tout moment, une chaîne de confiance intacte aille de la clé de confiance jusqu'aux enregistrements du domaine. Si un lien de cette chaîne casse, le domaine sera marqué comme bogus (RFC 4033, section 5) et rejeté par les résolveurs validants.

Enfin, le RFC étudie le rollover, le remplacement d'une clé. Les clés ne pouvant pas raisonnablement être utilisées éternellement, il faut prévoir à l'avance les remplacements périodiques et aussi, hélas les remplacements en urgence en cas de compromission. Il faut apporter beaucoup de soin à ce remplacement, si on veut éviter que, pendant une certaine période, les données publiées dans le DNS soient invalides et donc rejetées par un résolveur DNS paranoïaque (il faut publier la nouvelle clé suffisamment à l'avance pour qu'elle soit présente partout ou bien signer tous les enregistrements avec les deux clés, l'ancienne et la nouvelle). Mon article à la conférence SATIN en 2011 avait montré que c'était loin d'être le cas : les erreurs sont fréquentes, même pour les grandes zones sérieuses.

Bref, pour un gérant de zone DNS, déployer DNSSEC, ce n'est pas uniquement signer la zone : c'est aussi mettre en place des procédures de sécurité, analogues à celle d'une autorité de certification.

Maintenant, avec la section 3, voyons les détails pratiques. D'abord, la génération et le stockage des clés cryptographiques. D'abord, un message d'espoir : en lisant ce RFC, on peut avoir l'impression d'un ensemble de tâches très compliquées, impossible à réaliser correctement. Heureusement, il existe déjà des logiciels qui, en automatisant la plupart de ces tâches, rendent les choses bien plus faciles. J'utilise pour cela OpenDNSSEC.

D'abord, avant de se lancer, il faut faire certains choix technico-politiques :

  • Est-ce qu'on n'utilise qu'un type de clé ou bien est-ce qu'on sépare KSK (Key Signing Key) et ZSK (Zone Signing Key) ? Contrairement à ce qu'on lit souvent, la dichotomie entre une KSK et une ZSK n'a rien d'obligatoire, et elle complique les choses.
  • Est-ce que les KSK vont être configurés par certains comme clés de confiance, à partir desquels on valide ? Cela permet d'être indépendant des autres acteurs comme la racine mais cela augmente les responsabilités.
  • Quels sont les délais pertinents, par exemple le champ Expire du SOA, le temps de réaction souhaité en cas de problème ? Il faut aussi se demander si NOTIFY (RFC 1996) marche bien (ou si on ne peut compter que sur le paramètre Refresh de l'enregistrement SOA) et si on utilise IXFR (RFC 1995) ou AXFR,
  • Quels sont les choix cryptographiques (par exemple, concernant la longueur des clés RSA) ?

Une fois ces choix faits, on pourra configurer le résultat (dans OpenDNSSEC, fichier /etc/opendnssec/kasp.xml). Mais que choisir ?

Pour le choix entre une séparation KSK/ZSK et une clé unique, le choix est purement un problème opérationnel du côté du gestionnaire de zone. Les résolveurs ne feront pas de différence.

Un problème à garder en tête pour le stockage des clés est le risque de compromission de la clé (vol du disque sur lequel se trouve la partie privée de la clé, par exemple). Si la clé privée est sur le disque d'une machine connectée à l'Internet, le risque est plus élevé que s'il est sur une machine déconnectée et enfermée dans un coffre-fort. Encore mieux, pour les plus riches, l'usage des HSM permet d'être raisonnablement sûr qu'il n'y aura pas de vol de la clé. D'un autre côté, pour signer des enregistrements, une clé sur une machine non-connectée est certainement moins pratique. Une des façons de résoudre le dilemne est de séparer KSK et ZSK : on met la KSK en sécurité dans un endroit bien protégé (elle ne sert qu'à signer la ZSK, qui ne change pas tous les jours) et on fait les signatures des enregistrements de la zone avec la ZSK. En cas de compromission de la ZSK, son remplacement est relativement simple, puisqu'il est entièrement interne à la zone, il ne nécessite pas d'interaction avec la zone parente. (C'est ainsi, par exemple, que fonctionne la racine.)

Comme toujours en sécurité,il y a un fort risque de blinder la porte en oubliant la fenêtre : il ne sert pas à grand'chose de protéger la KSK avec des précautions de niveau militaire si les données de la zone, celles qu'on va signer, peuvent être facilement modifiées par un attaquant (encore que le RFC oublie de dire que la possession de la clé privée permette de générer des enregistrements mensongers sans que le registre s'en aperçoive). De même, le HSM empêche certes le méchant de copier la clé privée, mais il ne l'empêche pas de signer : si le pirate prend le contrôle de la machine connectée au HSM, il peut faire signer à ce dernier ce qu'il veut. Bref, il n'y a pas de solution miracle en matière de sécurité.

Séparer KSK et ZSK permet donc plus de souplesse dans la gestion de la sécurité. Mais cela rend les choses plus complexes. Si les clés sont gérés automatiquement par un outil comme OpenDNSSEC, ce n'est pas trop un problème. Sinon, il vaut peut-être mieux n'avoir qu'une clé.

Une question qui agite les milieux DNSSEC depuis de nombreuses années est celle du remplacement (rollover) des clés. Il y a deux écoles :

  • Celle qui dit que les remplacements doivent être systématiques et fréquents, pour qu'ils deviennent de la routine ; elle se sépare en deux sous-écoles, une qui favorise les remplacements périodiques et une qui préfère les faire au hasard,
  • Et l'école qui dit que les remplacements ne doivent se faire que s'il y a une bonne raison, par exemple une forte suspicion que la clé privée a été copiée.

Notre RFC note qu'il n'y a pas consensus sur cette question. Il note qu'un facteur important est « est-ce que la clé est utilisée comme clé de confiance quelque part ? », c'est-à-dire est-ce que des gens l'ont configuré dans leur résolveur validant (directives trusted-keys ou managed-keys de BIND et trust-anchor ou trust-anchor-file de Unbound) ? Cela peut se faire, par exemple pour éviter de dépendre de la hiérarchie du DNS (on peut imaginer une clé DNSSEC de installée dans les résolveurs des ministères pour être sûr de ne pas être affectés par des problèmes à l'AFNIC ou à la racine). Notez que cela peut arriver sans le consentement du gérant de la zone. Si ce dernier publie un DPS (DNSSEC Practice Statement) disant en gros caractères « n'utilisez pas notre KSK comme clé de confiance, ne vous fiez qu'au DS de la zone parente », alors, on peut tenir pour acquis qu'il y aura peu de cas où la KSK sera installée en dur dans les résolveurs. Autrement, le remplacement devient bien plus compliqué car il faut prévenir tous les gens qui ont configuré cette clé de confiance. Certains ne seront pas joignables ou ne réagiront pas et il faudra donc prendre le risque de casser leur accès DNSSEC. Ainsi, pour la racine (qui ne peut pas compter sur l'enregistrement DS de la zone parente) qui est forcément clé de confiance, on peut penser qu'il n'y aura jamais de remplacement de la KSK originelle, la 19036, sauf en cas de compromission : cela nécessiterait de changer trop de résolveurs.

Notez qu'il existe un mécanisme pour mettre à jour les clés de confiance, décrit dans le RFC 5011. Comme il n'est jamais sûr que tous les « clients » le mettent en œuvre, il est difficile de savoir si on peut compter dessus (dans Unbound, trust-anchor-file: "/etc/unbound/root.key" installe une clé de confiance statique et auto-trust-anchor-file: "/var/lib/unbound/root.key" - notez le auto- devant - installe une clé qui pourra être mise à jour par les procédures du RFC 5011). Ces procédures n'ont jamais été testées pour la racine.

Si on sépare KSK et ZSK, c'est normalement le bit SEP (Secure Entry Point, cf. RFC 3757) qui les distingue (dans le cas le plus courant, la ZSK aura un champ Flags de 256 et la KSK de 257 à cause du bit SEP). Ce bit n'est pas utilisé par les validateurs mais certains outils s'en servent pour trouver la KSK (par exemple le dnssec-signzone de BIND). Si on n'a qu'une seule clé, elle sert de KSK et doit donc avoir le bit SEP (autrement, le dnssec-signzone de BIND vous dira dnssec-signzone: fatal: No self signed KSK's found). Notez que certains outils ne vous laisseront pas facilement n'utiliser qu'une clé. Par exemple, avec dnssec-signzone, vous aurez le message dnssec-signzone: fatal: No non-KSK DNSKEY found; supply a ZSK or use '-z'. et vous devrez utiliser l'option indiquée pour signer quand même.

Un peu de cryptographie, maintenant. La durée de vie raisonnable d'une clé dépend de sa longueur. Le RFC suggère de décider d'une durée de vie, en tenant compte des contraintes opérationnelles, et d'en déduire la longueur. Une KSK qui a des enregistrements DS dans sa zone parente peut durer vingt ans sans problème, sauf si on désire tester régulièrement les procédures de remplacement ou sauf si la clé privée est compromise. Si on veut la remplacer régulièrement, une durée raisonnable proposée par le RFC est d'un an.

Quel algorithme cryptographique choisir ? Les quatre standardisés à l'heure actuelle (le RFC en cite trois mais ECDSA est apparu depuis), RSA, DSA et GOST sont bien connus et spécifiés et considérés comme fiables. En partie pour des raisons de performance, le RFC suggère la combinaison RSA/SHA-256 comme l'algorithme préféré (RFC 5702) et RSA/SHA-1 sinon.

Les algorithmes fondés sur les courbes elliptiques (GOST - RFC 5933 - et ECDSA - RFC 6605) ont des avantages importants sur RSA, notamment les clés et signatures plus petites. Mais très peu de résolveurs validant les gèrent et signer une zone uniquement avec ces algorithmes serait donc peu utile. D'autre part, même si le RFC ne le dit qu'en passant, les problèmes de brevet sont bien plus nombreux que pour RSA.

Si on a choisi RSA, il faut se décider pour une longueur de clé, suffisante pour résister à la cryptanalyse pendant la durée de vie de la clé (le RFC 3766 contient des calculs intéressants sur la solidité des clés). Comme le note le RFC, en dépit d'un FUD important, personne n'a encore annoncé la cryptanalyse d'une clé RSA de 1024 bits (le record publié est aux alentours de 700 bits). Et, le jour où cela arrivera, ce ne sera pas la fin de RSA mais la fin d'une seule clé. Bien sûr, la cryptanalyse progresse (et, le RFC oublie ce point, les meilleurs résultats ne sont pas forcément publiés) mais le RFC estime que les clés de 1024 bit sont encore sûres pour dix ans.

Néanmoins, utiliser des clés plus grandes est raisonnable si on veut une très longue durée de vie ou bien si on estime que le remplacement de la clé sera difficile (ce qui est certainement le cas de la clé de la racine). Pour ces cas, une clé de 2048 bits est donc utile. Attention, ce n'est pas gratuit, notamment la vérification est quatre fois plus lente et la signature huit fois moins rapide.

Certains férus de cryptographie peuvent tiquer à la pensée de n'utiliser que 1024 bits. Mais l'argument massue du RFC est celui de l'équilibre : on ne fait pas du DNSSEC pour le plaisir de la cryptographie. On le fait pour protéger quelque chose, par exemple un site Web de banque en ligne. Et ce genre de sites est en général protégé par TLS avec des clés qui ne sont souvent pas plus longues. Si un attaquant peut casser une clé de 1024 bits, il peut s'attaquer à TLS aussi bien qu'à DNSSEC. Avec des clés de 2048 bits, on blinde fortement la porte... alors que la fenêtre du rez-de-chaussée ne l'est pas toujours. Bref, si un brusque progrès de la cryptanalyse permet de casser ces clés de 1024 bits plus tôt que les dix ans indiqués, cela fera du bruit et cassera bien d'autres choses que DNSSEC.

Notons que, contrairement à son prédécesseur RFC 4641, notre RFC ne fait plus dépendre la solidité d'une clé du fait qu'elle soit largement utilisée ou pas. La cryptographie a évolué depuis le RFC 4641.

Où stocker ensuite ces clés ? Idéalement, sur une machine sécurisée et non connectée au réseau. On apporte les données sur cette machine, on signe et on repart avec les données signées pour les apporter au serveur de noms. C'est très sûr mais cela ne peut pas marcher si on utilise les mises à jour dynamiques du DNS (RFC 3007). Dans ce cas, il faut bien avoir la clé privée sur le serveur de noms (on parle de online key). C'est donc moins sûr et le RFC suggère, dans ce cas, que le serveur maître ne soit pas directement accessible de l'Internet (technique du hidden master, où le vrai maître n'est pas dans les enregistrements NS de la zone). Notez qu'une des motivations pour la séparation KSK/ZSK vient de là : avoir une KSK peu utilisée et dont la clé privée est stockéee de manière très sûre et une ZSK en ligne, plus vulnérable mais plus facile à changer.

Comme toujours en matière de sécurité, ces bons avis doivent être mis en rapport avec les contraintes opérationnelles et économiques. Ainsi, on peut sans doute améliorer la sécurité des clés en les gardant dans un HSM. Mais ces engins sont chers et pas pratiques pour les opérations quotidiennes.

Et la génération des clés ? C'est un aspect souvent oublié de la sécurité cryptographique mais il est pourtant essentiel. La clé doit être vraiment imprévisible par un attaquant et pour cela elle doit être générée en suivant les recommandations du RFC 4086 et de NIST-SP-800-90A, « Recommendation for Random Number Generation Using Deterministic Random Bit Generators ». Par exemple, avec les outils de génération de clés de BIND (dnssec-keygen), il ne faut pas utiliser l'option -r /dev/urandom en production, car elle n'utilise qu'un générateur pseudo-aléatoire. (Les HSM disposent tous d'un générateur correct.)

À noter que la version précédente de ce document, le RFC 4641 faisait une différence entre les zones DNS selon leur place dans la hiérarchie (plus ou moins haute). Cette distinction a disparu ici et les mêmes règles de sécurité s'appliquent à toutes. L'une des raisons de ce choix est qu'on ne peut pas facilement déterminer quelles zones sont importantes pour un attaquant ( est peut-être plus importante que le TLD .td, même si ce dernier est placé plus haut dans la hiérarchie). Cela n'empêche évidemment pas chaque gérant de zone de devoir déterminer si sa zone est critique ou pas, avant d'adapter les mesures de sécurité en conséquence.

La section 4 de notre RFC est ensuite consacrée au gros morceau de la gestion opérationnelle de DNSSEC : les remplacements de clés (key rollovers). Qu'on choisisse de faire des remplacements réguliers, pour qu'ils deviennent une simple routine, ou qu'on choisisse de n'en faire que lors d'évenements exceptionnels (comme une copie illégale de la clé), les remplacements sont une réalité et il faut s'y préparer. Par exemple, même si on décide de ne pas en faire systématiquement, il faut s'entrainer (et tester ses procédures) avec une zone de test. L'opération est délicate en raison de l'existence des caches DNS, qui vont garder la vieille information un certain temps. Personnellement, je déconseille fortement de faire les remplacements à la main : le risque d'erreur est bien trop grand. Il faut plutôt automatiser le processus, et avec un logiciel soigneusement débogué. L'expérience (mon article à la conférence SATIN en 2011) montre que les erreurs sont, elles aussi, une réalité.

Si on a décidé d'avoir deux clés, ZSK et KSK, leurs remplacements sont indépendants. Les ZSK sont les plus simples car elles peuvent être remplacées sans interaction avec la zone parente (pas d'échange d'enregistrements DS). Le RFC explique ensuite (en grand détail : je n'en donne qu'un court résumé ici) les deux méthodes connues pour remplacer une ZSK :

  • la pré-publication de la future clé,
  • et la double signature.

Dans le premier cas, on génére la nouvelle ZSK, on la publie (sans qu'elle signe quoi que ce soit) puis, lorsque le nouvel ensemble DNSKEY est dans tous les caches, on utilise la nouvelle ZSK pour signer. Une fois que les signatures faites avec l'ancienne clé ont disparu des caches, on arrête de publier l'ancienne clé. Le remplacement est terminé. Cette description très sommaire de l'algorithme suffit déjà, je crois, à montrer qu'il vaut mieux ne pas le faire à la main.

Quant à la double signature (plus rare, en pratique), elle consiste à signer tout de suite avec la nouvelle clé, tout en continuant à signer avec l'ancienne, pour les caches ayant seulement l'ancienne clé.

La section résume les avantages et inconvénients de chaque méthode. La pré-publication nécessite davantage d'étapes (ce qui est grave si on la fait à la main, et moins si on a tout automatisé). La double signature est plus coûteuse puisque la zone sera, pendant la période transitoire, bien plus grosse (les signatures forment l'essentiel de la taille d'une zone signée). Dans les deux cas, comme il n'y a pas besoin d'interagir avec la zone parente, le processus peut être entièrement automatisé et c'est bien ce que fait, par exemple, OpenDNSSEC.

Et pour remplacer une KSK ? La double signature devient alors plus intéressante, puisque la KSK ne signe pas toute la zone, seulement l'ensemble d'enregistrements DNSKEY. Les problèmes de taille ne se posent donc pas. Par rapport au remplacement d'une ZSK, la grosse différence est l'interaction avec la zone parente. Il n'existe pas d'API standard pour le faire. Les bureaux d'enregistrement (BE) utilisent en général EPPRFC 5910 - avec le registre mais le gestionnaire de la zone, avec son BE, a typiquement une interface Web, ou bien une API non-standard, par exemple à base de REST (cf. aussi la section 4.3.2). L'opération nécessite donc souvent une intervention manuelle comme décrit dans mon article sur un exemple avec OpenDNSSEC.

Et si on a une clé unique ? Le cas est proche de celui d'un remplacement de KSK et le RFC recommande la double-signature, car c'est la solution la plus simple (et, si on n'utilise qu'une clé, c'est qu'on aime la simplicité).

La section 4.2 couvre le cas des préparatifs pour un remplacement d'urgence. On arrive le lundi matin au bureau, le coffre-fort est grand ouvert et la clé USB qui stockait la clé privée a disparu (une variante moins gênante est celle où la clé privée est détruite, mais pas copiée, par exemple en raison d'un incendie). Il faut alors remplacer cette clé et c'est bien plus facile si on a planifié avant. Notez qu'il y a toujours un compromis ici : si on supprime immédiatement l'ancienne clé, désormais compromise, une partie des résolveurs (ceux qui ont les anciennes signatures, mais pas l'ancienne clé) dans leurs caches considéreront la zone comme invalide. Mais, si on continue à diffuser l'ancienne clé, on augmente la durée pendant laquelle le voleur pourra injecter des informations mensongères. Il existe une méthode intermédiaire, faire retirer l'enregistrement DS par la zone parente. Selon les TTL en jeu, cela peut permettre de diminuer la durée du problème. Comme on le voit, il vaut mieux faire les calculs, l'analyse et le choix de la meilleure méthode avant le fatal lundi matin...

Une solution possible est d'utiliser des Standby keys, qui seront publiées (et donc dans tous les caches) mais pas utilisées pour signer, et dont la partie privée sera gardée à un endroit différent.

Le problème est évidemment plus grave si la clé en question avait été configurée par certains comme clé de confiance dans leurs résolveurs. Il faut alors prévenir tout le monde de la compromission, par un message (authentifié) envoyé à plusieurs endroits, pour maximiser les chances de toucher tout le monde. Si la clé de la racine (ou d'un grand TLD comme .net) était compromise, on verrait sans doute l'annonce sur dns-operations, NANOG, Twitter, etc. Outre l'authentification de l'annonce, la nouvelle clé devra elle aussi être authentifiée, par un moyen non compromis : ne mettez pas la partie privée de la KSK dans le même coffre-fort que la partie privée de votre clé PGP !

Autre cas amusant pour les gérants d'une zone DNS, le changement d'opérateurs. Par exemple, le titulaire d'une zone décide de passer d'un hébergeur DNS à un autre (notez que l'hébergeur est souvent le BE mais ce n'est pas obligatoire). Si les deux hébergeurs (en pratique, c'est évidemment le perdant qui fait des histoires) coopèrent, le problème est relativement simple. Le RFC suppose que l'ancien hébergeur ne va pas transmettre la clé privée (si elle est dans un HSM, il ne peut tout simplement pas). Dans ce cas, l'ancien hébergeur doit mettre dans la zone la clé publique du nouveau, et les signatures calculées par le nouveau avec ses clés. Le nouvel opérateur publie la même zone et, une fois le changement terminé (une fois que les clés du nouvel hébergeur sont dans tous les caches), le nouvel hébergeur peut retirer les clés et les signatures de l'ancien. Ce n'est pas très pratique (il faut échanger clés publiques et signatures). Personnellement, je trouve cet algorithme tout à fait irréaliste. Dans le DNS d'aujourd'hui, des obligations bien plus modérées (en cas de changement d'hébergeur, continuer à servir la zone jusqu'à ce que les TTL sur les enregistrements NS expirent) ne sont jamais respectées par les hébergeurs perdants, même lorsqu'elles figurent dans les obligations contractuelles. Le RFC note à juste titre que c'est un problème économique et qu'il n'a pas de solution technique.

Il reste donc le cas qui sera sans doute le plus probable, celui où l'ancien hébergeur de la zone DNS ne coopérera pas. (Techniquement, il peut même saboter activement le transfert, en publiant un enregistrement DNSKEY avec un très long TTL, pour « empoisonner » les caches.) La seule solution est alors de passer par une phase où la zone ne sera pas sécurisée par DNSSEC : le parent retire l'enregistrement DS, on attend que l'ancien DS ait disparu des caches, puis on en remet un, pointant vers une clé du nouvel hébergeur.

Quelques mesures techniques dans les résolveurs validants peuvent aider :

  • Limiter les TTL qu'on accepte (RFC 2308) pour diminuer le risque d'obstruction,
  • Vérifier la délégation lorsque les enregistrements NS vont expirer, pour être sûr de ne pas rester bloqué sur de vieux serveurs de noms (c'est également une protection contre l'attaque des domaines fantômes),
  • Lorsque la validation échoue, réessayer après avoir viré les DNSKEY du cache.

Le gérant de la zone peut aussi aider en n'ayant pas des TTL trop longs.

Gérer proprement du DNSSEC impose une grande rigueur sur les questions temporelles. Avant DNSSEC, le temps dans le DNS était toujours relatif. Par exemple, le champ Expire de l'enregistrement SOA était relatif au moment de la dernière synchronisation avec le serveur maître. Même chose pour les TTL. Mais, avec DNSSEC, le temps devient absolu. Les dates de début et de fin de validité dans un enregistrement RRSIG, par exemple, sont absolues. Elles dépendent donc d'une horloge à l'heure.

Quelques conseils, donc, sur le temps :

  • La période de validité des signatures devrait être au moins égale au TTL (autrement, des signatures encore dans le cache pourraient être expirées),
  • Ne pas attendre le dernier moment pour re-signer. Cela laisse un délai pour corriger d'éventuels problèmes. Par exemple, si les signatures ont en permanence deux jours de validité devant elles, cela permet de survivre pendant un week-end, en cas d'incapacité à re-signer.
  • Ne pas mettre de TTL trop bas (du genre 5 minutes) à la fois à cause de la charge sur les serveurs et aussi parce que la validation DNSSEC nécessite de récupérer beaucoup d'enregistrements et qu'il ne faut pas que leur TTL expire avant que le processus ne soit terminé.
  • Pour une zone signée, avoir un Expire (dans le SOA) plus long que la durée de validité des signatures ne sert pas à grand'chose : un serveur esclave qui servirait des signatures qui ne sont plus valides serait pire qu'un serveur esclave qui ne servirait plus rien.

Bon, mais alors, quelle durée choisir pour la validité des signatures (les outils de signature de BIND mettent un mois, par défaut). C'est un compromis : une durée trop longue et on est vulnérable aux attaques par rejeu. Une durée trop courte et on risque de n'avoir pas assez de temps pour réagir en cas de problème. Une erreur dans la configuration du pare-feu, les serveurs esclaves qui ne peuvent plus se synchroniser, les signatures sur ces serveurs esclaves qui expirent et crac, la zone est invalide. Cela arrive vite. Mon opinion personnelle est qu'aujourd'hui, les procédures ne sont pas assez testées et l'expérience DNSSEC est insuffisante. Il faut donc jouer la sécurité et avoir des durées de validité longues (au moins deux semaines). Dans le futur, au fur et à mesure de la montée en compétence et de l'amélioration des logiciels, on pourra mettre des durées de validité des signatures plus courtes, fermant ainsi la porte aux attaques par rejeu.

Voilà, nous avons couvert le gros de ce RFC. La section 5, qui suit, se consacre à un problème rigolo, celui des enregistrements indiquant l'enregistrement suivant, les enregistrements next. L'un des choix importants de conception de DNSSEC était de permettre que les signatures se fassent entièrement hors-ligne. On ne pouvait donc pas prévoir toutes les questions posées au serveur et avoir une signature pour toutes les réponses « ce domaine n'existe pas ». Il y a donc des enregistrements qui disent « il n'y a pas de domaine ici », enregistrements qui sont signés pour qu'un résolveur validant puisse authentifier une réponse négative. Ces enregistrements next sont le NSEC et le NSEC3. Le premier est en clair (il indique le nom de l'enregistrement suivant celui qui n'existe pas), le second est brouillé (il indique le condensat suivant le condensat du nom qui n'existe pas). Pour l'administrateur, les NSEC sont plus pratiques, notamment au débogage. Mais ils permettent la récupération complète de la zone, en marchant de NSEC en NSEC.

Le choix entre NSEC et NSEC3 dépend du type de la zone. Si on a une petite zone au contenu prévisible (juste l'apex, un mail et un www, ce qui est le cas de très nombreuses zones), aucune raison d'utiliser NSEC3. Même chose si la zone est très structurée et donc très prévisible (, ENUM...). Même chose si la zone est publique, ce qui est le cas par exemple de la racine (il existe une autre raison d'utiliser NSEC3, l'opt-out, qui intéresse surtout les grandes zones de délégation comme certains TLD). Autrement, si on n'est dans aucun de ces cas, si on est une assez grande zone au contenu imprévisible et qui n'est pas publique, il est cohérent d'utiliser NSEC3 (RFC 5155).

NSEC3 a certains paramètres à configurer (et qui sont publiés dans l'enregistrement NSEC3PARAM). Notamment, on peut définir le nombre d'itérations de hachage. Cette possibilité protège des attaques par dictionnaires pré-calculés mais elle est coûteuse et elle mène à l'exécution de code à chaque requête pour un nom inexistant. Le RFC suggère un nombre de 100 itérations, ce qui est colossal par rapport à ce que font la plupart des zones NSEC3 aujourd'hui (5 par défaut avec OpenDNSSEC, mais beaucoup l'abaissent, on trouve 1 pour .fr et .com, et même 0 pour .org...) NSEC3 ajoute un sel au début de l'itération et notre RFC suggère de changer ce sel en même temps que la ZSK.

Les changements depuis le RFC 4641 sont résumés dans l'annexe E. D'abord, les erreurs connues ont été corrigées. Ensuite, la fonction de hachage SHA-256 a été ajoutée aux recommandations. La partie sur le changement d'hébergeur DNS a été ajoutée. Le modèle avec séparation KSK/ZSK ne bénéficie plus d'un privilège particulier puisque le modèle avec une seule clé est également décrit.

(Les juristes noteront que VeriSign a un brevet sur certaines des techniques présentées dans ce RFC.)

Téléchargez le RFC 6781

L'article seul

RFC 6821: Improving Peer Selection in Peer-to-peer Applications: Myths vs. Reality

Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : E. Marocco, A. Fusco (Telecom Italia), I. Rimac, V. Gurbani (Bell Labs, Alcatel-Lucent)
Pour information
Réalisé dans le cadre du groupe de recherche IRTF PeerToPeerResearchGroup
Première rédaction de cet article le 22 décembre 2012

Le trafic du pair-à-pair peut, on le sait, représenter une bonne part de l'activité d'un réseau, malgré les efforts de l'industrie du divertissement pour diaboliser cette technique. Il y a donc depuis plusieurs années de gros efforts de recherche pour optimiser ce trafic, notammment via l'amélioration de la sélection des pairs. Si je veux télécharger la saison 1 de Being human, et que trois pairs ont les données, auquel demander ? Le bon sens répond « au plus proche ». Mais le concept de « plus proche » est plus flou qu'il n'y parait, et, de toute façon, le logiciel pair-à-pair installé sur ma machine n'a pas forcément accès à toutes les informations nécessaires pour déterminer « le plus proche ». Il existe plusieurs solutions pour résoudre ce problème, mais notre RFC se penche plutôt sur le méta-problème : la sélection des pairs améliore-t-elle les choses ?

Tellement de choses ont été dites à ce sujet que l'ingénieur ou l'étudiant débutant qui se penche sur l'optimisation du pair-à-pair peut avoir une impression de grande confusion. Ce RFC choisit donc l'approche « retours aux faits ». Parmi toute la littérature scientifique et technique existante, peut-on trancher sur la question de l'intérêt de la sélection des pairs ?

Je préviens tout de suite que le titre de ce RFC, inutilement sensationnaliste, ne correspond pas à son contenu : le RFC ne dynamite pas de mythes, il examine un certain nombre de questions posées par la sélection des pairs et, pour chacune, en se basant sur des mesures ou des simulations déjà effectuées et publiées, fait une synthèse de leurs conclusions.

A priori, l'intérêt de la sélection est grand : comme les machines, dans un réseau pair-à-pair, ne connaissent pas la topologie sous-jacente (elles ne savent pas si les pairs sont proches ou lointains, s'ils sont joignables par des liens de peering gratuits ou par du transit payant, etc), elles risquent de ne pas choisir le meilleur pair. Une des conséquences fâcheuses sera l'utilisation d'inter-connexions lointaines, au lieu de rester dans le réseau du FAI. Il est donc logique que cette idée de sélection « intelligente » des pairs ait fait l'objet de nombreux travaux (résumés dans le RFC 6029 ; sinon, voir les articles « Can ISPs and P2P systems co-operate for improved performance? » d'Aggarwal, V., Feldmann, A., et C. Scheidler, ou « Taming the Torrent: A practical approach to reducing cross-ISP traffic in P2P systems » de Choffnes, D. et F. Bustamante, ou encore « P4P: Explicit Communications for Cooperative Control Between P2P and Network Providers » de Xie, H., Yang, Y., Krishnamurthy, A., Liu, Y., et A. Silberschatz) et qu'un groupe de travail de l'IETF, ALTO, travaille entièrement sur ce sujet (voir ses RFC 5693 et RFC 6708). (À noter que j'avais fait un exposé sur ces techniques en 2010.) L'évaluation de ces techniques n'est pas évidente, notamment de leur passage à l'échelle lorsque le réseau comprend des dizaines de millions de pairs.

Notre RFC suit le schéma suivant pour synthétiser la littérature existante :

  • Décrire une croyance (un mythe, dit le RFC, terme très exagéré),
  • Lister les faits (études, mesures, simulations, etc) disponibles,
  • Discuter ces données,
  • Conclure à la véracité ou à la fausseté de la croyance.

Naturellement, cette synthèse n'est valable qu'aujourd'hui : les progrès de la science pourront changer les conclusions. Ah et, sinon, question terminologie, en l'absence d'une norme unique du pair-à-pair, ce RFC utilise largement le vocabulaire de BitTorrent (section 2), comme le terme d'essaim pour désigner un groupe de pairs ayant les données convoitées.

Place maintenant aux croyances et à leur évaluation. La première : « la sélection des pairs permettra de diminuer le trafic entre domaines ». Les différents essais ou simulations montrent des réductions allant de 20 à 80 % (la variation importante donne une idée de la difficulté à estimer cette réduction). 70 % pour la simulation de Xie, H., Yang, Y., Krishnamurthy, A., Liu, Y., et A. Silberschatz déjà citée. 34 % en sortie et 80 % en entrée pour les mesures du RFC 5632. Et jusqu'à 99,5 % si le trafic est fortement localisé (beaucoup de pairs dans le même domaine) selon « Pushing BitTorrent Locality to the Limit » de Stevens Le Blond, Arnaud Legout et Walid Dabbous.

Bref, cette croyance est tout à fait justifiée (comme la plupart de celles citées par le RFC). On peut vraiment espérer une réduction du trafic entre opérateurs.

Cette réduction profite aux opérateurs, qui voient baisser leur facture d'interconnexion. Une autre croyance fait espérer des gains pour les utilisateurs : « la sélection des pairs se traduira par une amélioration des performances », en clair, on attendra moins longtemps pour charger la dernière ISO d'Ubuntu.

Les simulations de Xie, H., Yang, Y., Krishnamurthy, A., Liu, Y., et A. Silberschatz montrent une diminution du temps de transfert de 10 à 23 %. Celles de « Applicability and Limitations of Locality-Awareness in BitTorrent File-Sharing » par Seetharaman, S., Hilt, V., Rimac, I., et M. Ammar (article que je n'ai pas réussi à trouver en ligne et qui ne semble pas avoir été publié « officiellement ») montraient que le gain n'est pas systématique. Les mesures du RFC 5632 indiquent une augmentation du débit de 13 à 85 %. L'expérience de Choffnes, D. et F. Bustamante déjà citée a vu 31 % de gain de débit en moyenne (mais une perte dans certains cas).

La conclusion est donc plutôt « ça dépend ». En général, il y a une amélioration mais dans certains cas (capacité du lien montant faible, peu de pairs disponibles à proximité), on peut voir une dégradation. Donc, la croyance est probablement justifiée mais pas dans tous les cas.

Et l'occupation du lien réseau montant ? Cela pourrait être un effet négatif d'une meilleure sélection des pairs. Ils sont plus proches, donc on envoie plus vite les données, saturant le canal montant, souvent très petit sur les liens asymétriques comme l'ADSL ou DOCSIS. Cette crainte est-elle justifiée ?

Les mesures du RFC 5632 ne montrent pas un tel effet. Théoriquement, cela serait pourtant possible (si la sélection des pairs menait à choisir une machine mal connectée mais proche plutôt qu'une machine lointaine et ayant de fortes capacités réseau, la machine mal connectée verrait son lien montant plus utilisé). Mais, en pratique, cela ne semble pas le cas.

Autre croyance parfois entendue : la sélection des pairs va avoir une influence sur les accords de peering. Ceux-ci sont souvent fondés sur le volume de trafic échangé. Si la sélection des pairs améliore la localité, le trafic entre opérateurs va baisser, le faisant passer en dessous du seuil qu'exigent certains opérateurs pour peerer avec eux. Mais, sur ce point, on ne dispose pas de mesures ou de simulations. On ne peut faire pour l'instant qu'une analyse théorique.

Par exemple, si les deux opérateurs ont une base d'utilisateurs très différente (mettons qu'un opérateur a beaucoup de clients offrant du contenu et l'autre pas du tout), non seulement le trafic entre eux va baisser, mais il peut baisser nettement plus dans une direction que dans l'autre, remettant en cause un accord de peering fondé sur la réciprocité.

Curieusement, le RFC affirme que, si les opérateurs sont très similaires (même base d'utilisateurs, mêmes technologies d'accès), il n'y aura sans doute pas beaucoup de changement. Pourtant, comme indiqué plus haut, la seule baisse du trafic entre eux, même symétrique, peut changer les conditions du peering.

Le RFC rappele que des opérateurs ont déjà tenté d'injecter des paquets vers un autre opérateur, pour obtenir artificiellement des chiffres élevés de trafic, avant de pouvoir demander un peering (« The art of Peering: The peering playbook » de Norton). Ce n'est pas très subtil car ce trafic purement unidirectionnel apparait vite comme suspect. En revanche, avec des techniques de sélection des pairs, le même FAI peu scrupuleux pourrait faire mieux, en redirigeant systématiquement ses utilisateurs vers l'opérateur avec qui il espère négocier un accord de peering, créant ainsi un trafic nettement plus réaliste.

En conclusion (fondée sur un raisonnement purement théorique, contrairement à la grande majorité des croyances étudiées dans ce RFC), il est probable que la sélection des pairs amène à changer les accords de peering.

Et sur le transit, y aura-t-il un impact ? Là aussi, on peut imaginer des transitaires peu scrupuleux qui, en utilisant les techniques de sélection de pairs comme ALTO, redirigeront le trafic vers des clients payants, plutôt que vers des opérateurs pairs gratuits. Là encore, on ne dispose pas d'études à ce sujet. Mais, vue l'importance de la question pour le monde des opérateurs, le RFC recommande que l'on se penche sur la question. Des cas comme Sprint contre Cogent ou Cogent contre AOL illustrent bien l'extrême sensibilité du problème.

Un effet de bord négatif d'une bonne sélection des pairs avait été envisagé dans l'article Stevens Le Blond, Arnaud Legout et Walid Dabbous ci-dessus (mais les mesures faites ne montraient pas cet effet). Si la sélection marche trop bien, l'essaim de pairs va se fragmenter en plusieurs essaims, un par FAI, avec peu de communications entre eux, ce qui annulerait une partie de l'intérêt du pair-à-pair. En effet, les simulations de Seetharaman, S., Hilt, V., Rimac, I., et M. Ammar ont montré que cela pouvait se produire.

Le RFC conclut que l'effet dépend de l'algorithme utilisé. Si BitTorrent semble assez résistant à ce problème, comme montré par les mesures de Stevens Le Blond, Arnaud Legout et Walid Dabbous, d'autres algorithmes peuvent avoir le problème. Et que la croyance peut donc être justifiée dans certains cas. Attention donc, si vous concevez un algorithme de pair-à-pair à ne pas mettre tous vos œufs dans le même panier en ne sélectionnant que des pairs très proches.

Dernière croyance étudiée, celle que des caches P2P chez les FAI, combinés avec la sélection des pairs, va améliorer les choses. Un problème classique de tous les caches réseau est de les trouver, et de ne les utiliser que s'ils apportent réellement un gain. Avec la sélection des pairs, le problème est théoriquement résolu : le cache est un pair comme un autre et est sélectionné s'il est « plus proche ».

Une étude chez un FAI a montré (« Are file swapping networks cacheable? Characterizing p2p traffic » de Nathaniel Leibowitz, Aviv Bergman, Roy Ben-Shaul et Aviv Shavit) que le cache pouvait potentiellement gérer 67 % du trafic pair-à-pair. Cette croyance est donc plausible.

Téléchargez le RFC 6821

L'article seul

RFC 6817: Low Extra Delay Background Transport (LEDBAT)

Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : S. Shalunov (BitTorrent Inc), G. Hazel (BitTorrent Inc), J. Iyengar (Franklin and Marshall College), M. Kuehlewind (University of Stuttgart)
Réalisé dans le cadre du groupe de travail IETF ledbat
Première rédaction de cet article le 20 décembre 2012

Alors que tant d'efforts de recherche ont été dépensés pour faire des réseaux informatiques et des protocoles qui permettent d'aller plus vite, d'attendre moins longtemps avant de voir la page d'accueil de TF1, le groupe de travail LEDBAT (Low Extra Delay Background Transport ) de l'IETF travaillait à un tout autre projet : un protocole de transport de données qui aille moins vite, de façon à être un bon citoyen du réseau, à n'utiliser celui-ci que lorsqu'il est vide et qu'on peut donc faire passer ses bits sans gêner personnne. Ce RFC décrit l'algorithme LEDBAT, un algorithme « développement durable ».

LEDBAT n'est donc pas un protocole complet, mais un algorithme de contrôle de la fenêtre de congestion, ce mécanisme par lequel les protocoles de transport évitent de saturer le réseau. Le plus connu et le plus utilisé de ces mécanismes est celui de TCP (RFC 5681) et ses objectifs sont d'utiliser le réseau à fond et d'assurer une relative égalité entre les flots de données qui se concurrencent sur ce réseau. LEDBAT, au contraire, vise avant tout à céder la place aux autre flots, non-LEDBAT.

Mais pourquoi diable voudrait-on être si généreux ? Cela peut être parce qu'on estime les autres flots plus importants : si je télécharge Plus belle la vie pendant que je passe un coup de téléphone via SIP, je souhaite que le téléchargement ne prenne pas de capacité si SIP en a besoin (c'est la différence entre applications d'« arrière-plan » comme le transfert de gros fichiers et d'« avant-plan » comme un coup de téléphone ou une session SSH interactive). Ou bien cela peut être pour profiter de réductions offertes par le réseau : après tout, un routeur ou une fibre optique ne coûtent pas plus cher à l'usage, que les octets circulent ou pas (contrairement à un autoroute ou une voie ferrée). Il serait donc logique que les transports « charognards », comme LEDBAT, qui n'utilisent la capacité réseau que lorsque personne n'en veut, reçoivent une récompense financière, par exemple une réduction des prix (parlez-en à votre FAI).

Pour les détails sur les motivations de LEDBAT et les raisons pour lesquelles des technqiues comme le shaping ne conviennent pas, voir le premier RFC du groupe LEDBAT, le RFC 6297. Ici, je vais me focaliser sur l'algorithme spécifié par LEDBAT et qui répond au cahier des charges : céder la place le plus vite possible.

Le principe de cet algorithme est simple : utiliser les variations du temps de voyage des paquets pour détecter l'approche de la congestion et refermer alors la fenêtre de transmission. TCP utilise essentiellement le taux de pertes de paquets comme indicateur (ou les marques ECN du RFC 3168). Les routeurs ayant des tampons d'entrée-sortie, lorsque la ligne de sortie est saturée, les paquets commencent à s'entasser dans ce tampon. Lorsqu'il est plein, le routeur jette des paquets (et TCP va alors réagir). On voit que l'augmentation du temps de voyage (dû au séjour dans le tampon) précède la perte de paquets. En réagissant dès cette augmentation, LEDBAT atteint son objectif de céder la place à TCP. (À noter qu'il existe des variantes de TCP qui utilisent également le temps de voyage comme indicateur de l'approche de la congestion, par exemple TCP Vegas, documenté dans « TCP Vegas: New techniques for congestion detection and avoidance » de Brakmo, L., O'Malley, S., et L. Peterson, mais voir le RFC 6297 pour un tour d'horizon général.)

Où est-ce que LEDBAT va être mis en œuvre ? Cela peut être dans un protocole de transport, par exemple comme une extension de TCP, ou bien dans l'application. LEDBAT est un algorithme, pas un protocole précis. Il peut être utilisé dans plusieurs protocoles, du moment que ceux-ci permettent l'estampillage temporel des paquets, pour que les deux machines qui communiquent puissent mesurer le temps de voyage (section 4.1).

La section 2 décrit l'algorithme exact. LEDBAT a une fenêtre de congestion, notée cwnd qui indique combien d'octets l'émetteur peut envoyer avant un nouvel accusé de réception. L'émetteur met dans chaque paquet le moment où il a envoyé ce paquet. Le récepteur regarde l'heure, en déduit le temps de voyage (aller simple, puisque l'encombrement n'est pas forcément le même dans les deux sens, une mesure aller-retour ne servirait pas à grand'chose) et retransmet cette indication à l'émetteur. Lorsque celui-ci voit le temps de voyage augmenter (signe que les tampons des routeurs se remplissent), il diminue la fenêtre de congestion. L'émetteur notamment utilise deux paramètres, TARGET et GAIN. TARGET est l'augmentation du temps de voyage en dessous de laquelle LEDBAT ne fait rien. GAIN (qui vaut entre 0 et 1) indique le facteur d'échelle entre l'augmentation du temps de voyage et la réduction de la fenêtre de congestion. Plus il est élevé, plus LEDBAT réagit rapidement et vigoureusement. Un GAIN de 1 est équivalent à TCP Reno. À noter qu'on pourrait avoir deux valeurs de GAIN, une pour augmenter la fenêtre de congestion et une pour la diminuer. En mettant un GAIN plus grand pour la diminution de la fenêtre, on garantit que LEDBAT cédera très vite la place dès le plus petit signal d'un ralentissement. (Pour les amateurs de pseudo-code, une description de l'algorithme avec cette technique figure dans le RFC.)

Bien sûr, le temps de voyage varie pour tout un tas de raisons et il n'est pas forcément souhaitable de refermer la fenêtre de congestion à chaque dérapage. LEDBAT filtre donc les outliers à l'aide d'une fonction FILTER() qui fait partie des paramètres de l'algorithme (elle n'est pas imposée par le RFC, on peut tester plusieurs mécanismes de filtrage des données.) Un filtre sommaire est NULL (aucun filtrage, on accepte toutes les mesures). Un autre plus sophistiqué est EWMA (Exponentially-Weighted Moving Average). Un bon filtre résiste au bruit inévitable, mais reste sensible aux signaux indiquant une vraie congestion.

Le temps de voyage se décompose en temps de transmission sur le câble (qui dépend de la vitesse du médium, par exemple 100 Mb/s pour du Fast Ethernet), temps de propagation (lié à la vitesse de la lumière), temps d'attente dans les tampons et temps de traitement à la destination. Tous ces temps sont constants ou presque, à l'exception du temps d'attente dans les tampons. Ce sont donc ses variations qui déterminent l'essentiel des variations du temps de voyage. Pour estimer ce temps d'attente dans les tampons, LEDBAT calcule un temps de base (section 3.1.1) qui est le temps de voyage minimum observé. Il permet de connaître la valeur minimale en dessous de laquelle le temps de voyage ne pourra pas descendre. Les calculs de fenêtre de congestion se font à partir de (temps de voyage - temps de base), une grandeur qui part donc de zéro (les méthodes du RFC 6298 peuvent être utiles ici). L'algorithme de LEDBAT est linéaire : la fenêtre est réduite ou agrandie proportionnellement à cette grandeur, le facteur de proportionnalité étant le paramètre GAIN. Autre intérêt du concept de temps de base : en cas de changement de la route pendant la session (par exemple, panne d'un lien et re-routage par un chemin plus long), la mesure du temps de base pendant les N dernières secondes permettra de voir que le trajet a changé et que les calculs doivent utiliser le nouveau temps de base. (Le choix de N est un compromis : trop petit et le temps de base va varier souvent, trop grand et il retardera le moment où on détecte un changement de chemin.)

Avec son mécanisme de réduction de la fenêtre de congestion dès que le temps de voyage augmente, LEDBAT ne pousse normalement jamais jusqu'au point où il y aura des pertes de paquets. Néanmoins, celles-ci peuvent quand même survenir, et LEDBAT doit alors se comporter comme TCP, en refermant la fenêtre (section 3.2.2).

La section 4 du RFC discute ensuite de différents points intéressants de LEDBAT. Par exemple, LEDBAT est efficace pour céder rapidement à TCP lorsque celui-ci transfère de grandes quantités de données. Mais cela laisse le problème des applications qui envoient peu de données mais sont très sensibles à la latence, comme la voix sur IP. Si la conversation téléphonique envoie peu de données, il n'y aura jamais de remplissage des tampons, donc pas d'augmentation du temps d'attente dans ceux-ci donc LEDBAT se croira tranquille et enverra autant de données qu'il veut. Au moment où un des interlocuteurs parlera, ses paquets se trouveront donc peut-être coincés derrière un paquet LEDBAT. La seule protection contre ce problème est le paramètre TARGET qui ne doit donc pas être mis trop haut. La norme G.114 de l'UIT suggère 150 ms comme étant le maximum de retard tolérable pour le transport de la voix. LEDBAT doit donc choisir ses paramètres pour réagir avant les 150 ms. Le RFC recommande 100 ms pour le paramètre TARGET qui indique l'augmentation de délai de voyage à partir de laquelle LEDBAT réagit. (Ce paramètre TARGET détermine le temps maximal d'attente supplémentaire dû à LEDBAT.)

Autre point subtil, la compétition entre flots LEDBAT. On sait que TCP assure la « justice » entre flots TCP : si trois flots sont en compétition, chacun aura un tiers de la capacité. LEDBAT, lui, cède à TCP. Si un flot LEDBAT et un flot TCP sont en compétition, TCP aura toute la capacité. Mais si deux flots LEDBAT parallèles se concurrencent ? L'algorithme de LEDBAT ne garantit pas de justice. En général, c'est le flot le plus récent qui va gagner : arrivant tard, dans un réseau déjà bien encombré, il mesure un temps de base très élevé et ne voit donc pas d'augmentation due au temps d'attente dans les tampons, et ne réduit donc pas sa fenêtre de congestion (« Rethinking Low Extra Delay Background Transport Protocols » de Carofiglio, G., Muscariello, L., Rossi, D., Testa, C., et S. Valenti). Pour corriger cet effet, on ne peut compter que sur le bruit : de temps en temps, les tampons se videront, le temps de voyage diminuera, et le récent arrivé corrigera sa mauvaise estimation du temps de base.

La section 5 du RFC considère les points qui sont encore ouverts à expérimentation. Après tout, un protocole comme LEDBAT est quelque chose de très nouveau dans le zoo de l'Internet. Par exemple, l'effet de changement de routes pendant une session LEDBAT, modifiant le temps de base, n'est pas encore vraiment bien connu. Quant à la valeur des paramètres comme TARGET ou GAIN, elle aura certainement besoin d'être ajustée à la lumière de l'utilisation réelle. Enfin, le filtre des mesures, qui permet d'éliminer les mesures jugées anormales, et évite donc à LEDBAT d'ajuster brusquement sa fenêtre de congestion pour rien, aura certainement besoin de réglages, lui aussi.

Et la sécurité de LEDBAT ? La section 6 rappelle que, même si un attaquant arrive à tromper LEDBAT sur les valeurs du temps de voyage, dans le pire des cas, il ne pourra pas le faire se comporter de manière plus gloutonne que TCP. Par contre, il pourra faire une attaque par déni de service en lui faisant croire que le délai de voyage a augmenté et que LEDBAT devrait ralentir. Pour l'instant, il n'y a pas de mécanisme contre cela.

Le bon fonctionnement de LEDBAT dépend de bonnes mesures. Les fanas de métrologie seront donc ravis de l'annexe A, qui parle des causes d'erreur dans les mesures. Le principal problème est que, pour mesurer les temps de voyage aller-simple dont a besoin LEDBAT, il faut des horloges à peu près synchronisées. Si l'émetteur met dans le paquet une heure de départ à 13 heures, 37 minutes et 56,789 secondes, que le récepteur mesure une arrivée à 13 heures, 37 minutes et 57,123 secondes et que le récepteur a 0,5 secondes de retard sur l'émetteur, il mesurera un temps de voyage de 0,334 secondes (alors qu'il est en fait de 0,834 secondes). Reprenant le vocabulaire de NTP (RFC 5905), on peut dire qu'il y a deux sources de problèmes, l'écart des horloges par rapport à une référence et le décalage (la variation de l'écart). L'écart entraine une erreur fixe dans la mesure du temps (comme dans notre exemple ci-dessus). Mais LEDBAT n'utilise pas directement le temps mais la différence entre temps actuel et temps de base. Cette erreur s'annule donc et l'écart des horloges par rapport au temps correct n'est donc pas importante pour LEDBAT.

Plus embêtant est le décalage puisque lui ne s'annulera pas. Si l'horloge du récepteur bat plus vite que celle de l'émetteur, il aura toujours l'impression d'un réseau très encombré, puisque ses mesures de temps de voyage seront toujours supérieures au temps de base qu'il avait mesuré avant. Heureusement, alors que des écarts énormes sont souvent vus sur l'Internet (il est fréquent de voir plusieurs minutes, voire plusieurs heures de différence entre une machine et le temps UTC), les décalages sont typiquement bien plus petits. Les mesures citées par le RFC 5905 indiquent des décalages courants de 100 à 200 ppm, soit 6 à 12 ms d'erreur accumulée par minute. Comme une machine LEDBAT limite sa mémoire (paramètre BASE_HISTORY, pour lequel le RFC recommande actuellement une valeur de dix minutes), et n'utilise donc que des mesures récentes pour évaluer le temps de base, le problème reste donc limité.

Si malgré tout, le problème se pose, il n'affectera que le cas où le récepteur a une horloge plus rapide, et en déduira donc à tort qu'il doit ralentir. Dans le cas inverse (horloge du récepteur plus lente), l'émetteur aura simplement l'impression que le temps de base augmente.

Pour corriger ce problème de décalage, on peut imaginer d'envoyer les estampilles temporelles dans les deux sens, pour que chaque machine puisse calculer ce que devrait voir l'autre, pour pouvoir détecter qu'un pair a une mauvaise mesure. Ensuite, l'émetteur pourrait corriger ses propres calculs por s'adapter à ce récepteur erroné. Il peut même calculer si le décalage est constant (horloge battant trop vite ou trop lentement, mais à une fréquence constante).

Et question mises en œuvre effectives ? LEDBAT a été testé dans des logiciels comme μTorrent Transport Protocol library. Il est l'algorithme utilisé par le microTP de BitTorrent (voir la documentation officielle de µTP). Il est aussi mise en œuvre dans Swift.

Merci à Mathieu Goessens pour sa suggestion et à André Sintzoff pour ses inlassables corrections.

Téléchargez le RFC 6817

L'article seul

RFC 6731: Improved Recursive DNS Server Selection for Multi-Interfaced Nodes

Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : T. Savolainen (Nokia), J. Kato (NTT), T. Lemon (Nominum)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF mif
Première rédaction de cet article le 19 décembre 2012

Lorsqu'une machine connectée à l'Internet a plusieurs interfaces réseaux, et apprend (par exemple en DHCP) l'existence d'un résolveur DNS différent sur chaque interface, lequel utiliser ? Le principe de base de cette nouvelle norme est qu'il faudrait garder en mémoire chaque résolveur et utiliser à chaque fois celui qui correspond à l'interface réseau qu'on va utiliser.

Autrefois, le problème ne semblait pas crucial : après tout, un résolveur DNS en vaut un autre, puisque tous donnent les mêmes réponses. Mais ce n'est plus le cas aujourd'hui. Par exemple, sur certaines interfaces, le résolveur DNS peut donner accès à des noms de domaine privés, strictement locaux, que les autres résolveurs ne connaissent pas. On ne peut donc pas se contenter de prendre l'un des résolveurs au hasard, ni même « le meilleur » résolveur car chacun peut avoir des caractéristiques uniques (par exemple, l'un des résolveurs connait le domaine privé foo.example et un autre un autre domaine privé bar.example). D'où cette règle de garder en mémoire tous les résolveurs connus. (Le RFC utilise le terme de RDNSSRecursive DNS Servers - pour les résolveurs.)

Ce n'est pas tout de mémoriser tous les résolveurs, encore faut-il savoir lequel utiliser. C'est le rôle de nouvelles options DHCP normalisées ici, qui permettent de distribuer les méta-informations dont le client a besoin pour savoir de quel résolveur se servir.

Si on veut mieux comprendre le problème de ces machines ayant plusieurs interfaces réseaux, il faut lire le premier RFC du groupe de travail MIF, le RFC 6418, qui définit le problème. Un exemple d'une telle machine est un smartphone qui a accès à la fois à un réseau WiFi privé et à la 3G. Mais il y a aussi le cas où il n'y a qu'une seule interface physique, mais plusieurs virtuelles, par exemple un accès à l'Internet par le FAI local et un VPN vers le réseau sécurisé de l'entreprise. La partie la plus évidente du problème des machines à plusieurs interfaces est celui des noms privés (section 2.1). Imaginons que la société Foobar ait le domaine foobar.example et qu'un sous-domaine internal.foobar.example contienne les informations privées, spécifiques à l'entreprise et non visibles dans le DNS public. Cela se fait en configurant spécialement les résolveurs utilisés par les employés de l'entreprise. Par exemple, avec Unbound, pour un domaine nommé 42 et servi par et, cela serait :

   name: "42"

Si un de ces employés est en voyage, connecté depuis l'hôtel, ayant activé le VPN, et que sa machine utilise le résolveur de l'hôtel, il ne pourra pas utiliser les noms en internal.foobar.example. (Vous pouvez vous dire « il faut utiliser le résolveur DNS de l'entreprise pour tout ». Mais il sera en général plus lent et il pourra avoir ses propres limites, par exemple ne pas pouvoir résoudre car le résolveur de l'entreprise censure ce nom.)

Notez aussi que le fait que l'application de ce RFC permettre de gérer les noms de domaines privés (non rattachés à l'arbre principal du DNS) ne signifie pas que ces noms privés soient une bonne idée, approuvée par l'IETF. Ce point avait été une des grosses controverses dans le groupe de travail. La section 6 donne à ce sujet des conseils pour minimiser les risques associés à ces noms privés. (En gros, les choisir uniques, par exemple en les suffixant du nom de l'organisation, pour que tout le monde ne nomme pas ses machines dans .private ou .lan.)

En général, le « bon » résolveur à utiliser dépend de l'interface de sortie et les techniques de ce RFC sont donc à utiliser en combinaison avec celles du RFC 4191 et du RFC 3442. Même si un nom de domaine est visible partout, il peut se résoudre en des adresses IP différentes selon l'interface réseau utilisé (cas célèbre de qui ne donne pas le même résultat aux abonnés d'Orange et aux autres.) On peut encore citer le cas des extensions au DNS utilisées dans certains cas de coexistence IPv4-IPv6 (RFC 6147).

Il peut y avoir des cas encore plus complexes et notre RFC ne prétend pas tout résoudre (section 2.3).

Avant de décrire la solution standardisée, le RFC présente trois études de cas permettant d'illustrer un problème soluble (section 3). Des études de cas plus détaillées, avec examen des pratiques actuelles, figurent dans le RFC 6419.

D'abord, le cas d'un foyer connecté à l'Internet via un FAI ainsi qu'à un réseau privé, les deux connexions passant par le même CPE. Ce réseau privé utilise uniquement des noms dans un domaine qui n'apparait pas sur l'Internet (mettons hidden.example). Pour que tout marche, du point de vue de l'utilisateur, il faut envoyer les requêtes de résolution de noms au résolveur du réseau privé, si le nom se termine en hidden.example et au résolveur du FAI autrement. Le plus simple est qu'un relais DNS tourne sur le CPE et aiguille automatiquement les requêtes DNS vers le bon résolveur.

Autre scénario d'usage, celui mentionné plus tôt d'un smartphone connecte à la fois au réseau 3G et à un accès WiFi local. Pour des raisons financières, on souhaite utiliser le WiFi dans le plus grand nombre de cas. Mais on peut avoir besoin d'établir certaines connexions via la 3G, soit parce que certains services ne sont que là, soit pour des raisons de sécurité (à mon avis, le RFC surestime nettement la sécurité de la 3G mais c'est une autre histoire).

Le smartphone doit donc utiliser le DNS de l'accès WiFi par défaut mais avoir des règles (par exemple une liste de destinations sensibles qu'on ne veut contacter qu'en 3G) qui imposeront l'utilisation du résolveur DNS du fournisseur de 3G.

Enfin, dernière étude de cas, celui du road warrior doté d'un accès à un (ou plusieurs) VPN de son entreprise. Aussi bien pour des raisons de sécurité que d'accès à des noms de domaines privés, on veut faire passer les accès au réseau interne de l'entreprise (requêtes DNS comprises) par le VPN. Par contre, pour consulter Facebook et YouTube, on va passer par l'accès par défaut.

La section 4 du RFC donne ensuite les règles exactes à suivre pour que tout se passe bien. Le principe essentiel est que la machine doit construire une liste de résolveurs (et pas uniquement garder le dernier annoncé) accessibles, en notant pour chacun les options envoyées par DHCP (nouvelles options décrites un peu plus loin), qui vont permettre de sélectionner le résolveur à utiliser pour une requête donnée. Par défaut, on considère que tous les résolveurs sont équivalents (donnent les mêmes résultats). Mais certains critères permettent de les distinguer :

  • La confiance qu'on leur accorde (voir section 9.2 du RFC). C'est assez subjectif mais on peut penser, par exemple, qu'un résolveur atteint par un VPN IPsec vers son entreprise est plus digne de confiance que le résolveur d'un hotspot dans un café. Certains disent même que la 3G avec son fournisseur mobile est plus sûre (c'est l'exemple de pseudo-code dans l'annexe C, avec IF_CELLULAR préféré à IF_WLAN.) Cette confiance est à configurer dans le client, il n'y a pas de protocole pour la déterminer.
  • La préférence indiquée en DHCP (voir les nouvelles options DHCP plus loin.).
  • Les domaines privés qu'ils gèrent... ou pas.
  • Le fait qu'ils valident avec DNSSEC ou pas. À noter que cela peut aussi dépendre des clés DNSSEC connues. Dans le cas le plus fréquent, le résolveur ne valide qu'avec la clé de la racine du DNS. Mais, s'il a d'autres clés configurées, il faut lire l'annexe B du RFC car c'est un peu plus compliqué.

Avec tous ces critères, on peut faire une sélection intelligente du résolveur. Ainsi, s'il faut résoudre un nom en private.mycompany.example et qu'un seul des résolveurs annonce ce domaine (les autres gérant l'arbre public du DNS), c'est clair qu'il faut utiliser ce serveur, les autres ne pourront pas répondre. Les règles de sélection exactes figurent dans la section 4.1. Si vous préférez lire le pseudo-code, l'annexe C contient une mise en œuvre de cet algorithme.

Les sections 4.2 et 4.3 décrivent les nouvelles options pour DHCPv4 (RFC 2131) et DHCPv6 (RFC 8415). Elles sont quasiment identiques en v4 et v6 donc je me limite à celle de v6 :

  • Son code est 74 (146 en v4),
  • Elle contient l'adresse IPv6 du résolveur et la préférence attribuée à ce serveur (High, Medium ou Low),
  • Elle contient une liste de domaines que le résolveur connait, par exemple, (et . tout court s'il connait tous les domaines, ce qui est le cas d'un résolveur normal), ainsi qu'une liste de domaines correspondant à des préfixes IP pour les résolutions dans (RFC 3596).

Un client DHCP qui connait notre RFC met une demande de cette option dans sa requête et reçoit en échange la liste ci-dessus. Attention, elle est limitée en taille par les contraintes de DHCP (section 4.4), il ne faut donc pas espérer y indiquer des centaines de domaines possibles.

Une fois qu'un résolveur a été sélectionné pour une requête DNS, il doit continuer à être utilisé si cette requête déclenche à son tour d'autres requêtes (section 4.7). Imaginons qu'on cherche l'adresse IPv6 de, on va faire une requête AAAA et si on obtient une réponse CNAME, alors, la requête ultérieure AAAA doit utiliser le même résolveur, pour être cohérente, au cas où renvoie des adresses différentes selon le résolveur qui demande. Programmeurs, attention, cela implique de garder un état et de ne pas faire la sélection du résolveur de manière indépendante pour chaque requête.

De même qu'on garde une liste de résolveurs à utiliser, il faut aussi avoir autant de caches que d'interfaces, ou vider le cache entre deux requêtes, pour éviter qu'une information venant du cache n'« empoisonne » une résolution. Et il ne faut pas oublier, lorsqu'une interface réseau disparait, de vider le cache des données apprises via cette interface (section 4.8). Le logiciel local de la machine devient donc assez compliqué !

Voilà, vous savez tout. Si le problème vous intéresse et que vous voulez creuser la question, l'annexe A de ce RFC présente « ce qui aurait pu être », les autres mécanismes qui auraient pu être choisis (comme « envoyer la requête sur toutes les interfaces réseau et prendre la première réponse qui revient »).

Actuellement, il semble que certains systèmes de Nokia et de Microsoft (Name Resolution Policy Table) utilisent déjà ce mécanisme dans leurs téléphones.

Téléchargez le RFC 6731

L'article seul

RFC 6793: BGP Support for Four-octet AS Number Space

Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : Q. Vohra (Juniper Networks), E. Chen (Cisco Systems)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 19 décembre 2012

Un des nombres trop petits de l'Internet était la taille des numéros de système autonome. En 2007, elle était passée, avec le RFC 4893, de deux à quatre octets. Ce nouveau RFC est juste une révision mineure de cette norme.

Il est assez courant dans l'Internet que des nombres prévus très larges au début s'avèrent ridiculement petits avec la croissance du réseau. C'est bien sûr le cas des adresses IPv4, dont les 32 bits sont bien trop peu pour le nombre de machines connectées aujourd'hui, mais c'est aussi vrai pour les numéros de système autonome (AS pour autonomous system). Chacun de ces numéros identifie un système autonome de routage, au sein duquel une politique de routage cohérente peut s'appliquer. En gros, chaque opérateur a un numéro de système autonome, les plus gros en ayant plusieurs (surtout en cas de fusion ou d'acquisition).

Ces numéros sont notamment utilisés par le protocole de routage BGP (normalisé dans le RFC 4271), pour indiquer le chemin à suivre pour joindre un réseau. La petite fonction shell bgproute permet d'interroger les serveurs de Route Views et affiche les numéros de système autonomes traversés :

% bgproute
AS path: 3257 3356 20766 20766

On voit que le serveur de Route Views a reçu l'annonce de la part du système autonome 3257 qui l'avait lui même reçu du système autonome 3356.

Ces numéros étaient autrefois stockés sur seulement 16 bits, ce qui ne permettait que 65 535 systèmes en tout, bien trop peu pour l'Internet d'aujourd'hui, qui va des villes chinoises aux hébergeurs brésiliens. Si certains conservateurs, méprisants et élitistes, ont regretté le fait que « n'importe qui, avec une armoire et deux PC avec Quagga » veuille faire du BGP, le fait est que l'Internet touche bien plus de monde et que la population des opérateurs a augmenté. D'où le RFC 4893, qui avait fait passer la taille des numéros d'AS à 32 bits, soit quatre milliards d'opérateurs possibles.

Ces AS de quatre octets s'écrivent en notation ASPLAIN, en écrivant directement le nombre, par exemple 112617 (RFC 5396).

Les nouveaux AS sont ensuite annoncés par l'attribut AS4_PATH, n° 17 dans le registre des attributs.

Le changement lui-même est assez trivial mais, comme souvent sur Internet, le gros du travail était la gestion de la transition. Notre RFC explique avec beaucoup de soin comment un routeur BGP récent va pouvoir parler à un routeur de l'ancienne génération (le routeur doit annoncer sa capacité à gérer les AS de quatre octets avec le capability advertisment n° 65 du RFC 5492). Et comment les chemins d'AS 4-octets pourront être transmis même à travers des « vieux » routeurs, utilisant un mécanisme de tunnel (l'article de Geoff Huston l'explique très bien).

Pour cette transition, le nouveau BGP utilise un numéro d'AS spécial, le 23456, qui sert à représenter tous les AS 4-octets pour les anciens routeurs. Si vous voyez apparaitre ce système autonome, par exemple en tapant un show ip bgp sur un Cisco, c'est que votre logiciel est trop vieux. Ceci dit, cela doit être rare de nos jours, la gestion de ces AS sur quatre octets étant désormais présente dans toutes les mises en œuvre sérieuses de BGP.

Les numéros d'AS sur quatre octets sont distribués par les RIR depuis des années (voir par exemple la politique du RIPE-NCC et sa FAQ). Le RIPE-NCC a publié d'intéressantes statistiques à ce sujet, notamment sur le taux de numéros d'AS 32 bits renvoyés au RIPE-NCC car le titulaire s'est aperçu, après coup, qu'il y avait quelques problèmes techniques, chez lui ou chez ses fournisseurs.

L'annexe A résume les différences par rapport au RFC 4893 : rien de vital, juste un toilettage. Notamment, la gestion d'erreurs, absente du précédent RFC, est spécifiée en détail.

Téléchargez le RFC 6793

L'article seul

RFC 3: Documentation conventions

Date de publication du RFC : Avril 1969
Auteur(s) du RFC : Steve Crocker (University California Los Angeles (UCLA))
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 16 décembre 2012

Membre de la prestigieuse série des tous premiers RFC, publiés en même temps en 1969, ce RFC 3 expose le fonctionnement des RFC et pose donc le principe de l'ouverture des débats.

Il est ultra-court, comme l'étaient la plupart des RFC à l'époque. Mais son contenu est dense. Les deux points essentiels, qui pèseront lourdement dans le futur Internet, sont :

  • Discussion libre et ouverte des idées, sans considérer les documents écrits comme étant sacrés (le sigle de RFC, Request For Comments, appel à commentaires, vient de là).
  • Encouragement à publier sans se demander pendant des années si le texte est parfait.

Depuis, bien des électrons ont circulé dans les câbles. Les RFC ne sont plus des « appels à commentaires » mais des documents figés, qui ne changent pas après leur publication. Et celle-ci requiert de long et parfois pénibles débats. Mais l'idée que les idées doivent l'emporter par leur valeur et pas par un argument d'autorité reste.

La lecture de la liste des membres du Network Working Group (le futur IETF) dans ce RFC est instructive : essentiellement des étudiants, dont aucun ne pouvait imposer ses idées par ses titres et ses diplômes. Le concept de RFC vient de là.

Comme son titre l'indique, ce document contient aussi des conventions, comme le fait de numéroter les RFC (Bill Duvall était le premier RFC Editor, chargé de gérer ces numéros) et comme la longueur minimale d'un RFC (lisez le texte pour la connaître).

Merci à Laurent Chemla pour m'avoir signalé ce RFC dans un article récent.

Téléchargez le RFC 3

L'article seul

Finalement, je suis enfin passé à UTF-8

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

Normalement, en 2012, il y a longtemps que tout le monde est passé à UTF-8 et a abandonné le vieux Latin-1. Mais cela m'a pris plus longtemps que prévu et je viens juste de faire la transition.

Comme je l'avais expliqué dans un autre article, c'est en effet plus compliqué que ça n'en a l'air, surtout si on a accumulé au cours du temps plein de fichiers, de programmes, et de réglages spécifiques à Latin-1. Et puis, ne nous voilons pas les yeux. S'il est normal aujourd'hui d'utiliser un encodage capable de représenter tous les caractères d'un coup, en pratique, il reste encore quelques trucs qui ne marchent pas bien en UTF-8. Pour donner une idée de l'opération, j'ai dû :

  • Convertir les fichiers sources de ce blog (écrits en XML avec l'encodage Latin-1) avec un petit script Python. (Pour un fichier individuel, c'est simple, on change l'encodage et le mode nxml-mode d'emacs convertit. Mais, ici, il y avait 1 500 fichiers...)
  • Changer dans mon ~/.zshrc réglé à la main les variables environnement comme LC_CTYPE. Idem pour les fichiers de configuration d'autres logiciels comme le .emacs d'Emacs.
  • Encore faut-il avoir un terminal qui affiche UTF-8. J'ai dû abandonner mon terminal favori, wterm, qui ne gère pas UTF-8 (il existe un wterm-ml mais qui a un exécutable différent par langue : pas pratique du tout). Par contre, xterm, gnome-terminal ou lxterminal se débrouillent très bien.
  • Changer ses variables d'environnement ne convertit pas par magie les fichiers texte éparpillés un peu partout sur le disque. Pour certains répertoires importantes, j'ai tout converti à grands coups de commande recode. Pour les autres, je le ferai au fur et à mesure de leurs modifications.
  • Changer la configuration de mutt (set send_charset=us-ascii:utf-8) et tester avec les répondeurs de courrier pour être sûr que tout allait bien.
  • Éditer /etc/X11/fonts/misc/xfonts-base.alias pour mettre une police Unicode pour X11.
  • Remplacer des logiciels comme a2ps (qui ne gère pas du tout UTF-8). Pareil pour enscript. Il reste u2ps et uniprint, mais ils ne font hélas pas de pretty-printing. (Il existe une liste des applications non-UTF8 sur Debian.)
  • Passer de l'ack-grep un peu partout pour trouver tous les occurrences de « 8859 » ou de « Latin-1 » que j'aurais pu oublier. Cela ne m'a pas empêché d'en rater certaines et d'envoyer un fichier Latin-1 étiqueté UTF-8 sur la liste Frnog...

Voyons le côté positif, je peux désormais utiliser directement et nativement tous les caractères UTF-8 non Latin-1 comme Ÿ, œ, sans compter α ou des fantaisies comme ǝpoɔıu∩...

L'article seul

Exemple d'analyse d'un problème DNS

Première rédaction de cet article le 11 décembre 2012

Ce matin, pour regarder de près l'amusant problème de la disparation du RER C (les sites Web de recherche d'itinéraire en Île-de-France ne connaissent plus cette ligne et ne la proposent plus), je me suis promené sur Cela a fortement déplu à mon Firefox : plus de rafraîchissement des pages, réactions très lentes, voire nulles, etc. À l'origine, un problème DNS avec une zone très mal configurée.

Je sais en effet que Firefox réagit de manière pathologique aux problèmes DNS (contrairement à Chromium) : il se bloque à attendre des réponses qui ne viennent pas, même les autres onglets sont paralysés. Donc, il était logique de suspecter un problème DNS. Mais quel problème ? C'est d'autant plus difficile de le savoir que dig donne parfois des réponses correctes et parfois SERVFAIL (Server Failure). Il faut regarder de plus près.

Le journal du serveur de noms, un Unbound, explique pourquoi on a des problèmes :

Dec 11 11:30:05 batilda unbound: [2631:0] info: iterator operate: query A IN
Dec 11 11:30:05 batilda unbound: [2631:0] info: processQueryTargets: A IN
Dec 11 11:30:05 batilda unbound: [2631:0] debug: out of query targets -- returning SERVFAIL
Dec 11 11:30:05 batilda unbound: [2631:0] debug: return error response SERVFAIL

Dec 11 11:30:09 batilda unbound: [2631:0] info: iterator operate: query AAAA IN
Dec 11 11:30:09 batilda unbound: [2631:0] info: processQueryTargets: AAAA IN
Dec 11 11:30:09 batilda unbound: [2631:0] info: sending query: AAAA IN
Dec 11 11:30:09 batilda unbound: [2631:0] debug: sending to target: <>

Pour comprendre cette incohérence (problème de réseau ? bogue subtile ?), il faut regarder la configuration de Si on interroge un des serveurs faisant autorité pour, on trouve une délégation :

% dig A



OK, n'est pas dans la même zone que On note aussi qu'il n'y a que deux serveurs de noms et que leurs adresses IP, proches (dans le même /24) laissent supposer qu'il n'y a guère de redondance dans cette configuration. Mais passons et interrogeons les serveurs :

% dig A

; <<>> DiG 9.9.2-P1 <<>> A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: FORMERR, id: 1960
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; WARNING: Messages has 11 extra bytes at end

;			IN	A

;; Query time: 35 msec
;; WHEN: Tue Dec 11 12:47:34 2012
;; MSG SIZE  rcvd: 40

Aïe, déjà un problème. Le FORMERR veut dire Format error et signifie que le serveur n'a pas compris la requête. Depuis peu, dig utilise EDNS par défaut, comme la plupart des résolveurs, et c'est peut-être cela qui a suscité l'incompréhension de Essayons sans EDNS :

% dig +noedns A

; <<>> DiG 9.9.2-P1 <<>> +noedns A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10283
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;			IN	A

;; ANSWER SECTION:		300	IN	A		300	IN	A

;; Query time: 38 msec
;; WHEN: Tue Dec 11 12:49:37 2012
;; MSG SIZE  rcvd: 83

Cette fois, cela marche. Le RFC 2671, qui normalisait EDNS, date de 1999 mais, apparemment, c'est encore une technologie nouvelle pour certains.

Alors, suffit-il de se rabattre sur du vieux DNS sans EDNS ? Sauf qu'il y a d'autres problèmes. Par exemple, alors que est censé être une zone, les serveurs ne répondent pas aux requêtes SOA :

% dig +noedns SOA

; <<>> DiG 9.9.2-P1 <<>> +noedns SOA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 60719
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;			IN	SOA

;; Query time: 35 msec
;; WHEN: Tue Dec 11 13:55:35 2012
;; MSG SIZE  rcvd: 29

Refusé... Charmant. C'est pareil pour d'autres types de données (comme TXT). Et pour tous les noms situés en dessous de ? Le serveur répond correctement NXDOMAIN (No such domain) mais n'inclut pas le SOA obligatoire dans la réponse :

dig +noedns A

; <<>> DiG 9.9.2-P1 <<>> +noedns A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 16785
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;		IN	A

;; Query time: 36 msec
;; WHEN: Tue Dec 11 14:02:32 2012
;; MSG SIZE  rcvd: 34

Cela empêche le résolveur de déterminer le zone cut, la limite de la zone.

Maintenant, pourquoi est-ce que a des serveurs de noms aussi bogués ? Le plus probable est que utilise des logiciels assez classiques mais que a été délégué, pour les besoins du serveur Web, a une appliance programmée avec les pieds. De tels boîtiers sont courants, pour assurer des fonctions comme la répartition de charge et, écrits par des gens qui ne connaissent pas le DNS et exploités par des gens du Web qui ne le connaissent pas non plus, ils sont fréquemment horriblement bogués.

Mais revenons à mon problème initial. Puisque Unbound se rabat automatiquement en « sans EDNS » lorsqu'il reçoit la réponse FORMERR, pourquoi est-ce que cela marchait irrégulièrement ? L'examen du journal d'Unbound le montre : on voit des requêtes pour Il s'agit là de requêtes DANE (RFC 6698), lancées par une extension Firefox installée sur ma machine. Le nom n'existe pas, OK. Mais la réponse erronée, ne comprenant pas le SOA, perturbe Unbound, l'amenant à conclure que le serveur a un problème. Il ne l'interrogera pas ensuite, pour un moment, renvoyant SERVFAIL. En pratique, tout dépendra de l'ordre des requêtes (la requête habituelle en premier ou bien la requête DANE d'abord).

Un tel phénomène (réponse erronée amenant le résolveur à conclure que le serveur est défaillant) avait déjà été observé avec le déploiement du type AAAA (pour les adresses IPv6). Le problème avait été documenté dans le RFC 4074 en 2005. Mais les auteurs d'appliances ne lisent jamais les RFC...

Si vous voulez voir la curieuse disparition du RER C, voici l'itinéraire proposé ce matin, pour aller de la station Champ de Mars à la station Pont de l'Alma (stations consécutives sur le RER C, options de recherche "Réseau ferré" et "Le moins de correspondance"). suggère tout simplement de traverser la Seine pour aller prendre la ligne 9 ! rerc-disparu.jpg Si vous trouvez que les trains rampent trop bas et que vous préférez vous envoler, la zone a la même architecture, et pas mal de problèmes identiques.

L'article seul

Surveillez les dates d'expiration de vos certificats X.509 !

Première rédaction de cet article le 9 décembre 2012
Dernière mise à jour le 14 septembre 2017

Un certain nombre de services sur l'Internet, notamment de serveurs Web, sont protégés par le protocole TLS, qui utilise presque toujours un certificat X.509 pour vérifier l'authenticité du serveur. Ces certificats ont une durée de vie limitée et doivent donc être renouvelés de temps en temps. Comme un certain nombre d'administrateurs ont oublié, au moins une fois, un tel renouvellement, il me semble utile de donner ce conseil : intégrez la surveillance des dates d'expiration dans votre système de supervision !

Pourquoi est-ce que les certificats expirent ? Les mauvaises langues vous diront que c'est parce que les AC veulent gagner davantage d'argent. Mais il y a quand même une bonne raison technique : comme le mécanisme de révocation de X.509 marche très mal, la durée limitée du certificat est la seule vraie protection contre un vol de la clé privée : au moins, le voleur ne pourra pas jouir du fruit de son forfait éternellement.

Les certificats ont donc une date d'expiration, que les navigateurs Web peuvent montrer (dans les informations d'une connexion HTTPS), ici avec deux navigateurs différents : oarc-certif-fr.jpg oarc-certif.jpg Si on préfère la ligne de commande, OpenSSL permet d'afficher l'information :

% openssl  s_client -servername -connect < /dev/null > /tmp/oarc.pem
% openssl x509 -enddate -noout -in /tmp/oarc.pem                                      
notAfter=Aug 27 15:28:19 2014 GMT

Ici, on voit que le certificat de l'OARC n'expirera pas avant un an et demi.

Les clients TLS vérifient cette date et refusent normalement la connexion avec un serveur dont le certificat a expiré. Merci à François pour m'avoir signalé l'expiration de qui me permet de mettre de vrais exemples, ici avec Chrome : admin-lautre-expired.jpg

Comment éviter ce sort tragique ? Le mieux serait que l'AC prévienne ses clients lorsque le certificat va bientôt expirer. CAcert le fait, par exemple, mais toutes les AC ne le font pas. Bref, cela vaut la peine de tester l'approche de l'expiration, depuis son système de supervision habituel. On sera ainsi prévenu avant le problème.

Si on utilise Nagios, ou un de ses compatibles, comme Icinga, les programmes de tests standards savent en général tester. Par exemple, check_http a l'option -C qui prend deux paramètres, un obligatoire qui précise le nombre de jours où le certificat doit être valide avant que le logiciel de supervision ne lance un avertissement et un facultatif qui donne le nombre de jours où le certificat doit être valide avant que ce logiciel ne lance une alarme critique (par défaut, c'est lorsque le certificat a expiré que cette alarme se déclenche). Voici des exemples avec le certificat de l'OARC qui a encore 625 jours à vivre :

% /usr/share/nagios/libexec/check_http -H --ssl=1 -C 700,100
WARNING - Certificate '*' expires in 625 day(s) (08/27/2014 15:28).

Ici, on a un avertissement (WARNING) car on a demandé que le certificat ait encore 700 jours (une valeur irréaliste, mais c'est pour faire une démo de ce programme de test). Avec des valeurs plus raisonnables, check_http nous dit évidemment que tout va bien :

% /usr/share/nagios/libexec/check_http -H --ssl=1 -C 15,7
OK - Certificate '*' will expire on 08/27/2014 15:28.

Par contre, avec le certificat expiré vu plus haut :

% /usr/share/nagios/libexec/check_http -H --ssl=1 -C 15,7
CRITICAL - Certificate '*' expired on 12/08/2012 23:59.

On peut alors mettre ce test dans sa configuration Nagios, Icinga, etc :

define service{
	use         			generic-service
	host_name     			my-web
	service_description		HTTP
	check_command     		check_http!-H --ssl -C 15,7

Ou, avec un Icinga 2, plus récent :

vars.http_vhosts["web-cert"] = {
    http_uri = "/"
    http_vhost = ""
    http_ssl = true
    http_sni = true
    http_certificate = "15,7"

On sera désormais prévenu par les mécanismes habituels de son logiciel de supervision. Notez bien que d'autres programmes de test de Nagios ont une telle option, mais pas toujours la même (c'est -D pour check_imap, par exemple).

Attention, toutefois. La documentation de check_http le dit, mais de manière peu claire (« when this option is used the URL is not checked ») : dès qu'on active les tests du certificat, d'autres tests sont coupés, comme celui du code de retour HTTP (200, 401, 403, etc) ou comme celui de la présence d'une chaîne de caractères dans le contenu (option http_string). Il faut donc la plupart du temps faire deux tests, un avec l'option http_certificate et l'autre sans.

Et si on n'utilise pas Nagios ou un compatible et qu'on veut faire un programme de test ? Il existe évidemment plein de programmes pour cela.

Le plus souvent cité est ssl-cert-check, qui s'appuie sur OpenSSL. On le télécharge et on l'utilise ainsi (merci à Nicolas Legrand pour ce serveur, qui a une date d'expiration proche) :

% ssl-cert-check -s -p 443

Host                                            Status       Expires      Days
----------------------------------------------- ------------ ------------ ----                                Valid        Feb 4 2013   57 

Si le certificat a expiré, on a :

% ssl-cert-check  -s -p 443

Host                                            Status       Expires      Days
----------------------------------------------- ------------ ------------ ----                            Expired      Dec 8 2012   -1        

Il dispose de plusieurs options, par exemple pour indiquer quelle marge de manœuvre on accepte :

% ssl-cert-check -s -p 443 -x 60

Host                                            Status       Expires      Days
----------------------------------------------- ------------ ------------ ----                                Expiring     Feb 4 2013   57    

Ses deux principaux inconvénients sont qu'il ne définit pas le code de retour (ce qui le rend difficile à intégrer dans une solution de supervision automatisée, sauf à utiliser son option -n, conçue pour Nagios) et qu'il ne semble pas connaître le SNI (Server Name Indication, RFC 6066), ce qui est pénible pour le cas où on a plusieurs serveurs derrière la même adresse IP.

Autre solution, un programme écrit par Kim-Minh Kaplan, Il est conçu pour tester un groupe de serveurs (mis dans un fichier préalablement).

À noter que le programme sslscan est très utile pour faire un audit de son serveur mais ne semble pas adapté à la supervision. (Autre possibilité, mais je n'ai pas testé, SSLyze.)

Patrick Mevzek me fait remarquer qu'il faudrait, en toute rigueur, tester la date d'expiration, non seulement du certificat final, celui du serveur, mais aussi celle de tous les certificats intermédiaires, qui peuvent aussi expirer. J'ignore si les logiciels ci-dessus pensent à cela ( ne le fait pas). Les certificats intermédiaires sont ceux de professionnels de la sécurité et, normalement, ils ont moins souvent des problèmes que les certificats finaux. Mais il peut arriver en effet qu'un serveur stocke des certificats intermédiaires qui ont été mis à jour par l'AC mais que l'administrateur du serveur a oublié de changer.

Bref, avec tous ces outils, l'administrateur système qui laisse un certificat expirer n'a vraiment aucune excuse.

L'article seul

RFC 6789: ConEx Concepts and Use Cases

Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : B. Briscoe (BT), R. Woundy (Comcast), A. Cooper (CDT)
Pour information
Réalisé dans le cadre du groupe de travail IETF conex
Première rédaction de cet article le 6 décembre 2012

Premier RFC du groupe de travail CONEX de l'IETF, ce document expose les principes de bases du mécanisme de « publication de la congestion » (CONgestion EXposure). L'idée est d'indiquer dans les paquets la congestion prévue, pour que les équipements réseaux puissent prendre des décisions appropriées. Une fois normalisée (ce RFC 6789 n'est qu'une toute première étape), ce sera une des nombreuses techniques permettant de gérer la congestion dans les réseaux TCP/IP et notamment l'Internet.

Il n'y a pas encore de protocole normalisé pour cette « publication de la congestion » (les deux premiers utiliseront une option IPv6 et une option de TCP). Pour l'instant, notre RFC s'en tient à des usages : à quoi cela pourrait servir. La congestion est clairement une des plaies du réseau. La force de TCP/IP est de multiplexer la capacité des liens au niveau des paquets et pas des circuits. Cela permet une utilisation bien plus efficace du réseau. Mais cela ne crée pas magiquement de la capacité : quand trop de paquets rencontrent trop peu de capacité, la congestion survient. Elle se manifeste par des pertes de paquets (le routeur, n'arrivant pas à suivre, abandonne certains paquets), mais aussi par des retards (si les tampons du routeur amortissent la congestion, ils augmentent les délais d'acheminement), et par le marquage ECN (RFC 3168) de certains paquets.

Le récepteur des données est censé détecter ces signaux (un trou dans la séquence TCP, des RTT qui augmentent, les marques ECN) et il doit alors dire à l'émetteur de ralentir. Ce fonctionnement où seules les machines terminales agissent (les routeurs intermédiaires, à part éventuellement des marques ECN, n'ont pas grand'chose à faire, ils se contentent de router) est typique de l'Internet mais, dans certains cas, exposés dans ce RFC, il est insuffisant.

L'idée de base de ConEx est que l'émetteur mette dans les paquets IP qu'il envoie des indications sur la congestion qu'on lui a signalé. Ainsi, des équipements qui sont purement de niveau 3 sur le trajet peuvent être informés de la congestion (ECN les informe aussi mais ne concerne que les équipements en aval du point où est détectée la congestion, cf. figure 1 du RFC). Ainsi, le réseau pourra avoir une meilleure vision de la congestion, comptant les paquets qui vont rencontrer de la congestion aussi facilement qu'il compte aujourd'hui les paquets ou les octets.

Pourquoi est-ce important de connaître les paquets qui vont circuler dans des parties du réseau où il y a congestion ? Déjà, cela a une importance économique : un réseau ne coûte pas plus cher qu'il soit utilisé ou pas. Un trafic qui emprunte le réseau à un moment où celui-ci est peu chargé ne coûte donc rien à l'opérateur du réseau. Par contre, la congestion coûte cher puisqu'elle est le signe qu'il faut sortir son carnet de chèques pour mettre à jour le réseau, vers des capacités plus grandes. Ainsi, ConEx pourrait être une brique de base pour un système qui pénaliserait uniquement les flots de données qui contribuent à la congestion.

La section 2 présente en détail les concepts et la terminologie ConEx. D'abord, évidemment, la congestion. Tout le monde en parle mais il n'y a pas de définition rigoureuse et unique pour ce concept. Pour une analyse de ce terme, voir « The Evolution of Internet Congestion » de S. Bauer, S., D. Clark et W. Lehr. Dans ConEx, la congestion est définie comme la probabilité de perte de paquet (ou de marquage par ECN). Un autre effet de la congestion, le retard, n'est pas pris en compte (donc, ConEx ne mesurera pas l'effet du bufferbloat).

Deuxième concept, le volume de congestion. Il s'agit du nombre d'octets perdus suite à la congestion. L'idée est de rendre les émetteurs responsables : envoyer 10 Go sur un lien congestionné n'est pas la même chose que d'y envoyer quelques octets. Par exemple, si Alice envoie un fichier d'un Go sur un lien où la probabilité de perte est de 0,2 %, son volume de congestion est de 2 Mo. Si, plus tard dans la journée, elle envoie un fichier de 30 Go alors que la ligne, moins encombrée, ne perd plus que 0,1 % des paquets, elle ajoutera 3 Mo à son volume de congestion (donc, 5 Mo en tout). L'un des intérêts de cette métrique est qu'elle est très facilement mesurable par un routeur : il lui suffit de compter le volume total des paquets qu'il a dû jeter (ou marquer avec ECN, s'il utilise cette technique). C'est donc quasiment la même chose que les compteurs de volume actuels.

Troisième concept important, la congestion aval (Rest-of-path congestion ou downstream congestion dans la langue de Van Jacobson). C'est celle que le flot de données va supporter entre le point de mesure et sa destination (la congestion amont étant évidemment celle entre la source et le point de mesure : aujourd'hui, elle est bien plus difficile à mesurer si on n'utilise pas ECN).

La section 3 décrit ensuite le principal scénario d'usage envisagé pour ConEx. Si vous vous demandez « mais à quoi sert ce truc ? » depuis tout à l'heure, vous allez bientôt avoir une réponse. Soit un opérateur réseau qui a des clients. La plupart consomment peu mais certains sont des acharnés et font passer en permanence des gigaoctets à travers le réseau. L'opérateur voudrait que les mesures désagréables qu'il va prendre pour limiter la congestion frappent en priorité ces gros consommateurs.

Il va pour cela placer un équipement qui regarde les indications de congestion ConEx et va ensuite limiter le trafic en fonction de ces indications (en fonction du volume de congestion). (Les limitations de trafic habituelles visent le débit, pas la participation à la congestion. Or comme on l'a vu, débiter 100 Mb/s sur un réseau vide n'est pas du tout la même chose que de le débiter sur un réseau chargé. Il est donc dommage de limiter le débit dans tous les cas.) L'article « Policing Freedom to Use the Internet Resource Pool » de B. Briscoe, A. Jacquet et T. Moncaster, détaille ce mécanisme. La force de cette méthode est qu'aucune limite, aucune mesure contraignante et désagréable, n'est prise lorsqu'il n'y a pas de congestion (car, dans ce cas, l'usage du résau ne coûte rien). Avec ConEx, un bit n'est plus égal à un bit : celui envoyé pendant la congestion coûte plus cher au réseau et doit donc, d'une certaine façon, être « payé » par l'utilisateur.

Si l'opérateur est un FAI ADSL, un bon endroit pour mettre cette supervision de la congestion et cette limitation du trafic est sans doute le BRAS. (Voir le rapport du DSL Forum « Technical Report TR-059: Requirements for the Support of QoS-Enabled IP Services » mais il ne semble pas en ligne.)

Ainsi, les utilisateurs seront encouragés à utiliser des protocoles que notre RFC appelle « charognards » dans la mesure où ils n'utilisent que la capacité dont personne ne veut (le charognard a une mauvaise image de marque mais c'est bien à tort : il consomme les ressources négligées par tous les autres). Ces protocoles n'envoient du trafic que lorsque le réseau est inutilisé. Leur coût est donc à peu près nul pour l'opérateur. Le RFC 6297 décrit ces protocoles. Pour encourager leur usage, on ne peut pas seulement compter sur des exhortations citoyennes, dont l'écologie montre le peu d'efficacité. Il faut aussi des motivations plus pratiques.

Mais il existe d'autres approches, déjà, pour ce genre de gestion (ralentir les gros consommateurs, ceux qui sortent franchement du rang), non ? La section 3.3 les examine :

  • On l'a vu, il est courant de limiter le débit, ou bien d'imposer un total de données transféré maximum (cette dernière technique est courante en 3G). Cette approche est très grossière car elle mène à sous-utiliser ou sur-utiliser le réseau. S'il n'y a pas de congestion, on va sous-utiliser le réseau, alors qu'il est libre (pire, on décourage l'utilisation de protocoles « charognards » puisque leur utilisateur serait pénalisé pour le volume envoyé, au lieu d'être récompensé pour le soin qu'il met à ne l'envoyer qu'en l'absence de congestion). S'il y a congestion, on risque de sur-utiliser le réseau car, tant que le quota n'est pas atteint, l'utilisateur n'a pas de raison de se gêner.
  • Les techniques de fair queuing visent à égaliser le trafic entre les différents utilisateurs. Agissant en temps réel et n'ayant pas de mémoire, elles favorisent, sur le long terme, les plus gros consommateurs alors qu'on voudrait le contraire.
  • Plus subtile, la technique décrite dans le RFC 6057 ne mesure le débit que lorsqu'il y a congestion et donc effectivement gêne pour le réseau. Mais, lors de la congestion, tout le trafic est compté comme y contribuant et cette technique, comme les deux précédentes, n'encourage absolument pas à utiliser les protocoles « charognards ».
  • Dernière méthode possible, un examen plus ou moins poussé du paquet (allant jusqu'à la DPI) pour décider quelle est l'application utilisée, suivi d'une dégradation du service pour cette application particulière (par exemple BitTorrent). Elle est évidemment incompatible avec des techniques de sécurité comme IPsec et elle soulève de sérieuses questions politiques. ConEx, lui, est neutre par rapport à l'application utilisée.

Toutes ces solutions ont un autre défaut en commun : elles laissent l'utilisateur dans l'incertitude des performances qu'il obtiendra. Le principal intérêt des tarifs forfaitaires pour l'accès Internet (je parle des vrais forfaits, ceux où le prix est connu d'avance, pas de ce que les commerciaux menteurs de la téléphonie mobile appelent « forfait ») est la certitude : pas de mauvaises surprises au moment de l'arrivée de la facture. Mais cette certitude ne porte que sur les prix. Les performances, elles, peuvent varier, par exemple si le trafic émis était tel qu'on est désormais limité. Au contraire, avec Conex, l'utilisateur est en mesure de voir sa propre contribution à la congestion, et peut ajuster son comportement en fonction de cela. (À mon avis, c'est une vision un peu idéale, car elle suppose que le réseau n'agit sur les performances qu'en réponse aux indicateurs ConEx.)

Ce scénario d'usage de la section 3, informer l'opérateur sur la contribution des utilisateurs à la congestion, est le principal but de ConEx à l'heure actuelle. Les versions initiales de ce RFC traitaient sur un pied d'égalité plusieurs scénarios mais le groupe de travail, après bien des discussions, a décidé de prioritiser celui qui semblait le plus prometteur. Ceci dit, la section 4 présente quelques autres cas d'usage :

  • Mesurer la contribution à la congestion non pas par utilisateur mais par opérateur. Comme les indicateurs ConEx sont vus par tous les routeurs intermédiaires (y compris les routeurs de bordure entre opérateurs), chaque opérateur peut savoir ce que chacun de ses voisins va lui apporter comme congestion (et réciproquement). De beaux débats sur la répartition des investissements à prévoir !
  • Avoir de meilleures indications sur l'utilisation globale du réseau, pour mieux planifier l'avitaillement (provisioning) en capacité.

La section 5 se penche ensuite sur le déploiement de ConEx. Ce système ne nécessite pas un accord simultané de tous les acteurs (heureusement). ConEx est donc utile même si certains routeurs du trajet ne marquent pas et même si certains ne lisent pas l'information ConEx.

Par contre, il faut qu'au moins deux acteurs bougent : au moins un routeur doit marquer les paquets et au moins une machine doit réagir et signaler la congestion dans les paquets qu'elle émet. Les développeurs d'une application Ledbat (voir RFC 6297 et RFC 6817), par exemple, peuvent se lancer en espérant que cela motivera les routeurs pour s'y mettre.

Si certains paquets sont marqués par ConEx et d'autres non, que va faire le routeur ? Pour le déploiement de ConEx, il serait préférable que les paquets marqués soient favorisés d'une manière ou d'une autre. Mais comme la raison du marquage est leur contribution à la congestion, ce n'est pas forcément idéal... En outre, cela soulève un problème de sécurité (le marquage n'est pas authentifié et une machine peut mentir) sur lequel ce RFC 6789 est complètement muet (le problème sera traité dans les futurs RFC, plus concrets).

Comme ConEx va tripoter dans la couche 3, cœur de l'Internet, il risque de perturber le fonctionnement d'IP. Il faut donc considérer ConEx comme plutôt expérimental et la section 6 fait la liste des questions encore ouvertes, par exemple :

  • ConEx est actuellement limité à IPv6, l'idée est que le délai de déploiement sera de toute façon tel qu'IPv6 sera largement dominant lorsque ConEx sera généralisé. Était-ce une bonne idée ?
  • ConEx ne fait pas de différence entre l'auto-congestion (un utilisateur qui se gêne lui-même) et la congestion infligée aux autres (lorsqu'on encombre des ressources partagées). Moralement, il serait intéressant de séparer les deux mais n'est-ce pas trop complexe ?
  • ConEx est plus ambitieux qu'ECN et s'appuie sur lui. Mais le déploiement d'ECN est très limité. Est-ce que ConEx sera quand même utile si le déploiement d'ECN en reste où il est maintenant ?

Téléchargez le RFC 6789

L'article seul

RFC 6808: Test Plan and Results Supporting Advancement of RFC 2679 on the Standards Track

Date de publication du RFC : Décembre 2012
Auteur(s) du RFC : L. Ciavattone (AT&T Labs), R. Geib (Deutsche Telekom), A. Morton (AT&T Labs), M. Wieser (Technical University Darmstadt)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 6 décembre 2012

Voici le premier RFC à mettre en application la démarche du RFC 6576, qui définissait la méthode pour faire avancer un RFC décrivant des métriques sur le chemin des normes. Si l'IETF avait une grande expérience dans la mesure du déploiement et de la qualité d'un protocole, c'était moins évident pour les métriques, ces grandeurs définies rigoureusement et qu'on cherche à mesurer. Le RFC 6576 ayant déblayé ce terrain, ceci est sa première application : l'étude de l'avancement de la métrique « délai d'acheminement d'un paquet », qui avait été normalisée dans le RFC 2679 et l'est désormais dans le RFC 7679.

Deux mises en œuvre différentes de ce RFC 2679 ont été testées, pour vérifier que leurs résultats, face aux mêmes données, étaient compatibles. C'est le cas et cela plaide en faveur du RFC 2679 : il était clair et non ambigu puisque deux équipes différentes l'ont implémenté de manière compatible. On n'a pas dit « identique » car les métriques permettent une certaine souplesse et, de toute façon, la mesure est un domaine délicat, avec plein de possibilités d'erreur. On ne vérifie donc pas que ces deux programmes donnent les mêmes résultats, mais que leurs résultats sont équivalents, aux erreurs acceptables près.

L'essentiel du RFC est constitué de la description de l'environnement de test, et des mesures effectuées. Les deux implémentations sont NetProbe et Perfas+. NetProbe utilise des paquets UDP de taille variable, et peut produire des distributions de paquets suivant Poisson (RFC 3432) ou bien tout simplement périodiques (RFC 2330). Perfas+, lui (développé par Deutsche Telekom), peut aussi utiliser TCP. Entre deux sites connectés via l'Internet, les expérimentateurs ont monté un tunnel L2TP (RFC 3931), afin de diminuer la variation dans les mesures (autrement, certains équipements sur le trajet auraient pu distribuer le trafic de test sur plusieurs liens, en hachant par exemple les adresses IP des engins de test).

Le trafic passait par netem, un module du noyau Linux qui permet d'ajouter des pertes ou des retards quelconques. (Par exemple, pour le premier test, netem avait été configuré pour ajouter 100 ms de retard, avec une variation uniforme de ±50 ms.)

Les auteurs notent avec honnêteté que les ports des commutateurs étaient en half-duplex, ce qui n'était ni prévu, ni souhaitable (mais ils s'en sont aperçu une fois les mesures faites).

Les tests ont été faits avec des distributions périodiques et de Poisson, des rythmes allant de 1 à 10 p/s et des tailles de 64, 340 et 500 octets, ce que le RFC 2330, section 15, nomme des « paquets standards » (ce qui exclut les fragments).

Des centaines de paquets ont ensuite été envoyés. En conformité avec le RFC 2679 (section 3.8.4), un traceroute a été effectué et ses résultats sont inclus dans le RFC (NetProbe permet de faire le traceroute depuis l'outil, en même temps que la mesure, pour pouvoir analyser a posteriori des résultats surprenants, par exemple des variations inexpliquées).

Étape indispensable (mais pas forcément folichonne) dans une campagne de mesures, l'étalonnage des erreurs est décrite dans la section 4. Par exemple, NetProbe n'utilise pas réellement comme moment d'envoi d'un paquet le wire time défini par le RFC 2330 (il se sert du moment d'acceptation du paquet UDP par le noyau, qui peut être différent si la machine est chargée). L'horloge de la machine est synchronisée avec NTP et la résolution de NTP (typiquement pas mieux qu'une milli-seconde) est également à prendre en compte comme source d'erreur (mais cela peut être amélioré par les méthodes décrites dans la section 4.1 : pour ces mesures, la stabilité de l'horloge est plus importante que sa justesse).

Toutes les sources de l'erreur, après évaluation, ont ensuite été données à R qui nous donne les divers intervalles d'erreur.

Perfas+, lui, utilise un récepteur GPS pour son horloge mais d'autres causes font que ses intervalles d'erreur sont plus larges (et donc moins bons) que ceux de NetProbe.

La section 5 explique ensuite ce que veut dire « équivalent ». En raison de la souplesse de la métrique, et des erreurs dans la mesure, on ne peut pas espérer que les deux logiciels affichent pile les mêmes résultats. On pose donc les limites tolérables, pour une comparaison faite avec Anderson-Darling. (Rappelons que le but de cette expérience n'était pas de mesurer un réseau, mais de savoir si la norme du RFC 2679 était suffisamment bien écrite et précise, et que les implémentations étaient donc équivalentes dans leurs résultats.)

Les tests et leurs résultats figurent en section 6. On note que, dans l'un des tests, un des deux programmes n'a pas réussi le test de l'équivalence avec lui-même (les variations provoquées par le réseau ont été trop grandes). À part ça, toutes les comparaisons Anderson-Darling ont réussi.

La section 7 n'a plus qu'à résumer la conclusion : c'est bon, les deux programmes utilisés sont statistiquement équivalents, ce qui semble indiquer que la norme qu'ils ont tous les deux implémentée était correctement définie. La métrique définie par le RFC 2679 mérite donc d'avancer sur le chemin des normes. Quelques erreurs mineures dans la norme ont été détectées et il est proposé qu'elles soient corrigées dans la prochaine version. (Voir les errata.)

À noter que l'avancement de la métrique sur le chemin des normes a nécessité une nouvelle version du RFC 2679, le RFC 7679.

Une description de l'utilisation de NetProbe sur le réseau d'AT&T est documentée en ligne.

Téléchargez le RFC 6808

L'article seul

My first Nagios plugin in Go

First publication of this article on 4 December 2012

An important feature of the Nagios monitoring system (or of its compatibles like the one I use, Icinga), is that you can easily write your own plugins, to test things that cannot be tested with the "standard" Nagios plugins. I wrote several such plugins in my life, to do tests which were useful to me. This one is the first I wrote in Go, and it tests a DNS zone by querying every name server, thus checking that all name servers are OK.

This is an important test because DNS is too robust for monitoring: even with almost all the name servers down or broken, the zone will work, thus leaving people with a feeling of false security. Hence the idea of testing every name server of the zone (monitoring typically requires that you test differently from what the ordinary user does, to see potential problems). The original idea comes from the check_soa program, distributed in the famous book "DNS and BIND" (the code is available on line).

And why using Go? Well, Nagios plugins can be written in any language but I like Go: faster and lighter than Perl or Python but much easier to deal with than C. A good language for system and network programming.

Nagios plugins have to abide by a set of rules (in theory: in practice, many "quick & dirty" plugins skip many of the rules). Basically, the testing plugin receives standard arguments telling it what to test and with which parameters, and it spits out one line summarizing the results and, more important, exits with a status code indicating what happened (OK, Warning, Critical, Unknown).

That's one point where my plugin fails: the standard Go library for parsing arguments (flag) cannot do exactly what Nagios wants. For instance, Nagios wants repeating options (-v increases the verbosity of the output each time it appears) and they are not possible with the standard module. So, in practice, my plugin does not conform to the standard. Here is its use:

% /usr/local/share/nagios/libexec/check_dns_soa  -h
  -4=false: Use IPv4 only
  -6=false: Use IPv6 only
  -H="": DNS zone name
  -V=false: Displays the version number of the plugin
  -c=1: Number of name servers broken to trigger a Critical situation
  -i=3: Maximum number of tests per nameserver
  -r=false: When using -4 or -6, requires that all servers have an address of this family
  -t=3: Timeout (in seconds)
  -v=0: Verbosity (from 0 to 3)
  -w=1: Number of name servers broken to trigger a Warning

The most important argument is the standard Nagios one, -H, indicating the zone you want to test. For instance, the TLD .tf :

% /usr/local/share/nagios/libexec/check_dns_soa  -H tf
CHECK_DNS_SOA OK: Zone tf. is fine

% echo $?

The return code show that everything was OK. You can test other, non-TLD, domains:

% /usr/local/share/nagios/libexec/check_dns_soa  -H
CHECK_DNS_SOA OK: Zone is fine

The plugin works by sending a SOA request to every name server of the zone and checking there is an answer, and it is authoritative. With tcpdump, you can see its activity ( is the local DNS resolver):

# Request the list of name servers
12:00:39.954330 IP > 0+ NS? (28)
12:00:39.979266 IP > 0 4/0/0 NS, NS, NS, NS (114)

# Requests the IP addresses
12:00:40.063714 IP > 0+ A? (36)
12:00:40.064237 IP > 0 1/0/0 A (52)
12:00:40.067517 IP > 0+ AAAA? (36)
12:00:40.068085 IP > 0 1/0/0 AAAA 2001:500:94:1::16 (64)

# Queries the name servers
12:00:40.609507 IP > 0 SOA? (28)
12:00:40.641900 IP > 0*- 1/4/0 SOA (161)
12:00:40.648342 IP6 2a01:e35:8bd9:8bb0:ba27:ebff:feba:9094.33948 > 2001:500:94:1::16.53: 0 SOA? (28)
12:00:40.689689 IP6 2001:500:94:1::16.53 > 2a01:e35:8bd9:8bb0:ba27:ebff:feba:9094.33948: 0*- 1/4/0 SOA (161)

Then, you can configure Nagios (or Icinga, in my case), to use it:

define command {
        command_name    check_dns_soa
        command_line    /usr/local/share/nagios/libexec/check_dns_soa -H $HOSTADDRESS$ $ARG1$ $ARG2$

define hostgroup
       hostgroup_name my-zones

define service {
       use generic-service
       hostgroup_name my-zones
       service_description CHECK_DNS_SOA
       check_command check_dns_soa

Nagios (or Icinga) forces you to declare a host, even if it makes no sense in this case. So, my zones are declared as a special kind of hosts:

define host{
        name                            dns-zone
        use                      generic-host
	check_command             check-always-up
        register 0
        # Other options, quite ordinary

define host{
        use dns-zone

Nagios wants a command to check that the "host" is up (otherwise, the "host" stays in the "pending" state for ever). That's why we provide check-always-up which is defined as always true:

define command{
        command_name    check-always-up
        command_line    /bin/true

With this configuration, it works fine and you can see nice trends of 100 % uptime if everything is properly configured and connected. And if it's not? Then, the plugin will report the zone as Warning or Critical (depending on the options you used, see -c and -w) :

% /usr/local/share/nagios/libexec/check_dns_soa  -H ml
CHECK_DNS_SOA CRITICAL: Cannot get SOA from read udp i/o timeout

% echo $?

If you are more lenient and accept two broken name servers before setting the status as Critical, use -c 3 and you'll just get a Warning:

% /usr/local/share/nagios/libexec/check_dns_soa  -v 3 -c 3 -H ml
CHECK_DNS_SOA WARNING: Cannot get SOA from read udp i/o timeout (SERVFAIL) 

% echo $?

This plugin is hosted at FramaGit, where you can retrieve the code, report bugs, etc. To compile it, see the README. You'll need the excellent Go DNS library first (a good way to make DNS requests from Go).

Two implementation notes: the plugin does not use one of the Go's greatest strengths, its built-in parallelism, thanks to "goroutines". This is because making it parallel would certainly decrease the wall-clock time to run the tests but, for an unattended program like Nagios, it is not so important (it would be different for an interactive program). And, second, there is a library to write Nagios plugins in Go but I did not use it because of several limitations (and I do not use performance data, where this library could be handy). Note also that other people are using Go with Nagios in a different way.

Thanks to Miek Gieben for his reading and patching.

L'article seul

Limiter le nombre de requêtes sur des scripts WSGI

Première rédaction de cet article le 3 décembre 2012

Le standard WSGI permet de développer facilement des scripts en Python pour réaliser un service accessible via le Web. Ces services nécessitent souvent pas mal de traitement côté serveur et risquent donc de faire souffrir celui-là si un client maladroit appelle le service en boucle (ou, pire, si un client méchant essaye délibérement de planter le serveur en lançant plein de requêtes). Il est donc souhaitable de limiter le nombre de requêtes.

Voici la technique que j'utilise (il y en a plein d'autres, avec Netfilter, ou avec Apache). On crée un seau qui fuit (dans le fichier Chaque requête en provenance d'une adresse IP donnée ajoute une unité dans le seau. Le temps qui passe vide le seau. Lorsqu'une requête arrive, on vérifie si le seau est plein et on refuse la requête autrement. Cela nécessite une entrée par client dans la table des seaux (chaque client a un seau différent). Avec le, cela donne :

if buckets[ip_client].full():
    # Refus

En pratique, on va regrouper les adresses IP des clients en préfixes IP, de manière à limiter le nombre de seaux et à éviter qu'un attaquant ne disposant d'un préfixe contenant beaucoup de machines ne puisse éviter la limitation en lançant simplement beaucoup d'adresses IP différentes à l'attaque. De manière assez arbitraire, on a mis 28 bits pour IPv4 et 64 pour IPv6. Pour faire les calculs sur les adresses IP, on se sert de l'excellent module Python netaddr :

ip_client = netaddr.IPAddress(environ['REMOTE_ADDR'])
if ip_client.version == 4:
    ip_prefix = netaddr.IPNetwork(environ['REMOTE_ADDR'] + "/28")
elif ip_client.version == 6:
    ip_prefix = netaddr.IPNetwork(environ['REMOTE_ADDR'] + "/64")
# Et on continue comme avant :
if buckets[ip_prefix.cidr].full():

Et comment se manifeste le refus ? On renvoie le code HTTP 429, Too Many Requests, normalisé par le RFC 6585. En WSGI :

status = '429 Too many requests'
output = "%s sent too many requests" % environ['REMOTE_ADDR']
response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]

Cela donne quoi en pratique ? Testons avec curl :

% for i in $(seq 1 50); do
    curl --silent --output /dev/null \
          --write-out "$i HTTP status: %{http_code} ; %{size_download} bytes downloaded\n" \
1 HTTP status: 200 ; 278 bytes downloaded
2 HTTP status: 200 ; 278 bytes downloaded
3 HTTP status: 200 ; 278 bytes downloaded
4 HTTP status: 200 ; 278 bytes downloaded
5 HTTP status: 200 ; 278 bytes downloaded
6 HTTP status: 200 ; 278 bytes downloaded
7 HTTP status: 200 ; 278 bytes downloaded
8 HTTP status: 200 ; 278 bytes downloaded
9 HTTP status: 200 ; 278 bytes downloaded
10 HTTP status: 200 ; 278 bytes downloaded
11 HTTP status: 429 ; 36 bytes downloaded
12 HTTP status: 429 ; 36 bytes downloaded
13 HTTP status: 200 ; 278 bytes downloaded
14 HTTP status: 200 ; 278 bytes downloaded
15 HTTP status: 429 ; 36 bytes downloaded
16 HTTP status: 429 ; 36 bytes downloaded

On voit bien l'acceptation initiale, puis le rejet une fois le nombre maximal de requêtes fait, puis à nouveau l'acceptation lorsque le temps a passé. Attention en configurant la taille du seau (default_bucket_size dans : il y a plusieurs démons WSGI qui tournent et le nombre de requêtes acceptées est donc la taille du seau multipliée par le nombre de démons.

Comme souvent avec les mesures de sécurité, elles peuvent avoir des effets secondaires, parfois graves. Ici, le serveur alloue une table indexée par le nombre de préfixes IP. Si un attaquant méchant peut envoyer des paquets depuis d'innombrables adresses IP usurpées (c'est non trivial en TCP), il peut vous faire allouer de la mémoire en quantité impressionnante.

Si vous voulez les fichiers authentiques et complets, voir les fichiers de ce blog (fichiers wsgis/ et wsgis/

Merci à David Larlet pour l'amélioration du code.

L'article seul

Quelles informations envoie réellement votre navigateur Web ?

Première rédaction de cet article le 1 décembre 2012

Supposons que vous soyiez un développeur Web qui veut savoir quelles sont les informations que le serveur distant récupère de son navigateur, afin d'améliorer une application. Ou que vous soyiez simplement un curieux qui veut connaître ce qui se passe sur le réseau. Bien sûr, vous pouvez toujours demander au navigateur d'afficher cette information (par exemple avec l'extension Live HTTP Headers de Firefox). Ou vous pouvez utiliser un programme d'espionnage du réseau comme Wireshark. Mais ils ne vous donnent qu'une vision locale, ce qu'envoie le client. Si la requête est modifiée en route (routeur NAT, relais HTTP), ce que verra le serveur n'est pas forcément ce que le client aura envoyé. D'où l'intérêt des sites Web qui affichent cette information.

J'en connais trois qui permettent de retourner les données vues par le serveur sous une forme structurée, analysable par un programme (tous les trois font du JSON, cf. RFC 8259). Mais, si vous en trouvez d'autres, je suis preneur :

  • est le plus riche en fonctions (possibilité de n'envoyer qu'une partie des données, possibilité d'introduire un retard artificiel, etc). Mais il ne marche qu'en IPv4.
  •, lui, fonctionne en IPv6.
  • Et j'ai réalisé un tel service,, fait en WSGI. Contrairement aux précédents, son source (il est vrai que c'est assez trivial) est disponible (dans wsgis/ dans l'archive des fichiers de ce blog). Il semble être le seul à afficher le nom correspondant à l'adresse IP du client (oui, vous pourriez faire un dig vous-même mais, dans certains cas, la résolution d'adresse en nom ne donne pas le même résultat de partout). Ce nom est dans le champ origin_name (s'il existe : toutes les adresses IP ne pointent pas vers un nom).

Voici des exemples d'utilisation avec curl, montrant le JSON produit :

% curl
  "url": "",
  "headers": {
    "Content-Length": "",
    "Connection": "keep-alive",
    "Accept": "*/*",
    "User-Agent": "curl/7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/ libidn/1.15 libssh2/1.2.6",
    "Host": "",
    "Content-Type": ""
  "args": {},
  "origin": ""
% curl
  "version" : "HTTP/1.0",
  "method" : "GET",
  "path" : "/echo",
  "decode_path" : {
    "path" : "/echo",
    "query_string" : "",
    "qs" : {
    "path_info" : [
  "headers" : {
    "Accept" : "*/*",
    "User-Agent" : "curl/7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/ libidn/1.15 libssh2/1.2.6",
    "Connection" : "close",
    "X-Forwarded-For" : "2001:db8:8bd9:8bb0:da:8aa3:5f22:df56",
    "X-Real-Ip" : "2001:db8:8bd9:8bb0:da:8aa3:5f22:df56",
    "Host" : ""
  "body" : "",
  "json" : {
  "form" : {
% curl
  "origin": "2001:db8:8bd9:8bb0:da:8aa3:5f22:df56", 
  "headers": {
    "HOST": "", 
    "USER_AGENT": "curl/7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/ libidn/1.15 libssh2/1.2.6", 
    "ACCEPT": "*/*"
  "method": "GET",
  "origin_name": ""

Bien sûr, votre navigateur Web envoie d'autres informations, par exemple par les cookies. (Une excellente application pratique de ces informations, pour montrer la facilité à repérer un utiisateur unique, est le Panopticlick.) Mais on s'est limité ici aux informations strictement HTTP.

L'article seul

RFC 6815: RFC 2544 Applicability Statement: Use on Production Networks Considered Harmful

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : S. Bradner (Harvard University), K. Dubray (Juniper Networks), J. McQuaid (Turnip Video), A. Morton (AT&T Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF bmwg
Première rédaction de cet article le 1 décembre 2012

Lors de la publication du RFC 2544, sur les tests de performances des équipements réseau, un point n'avait pas été mis assez clairement : comme tous les RFC du BMWG, le RFC 2544 ne concerne que les tests en laboratoire, dans des conditions bien contrôlées, et sans avoir peur de gêner un réseau de production. Comme certains avaient apparemment raté cette limitation, notre RFC 6815 enfonce le clou : ne faites pas les tests du RFC 2544 sur un vrai réseau !

Ce point est clairement précisé dans la charte du groupe de travail BMWG (Benchmarking Methodology Working Group). Les tests produits par ce groupe sont conçus pour des réseaux isolés (section 3 : un réseau isolé est un réseau dont le trafic de test ne sort pas et où le trafic non lié au test ne rentre pas). Il n'est pas prévu de les utiliser pour, par exemple, vérifier des SLA sur un réseau de production.

Mais pourquoi est-ce mal d'utiliser les tests BMWG sur un réseau de production ? La section 4 donne les deux raisons :

  • Dans l'intérêt du test, il ne faut pas que le trafic de test soit mêlé à du trafic sans lien avec le test, si on veut que les résultats soient précis et reproductibles.
  • Dans l'intérêt du réseau de production, il ne faut pas que le trafic de test (qui peut être intense, voir par exemple les tests de la capacité du réseau, qui fonctionnent en essayant de faire passer le plus de données possible) puisse rentrer en concurrence avec le trafic des vrais utilisateurs.

C'est d'ailleurs pour faciliter l'isolation et garder le trafic de test à part qu'il existe des plages d'adresses IP dédiées aux tests, le (RFC 2544, annexe C.2.2) et le 2001:2::/48 (RFC 5180, section 8 mais notez que ce RFC comporte une grosse erreur). On peut ainsi facilement filtrer ces plages sur ses routeurs et pare-feux, pour empêcher du trafic de test de fuir accidentellement.

Et si on veut quand même faire des mesures sur des réseaux de production ? Il faut alors se tourner vers un autre jeu de tests, ceux développés par le groupe de travail IPPM. Notez que cela n'est pas par hasard que cet autre jeu ne comporte pas de méthode pour la mesure de la capacité (RFC 5136) : une telle mesure perturbe forcément le réseau mesuré.

Téléchargez le RFC 6815

L'article seul

RFC 6814: Formally Deprecating some IPv4 Options

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : C. Pignataro (Cisco Systems), F. Gont (UTN-FRH / SI6 Networks)
Chemin des normes
Première rédaction de cet article le 29 novembre 2012

Ce très court RFC est purement administratif et n'aura pas de conséquences pratiques : il note simplement comme officiellement abandonnées neuf des options d'IPv4.

IPv4 (RFC 791, section 3.1) prévoit l'ajout d'options dans l'en-tête d'un paquet (en pratique, elles sont peu utilisées). Parmi les options enregistrées, certaines n'avaient jamais été déployées, ou bien était tombées en désuétude depuis longtemps. Lire ce RFC, c'est donc fouiller le grenier et retrouver des trucs que tout le monde croyait perdus... Le registre des options IP est mis à jour pour que ces options soient formellement retirées (et le RFC correspondant marqué comme « intérêt historique uniquement »). Ce sont :

  • Stream ID (RFC 791), déjà marquée comme inutile par les RFC 1122 et RFC 1812. Elle servait à la compatibilité avec le défunt réseau SATNET, tellement oublié que même Wikipédia n'en parle pas.
  • Extended Internet Protocol (RFC 1385), une tentative pour prolonger la vie d'IPv4 en attendant IPv6.
  • Traceroute (RFC 1393), qui aurait permis (si elle avait été déployée, mais elle nécessitait de modifier tous les routeurs) de faire des traceroute plus économiques (cette option demandait au routeur de renvoyer un paquet d'information à la source).
  • Encode, qui avait un rapport avec le chiffrement mais qui ne semble pas avoir eu de RFC.
  • VISA, une expérience à l'USC qui n'est jamais allé loin.
  • Address Extension (RFC 1475), un autre essai de l'époque où l'IETF cherchait un successeur à IPv4. Cette technique, TP/IX: The Next Internet, avait reçu le numéro 7 et aurait donc été IPv7 si elle avait réussi.
  • Selective Directed Broadcast (RFC 1770), un projet de l'armée qui ne semble pas avoir été utilisé.
  • Dynamic Packet State, une partie de DiffServ, qui n'est jamais devenue un RFC.
  • Upstream Multicast Packet, un truc pour le multicast, jamais décrit dans un RFC, officiellement abandonné par le RFC 5015.

D'autres options, MTU Probe et MTU Reply, avaient déjà été « nettoyées » par le RFC 1191.

Téléchargez le RFC 6814

L'article seul

RFC 6770: Use Cases for Content Delivery Network Interconnection

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : G. Bertrand (France Telecom - Orange), E. Stephan (France Telecom - Orange), T. Burbridge, P. Eardley (BT), K. Ma (Azuki Systems), G. Watson (Alcatel-Lucent - Velocix)
Pour information
Réalisé dans le cadre du groupe de travail IETF cdni
Première rédaction de cet article le 20 novembre 2012

Le groupe de travail CDNI de l'IETF travaille à normaliser les interfaces entre CDN pour permettre à deux de ces systèmes de distribution de contenu de coopérer pour servir un client. Ce second RFC du groupe (le premier, le RFC 6707, décrivait en détail le problème à résoudre et l'état de l'art) rassemble trois études de cas, illustrant ainsi par ces scénarios l'utilité du travail du groupe.

Un ancien effort de normalisation des CDN à l'IETF avait eu lieu, produisant des documents comme le RFC 3570, qui décrivait déjà des scénarios d'usage. Ce nouveau RFC remplace ce RFC 3570 ; la terminologie est notamment très différente et reprend celle du RFC 6707. Conjointement avec ce RFC 6707, il va servir de base au document « cahier des charges » du groupe de travail CDNI, qui sera publié en RFC 7337.

Interconnecter des CDN offre en théorie de nombreux avantages : améliorer le vécu de l'utilisateur (temps de réponse plus courts, voir le RFC 6390) et diminuer les coûts pour l'opérateur (on n'utilise que le réseau interne au lieu des lignes extérieures) notamment. Mais, actuellement, chaque CDN fonctionne de manière indépendante des autres, ce qui fait qu'il n'est pas toujours possible de récolter ces bénéfices. Voyons les trois études de cas.

D'abord (section 2), le cas d'un CDN qui a une couverture géographique insuffisante. Un opérateur de CDN est présent dans une région donnée (mettons l'Europe) mais ne peut pas fournir de service aux lecteurs en Asie ou en Amérique. Et imaginons un autre opérateur de CDN en Amérique qui n'a pas de présence en Europe. Les interconnecter permettrait au nouvel ensemble de servir les deux continents, sans que chaque opérateur n'ait eu à supporter d'énormes investissements.

Un autre cas proche est celui où un FAI a construit un CDN en interne pour distribuer du contenu dont il a les droits. Un autre fournisseur de contenu a déjà un contrat avec un autre opérateur de CDN. Dans ce cas, le FAI va recevoir un gros trafic de la part de ce CDN, qui va saturer ses liaisons externes, alors que ce contenu pourrait être distribué plus efficacement par le CDN du FAI. Pour le FAI en question, il serait utile que cet autre CDN puisse s'interconnecter avec le CDN du FAI (section 2.3), afin d'améliorer les performances et de décongestionner les liens d'interconnexion.

Deuxième étude de cas (section 3), celle où le CDN a une couverture géographique jugée suffisante mais des capacités trop petites pour la charge. Cela peut être à cause d'une énorme augmentation temporaire de la demande (effet Slashdot, dit aussi flash crowd) par exemple suite à un événement particulier. Cet événement peut être prévu - match de football à diffuser - ou imprévu. (Le RFC cite l'exemple de la vidéodiffusion du mariage d'une célébrité ; il est triste de penser que des technologies si sophistiquées servent à de telles conneries.) Le CDN menace alors de s'écrouler sous la charge. Appelons un autre CDN à son secours ! L'idée est que le gestionnaire du CDN trop petit va payer un autre CDN, s'interconnecter à lui, et que les deux CDN feront face ensemble à la charge. (Une autre solution serait d'agrandir le CDN, mais, avec l'interconnexion des CDN, on peut prendre des marges de dimensionnement moins importantes, sans pour autant perdre sa capacité de faire face à d'éventuels pics de trafic.)

Une variante de ce cas est la résilience en cas de problème, par exemple une attaque par déni de service ou une panne massive d'une partie d'un CDN (section 3.2). S'interconnecter à un autre CDN permet alors de continuer à fonctionner. Actuellement, chaque CDN doit se débrouiller seul en cas de panne.

Dernière étude de cas (section 4), celui où le CDN n'a, ni problème de couverture géographique, ni problème de capacité, mais un problème de fonctions : le client a des exigences techniques particulières que le CDN ne sait pas remplir. Par exemple, un CDN sert du contenu en HTTP mais un client réclame qu'une partie du contenu soit servie en HTTPS (qui, entre autres, nécessite des processeurs plus rapides, pour les calculs cryptographiques) qu'il ne sait pas faire. S'allier avec un CDN qui, lui, sait faire du HTTPS, permettrait de rendre le client heureux (en lui évitant de signer deux contrats). Autre exemple donné par le RFC (mais peu convaincant depuis l'échec ridicule de WAP), celui d'un client qui demanderait tout à coup un protocole de distribution qui soit spécifique aux engins mobiles, alors que le CDN habituel de ce client n'a pas mis en œuvre ce protocole.

Et, bien sûr, exemple évident, un CDN qui serait toujours, en 2012, uniquement en IPv4 et à qui des clients réclameraient qu'il utilise enfin un protocole de ce siècle, IPv6. Sous-traiter la distribution en IPv6, par le biais des protocoles d'interconnexion que concevra le groupe de travail CDNI, permettrait au CDN IPv4 d'attendre encore un peu.

Plus subtil, le cas où le CDN peut distribuer le contenu avec le protocole demandé, mais pas avec les exigences quantitatives du client (par exemple portant sur la latence). S'associer avec un autre CDN, meilleur de ce point de vue, peut être utile.

Dans ces trois cas, si on pouvait facilement interconnecter des CDN, tout irait bien et les oiseaux chanteraient plus mélodieusement. Mais, à l'heure actuelle, une telle interconnexion se heurte à l'absence totale de normes techniques (cf. RFC 6707). Chaque fois que deux CDN s'interconnectent, ils doivent développer du code spécifique à ce couple. C'est justement le travail du groupe CDNI que de spécifier ces normes techniques, en attendant leur futur développement et déploiement. Une fois que cela sera fait, l'interconnexion de deux CDN ne sera plus « que » une affaire de business... (Comme l'accord Orange/Akamai annoncé le même jour que le RFC...)

Ah, un petit point à ne pas oublier (section 5), l'application de politiques de distribution restrictives. C'est une demande courante des clients (distribuer une vidéo en Amérique du Nord seulement, par exemple, et donc barrer l'accès aux visiteurs d'autres régions, ou bien ne permettre l'accès gratuit que pendant 24 h). Cela ajoute une contrainte assez ennuyeuse à l'interconnexion de CDN : il faut aussi transmettre ces restrictions. L'annexe A.1 traite en détail ce problème.

Dernier problème lors de l'interconnexion, la marque (branding), vue en annexe A.3. Un CDN qui fait appel à un autre pour traiter une partie de son travail peut souhaiter que sa marque apparaisse quand même (par exemple, URL avec son nom de domaine). La solution d'interconnexion doit donc penser à fournir une solution à ce problème.

Merci à Gilles Bertrand pour sa relecture.

Téléchargez le RFC 6770

L'article seul

RFC 6797: HTTP Strict Transport Security (HSTS)

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : J. Hodges (PayPal), C. Jackson (Carnegie Mellon University), A. Barth (Google)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF websec
Première rédaction de cet article le 20 novembre 2012

La technique HSTS (HTTP Strict Transport Security), normalisée dans ce RFC (mais déjà largement déployée) vise à résoudre une attaque contre TLS. Si un site Web est accessible en HTTPS, et qu'un méchant arrive à convaincre un utilisateur de se connecter en HTTP ordinaire à la place, le méchant peut alors monter une attaque de l'homme du milieu. Le fait que le site soit protégé par TLS n'aidera pas dans ce cas. Pour éviter cette attaque, HSTS permet à un site de déclarer qu'il n'est accessible qu'en HTTPS. Si l'utilisateur a visité le site ne serait-ce qu'une fois, son navigateur se souviendra de cette déclaration et ne fera plus ensuite de connexions non sécurisées.

Bien sûr, il n'y aurait pas de problème si l'utilisateur utilisait systématiquement des URL https://.... Mais les erreurs ou les oublis peuvent arriver, l'utilisateur peut cliquer sur un lien http://... dans un spam, il peut être victime d'une page Web certes sécurisée mais qui contient des images chargées via un URL http://.... Bref, il y a encore trop de risques. D'où l'idée d'épingler la politique de sécurité du site Web dans le navigateur, en permettant à un site de déclarer au navigateur « je suis sécurisé, ne reviens jamais me voir en HTTP ordinaire » et de compter sur le fait que le navigateur respectera automatiquement cette politique, et s'en souviendra. Cette déclaration se fera par l'en-tête HTTP Strict-Transport-Security:, par exemple Strict-Transport-Security: max-age=7905600.

TLS est normalisé dans le RFC 5246. (Son prédécesseur, SSL, est dans le RFC 6101.) L'utilisation de HTTP au dessus de TLS (HTTPS) est décrite dans le RFC 2818. Un navigateur Web va typiquement appliquer des politiques de sécurité différentes selon que la connexion se fait en HTTP ou en HTTPS. Un exemple typique est fourni par les cookies du RFC 6265 : s'ils ont été envoyés par le serveur avec l'attribut Secure, ils ne seront retransmis par le navigateur que si la connexion est en HTTPS.

Pour vérifier l'identité du serveur en face, les navigateurs valident les certificats présentés par le serveur. Si cette vérification échoue (c'est en général suite à une erreur de l'administrateur du serveur, mais cela est parfois dû à une attaque d'un intermédiaire), le navigateur affiche typiquement un avertissement à l'utilisateur, en lui permettant de continuer de manière non sûre s'il le souhaite (cette possibilité est « officialisée » par la section 3.1 du RFC 2818). Ce mécanisme de click-through security, que le navigateur rend plus ou moins facile, est très critiqué : comme l'utilisateur veut avant tout continuer sa tâche, il va toujours chercher à passer outre l'avertissement de sécurité. C'est même une attitude raisonnable, compte tenu du fait que la plupart des erreurs d'authentification avec TLS ne sont pas des attaques, et aussi compte tenu de la difficulté, même pour un expert, d'analyser ces problèmes et de comprendre ce qui s'est passé. Deux bons articles sur les questions d'interface utilisateur liées à ce problème de sécurité sont « Crying Wolf: An Empirical Study of SSL Warning Effectiveness » de Sunshine, J., Egelman, S., Almuhimedi, H., Atri, N., et L. Cranor, puis « Stopping Spyware at the Gate: A User Study of Privacy, Notice and Spyware » de Good, N., Dhamija, R., Grossklags, J., Thaw, D., Aronowitz, S., Mulligan, D., et J. Konstan. Mais d'autres articles, non cités par ce RFC, prennent un point de vue différent, expliquant qu'ignorer les avertissements de sécurité peut être une attitude rationnelle.

Pour éviter ces risques, l'article de C. Jackson et A. Barth (deux des auteurs du RFC), « ForceHTTPS: Protecting High-Security Web Sites from Network Attacks » proposait une approche où le site Web disait à ses clients qu'ils devaient utiliser HTTPS pour se connecter. Ce RFC utilise une technique différente de celle de l'article mais l'idée est la même.

La section 2 décrit en détail le problème de sécurité. Si vous êtes plutôt intéressé par la solution, il faut sauter à la section 5. Sinon, si on continue dans l'ordre, une analyse des menaces. HSTS gère trois menaces :

  • Les attaques passives. Ce sont celles où l'attaquant ne fait qu'écouter. Par exemple, sur un réseau WiFi typique, écouter est possible, que le réseau soit sécurisé ou pas (« Practical Attacks Against WEP and WPA » de Beck, M. et E. Tews). Il existe même des outils tous faits pour cela comme Aircrack L'attaquant peut alors intercepter des mots de passe, des cookies, etc. Une extension Firefox spectaculaire, Firesheep, permet d'automatiser cette tâche et de se retrouver rapidement connecté au compte Facebook de ses voisins de Starbucks. HTTPS empêche complètement ces attaques passives s'il est utilisé. Par exemple, si un site est accessible normalement à la fois en HTTP et en HTTPS, il suffit d'une seule requête HTTP, faite par accident ou oubli, et les cookies peuvent être copiés.
  • Plus sophistiqué est l'attaquant actif. Il peut agir sur le DNS, ou sur le routage ou tout simplement installer un point d'accès WiFi pirate, ayant le même SSID que le vrai. Il risque plus d'être détecté mais il a ainsi des possibilités bien plus grandes. Notons que l'attaquant actif peut être un État (l'Iran s'en est fait une spécialité) et que, dans ce cas, l'attaque est bien plus facile pour lui, car il contrôle toutes les liaisons du pays. Cette fois, contre ces attaquants actifs, juste faire tourner HTTP sur TLS ne suffit plus : il faut aussi authentifier le serveur distant. Les certificats auto-signés (ou signés par une AC qui n'est pas connue du navigateur) sont dangereux car ils ne protègent pas du tout contre les attaquants actifs. Si l'on accepte les sites présentant un certificat auto-signé (ce que permettent tous les navigateurs, après un sermon sur la sécurité et l'obligation de cliquer sur un lien « je sais ce que je fais »), c'est comme si on n'utilisait pas TLS du tout puisqu'on n'est pas sûr de parler au bon site. (Une protection minimale peut être fournie par des outils comme Certificate Patrol.)
  • Mais il n'y a pas que les attaquants actifs et passifs qui peuvent compromettre la sécurité de HTTP. Il y a aussi les bogues dans les sites Web. Par exemple, si une page a un contenu en Flash, et que ce contenu est chargé via une connexion non sécurisée, l'attaquant passif pourra lire les cookies et l'attaquant actif pourra remplacer le Flash par un autre code, qui fera des tas de choses vilaines chez le client. (Dans une certaine mesure, c'est également faisable avec JavaScript ou même une CSS.) Une protection contre cela est le refus, par le navigateur, de charger du « contenu de contextes de sécurité différents » (page HTML chargée en HTTPS et Flash chargé en HTTP) mais tous ne le font pas (cf. section 12.4), et beaucoup se contentent d'un avertissement qui peut facilement passer inaperçu. (À noter que ce contenu de contextes de sécurité différents est souvent appelé « contenu mixte » mais notre RFC déconseille ce terme, qui a un sens bien précis - et différent - en XML.)

Une analyse de sécurité sérieuse doit indiquer quelles sont les menaces traitées mais aussi celles qu'on ne prétend pas traiter. La section 2.3.2 liste les « non-buts » de HSTS :

  • Le hameçonnage, où un utilisateur va donner à un site Web, authentifié et utilisant HTTPS, mais pas digne de confiance, des informations secrètes. HSTS vous protège si vous essayez d'aller sur https://www.mybank.example/ et qu'un attaquant tente de vous détourner. Mais il ne peut rien faire si, suite à un spam, vous visitez
  • Les failles de sécurité dans le navigateur : HSTS ne protège que si le navigateur est fiable.

Maintenant, place à la solution. L'effet de l'épinglage HSTS sera double :

  • Le client HTTP remplacera tous les URL http://... par des https://... avant de se connecter.
  • Toute erreur de validation sera fatale, sans rémission possible.

Bref, avant de déclarer en HSTS qu'on ne doit être contacté que de manière sécurisée, il faut être sûr de soi...

La section 5 du RFC expose la solution. Comme indiqué plus haut, un serveur HTTPS qui veut être sûr de n'être accédé qu'en HTTPS le déclare en envoyant un en-tête Strict-Transport-Security: (en-tête désormais dans le registre des en-têtes). Évidemment, cet en-tête ne sera utilisé que si la session était sécurisée avec HTTPS (envoyé sur de l'HTTP ordinaire, il sera ignoré). La politique HSTS du site comprend une durée de vie maximale de l'information, et le choix d'inclure ou pas les sous-domaines. Pour la durée de vie, cela se fait avec une valeur max-age en secondes. Le navigateur pourra se souvenir, pendant ce temps, que le site ne doit être accédé qu'en HTTPS. Après, il pourra redemander (cela permet éventuellement de ne plus avoir HSTS, si l'on veut se remettre à autoriser HTTP). Pour les sous-domaines, c'est fait avec une directive includeSubDomains.

La section 6 va davantage dans les détails en couvrant la syntaxe exacte de cet en-tête. Par exemple, un max-age de zéro spécifie que le client HTTP doit tout de suite oublier les choix HSTS : cela revient à dire « j'arrête d'exiger HTTPS ».

Plusieurs sites Web aujourd'hui utilisent déjà HSTS. Par exemple, Gmail annonce une politique d'une durée d'un mois  :

Strict-Transport-Security: max-age=2592000; includeSubDomains

Et l'EFF (qui n'utilise pas l'option includeSubDomains mais a presque la même durée de vie) :

Strict-Transport-Security: max-age=2628000

On l'a vu, la syntaxe est simple. Les sections suivantes portent sur une question plus complexe, le comportement des logiciels lorsqu'ils rencontrent cette option. D'abord, le serveur (section 7). S'il veut utiliser HSTS, il met cette option dans la réponse, si elle est protégée par TLS. Sinon (HTTP ordinaire), le serveur ne doit pas mettre l'en-tête HSTS et le RFC recommande une redirection (code HTTP 301, par exemple) vers un URL https://. Notons que c'est risqué : un attaquant actif peut aussi faire des redirections, si la requête était en HTTP. Voir l'excellente « Transport Layer Protection Cheat Sheet » de Coates, M., Wichers, d., Boberski, M., et T. Reguly.

Et le client HTTP (typiquement un navigateur Web) ? La section 8 lui donne des instructions : si on reçoit l'en-tête HSTS sur une session HTTP ordinaire, l'ignorer (cela peut être une blague, puisque la session n'est pas authentifiée), si on le reçoit sur HTTPS, enregistrer cette information (avec la durée de vie associée). Puis, à la prochaine visite de ce serveur (les règles exactes sont un peu plus compliquées, avec les sous-domaines, et les IDN) :

  • Ne se connecter qu'en HTTPS (si le navigateur reçoit, par frappe de l'utilisateur, ou dans une page HTML, un URL http://..., le réécrire automatiquement en https://...).
  • N'accepter aucune erreur d'authentification (pas de dialogue « voulez-vous quand même continuer même si le certificat X.509 est pourri ? »). Si un serveur met cet en-tête, c'est que son administrateur sait ce qu'il fait et qu'il s'engage à gérer son serveur correctement (pas de certificat expiré, par exemple, cf. l'exemple à la fin).

À noter que l'en-tête HSTS doit être envoyé via le protocole réseau, pas via le contenu du document : le truc HTML <meta http-equiv="Strict-Transport-Security" ...> est explicitement interdit.

Les sections 11 et 12 donnent des avis aux programmeurs sur la bonne façon de mettre en œuvre ce système de sécurité. D'abord, les serveurs (section 11). Le RFC leur rappelle que le serveur ne peut pas savoir si son client respecte l'en-tête qu'on lui envoie. On ne peut donc pas compter uniquement sur HSTS pour traiter les menaces décrites en section 2.

Ensuite, le choix de la durée de vie (via l'attribut max-age). Il y a deux approches : une durée constante ou bien un max-age calculé à chaque fois pour correspondre à une date d'expiration choisie. La première est évidemment plus facile à mettre en œuvre (sur Apache, un Header set Strict-Transport-Security "max-age=604800" dans la configuration ou bien dans un .htaccess suffit). La seconde nécessite un calcul dynamique mais a l'avantage de pouvoir faire correspondre la date d'expiration de HSTS avec une autre date importante (le RFC suggère celle d'expiration du certificat X.509 ; si on ne renouvelle pas le certificat, c'est une bonne chose si HSTS cesse également).

Le RFC met aussi en garde contre les certificats auto-signés ou bien signés par une AC non connue de certains navigateurs (comme CAcert). HSTS interdisant formellement de passer outre un problème X.509 (pas de formulaire « voulez-vous continuer bien que je ne connaisse pas cette AC ? »), si on active HSTS en envoyant l'en-tête Strict-Transport-Security:, et qu'il est accepté, on risque, si on change ensuite de certificat, d'être injoignable par tous les clients (cas où on est passé à un certificat auto-signé) ou par une partie d'entre eux (cas où est est passé à une AC peu connue). Rappelez-vous que HSTS est une déclaration « je suis un parano expert en crypto et je ne ferai jamais d'erreur, n'utilisez que HTTPS ». Réflechissez donc bien avant de l'activer.

Autre piège pour l'administrateur d'un serveur HTTPS, le cas du includeSubDomains. Si on l'utilise, on peut bloquer tout sous-domaine qui ne serait pas accessible en HTTPS. Si vous gérez le domaine d'une grande entreprise, mettons, et que vous mettez un Strict-Transport-Security: max-age=15768000 ; includeSubDomains, alors le petit site Web que vous aviez oublié,, qui n'était accessible qu'en HTTP, deviendra inutilisable pour tous ceux qui utilisent HSTS. Soyez donc sûr de vos sous-domaines avant d'activer cette option. (Le RFC cite l'exemple d'une AC ca.example qui veut permettre l'accès à OCSP en HTTP ordinaire : la directive includeSubDomains pourrait bloquer D'un autre côté, sans cette option, vous n'êtes plus sûr de protéger les cookies (cf. section 14.4) puisque ceux-ci peuvent être envoyés à tout serveur d'un sous-domaine. (Avec secure, ce sera forcément en HTTPS mais pas forcément blindé par HSTS.)

Et pour les auteurs de navigateurs Web ? La section 12 leur dispense de sages conseils. D'abord, elle leur rappelle un principe central de HSTS : pas de recours pour les utilisateurs. Si un site est étiqueté en HSTS et qu'il y a un problème d'authentification, il est interdit de permettre aux utilisateurs de passer outre. HSTS est là pour la sécurité, pas pour faciliter la vie des utilisateurs. Le but est d'éviter qu'une attaque de l'Homme du Milieu soit possible parce que l'utilisateur est trop prêt à prendre des risques.

Une suggestion intéressante pour les auteurs de navigateurs est celle de livrer le logiciel avec une liste pré-définie de sites HSTS (grandes banques, etc), comme ils ont aujourd'hui une liste pré-définie d'AC. Cela permettrait de fermer une des faiblesses de HSTS, le fait que la première connexion, si elle n'est pas faite en HTTPS (et sans erreur), n'est pas sécurisée. Après, on peut imaginer que cette liste soit éditable (possibilité d'ajouter ou de retirer des sites) mais permettre de retirer un site est dangereux : un utilisateur inconscient risquerait de virer un site important et de se retrouver ainsi vulnérable. En tout cas, le RFC dit que cette possibilité de retirer un site ne doit pas être accessible à JavaScript, pour éviter qu'un logiciel malveillant dans une page Web ne s'attaque à la sécurité de HSTS.

Tout ce RFC est évidemment consacré à la sécurité mais la traditionnelle section Security considerations (section 14) est néanmoins utile pour évaluer les risques restants. Ainsi, HSTS ne protège pas contre les attaques par déni de service. Il peut même les faciliter : par exemple, un attaquant actif peut envoyer le trafic HTTPS vers un serveur qu'il contrôle et, si l'utilisateur accepte le certificat invalide, le serveur pourra alors mettre un Strict-Transport-Security: non prévu et qui empêchera l'accès au serveur légitime dans certains cas. Autre possibilité, si le navigateur permet à l'utilisateur ou, pire, à du code JavaScript, d'ajouter un site à la liste locale des sites HSTS, les sites pas accessibles en HTTPS deviendront inutilisables.

Autre problème que HSTS ne résout pas complètement : la première connexion. Si, sur une nouvelle machine (dont la mémoire HSTS est vide), vous vous connectez à, HSTS ne vous protège pas encore. Si aucun attaquant n'était là pendant la première connexion, vous serez redirigé vers, l'en-tête Strict-Transport-Security: définira ce site comme HSTS et tout sera protégé par la suite. Mais, si un attaquant était présent au moment de cette première connexion, HSTS ne pourra rien faire. C'est un des cas où la liste pré-définie de sites HSTS, livrée avec le navigateur, est utile.

Dernier piège, plus rigolo, un attaquant peut découvrir (par une combinaison de noms de domaines qu'il contrôle et d'un script tournant sur le navigateur) si le navigateur a déjà visité tel site HSTS (car, dans ce cas, les liens vers un URL http://... seront automatiquement réécrits en https://...). Cela permet une forme de flicage du navigateur (voir la synthèse « Web Tracking » de N. Schmucker.)

Deux annexes du RFC intéresseront les concepteurs de protocoles. L'annexe A documente les raisons des choix effectués par HSTS. Par exemple, la politique HSTS est indiquée par un en-tête et pas par un cookie car les cookies peuvent être manipulés et modifiés quand ils sont dans la mémoire du navigateur. Autre cas qui a suscité des discussions, le fait que le client HTTPS fasse confiance à la dernière information reçue via Strict-Transport-Security:. Par exemple, si un serveur annonce un max-age d'un an le 18 novembre 2012, puis d'un mois le 19 novembre 2012, l'information expirera-t-elle le 18 novembre 2013 ou bien le 19 décembre 2012 ? Avec HSTS, c'est le dernier en-tête qui gagne, donc l'expiration sera le 19 décembre 2012. C'est peut-être une faiblesse, question sécurité, mais cela permet aux gérants des sites Web de corriger leurs erreurs (comme un max-age excessif).

À propos du max-age, la même annexe explique aussi pourquoi il indique une durée et pas une date d'expiration : c'est pour éviter d'être dépendant de la synchronisation des horloges. Le RFC donne une autre raison, le fait d'être ainsi dispensé de la définition et de l'implémentation d'une syntaxe pour représenter les dates. Cela ne me semble pas convaincant : il existe déjà une syntaxe normalisée et largement implémentée, celle du RFC 3339. Mais, bon , la sécurité préfère des normes simples, X.509 est un parfait exemple des résultats auxquels mènent des normes compliquées.

Quant à l'annexe B, elle explique les différences entre HSTS et la SOP (Same-Origin Policy) du RFC 6454.

Ce RFC normalise une technique déjà largement déployée. Plusieurs sites Web envoient déjà cet en-tête et plusieurs navigateurs le reconnaissent (on trouve deux bonnes listes sur le Wikipédia anglophone).

À noter qu'il y eu des projets plus ou moins avancés de mettre cette déclaration « TLS seulement » dans le DNS (évidemment avec DNSSEC) plutôt que dans HTTP. Cela aurait permis de fermer la faille de la première connexion, et de gérer le cas des autres protocoles sécurisés avec TLS. Deux exemples de cette voie (tous les deux n'ayant pas été poursuivis) : l'Internet-Draft draft-hoffman-server-has-tls et un article de George Ou.

J'ai testé HSTS avec un Chromium « Version 20.0.1132.47 Ubuntu 12.04 (144678) » et tcpdump qui écoute. Tout marche bien. L'en-tête HSTS est ignoré si le certificat n'a pas pu être validé (AC inconnue). Une fois le certificat validé (AC ajoutée au magasin du navigateur), dès que l'en-tête HSTS a été reçu, plus aucune tentative n'est faite en HTTP, le navigateur file sur le port 443 directement.

Quant à Firefox, voici ce qu'il affiche quand un site qui avait auparavant été accessible en HTTPS authentifié ne l'est plus (ici, parce que le certificat a expiré) : firefox-hsts.png

HSTS est également mis en œuvre dans wget (voir la documentation) et c'est activé par défaut.

Merci à Florian Maury pour sa relecture attentive. Un autre article sur HSTS est celui de Cloudflare.

Téléchargez le RFC 6797

L'article seul

Informations médicales sur le Web : s'y fier ?

Première rédaction de cet article le 18 novembre 2012

Le World Wide Web a permis la mise à disposition, pour beaucoup de gens, d'une quantité formidable d'informations, beaucoup n'étant accessible autrefois qu'à une petite minorité. C'est par exemple le cas des informations médicales. Mais peut-on se fier à ce qu'on trouve sur le Web ?

Bien sûr, les gens qui connaissent le Web savent déjà la réponse : « c'est comme les sources d'information traditionnelles (experts ou papier) : ça dépend ». Mais il y a des gens qui ne connaissent pas le Web et qui racontent n'importe quoi à ce sujet. On voit dans le film « La guerre est déclarée » les deux parents discuter, après avoir appris que leur enfant souffre d'une grave maladie, de la stratégie à adopter. Ils s'engagent à ne jamais chercher d'information sur l'Internet, et à se fier exclusivement aux médecins. Bonne idée ou pas ? Cela dépend.

Plus embêtant, un article « Attention Dr Google n'existe pas ! » dans « La revue des parents », magazine de la FCPE (numéro d'octobre 2012). D'abord, parce que le titre confond le Web avec un moteur de recherche particulier, celui de Google. Cela indique bien que l'auteure de l'article n'a pas les idées très claires sur le Web (sur les défauts des moteurs de recherche, cf. mon exposé ). Mais surtout embêtant car l'article défend un point de vue très réactionnaire : seuls les experts savent, il ne faut se fier à personne d'autre. Et de citer abondamment... un représentant de l'Ordre des médecins, institution créée par Vichy et dont la ligne politique est plutôt à l'opposé de celle de la FCPE. Mais, dès qu'il s'agit d'Internet, les autorités traditionnelles font bloc et organisent la résistance commune. Les intermédiaires voient leur exclusivité d'accès à l'information remise en cause et, au lieu de chercher une nouvelle façon de pratiquer leur métier, préfèrent jeter le bébé avec l'eau du bain et décréter qu'Internet, le Web et Google (notions qu'ils confondent en général complètement) sont le Mal (ce syndrome frappe beaucoup les journalistes, par exemple).

L'article note pourtant, à juste titre, que si les patients consultent le Web, c'est tout simplement qu'ils ne sont pas satisfaits de leur médecin ! Absence de réponses aux questions, consultations expédiées en vitesse, difficultés à avoir un rendez-vous, impossibilité de dialoguer avec un médecin en dehors du rendez-vous physique (mes félicitations au passage à la pédiatre de mes enfants, qui a toujours été disponible au téléphone pour les parents inquiets). Malgré quelques exceptions, c'est cela, le vécu des patients. Et le Web, lui, est toujours disponible. Avant de taper sur Google, les médecins (et les journalistes) devraient d'abord s'interroger sur leur propre pratique.

Autre erreur courante dans l'article de « La revue des parents », celle de prêter à des entités abstraites des pensées et des intentions. « Il ne faut pas croire tout ce que disent les sites », affirme bien haut le représentant de l'Ordre. Mais « les sites » ne disent rien, ce sont des humains qui écrivent les textes. Le Web ne met pas en communication des lecteurs avec des « sites » mais des humains avec d'autres humains. Ceux qui écrivent les textes qu'on peut lire sur le Web sont, comme tous les humains, capables de se tromper, de mentir... ou de donner gratuitement de l'information correcte et bien expliquée.

Plus drôle, l'accusation comme quoi l'information trouvée sur « les sites » serait douteuse car certains sites Web sont financés par la publicité qui peut les influencer. Comme si les médecins, eux, tiraient leurs informations uniquement de leur pratique et de leurs collègues, et pas des visiteurs médicaux et des brochures des laboratoires pharmaceutiques ! (Ce numéro de « La revue des parents » a, en dernière page, une publicité pour des substances bénéfiques, maigrir, « purifier l'organisme », retrouver son tonus, substances « conseillées par des experts de haut niveau ».) Cette mésinformation des médecins par la publicité est un des chevaux de bataille de la revue Prescrire.

Autre erreur fondamentale commises par ces représentants de l'autorité qui expliquent que le Web est dangereux : tout mettre dans le même panier. Il existe des tas de sites différents. Doctissimo, ce n'est pas la même chose que le blog d'un médecin et ce n'est pas la même chose qu'un site Web d'un illuminé qui vend des poudres comme dans la publicité citée ci-dessus. Au fait, il existe un effort pour labeliser les sites Web qui donnent de l'information sérieuse en médecine, le label HON que vous verrez souvent sur les sites médicaux. (Il est bien sûr contesté.)

C'est pourtant le même représentant de l'Ordre qui donne une bonne piste d'amélioration des choses : « Nous encourageons les médecins à créer leur propre blog avec des liens sûrs scientifiquement [...] pour guider les patients ». Excellente démarche (qu'il ne suit pas complètement : en tout cas Google ne trouve pas de blog à son nom - mais il est sur Twitter) : si on n'est pas satisfait de ce qui existe sur le Web (et on trouve en effet plein d'énormités), il faut diffuser de la bonne information, et pas se replier dans sa tour d'ivoire. Soyons positifs, terminons sur un bon exemple, le site de Martin Winckler.

Merci à Fil, Victoria Bohler, Julien Moragny et André Sintzoff pour leurs utiles remarques et corrections (naturellement, le ton, les idées et le choix des mots et des opinions sont de moi, pas d'eux).

L'article seul

Utiliser l'Autorité de Certification CAcert

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

Comme vous le savez peut-être déjà, les sites Web auxquels on accède avec un URL commençant par https sont sécurisés avec le protocole TLS (décrit dans le RFC 6347). Pour s'assurer de l'authenticité du site, avant de commencer le chiffrement de la session, TLS se repose sur des certificats, qui sont simplement une la partie publique d'une clé cryptographique plus la signature d'un organisme auquel on doit faire confiance. Dans le format de certificats le plus répandu, X.509, cet organisme se nomme une Autorité de Certification. Elles sont typiquement chères et n'apportent pas forcément une sécurité géniale (les forces du marché tirent les procédures de vérification vers le bas...) Une alternative est donc d'employer une Autorité de Certification gratuite, fonctionnant de manière simple et totalement automatisée, CAcert.

Écartons tout de suite un faux débat : est-ce que CAcert est une « vraie » Autorité de Certification (AC), une « officielle » ? C'est un faux débat car il n'existe pas d'AC officielle : chaque éditeur de logiciels (par exemple Microsoft pour Internet Explorer et Mozilla pour Firefox) décide selon ses propres critères de quels AC sont mises ou pas dans son magasin d'AC (et ce ne sont pas forcément les mêmes). Donc, CAcert, comme toute AC, est reconnue par les gens qui lui font confiance, point. (En France, l'ANSSI publie une liste des AC « qualifiées » mais cette liste n'a rien à voir avec ce qui se trouve dans les navigateurs, la seule chose importante pour les utilisateurs.)

Mais est-ce que CAcert fournit le même niveau de sécurité que les grosses AC commerciales comme VeriSign (l'activité d'AC sous ce nom appartient désormais à Symantec) ou Comodo ? D'abord, ces AC ne sont pas forcément parfaites comme l'ont montré le piratage de Comodo ou l'Opération Tulipe Noire contre DigiNotar. Ensuite, tout dépend des menaces envisagées. S'il s'agit simplement de protéger la page d'administration du blog de votre association, payer Symantec ou Comodo est franchement exagéré.

Par contre, comme CAcert n'est pas inclus par défaut dans les magasins de tous les navigateurs, vos visiteurs utilisant HTTPS recevront peut-être le fameux avertissement comme quoi le site n'est pas authentifié par une autorité reconnue (l'intéressante étude « Crying wolf » étudie cette question des avertissements de sécurité TLS.) En pratique, le moyen le plus simple est alors d'ajouter CAcert à son navigateur. C'est simple mais, évidemment, si vous gérez un site avec beaucoup de visiteurs pas du tout informaticiens, cela peut devenir très gênant. Si vous avez un public limité, ou bien si celui-ci est plutôt geek (ceux-ci auront souvent déjà installé CAcert), c'est moins grave.

Dans votre cas, testez en allant en S'il n'y a aucun avertissement de sécurité et que vous voyez le fameux cadenas, c'est bon, CAcert est connu de votre navigateur. Sinon, si vous n'avez pas encore mis CAcert dans les AC reconnues, rendez-vous en (je n'ai pas mis https puisque, à ce stade, vous ne connaissez pas l'AC CAcert). Du point de vue sécurité, il y a à ce moment un problème de bootstrap : pour authentifier le site de CAcert vous avez besoin du certificat... qui se trouve sur ce site. Si vous êtes prudent, vous allez valider le certificat de l'AC CAcert avant de l'installer, par exemple en vérifiant son empreinte (13:5C:EC:36:F4:9C:B8:E9:3B:1A:B2:70:CD:80:88:46:76:CE:8F:33 en SHA-1) auprès d'un ami qui l'a déjà installé. Par exemple, avec OpenSSL, si vous avez téléchargé le certificat en root.crt :

% openssl x509 -fingerprint -in root.crt 
SHA1 Fingerprint=13:5C:EC:36:F4:9C:B8:E9:3B:1A:B2:70:CD:80:88:46:76:CE:8F:33

Ensuite, installer le certificat de l'AC nécessite simplement de suivre le lien « Root Certificate (PEM Format) ». À partir de là, les certificats émis par CAcert seront acceptés par votre navigateur. Si la pensée que CAcert pourrait devenir méchant et émettre un vrai-faux certificat pour le site Web de votre banque, rassurez-vous en pensant que n'importe laquelle des centaines d'AC installées par défaut dans votre navigateur (regardez par exemple tout ce qu'il y a par défaut, de CNNIC à TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı) peut en faire autant.

C'est bon ? Vous pouvez visiter sans avertissement de sécurité ? Parfait, maintenant, allons demander à CAcert des certificats.

Comment fonctionne CAcert ? On se rend sur le site Web et on crée un compte, comme sur tant d'autres sites Web. On choisit évidemment un mot de passe sérieux. Puis on se connecte. Commençons par l'option Domains. Normalement, votre liste de domaines est vide à ce stade. CAcert a besoin de connaître les domaines que vous gérez, pour signer ensuite des certificats. Choisissez Add pour ajouter un domaine. Vous pouvez indiquer n'importe lequel ? Non, heureusement pas. CAcert vérifie que vous êtes bien un administrateur du domaine en envoyant un secret qu'il a choisi à une des adresses de courrier du domaine. Pour cela, il analyse le résultat de whois et il se sert aussi des adresses normalisées dans le RFC 2142. Pour le domaine, cela donne :

Please choose an authority email address

La première adresse venant de whois et les suivantes du RFC 2142. Les fanas de sécurité noteront deux choses : l'utilisateur de CAcert choisit quelle adresse servira, donc c'est la sécurité de l'adresse la moins protégée qui détermine la sécurité de l'ensemble. Et, deuxième point, la sécurité de CAcert dépend de celle du courrier, et des protocoles qu'il utilise, comme le DNS (CAcert n'exige pas, aujourd'hui, que les noms de domaines dans les adresses de courrier soient protégés par DNSSEC). Notez que pas mal d'AC commerciales ne font pas mieux, question vérifications !

Vous allez ensuite recevoir dans votre boîte aux lettres un message vous demandant de visiter une page Web dont l'URL est secret, pour confirmer que vous avez bien reçu le message (et que vous êtes donc bien administrateur du domaine) :

Subject: [] Email Probe
X-Mailer: Website

Below is the link you need to open to verify your domain ''. Once your
address is verified you will be able to start issuing certificates to your heart's

(Le lien est à usage unique et je n'ai donc pas de crainte à le donner ici.)

Une fois la visite faite, le nom de domaine est associé à votre compte et vous le voyez dans la liste du menu Domains. Vous pouvez alors demander la signature de certificats. En effet, CAcert ne fait pas le certificat pour vous (car, alors, il connaîtrait la partie privée de la clé ). Vous devez créer un certificat, le transmettre à CAcert, qui le signe. Avec les outils d'OpenSSL, cela se passe ainsi :

[On fabrique le CSR, Certificat Signing Request]
% openssl req -new -nodes -newkey rsa:2048 -keyout server.key -out server.csr -days 1000
Common Name (eg, YOUR name) []:

Le -newkey qui demande une clé RSA de 2 048 bits est obligatoire. CAcert n'accepte plus les clés de 1 024 bits, trop vulnérables. Notez que la durée de validité demandée, ici mille jours, n'a aucune importance, CAcert mettra sa propre durée, six mois. Ensuite, on copie/colle le CSR (fichier d'extension .csr) dans le formulaire sur le site de CAcert. Ce dernier affiche, pour vérification, les informations du certificat qu'il incluera dans le certificat final. Les informations exclues sont celles que CAcert ne peut vérifier (donc, presque tout sauf le nom de domaine.) Le message est « No additional information will be included on certificates because it can not be automatically checked by the system. ». CAcert fournit alors un certificat qu'on copie/colle dans un fichier d'extension .crt. On peut le vérifier avec son OpenSSL local :

% openssl x509 -text -in server.crt
        Version: 3 (0x2)
        Serial Number: 818193 (0xc7c11)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: O=Root CA, OU=, CN=CA Cert Signing Authority/
            Not Before: Nov 13 20:55:41 2012 GMT
            Not After : May 12 20:55:41 2013 GMT

Naturellement, on n'est pas obligé d'utiliser openssl directement, on peut aussi se servir d'un script plus accessible comme CSRGenerator.

Et voilà, on a un beau certificat qui marche, il n'y a plus qu'à le copier là où l'attend le serveur HTTP, Apache, Nginx ou un autre.

CAcert est capable de reconnaître pas mal d'extensions de X.509 comme les subjectAltName, si pratiques lorsqu'il s'agit de mettre plusieurs sites Web derrière une seule adresse IP. Il prévient alors :

Please make sure the following details are correct before proceeding any further.

No additional information will be included on certificates because it can not be automatically checked by the system.

The following hostnames were rejected because the system couldn't link them to your account, if they are valid please verify the domains against your account.

Le nom rejeté, à la fin, est parce que le compte CAcert utilisé avait vérifié le domaine mais pas le domaine

Voilà, vous pouvez maintenant vous détendre en sécurité, grâce à vos nouveaux certificats. CAcert vous préviendra lorsqu'ils seront proches de l'expiration et qu'il faudra les renouveler (naturellement, si vous êtes prudent, vous superviserez cela vous-même.)

Notez que CAcert propose d'autres services, par exemple des certificats plus vérifiés, en utilisant la communauté. Une alternative souvent citée pour avoir des certificats partiellement gratuits est StartSSL mais je n'ai pas testé.

Merci à John Doe (ah, ah) pour ses remarques et à Florian Maury pour sa relecture et son appréciation que cet article est « de loin, le plus mauvais conseil que j'ai pu lire sur ton blog ». Sur la valeur de CAcert, vous pouvez aussi lire une discussion chez OpenBSD et une chez Debian (deux systèmes qui incluent le certificat de CAcert par défaut).

L'article seul

RFC 6743: ICMP Locator Update message for ILNPv6

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012

Le protocole ILNP, décrit dans le RFC 6740, permet de séparer l'identificateur et le localisateur d'une machine. L'identificateur est stable, voire très stable, et identifie une machine, le localisateur est bien plus changeant et identifie un point d'attachement au réseau. Lors d'une communication entre deux machines, si le localisateur change, il faut pouvoir prévenir son correspondant. C'est le rôle des nouveaux messages ICMP Locator Update. Ce RFC 6743 décrit ces messages pour le cas d'IPv6.

Donc, comme déjà expliqué dans les RFC 6740 et RFC 6741, une machine ILNP peut avoir besoin de modifier dynamiquement la liste de ses localisateurs. Par exemple parce qu'elle s'est déplacée. Ou, tout simplement, parce qu'un nouvel attachement au réseau est disponible (nouveau FAI, par exemple).

Cela se fait avec des paquets ICMP envoyés au(x) correspondant(s). Ces paquets ont le type 156 et ne sont utilisés que pour ILNPv6 (ILNP sur IPv6 ; leur équivalent IPv4 est dans le RFC 6745). Le type 156 a été enregistré à l'IANA.

Leur syntaxe est décrite en section 2. Les champs les plus importants :

  • Operation, qui indique si on publie une liste de localisateurs ou bien si on accuse réception d'une liste,
  • Num of Locs, le nombre (> 0) de localisateurs dans le message,
  • Locator(s), qui est une liste de tuples {Locator, Preference, Lifetime}. Locator est un localisateur (64 bits en ILNPv6), Preference un entier qui représente la préférence associée à ce localisateur (plus elle est basse, plus il est préféré, voir aussi le RFC 6742) et Lifetime le nombre de secondes que ce localisateur va être valide (typiquement identique au TTL de l'enregistrement DNS L64, cf. RFC 6742).

Lorsqu'une liste de localisateurs change pour un nœud (ajout ou retrait d'un localisateur), le nœud envoie ce message à tous ses correspondants (tous les nœuds avec lesquels il est en train de communiquer). Ceux-ci enverront un accusé de réception (même contenu, seul le champ Operation changera). Le RFC ne spécifie pas quoi faire si on ne reçoit pas d'accusé de réception (les messages ICMP peuvent se perdre). C'est volontaire : le manque d'expérience pratique avec ILNP ne permet pas encore de recommander une stratégie de rattrapage particulière (réemettre, comme avec le DNS ?)

Notez que c'est une liste complète de tous les localisateurs qui est envoyée. Elle peut donc être grosse, programmeurs, attention aux débordements de tampon si Num of locs vaut sa valeur maximale, 256.

Le message Locator Update doit être authentifié (section 6) en incluant, pour chaque correspondant, l'option IPv6 Nonce (RFC 6744) avec la valeur en service pour ce correspondant. Les messages seront ignorés si le numnique (valeur choisie de manière à être imprévisible par l'attaquant) est incorrect. (Dans les environnements où on souhaite encore plus de sécurité, on peut ajouter IPsec.)

Et comment se passera la cohabitation avec les machines IPv6 classiques ? La section 5 traite ce cas. Comme le type ICMP 156 est inconnu des machines IPv6 classiques, elles ignoreront ces messages Locator Update (RFC 4443, section 2.4).

Téléchargez le RFC 6743

L'article seul

RFC 6744: IPv6 Nonce Destination Option for ILNPv6

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012

Une grande partie de la sécurité d'ILNP, architecture de séparation de l'identificateur et du localisateur, dépend d'un numnique, nombre imprévisible choisi par une machine et transmis à son correspondant au début d'une session. En renvoyant ce nombre, le pair prouve qu'il est bien le même correspondant. Ce RFC décrit les détails de l'option IPv6 Nonce (numnique), utilisée pour ILNP sur IPv6.

ILNP est décrit dans le RFC 6740, avec certains détails pratiques dans le RFC 6741. Comme tous les systèmes à séparation de l'identificateur et du localisateur, son talon d'Achille est le lien (binding) entre l'identificateur d'une machine et son localisateur. Si on reçoit un paquet disant « pour joindre la machine d'identificateur 3a59:f9ff:fe7d:b647, envoie désormais les paquets au localisateur 2001:db8:43a:c19 », faut-il le croire ? Évidemment, non, pas sur l'Internet public en tout cas. La solution adoptée par ILNP est d'avoir un numnique. C'est un nombre généré de manière imprévisible par un tiers (idéalement, ce devrait être un nombre aléatoire), que chaque machine envoie au début de la session ILNP. Lorsqu'un correspondant veut s'authentifier (par exemple lorsqu'il envoie le message de changement de localisateur cité plus haut, cf. RFC 6743), il inclura ce numnique.

Ce numnique sera transporté, aussi bien pour le début de la session que pour les mises à jour de localisateur, dans une option Destination IPv6 (ces options sont décrites dans le RFC 2460, section 4.6). Cette option sert donc à la sécurité d'ILNP. Mais elle a aussi une autre fonction, signaler, lors du débat d'une conversation, qu'on connait ILNP et que le correspondant peut l'utiliser (la coexistence pacifique d'ILNPv6 et d'IPv6 Classic en dépend). Elle ne doit donc apparaître que dans les paquets ILNP.

L'en-tête « options pour la Destination » peut contenir plusieurs options (en pratique, à l'heure actuelle, comme le note notre RFC, il n'est quasiment jamais utilisé), mais il ne doit y avoir qu'une seule option Nonce. Si d'autres options sont quand même présentes (comme celle du RFC 5570), le RFC recommande que Nonce soit la première dans l'en-tête.

La section 2 décrit la syntaxe de cette option. Elle comporte les champs obligatoires, Option Type (0x8b dans le registre IANA), Option length (en octets ; le numnique n'a pas de longueur fixe mais au moins les valeurs de 4 et 12 octets doivent être acceptées par les mises en œuvre de ce RFC) et Nonce (la valeur du numnique, de préférence générée selon les bons principes du RFC 4086).

En l'absence de l'option Nonce dans un paquet entrant, ILNP jettera le paquet si le localisateur source n'est pas dans la liste actuellement connue et stockée dans l'ILCC (Identifier-Locator Communication Cache, cf. RFC 6741). Lorsqu'une machine ILNP change sa liste de localisateurs (section 4), elle envoie un paquet avec la nouvelle liste et ce paquet doit inclure l'option Nonce (avec un numnique correct) pour être accepté. Le RFC recommande également d'inclure cette option dans les paquets suivants, pour une durée d'au moins trois RTT, afin de se prémunir contre un éventuel réordonnancement des paquets. (Notez que cela ne règle que le cas d'un retard du Locator Update, pas le cas de sa perte. Recevoir le paquet avec le numnique correct ne suffit pas à changer les localisateurs mémorisés, ne serait que parce que ce paquet ne contient qu'un seul localisateur et pas la liste actuelle.)

Si vous êtes en train de programmer une mise en œuvre d'ILNP, lisez aussi la section 5, qui donne d'utiles conseils, notamment sur l'ILCC (qui garde en mémoire le numnique actuel de la session, c'est une des informations les plus importantes qu'il stocke).

L'Internet à l'heure actuelle ne contient que des machines IP Classic. Comment cela va t-il se passer pour les premières machines ILNP ? La section 6 décrit la compatibilité. L'option Nonce sert à deux choses, indiquer le numnique, bien sûr, mais aussi signaler qu'ILNP est utilisé. Cette nouvelle option ne doit donc pas être présente dans des paquets IP Classic. Dans les paquets ILNP, elle doit être présente dans les premiers paquets (pour signaler qu'on connait ILNP) et dans tous les messages ICMP générés par les machines ILNP (comme le Locator Update du RFC 6743). Elle peut aussi être mise dans tous les paquets mais ce n'est pas indispensable. Le RFC recommande quand même de le faire si le taux de pertes de paquets de la session est particulièrement élevé (car les paquets portant l'option pourraient être perdus).

Donc, la machine recevant le premier paquet ILNP sait que son correspondent connait ILNP grâce à l'option Nonce. Et la machine qui émet le premier paquet ? Comment sait-elle que le pair connait ILNP ? La principale méthode est, comme toujours dans ILNP, via le DNS. Comme décrit en détail dans le RFC 6742, la présence d'enregistrements NID dans le DNS indique que la machine distante connait ILNP. Et si l'information dans le DNS est fausse ou dépassée ? Dans ce cas, vu le type de l'option Nonce (avec les deux bits de plus fort poids à 10, ce qui indique que le paquet doit être rejeté si cette option n'est pas comprise, RFC 2460, section 4.2). L'émetteur, en recevant le message ICMP de rejet (Parameter Problem), saura qu'il ne faut plus essayer en ILNP.

Dans un monde idéal, cela s'arrêterait là. Mais les options de destination comme celle décrite ici sont rares dans l'Internet actuel et il serait bien imprudent de promettre que celle d'ILNP passera sans problème. Comme l'a montré l'expérience d'IPv4, ce qui n'est pas utilisé finit par ne plus être géré correctement, notamment par les équipements intermédiaires. Le RFC ne mentionne pas ce problème mais évoque un problème proche, se contentant de dire que les routeurs IPv6 correctement programmés devraient ignorer tout l'en-tête Destination Options (dans un monde idéal, là encore).

La section 7 revient sur les exigences de sécurité. Le numnique ne doit pas être prévisible par un attaquant extérieur, il est donc recommandé qu'il soit généré selon les règles du RFC 4086. Notez bien que cela ne sert à rien si l'attaquant est situé sur le chemin des paquets et peut les sniffer. C'est également le cas en IP Classic et le seul mécanisme vraiment sûr dans ce cas est IPsec, si on veut protéger jusqu'à la couche 3.

Si vous aimez regarder les paquets qui passent sur le réseau avec wireshark ou tcpdump, désolé, mais ces logiciels ne gèrent pas encore les options spécifiques à ILNP et ne les analyseront pas.

Téléchargez le RFC 6744

L'article seul

RFC 6740: ILNP Architectural Description

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012

Le protocole ILNP vient d'être spécifié dans une série de neuf RFC, dont ce RFC 6740 est le point de départ, décrivant l'architecture générale d'ILNP. ILNP appartient à la famille des protocoles à séparation de l'identificateur et du localisateur. Ces protocoles visent à résoudre une limite fondamentale de l'Internet : l'adresse IP est utilisée à la fois comme identificateur (nommer une machine, par exemple pendant la durée d'une session TCP) et comme localisateur (indiquer son point d'attachement au réseau). Cette confusion rend certaines configurations, notamment le multi-homing et la mobilité, très difficiles.

Ce n'est pas qu'ILNP soit le premier protocole à vouloir séparer ces deux fonctions. Avant de donner le feu vert à la publication de ces RFC, l'IESG a notamment examiné HIP et LISP, avant de conclure qu'ILNP avait des caractéristiques suffisamment originales pour qu'il soit intéressant qu'il soit décrit dans des RFC.

ILNP avait été choisi par les présidents du groupe de recherche Routage de l'IRTF comme étant la base des futurs travaux sur une meilleure architecture pour l'Internet (travaux décrits dans le RFC 6115). S'il faut le résumer en cinq points :

  • ILNP est défini comme une architecture abstraite, avec plusieurs concrétisations possibles. Celle décrite dans ces RFC est compatible avec l'Internet actuel (une autre, plus « table rase », serait possible).
  • ILNP fonctionne entièrement dans les machines terminales, les routeurs ne sont pas changés.
  • Chaque machine ILNP a au moins un Identificateur et au moins un Localisateur. En IPv6, ils sont indiqués dans chaque paquet (ILNP peut aussi tourner au-dessus d'IPv4 mais c'est plus complexe.)
  • Pour trouver le Localisateur d'une machine qu'on veut contacter, la méthode standard est d'utiliser le DNS (ILNP repose nettement plus sur le DNS que ses concurrents).
  • Les changements de localisateur en cours de session sont faits par un nouveau message ICMP, Locator Update. Ces derniers sont sécurisés par un numnique, nombre imprévisible envoyé au début de la session.

Bon, après cette introduction rapide, voyons tout en détail. D'abord, pourquoi veut-on à tout prix séparer identificateur et localisateur ? Le mieux est de relire le RFC 4984 pour avoir tous les détails. Disons que l'actuelle confusion de l'identificateur et du localisateur est pénible pour :

  • La croissance des tables de routage : pour avoir des adresss IP stables, certains réservent du PI et l'annoncent dans la table de routage globale.
  • Le multi-homing : sans adresses PI, pas de moyen facile de gérer les adresses de ses fournisseurs d'accès.
  • La mobilité : changer d'endroit ou de fournisseur casse les connexions TCP en cours.

Face à ces problèmes, des tas de propositions pour améliorer les mécanismes d'adressage et de nommage dans l'Internet ont été faites : RFC 814, RFC 1498, RFC 2101, RFC 2956 et bien d'autres. La conclusion était souvent la même : le mélange de fonctions d'identification d'une machine et de sa localisation dans le réseau est une mauvaise idée. Ces fonctions devraient être séparées.

Il y a un petit problème terminologique ici : les architectures où ces fonctions sont séparées sont parfois toutes appelées « séparation de l'identificateur et du localisateur ». Mais notre RFC adopte un vocabulaire plus strict. Il réserve ce terme de « séparation de l'identificateur et du localisateur » aux architectures (comme ILNP) où la séparation est faite dès le début (dans les machines terminales) et utilise le terme de « map and encapsulate » (qu'on trouve souvent abrégé en map-and-encap) aux architectures qui utilisent un tunnel pour transporter les paquets entre deux machines ne connaissant pas la séparation Identificateur/Localisateur. Selon cette terminologie, LISP, dont le nom veut dire Locator/Identifier Separation Protocol, n'est donc pas un « vrai » système « à séparation de l'identificateur et du localisateur ».

Ce RFC, le premier à lire lorsqu'on veut comprendre ILNP, est d'abord la description d'une architecture. On n'y trouvera pas de protocole, de format des paquets, etc. Les protocoles concrets viennent après, dans d'autres RFC. Deux protocoles qui mettent en œuvre l'architecture ILNP ont été définis, ILNPv4 pour IPv4 et ILNPv6 pour IPv6. Je parlerai surtout d'ILNPv6, qui est plus simple à exposer (le faible espace d'adressage d'IPv4 a nécessité quelques astuces qui rendent ILNPv4 plus difficile à comprendre).

Comme indiqué plus haut, d'autres incarnations de l'architecture ILNP peuvent être imaginées, notamment en choisissant une approche « table rase » qui ferait tourner cette architecture sur un nouveau protocole, sans relation avec IP. Mais, pour l'instant, ces hypothétiques incarnations n'ont pas été définies.

Les autres RFC à lire, une fois celui-ci achevé, sont :

  • RFC 6741, « ILNP Engineering and Implementation Considerations », qui décrit les questions concrètes communes à ILNPv4 et ILNPv6,
  • RFC 6742, « DNS Resource Records for ILNP », qui explique les enregistrements DNS nécessaires pour ILNP,
  • RFC 6743, « ICMPv6 Locator Update message », définit le nouveau message ICMP Locator Update,
  • RFC 6744, « IPv6 Nonce Destination Option for ILNPv6 », normalise la nouvelle option IPv6 permettant d'indiquer le numnique de la connexion,
  • RFC 6745, « ICMPv4 Locator Update message », définit le nouveau message ICMP Locator Update pour IPv4,
  • RFC 6746, « IPv4 Options for ILNP », normalise deux nouvelles options IPv4, une pour indiquer le numnique de la connexion, une pour indiquer l'identificateur (pour IPv6, il tient dans l'adresse et cette option n'est pas nécessaire),
  • RFC 6747, « ARP Extension for ILNPv4 », qui décrit comment adapter le vieux protocole ARP à ILNP,
  • RFC 6748, « Optional Advanced Deployment Scenarios for ILNP », explore des fonctions plus avancées d'ILNP et des perspectives plus lointaines.

Les section 2 et 3 détaillent cette architecture. Parmi les propriétés importantes de l'Identificateur, le fait qu'une machine puisse en avoir plusieurs, par exemple à des fins de protection de la vie privée : avoir le même Identificateur tout le temps permettrait la traque d'une machine à travers ses déplacements, un problème analogue à celui qui a mené au RFC 8981. Une machine peut donc utiliser plusieurs identificateurs (mais, évidemment, pas au sein d'une même session).

Si l'application ne se sert que de noms de domaine pour contacter son pair, elle est dite « bien élevée » et fonctionnera sans problèmes avec ILNP. Ce comportement est celui recommandé par le RFC 1958. Si, par contre, l'application utilise explicitement des adresses IP (le RFC cite les fichiers de configuration d'Apache), elle pourra avoir des ennuis avec ILNP, où ces adresses ont une sémantique différente.

Les connexions des protocoles de transport, comme TCP, utilisent uniquement l'identificateur, résistant ainsi aux changements de localisateurs. Une machine d'un site multi-homé peut ainsi basculer d'un FAI à l'autre sans casser ses connexions TCP (cf. section 3.4).

Notez bien que l'identificateur identifie une machine, pas une interface réseau. Sa sémantique est donc très différente de celle des adresses IPv4, IPv6, ou des Interface Identifier d'IPv6 (RFC 4219).

Cela ne signifie pas que l'identificateur puisse être utilisé directement par les applications clientes. Comme indiqué plus haut, il est plutôt recommandé de se servir du nom de domaine.

Dans cette architecture, qu'est-ce qui est le plus proche d'une adresse IP ? Probablement le couple {Identificateur, Localisateur}, I-LV (pour Identifier - Locator Vector, cf. section 3.3). Ce couple désigne une liaison, notée (I, L), entre un identificateur et un localisateur.

Bref, un paquet ILNP contiendra un I-LV source et un I-LV destination. Notez que la sémantique d'un I-LV est proche de celle d'une adresse IP mais pas identique (l'I-LV se sépare en deux, I et L, l'adresse IP est structurée différemment, avec plusieurs préfixes hiérarchiquement emboîtés, etc). Le RFC 6741 indique comment ces IL-V sont représentés dans un paquet IP.

Dans les fichiers ou entre discussions entre humains, les identificateurs ont le format d'un Interface Identifier IPv6 (section 3.1.2). Ce format, normalisé dans le RFC 4291 est fondé sur le format EUI-64 par exemple 3a59:f9ff:fe7d:b647. Si le bit « global » est mis à 1, l'identificateur est supposé être unique au niveau mondial.

Le localisateur a une syntaxe analogue (par exemple, 2001:db8:43a:c19). Une machine peut aussi avoir plusieurs localisateurs (par exemple parce qu'elle a plusieurs connexions réseau). Le routage sera fait sur la base des localisateurs, comme avec IP Classique aujourd'hui (ce n'est donc pas par hasard que le localisateur ressemble à un préfixe IPv6). Le localisateur peut être modifié en route (cas du NAT). Contrairement à l'identificateur, relativement stable (en tout cas pendant la durée d'une connexion), le localisateur peut changer souvent (par exemple en situation de mobilité). Lorsque cela se produit, la machine avertit ses correspondants (CN pour Correspondent Nodes) avec un message ICMP Locator Update. Si elle veut être contactée (si c'est un serveur), elle doit aussi mettre à jour le DNS. Ces deux mécanismes sont décrits en détail dans le RFC 6741.

Ces identificateurs et localisateurs sont publiés dans le DNS (cf. RFC 6742). Une application qui veut contacter aujourd'hui utilise le DNS pour connaître l'adresse IP correspondante. Demain, elle utilisera ILNP pour connaître identificateur et localisateur. (Pour des raisons de sécurité, DNSSEC est recommandé.)

Il est aussi précisé que l'un des buts d'ILNP est de pouvoir l'incarner dans des protocoles qui sont compatibles avec l'existant (pour permettre à ILNP et IP Classique de coexister) et déployables de manière incrémentale (ne pas exiger que tout le monde passe à ILNP d'un coup).

La section 4 explique ensuite comment se fait le routage. Alice et Bob connaissent ILNP et veulent se parler, avec, entre eux, plusieurs routeurs traditionnels ne connaissant rien à ILNP. (En terminologie ILNP, Bob est le CN - Correspondent Node.) Dans le cas le plus courant, Bob a mis son (ou ses) Identificateurs et son (ou ses) Localisateurs dans le DNS (notez que les serveurs DNS utilisés n'ont pas besoin de connaître ILNP, mais cela optimise le temps de réponse DNS s'ils le gèrent). Cela a pu être fait manuellement ou, mieux, automatiquement via les mises à jour dynamiques (de préférence sécurisées, cf. RFC 3007). Alice va faire une requête DNS (cf. RFC 6742) et récupérer ainsi Identificateur et Localisateur de Bob (notez qu'ILNP n'a pas pour l'instant de mécanisme pour récupérer un Localisateur à partir d'un Identificateur).

Alice et Bob vont avoir besoin dans leurs systèmes d'une nouvelle structure de données, l'ILCC (I-L Communication Cache, section 4.2 et RFC 6741) qui permet de se souvenir des Localisateurs actuellement en service pour un CN donné. Au début, on y met les localisateurs récupérés via le DNS.

Ensuite, en IPv6, tout est simple. Alice fabrique un paquet IPv6, contenant l'option Nonce (numnique) du RFC 6744, et dont la source est la concaténation de son Localisateur et de son Identificateur (avec les valeurs données plus haut à titre d'exemple, ce sera 2001:db8:43a:c19:3a59:f9ff:fe7d:b647). La destination est formée en concaténant Localisateur et Identificateur de Bob. Les deux adresses ainsi fabriquées sont des adresses IPv6 tout à fait normales et les routeurs entre Alice et Bob suivent la méthode de routage, et de résolution d'adresses en local (NDP) traditionnelles.

En IPv4, cela sera toutefois plus complexe (on ne peut pas mettre Identificateur et Localisateur dans les 32 bits d'une adresse IPv4, et ARP ne permet pas de résoudre un Identificateur, trop gros pour lui). Voir les RFC 6746 et RFC 6747 pour les solutions adoptées.

Comment est-ce que cela résout le problème du multi-homing, déjà cité plusieurs fois ? Comme l'explique la section 5, ILNP traite le Muti-homing en fournissant un Identificateur par machine et au moins un Localisateur par FAI. Alice utilise un des localisateurs pour le paquet initial, puis prévient Bob par un message ICMP Locator Update pour annoncer les autres. En cas de panne ou de ralentissement d'un des FAI, Bob pourra envoyer ses paquets via les autres localisateurs (l'identificateur restant inchangé).

Pour les connexions entrantes (si Alice est un serveur Web), on publiera dans le DNS tous les localisateurs et le client les essaiera tous.

Multi-homing est en fait un terme très large. Il y a plusieurs cas :

  • Host multi-homing où une machine a plusieurs connexions à l'Internet. C'est relativement rare mais cela peut être, par exemple, un smartphone connecté en Wi-Fi et 3G en même temps. ILNP permet à cette machine d'utiliser les deux localisateurs, chacun issu des deux connexions possibles.
  • Site multi-homing où c'est un site entier qui est connecté à plusieurs opérateurs. Le RFC cite le cas où le site a des adresses PI et les annonce en BGP (ce qui charge la table de routage globale) mais il oublie le cas où les routeurs de sortie du site font simplement du NAT vers les adresses des FAI (ce qui ne permet ni la redondance des connexions entrantes, ni la continuité des connexions TCP). Dans le scénario typique de site multi-homing avec ILNP, les routeurs du site annoncent sur le réseau local avec RA (Router Advertisement) les N préfixes des N opérateurs utilisés, et les machines les utilisent comme localisateurs. Dans ce cas, les routeurs du site n'ont pas besoin de connaître ILNP, les machines terminales font tout le travail (enregistrer les localisateurs, les abandonner s'ils ne sont plus annoncés, etc).

Dans ILNP, la mobilité est traitée quasiment comme le multi-homing (section 6). Elle est donc très différente du Mobile IP du RFC 6275. Dans les deux cas, l'identificateur reste constant pendant que le localisateur actuellement utilisé peut changer. La principale différence est le délai : en cas de mobilité rapide, les mécanismes d'ILNP peuvent être trop lents pour assurer la transition (point que le RFC oublie de mentionner).

Comme pour le multi-homing, il peut y avoir mobilité d'une machine (le smartphone cité précédemment qui, maintenant, se déplace) ou d'un réseau entier (cas d'un bateau en déplacement, par exemple, où il faudra que les machines à bord connaissent ILNP). ILNP obtient le maintien de la connectivité grâce à des localisateurs qui changent dynamiquement (même en cours de session), une mise à jour de la liste que connait le CN, grâce aux messages ICMP Locator Update et enfin les mises à jour dynamiques du DNS (RFC 2136) pour continuer à recevoir de nouvelles sessions même après déplacement.

Avec IP Classic, si le téléphone se déplace et perd la Wi-Fi, les connexions TCP en cours sont coupées. Avec ILNP, le téléphone pourra simplement utiliser le(s) localisateur(s) restant(s) (ici, celui de la 3G) et garder ses connexions.

On a vu qu'ILNP était un truc assez ambitieux, promettant de résoudre plein de problèmes. Mais, comme l'ont montré les malheurs de plusieurs protocoles, être meilleur ne suffit pas. L'inertie de la base installée est forte. Il faut donc absolument, pour qu'un nouveau protocole ait la moindre chance de réussir, des mécanismes de compatibilité avec l'existant et de déploiement incrémental (on ne peut pas exiger que tout le monde migre au même moment). La section 8 discute en détail ces points. D'abord, un paquet ILNPv6 ne se distingue en rien d'un paquet IPv6 actuel (c'est un peu plus compliqué avec ILNPv4, pour lequel le traditionnel ARP ne suffit pas, cf. RFC 6747). Cela veut dire que les routeurs, de la petite box au gros routeur du cœur de l'Internet n'auront besoin d'aucun changement. Le routeur ne sait même pas que le paquet est de l'ILNPv6 (voir le RFC 6741 sur les détails concrets des paquets ILNP). On est donc dans un cas très différent de celui d'IPv6 où il fallait modifier tous les routeurs situés sur le trajet.

Côté DNS, il faudra des nouveaux types d'enregistrement (RFC 6742). Cela ne nécessite pas de modifications des résolveurs/caches. Sur les serveurs faisant autorité, il faudra légèrement modifier le code pour permettre le chargement de ces nouveaux types.

Il serait tout de même souhaitable que les serveurs DNS, lorsqu'ils reçoivent une requête pour des noms qui ont des enregistrements ILNP, envoient tous ces enregistrements dans la réponse. Ce n'est pas nécessaire (le client pourra toujours les demander après) mais cela diminuera le temps total de traitement. (Les requêtes de type ANY, « donne-moi tous les enregistrements que tu as », ne renvoient pas forcément le résultat attendu, un cache n'ayant pas forcément tous les enregistrements correspondant à un nom.)

Si Alice et Bob connaissent tous les deux ILNP et qu'Alice initie une session avec Bob, tout se passera bien. Alice demandera l'enregistrement DNS de type NID, le serveur lui renverra l'identificateur de Bob, les localisateurs seront ajoutés par le serveur DNS (s'il connait ILNP) ou demandés explicitement par Alice par la suite. Alice générera le numnique, et l'enverra à Bob avec sa demande de connexion (RFC 6744). Mais, dans une optique de déploiement incrémental, il faut prévoir le cas où Alice aura ILNP et pas Bob, ou bien l'inverse. Que se passera-t-il alors ?

Si Alice connait ILNP et pas Bob, il n'y aura pas d'enregistrement NID dans le DNS pour Bob. Alice devra alors reessayer avec de l'IP classique. Si un enregistrement NID était présent à tort, Alice tentera en ILNP et enverra le numnique. Bob, en recevant cette option inconnue, rejettera le paquet en envoyant un message ICMP indiquant à Alice ce qui s'est passé.

Si Alice ne connait pas ILNP alors que Bob le connait, Alice ne demandera pas le NID et ne tentera rien en ILNP. Si Bob accepte l'IP Classic, la connexion marchera, sans ILNP.

Vu du point de vue de Bob (qui ne connait pas les requêtes DNS qui ont été faites), la connexion est en ILNP si l'option Nonce était présente dans le paquet initial, et en IP Classic autrement.

Le RFC ne mentionne toutefois pas trois problèmes pratiques :

  • Si un enregistrement DNS annonce à tort que Bob connait ILNP, Alice essaie d'abord en ILNP puis passe en IP Classic, ce qui augmentera le temps d'établissement d'une connexion.
  • Plus grave, si le paquet ICMP indiquant que Bob ne connait pas ILNP est perdu ou filtré (un certain nombre de sites bloquent stupidement la totalité des messages ICMP), le délai avant qu'Alice n'essaie en IP Classic sera très long. C'est le problème connu sous le nom de « malheur des globes oculaires » (RFC 6555 et RFC 6556).
  • Les options IPv6 sont très rares dans l'Internet d'aujourd'hui. Les mauvaises expériences avec les options IPv4 font qu'on peut être inquiet de leur viabilité.

Et la sécurité ? La section 7 couvre le cas particulier des interactions entre ILNP et IPsec (RFC 4301). La principale différence avec IP Classic est que l'association de sécurité IPsec se fait avec les identificateurs et plus avec les adresses.

Pour la sécurité d'ILNP en général, c'est la section 9 qu'il faut lire. En gros, ILNP a le même genre de risques qu'IP (on peut mentir sur son localisateur aussi facilement qu'on peut mentir sur son adresse IP) et les mêmes mesures de protection (comme IPsec).

Les Locator Updates d'ILNP, qui n'ont pas d'équivalent dans IP, sont protégés essentiellement par le numnique (RFC 6744). Sans cela, un méchant pourrait faire un faux Locator Update et rediriger tout le trafic chez lui. Avec le numnique, les attaques en aveugle sont extrêmement difficiles. Par contre, si l'attaquant peut espionner le trafic (par exemple s'il est sur le chemin de celui-ci), le numnique ne protège plus (c'est analogue au problème du numéro de séquence initial de TCP, cf. RFC 6528). Il faut alors chiffrer toute la session avec IPsec (selon le type de menaces, on peut aussi envisager SSH ou TLS). Cette situation n'est pas très différente de celle d'IP Classic.

Notez qu'il existe deux numniques par session, un dans chaque sens. Les chemins sur l'Internet étant souvent asymétriques, cela complique la tâche de l'attaquant (s'il n'est que sur un seul chemin, il ne trouvera qu'un seul numnique).

Autre attaque courante sur l'Internet (même si le RFC dit, curieusement, qu'elle existe mais n'est pas répandue), l'usurpation d'adresses. Il est facile de mentir sur son adresse IP. Peut-on mentir sur son Identificateur ou bien son Localisateur ? Disons que mentir sur son Identificateur est en effet facile et qu'on ne peut guère l'empêcher. Contrairement à HIP, ILNP n'a pas forcément de protection cryptographique de l'identificateur (cf. RFC 7343). Il est possible d'utiliser les adresses cryptographiques du RFC 3972, il reste à voir si cela sera déployé. Autre solution dans le futur, utiliser IPsec avec des clés indexées par l'identificateur (mais cela reste bien théorique).

En revanche, un mensonge sur le Localisateur est plus difficile. Il peut être protégé par les techniques du RFC 2827 et RFC 3704. Certains protocoles au-dessus, comme TCP avec ses numéros de séquence initiaux imprévisibles, ajoutent une autre protection.

Autre aspect de la sécurité, la vie privée. Comme le rappele la section 10, avoir un identificateur stable peut faciliter le suivi d'une machine (et donc de son utilisateur) même lorsqu'elle se déplace. Ce problème est connu sous le nom d'identity privacy. Le problème avait déjà été mentionné avec IPv6 et la solution est la même : se servir des identificateurs temporaires du RFC 8981. (Une machine ILNP n'est pas forcée de n'avoir qu'un seul identificateur.)

Autre menace, celle sur la location privacy. Non spécifique à ILNP, c'est le fait qu'on puisse connaître la localisation actuelle d'une machine via son localisateur. Le problème est très difficile à résoudre, la qualité de la connectivité étant inversement proportionnelle à la dissimulation de l'adresse. Si on force le passage par une machine relais fixe (comme le permet Mobile IP), on a une bonne protection de la vie privée... et une bonne chute des performances et de la résilience.

Si le localisateur a été publié dans le DNS, un indiscret qui veut le connaître n'a même pas besoin d'une communication avec la machine qu'il veut pister, interroger le DNS (qui est public) suffit. Si une machine veut rester discrète sur sa localisation et qu'elle n'a pas besoin d'être contactée, le mieux est qu'elle ne mette pas son localisateur dans le DNS.

Il n'existe encore aucune mise en œuvre publique d'ILNP. Un projet existe mais rien n'est encore sorti.

Pour les curieux d'histoire, la section 1.2 présente la vision des auteurs sur les différentes étapes ayant mené à ILNP. Ils remontent jusqu'en 1977 où la note IEN1 notait déjà le problème qu'il y avait à faire dépendre les connexions d'une adresse qui pouvait changer. Cette note proposait déjà une séparation de l'identificateur et du localisateur, qui n'a pas eu lieu dans TCP/IP. Par exemple, TCP utilise dans la structure de données qui identifie une connexion les adresses IP de source et de destination. Tout changement d'une de ces adresses (par exemple parce que la machine a bougé) casse les connexions TCP en cours.

Après ce choix, et quelques années plus tard, l'idée d'une séparation de l'identificateur et du localisateur est revenue, compte-tenu de l'expérience avec TCP/IP. En 1994, une note de Bob Smart repropose cette idée. Même chose en 1995 avec Dave Clark. Enfin, en 1996, Mike O'Dell propose son fameux 8+8, qui n'atteindra jamais le statut de RFC mais reste la référence historique des propositions de séparation de l'identificateur et du localisateur. (Une grosse différence entre 8+8 et ILNP est que ce dernier n'impose pas de réécriture du localisateur en cours de route).

Depuis, plusieurs autres travaux ont été faits en ce sens, mais sans déboucher sur beaucoup de déploiements. Des « vrais » protocoles de séparation de l'identificateur et du localisateur (rappelons que les auteurs ne considèrent pas LISP comme faisant partie de cette catégorie), seul HIP a connu une description dans un RFC et plusieurs mises en œuvres. ILNP offre sans doute moins de sécurité que HIP (contrairement à HIP, pas besoin d'établir une connexion avant toute communication) mais autant qu'avec l'IP actuel. Et ILNP est moins disruptif que HIP, ce qui peut être vu comme un avantage ou un inconvénient.

Quelques lectures :

Téléchargez le RFC 6740

L'article seul

RFC 6742: DNS Resource Records for ILNP

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews), Scott Rose (US NIST)
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012

Le système ILNP, qui vise à fournir une nouvelle (et meilleure) architecture à l'Internet, dépend du DNS pour plusieurs fonctions critiques. Plusieurs nouveaux types d'enregistrement DNS sont nécessaires et ce RFC les décrit.

Avant de lire ce RFC, il faut connaître ILNP. Le mieux est de commencer par le RFC 6740, qui décrit tout le système. Le RFC 6741 fournit ensuite quelques détails pratiques. Il faut aussi naturellement connaître les bases du DNS (RFC 1034 et RFC 1035).

C'est fait ? Vous avez lu tout cela ? Alors, place à ce nouveau RFC, le RFC 6742. ILNP utilise le DNS essentiellement pour permettre un rendez-vous entre deux machines. Celle qui veut commencer connaît le nom de l'autre mais aucune information pratique sur comment la rencontrer. Quatre types d'enregistrements sont utilisés pour cela :

  • NID qui permet de trouver l'identificateur d'une machine à partir de son nom,
  • L64 et L32 qui permettent de trouver le localisateur d'une machine à partir de son nom,
  • Et LP, une optimisation facultative qui sera présentée plus loin.

Commençons par le NID. Un de ses rôles est d'indiquer à la machine qui veut en contacter une autre si sa future correspondante connait ILNP (ou bien si elle est uniquement en IP Classic). Sa présence dans le DNS est donc un signal : « tu peux y aller, elle parle ILNP ». Un enregistrement erroné (disant qu'une machine a un NID alors qu'en fait elle ne parle pas ILNP) n'est pas fatal mais ralentirait sérieusement l'établissement de la connexion.

Le NID a reçu le numéro 104 (cf. le registre IANA) et il comporte deux champs, une préférence et l'identificateur. Attention, ce sont les préférences les plus faibles qui sont celles à choisir en premier. Par exemple, voici trois NID pour : IN NID 10 0014:4fff:ff20:ee64
                   IN NID 20 0015:5fff:ff21:ee65
                   IN NID 50 0016:6fff:ff22:ee66

L'identificateur 0014:4fff:ff20:ee64 est le préféré. (La syntaxe des identificateurs et des localisateurs est décrite dans le RFC 6740.)

Si un serveur DNS « connaît ILNP », c'est-à-dire qu'il a été programmé avec du code spécifique pour ILNP, au lieu d'attribuer aux enregistrements ILNP le traitement par défaut, il peut optimiser, par exemple en envoyant des enregistrements non demandées mais qui seront probablement utiles. Cette optimisation, qui n'a rien d'obligatoire, est analogue à ce que font les serveurs actuels pour une requête MX : si la réponse est, ils incluent également les adresses IP de dans la réponse, conscients qu'elles seront probablement nécessaires bientôt (si on demande le MX de, c'est en général pour lui envoyer du courrier juste après). Ici, un serveur « connaissant ILNP » à qui on demande le NID de peut aussi mettre dans le réponse des L64 et des L32, non demandés mais qui seront probablement utiles juste après.

Le type L64 stocke des localisateurs pour ILNPv6, c'est_à-dire ILNP tournant sur IPv6. La présence de L64 dans le DNS indique que la machine peut faire de l'ILNP au-dessus d'IPv6. Pour ce protocole, les localisateurs font 64 bits, d'où le nom de ce type. Son numéro est 106. Lui aussi a une préférence, suivie par le localisateur proprement dit.

Voici un exemple où la machine a deux localisateurs, avec une préférence pour 2001:0db8:1140:1000 : IN L64 10 2001:0db8:1140:1000
                   IN L64 20 2001:0db8:2140:2000

Rappelez-vous que les localisateurs d'ILNPv6 ont une syntaxe qui ressemble à celle des adresses IPv6 mais il s'agit bien d'un type différent.

Quant au type L32, il stocke des localisateurs pour ILNPv4, c'est-à-dire l'incarnation d'ILNP pour IPv4. Leur présence dans le DNS indique que la machine peut faire de l'ILNP au-dessus d'IPv4. Pour ce protocole, les localisateurs font 32 bits, d'où le nom de ce type. Son numéro est 105. Il comprend une préférence, puis le localisateur proprement dit.

Voici un exemple où la machine a trois localisateurs, étant le préféré (la machine est sans doute multi-homée) : IN L32 10
                   IN L32 20
                   IN L32 30

Le dernier type d'enregistrement DNS, LP, est un peu différent. Il s'agit de fournir un niveau d'indirection. En effet, si une machine change de localisateurs (ce qui est normal, en ILNP), et veut pouvoir être jointe, la méthode est de mettre à jour le DNS. Or, la zone où est déclarée la machine peut ne pas être facilement accessible en écriture (RFC 2136 ou méthode équivalente). L'idée (voir RFC 6740) est donc de pointer, via un enregistrement LP, vers une zone prévue pour les mises à jour rapides, où se trouveront les localisateurs.

L'enregistrement LP a le numéro 107 et comprend une préférence et un FQDN. Ce FQDN aura à son tour des L32 ou des L64. Voici un exemple : IN LP 10
                   IN LP 20

; Puis, dans la zone : IN L64 50 2001:0db8:1140:1000
                             IN L64 100 2001:0db8:2140:2000

Avec cet exemple, si change de localisateur, on ne touche pas à la zone, on ne modifie que Cette indirection via les LP n'est pas indispensable mais elle aidera dans bien des cas, lorsque la zone « principale » ne permettra pas les mises à jour rapides. Autre avantage, toutes les machines d'un même sous-réseau ayant le même localisateur, leurs noms pourront pointer vers le même LP et une seule mise à jour suffira pour tout le monde.

La section 3 synthétise ensuite l'usage de ces types d'enregistrement. Le minimum pour une machine ILNP est un NID + un L64 (ou L32 en ILNPv4) : IN NID 10 0014:4fff:ff20:ee64
                   IN L64 10 2001:0db8:1140:1000

Si la machine est multi-homée, on aura plusieurs L64 : IN NID 10 0014:4fff:ff20:ee64
                   IN L64 10 2001:0db8:1140:1000
                   IN L64 20 2001:0db8:2140:2000

Si la machine est mobile, elle aura souvent intérêt à utiliser les LP et cela donnera quelque chose du genre : IN NID 10 0014:4fff:ff20:ee64
                   IN LP  10

; ... IN L64 2001:0db8:8140:8000

Rappelons que ces enregistrements ne doivent apparaître que si la machine parle ILNP. Un de leurs rôles est de signaler qu'ILNP est disponible.

Un client ILNP qui veut récupérer ces informations ne doit pas compter qu'elles soient toutes envoyées d'un coup (même si c'est une optimisation recommandée). Au passage, rappelez-vous que la requête ANY, envoyée à un résolveur, n'a pas forcément la sémantique attendue (elle renvoie ce que le résolveur a dans son cache, pas forcément toutes les données disponibles sur les serveurs faisant autorité). D'autre part, même si la réponse du serveur faisant autorité incluait tous les enregistrements, certains résolveurs peuvent, pour des raisons de sécurité, en jeter certains. Enfin, même si les données sont gardées dans le cache, elles expirent au bout d'un moment et les TTL ne sont pas forcément les mêmes pour tous les types d'enregistrement. Le client ILNP doit donc se préparer à faire plusieurs requêtes, par exemple NID (s'il n'y a pas de résultat, la machine distante ne parle pas ILNP) puis LP (qui est facultatif), puis L64 puis enfin, s'il n'y a pas de L64, se résigner à L32.

À propos des TTL, notez qu'il est logique que les TTL soient assez longs pour les NID (une information normalement très stable, je dirais que plusieurs jours ne sont pas un problème). En revanche, les L32 et L64 peuvent avoir des TTL bien plus courts (le RFC ne donne pas de chiffre mais, disons, moins d'une minute), surtout si la machine ou le réseau est mobile. On peut alors s'inquiéter « est-ce que ces courts TTL, empêchant une mise en cache sérieuse, ne vont pas augmenter excessivement la charge sur le système DNS, et ralentir les requêtes ? ». Mais plusieurs articles (« Reducing DNS Caching », « DNS performance and the effectiveness of caching ») ont montré que les caches du DNS étaient surtout rentables pour l'information d'infrastructure (enregistrements NS et colle). Pour les enregistrements « terminaux » comme les adresses IP ou les localisateurs, les caches sont moins nécessaires.

Un petit mot sur la sécurité, maintenant. Comme les informations nécessaires sont vraiment critiques (un L64 erroné et tout le trafic va à une autre machine), la section 4 recommande d'utiliser DNSSEC (RFC 4033) pour protéger ses informations. (À l'été 2012, le déploiement de DNSSEC est très avancé, alors que celui d'ILNP est inexistant. Il est donc raisonnable de compter que DNSSEC sera disponible.) Lors des mises à jour dynamiques, il faut utiliser les sécurités décrites dans le RFC 3007. Par exemple, avec le serveur de noms Yadifa, on peut mettre à jour dynamiquement une zone signée. On copie la clé privée (par exemple, pour une clé générée avec dnssec-keygen pour la zone secure.example, le fichier de la clé privée peut être Ksecure.example.+005+05461.private) dans le répertoire indiqué par la directive keyspath de Yadifa et c'est tout. Les mises à jour dynamiques seront faites et automatiquement signées. Le journal de Yadifa dira :

2012-09-25 20:54:12.754705 | server   | I | update (831e) secure.example. SOA (
2012-09-25 20:54:12.754749 | server   | D | database: update: checking DNSKEY availability
2012-09-25 20:54:12.754778 | server   | D | database: update: processing 0 prerequisites
2012-09-25 20:54:12.754791 | server   | D | database: update: dryrun of 2 updates
2012-09-25 20:54:12.754828 | server   | D | database: update: opening journal page
2012-09-25 20:54:12.755008 | server   | D | database: update: run of 2 updates
2012-09-25 20:54:13.000526 | server   | D | database: update: closed journal page

À la date de publication de ce RFC, il n'existe pas encore de logiciel DNS qui gère ILNP.

Pour finir, quelques articles sur l'idée d'utiliser le DNS pour localiser une machine mobile : « An End-To-End Approach To Host Mobility », « Reconsidering Internet Mobility » et « Mobile Host Location Tracking through DNS ».

Téléchargez le RFC 6742

L'article seul

RFC 6741: ILNP Engineering Considerations

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : RJ Atkinson (Consultant), SN Bhatti (U. St Andrews)
Réalisé dans le cadre du groupe de recherche IRTF RRG
Première rédaction de cet article le 10 novembre 2012

Le RFC 6740 décrivait l'architecture générale du mécanisme de séparation de l'identificateur et du localisateur ILNP. C'était le premier document à lire pour comprendre ILNP. Ce RFC 6741 est plus concret, exposant les questions d'ingéniérie autour d'ILNP. Il décrit surtout des points qui sont indépendants de la version d'IP utilisée, d'autres RFC couvrent les points spécifiques à IPv4 (RFC 6745 et RFC 6746) ou IPv6 (RFC 6743 et RFC 6744).

Donc, ILNP vise à fournir une meilleure architecture à l'Internet, en faisant évoluer IP vers une séparation de l'identificateur d'une machine (stable, indépendant de comment et par qui la machine est attachée au réseau) avec le localisateur (lié à l'attachement actuel au réseau, et pouvant donc changer). ILNP est décrit dans le RFC 6740 mais celui-ci ne donne qu'une vision de haut niveau, à laquelle manquent pas mal de détails. C'est le rôle de notre RFC que de combler ces manques. L'architecture ILNP peut avoir bien des incarnations concrètes, y compris par des approches « table rase » où on ne tient aucun compte de l'existant. Ce RFC 6741 présente une autre approche, plus progressive, où on essaie de déployer ILNP dans l'Internet actuel.

Vous avez bien lu le RFC 6740 d'architecture d'ILNP ou son résumé ? Alors, allons-y, plongeons nous dans les détails ILNP. D'abord, les identificateurs (section 2). Toute machine ILNP en a au moins un. Ils ne sont pas liés à une interface réseau et une machine avec N interfaces peut très bien n'avoir qu'un seul identificateur. (Notez toutefois qu'un identificateur peut être formé à partir d'une caractéristique d'une interface, comme l'adresse MAC. Mais ce n'est qu'un mécanisme de génération de l'identificateur, la carte réseau peut ensuite être changée sans affecter celui-ci.)

Les identificateurs sont des chaînes de 64 bits et la représentation la plus simple est donc un entier non signé de 64 bits (uint64_t dans un programme en C, par exemple). Comme les identificateurs d'interface d'IPv6 (section 2.5.1 du RFC 4291), ils utilisent la syntaxe EUI-64. Cette syntaxe décrit notamment deux bits, U et G, le premier indiquant si l'identificateur est globalement unique ou non, et le second indiquant s'il s'agit d'une adresse de groupe. Attention pour les programmeurs, rien n'empêche une machine de prendre l'identificateur qu'elle veut et, en pratique, des collisions peuvent se produire. À plusieurs reprises, notre RFC donne des conseils à ceux qui mettent en œuvre ILNP pour que ces collisions n'aient pas de conséquences graves.

Si le bit U est à 1, cela indique que l'identificateur dérive de l'adresse MAC, et est donc garanti unique via l'enregistrement à l'IEEE.

Si le bit U est à 0, cela veut dire que l'identificateur n'est pas dérivé d'un registre central et n'a donc qu'une signification locale. Cela permet à ILNP de se passer d'une dépendance vis-à-vis d'une autorité unique. Autre intérêt, on peut alors générer un identificateur qui soit une clé cryptographique, par exemple (RFC 3972). On peut aussi avoir des identificateurs temporaires, pour préserver la vie privée, comme on le fait en IPv6 avec les adresses temporaires du RFC 8981.

Normalement, ce RFC n'était censé couvrir que les points indépendants de la famille d'adresses utilisée. Néanmoins, on y trouve aussi l'encodage des localisateurs et identificateurs dans un paquet IP (section 3). En IPv6, dans les champs « adresse IP » (source et destination), le localisateur prend les 64 bits de plus fort poids, et l'identificateur le reste. Grâce à cet encodage, le routeur IPv6, qui ne tient compte que du préfixe, traitera le localisateur comme un préfixe IP normal et n'aura besoin d'aucune modification pour gérer de l'ILNP. Le format du paquet ILNPv6 est en effet exactement le même que celui du paquet IPv6 classique.

C'est plus complexe en IPv4, en raison de la petite taille des champs adresse. On met donc les localisateurs dans l'adresse (source et destination), afin que les routeurs IPv4 puissent travailler comme aujourd'hui, et l'identificateur (qui fait toujours 64 bits) doit être mis dans une option IP, comme décrit dans le RFC 6746.

Et au niveau 4 (transport), qu'est-ce qui doit changer ? La principale modification est que TCP ou UDP doivent lier l'état d'une session en cours uniquement à l'identificateur et non plus à une adresse. Ainsi, le tuple traditionnel de TCP {adresse IP locale, port local, adresse IP distante, port distant}, qui identifie une connexion en cours, doit être remplacé par {identificateur local, port local, identificateur distant, port distant}, afin de bénéficier d'ILNP (notamment de la possiblité de changer d'adresse sans casser la connexion).

Attention, TCP doit normalement remplir le champ « somme de contrôle » (Checksum dans l'en-tête TCP) en incluant les deux adresses IP, locale et distante. En ILNP, il ne doit plus utiliser que les identificateurs, les localisateurs étant remplacés, pour le calcul de la somme de contrôle, par une série de bits nuls.

Un aspect d'ingéniérie très important d'ILNP est l'ILCC, Identifier-Locator Communication Cache. Cette structure de données, décrite en section 5, garde trace des détails permettant de maintenir une communication avec les CN (Correspondent Node, les machines ILNP avec qui on parle). De tels caches existent déjà pour certains protocoles (par exemple pour ARP, sur une machine Unix, vous pouvez l'afficher avec la commande arp -a -n, pour NDP, sur Linux, avec ip -6 neighbour show). Et ceci sans parler des informations que doit garder TCP. Donc, le nouvel ILCC n'est pas forcément une grosse contrainte pour les machines.

Que stocke l'ILCC ?

  • Le ou les Identificateurs du nœud local, en indiquant les préférences, et s'ils sont actuellement en service (utilisables pour une nouvelle session),
  • Le ou les Localisateurs du nœud local, en indiquant les préférences, et s'ils sont actuellement en service,
  • Le ou les Identificateurs de chaque correspondant (CN), en indiquant les préférences, leur validité, et s'ils sont actuellement en service,
  • Le ou les Localisateurs de chaque correspondant, en indiquant les préférences, leur validité, et s'ils sont actuellement en service,
  • Les numniques à utiliser pour chaque correspondant, celui vers le CN et celui depuis le CN.

La validité peut être déterminée par divers moyens. Lorsque l'information a été apprise dans le DNS, c'est typiquement le TTL qui est utilisé. Toutefois, même lorsque le TTL expire, ce n'est pas une bonne idée de retirer les valeurs immédiatement (on risque de se couper d'un CN qui n'a pas mis à jour ses données assez vite). Il vaut donc mieux marquer un Localisateur comme « pas à jour mais peut-être encore utilisable si on n'a pas le choix ».

Et pour accéder à l'ILCC, quelle clé de recherche utilise-t-on ? L'identificateur, ce qui serait logique ? Raté. Pour les paquets qui contiennent un numnique, on utilise un tuple {Identificateur, Numnique} et pour les autres un tuple {Identificateur, Localisateur}. Le but de ce choix est de se prémunir contre les cas où deux machines utiliseraient le même identificateur (ce qui peut arriver, surtout avec le bit U à zéro).

On a vu qu'un des buts d'ILNP était de gérer proprement les cas où une machine change de connectivité (panne d'un lien, déplacement, etc). La section 6 explique les détails de ce cas. Lorsqu'une machine apprend qu'un de ses localisateurs ne marche plus, elle prévient ses CN (Correspondent Node) par un message ICMP Locator Update (RFC 6743 et RFC 6745). Ce message permet de retirer ou d'ajouter des localisateurs. Il est authentifié par le numnique, qui doit être identique à celui d'une session en cours (sinon, le paquet entrant ne correspond à aucune entrée dans l'ILCC, voir la section précédente).

Ça, c'est pour les sessions en cours. Pour les nouvelles, si une machine veut être contactée, elle doit mettre à jour la liste de ses localisateurs dans le DNS. ILNP dépend donc assez fortement des mises à jour dynamiques du DNS (RFC 2136 et RFC 3007), ou d'un mécanisme similaire.

Le lecteur attentif a pu remarquer plus tôt que le localisateur joue le rôle d'un préfixe IP, le routage est fondé sur lui. Mais un préfixe IP n'a pas forcément une longueur fixe. En IPv6, on peut parfaitement avoir un Tier 1 qui annonce un /32 en BGP, qui route ensuite dans son IGP des /48 et finalement un réseau local d'un client de l'opérateur qui route sur des /64. ILNP ne change rien à cela (section 7). Le localisateur comprend en fait deux parties, de longueur variable, un préfixe de localisateur et un sélecteur de réseau. Dans le cas de l'annonce BGP citée plus haut, les 64 bits du localisateur se partagent entre 32 bits de préfixe et 32 bits pour choisir un réseau.

On a vu qu'ILNP dépend énormément du DNS. Il est donc logique que ce RFC compte une une section 8 consacrée à ce service. D'abord, comme on l'a vu, pour des raisons de sécurité, ILNP recommande fortement de sécuriser les mises à jour du DNS (RFC 3007). Cette technique marche dans de nombreuses mises en œuvre du DNS (par exemple, BIND ou Active Directory l'ont depuis des années). Les clients capables d'utiliser TSIG ou une technique similaire pour mettre à jour un serveur DNS sont disponibles pour toutes les plate-formes (comme nsupdate sur Unix). Un exemple figure dans mon article sur le RFC 6742.

Pour accéder à l'information disponible, quatre nouveaux types d'enregistrement DNS sont créés par le RFC 6742 :

  • NID pour stocker l'identificateur,
  • L32 et L64 pour stocker des localisateurs de 32 (pour IPv4) et 64 bits,
  • LP, pour ajouter un niveau d'indirection vers le localisateur, apportant ainsi davantage de souplesse pour les changements (qui peuvent être fréquents) des localisateurs, qui peuvent être délégués à une autre zone.

Quels TTL utiliser pour ces enregistrements ? Le choix est particulièrement important pour les localisateurs, qui peuvent parfois changer vite. Dans certains cas, un TTL de quelques secondes seulement peut donc être une valeur raisonnable pour les L32 et L64. Si cela vous semble peu, rappelez-vous que des études comme celle de Alex C. Snoeren, Hari Balakrishnan, & M. Frans Kaashoek, « Reconsidering Internet Mobility » (dans Proceedings of 8th Workshop on Hot Topics in Operating Systems en 2002) ou celle de S. Bhatti & R. Atkinson, « Reducing DNS Caching » (dans Proc. GI2011 - 14th IEEE Global Internet Symposium en 2011) ont montré qur le cache dans le DNS est surtout utile pour les enregistrements d'infrastructure (type NS et colles, c'est-à-dire adresses IP des serveurs situés dans la zone qu'ils servent), pas pour les enregistrements « terminaux » comme AAAA ou MX.

Les enregistrements LP et NID sont bien plus stables et peuvent, eux, avoir des TTL de plusieurs jours. Dans le cas d'identificateurs temporaires et/ou cryptographiquement signés, un TTL plus court est toutefois à envisager.

À noter que le RFC recommande que les machines ILNP publient dans le DNS, non seulement les NID et L64 spécifiques d'ILNP mais aussi des plus traditionnels AAAA pour les machines non-ILNP. Un serveur DNS qui connait ILNP peut également envoyer d'autorité les NID et L64 dans la section additionnelle de la réponse DNS. Les machines non-ILNP ignoreront ces enregistrements inconnus mais les autres pourront en tirer profit.

L'expérience (douloureuse) d'IPv6 a montré que la possibilité d'un déploiement progressif, n'exigeant pas de tout le monde qu'il migre, était un élément nécessaire de tout nouveau protocole réseau. La section 10 de notre RFC regarde donc de près si ILNP est déployable progressivement. D'abord, les paquets ILNP, que ce soit ILNPv4 ou ILNPv6 sont indistinguables, pour les routeurs, les pare-feux et autres équipements, de paquets IPv4 et IPv6 classiques. Ils devraient donc passer sans problème sur ces équipements, sans qu'on change leurs configurations, leurs protocoles de routage, etc. ILNP, comme HIP, peut en effet être déployé uniquement sur les machines terminales, par une simple mise à jour logicielle. Pour la même raison, des machines ILNP peuvent coexister avec des machines IP Classic sur un même lien.

Je trouve que le RFC est trop optimiste : l'expérience montre que les options IP, nécessaires à ILNP, passent mal dans l'Internet IPv4 actuel et n'ont guère été testées en IPv6 (le RFC ne mentionne que le cas des pare-feux qui bloqueraient explicitement les options et pas celui de routeurs bogués). De toute façon, une exception est à prévoir, en ILNPv4 uniquement, les routeurs du réseau local devront être mis à jour pour gérer une extension d'ARP. Autre exception, certains routeurs NAT, selon la façon dont ils sont réglés, peuvent casser ILNP en réécrivant ce qu'ils croient être une adresse et qui serait un bout de l'identificateur.

Pour les applications, c'est plus compliqué. Si l'application est « bien élevée » (n'utilise que des noms de domaine, ne manipule pas explicitement d'adresses IP), elle devrait fonctionner en ILNP sans problème. Mais bien des applications ne sont pas bien élevées (FTP, SNMP...)

La section 14, consacrée aux applications et API revient en détail sur ces questions. D'abord, une bonne partie des applications existantes, notamment parmi celles écrites en C, utilise l'API dite BSD Sockets. Elle n'est pas forcément incompatible avec ILNP. Par exemple, les applications IPv6 peuvent mettre la concaténation du localisateur et de l'identificateur dans les champs de l'API prévus pour mettre une adresse IP et cela passera, puisque c'est justement l'encodage du couple {Identificateur, Localisateur} sur le câble. Néanmoins, cette API est de trop bas niveau, même sans tenir compte d'ILNP (par exemple, elle oblige à avoir un portage d'IPv4 en IPv6 alors que cette modification dans la couche 3 devrait être invisible des applications). Souhaitons donc (et pas seulement pour ILNP) que les programmeurs passent à des API plus abstraites.

Tout le monde ne programme pas en C. Pour les autres langages, il est courant d'utiliser des API de plus haut niveau que ces sockets. Ainsi, en Java, les clients Web vont plutôt faire appel à la classe Ainsi, complètement isolés des couches basses, ils passeront à ILNP sans s'en rendre compte. Même chose pour des langages comme Ruby ou Python.

Le piège classique des API réseau est l'utilisation de références, lorsqu'Alice dit à Bob « va voir Charlie ». Ces références cassent pas mal de protocoles. Une solution pour ILNP serait de faire des références avec des FQDN.

Et pour communiquer entre machines ILNP et non-ILNP ? Le RFC recommande que les machines ILNP gardent également l'IP Classic, approche connue sous le nom de dual stack (être capable de parler les deux protocoles). Une longue coexistence d'ILNP avec des machines IP est prévue. Pour la machine qui initie la connexion, si elle trouve un NID dans le DNS, elle tente ILNP (en mettant l'option Nonce/numnique), sinon elle reste en IP Classic. Si la machine distante ne gère pas ILNP (malgré ce que raconte le DNS), elle rejettera l'option Nonce avec un message ICMP (l'option a un type qui indique que le paquet doit être rejeté par ceux qui ne comprennent pas l'option, cf. RFC 2460, sections 4.2 et 4.5), qui permettra à l'initiateur de voir qu'il s'est trompé et doit réessayer en IP traditionnel.

Pour la machine qui répond aux demandes de connexion, si le paquet initial contient une option Nonce, c'est que le demandeur gère ILNP. Sinon, on s'en tient à l'IP de nos grand-mères.

Question sécurité, la section 9 est consacrée à IPsec. Il n'est pas très différent avec ILNP de ce qu'il est avec IP Classic. Le principal changement est que les associations de sécurité se font avec l'identificateur, pas avec l'adresse (elles ne changent donc pas si une machine change de localisateur). Ainsi, AH ne valide que l'identificateur (le localisateur n'est pas protégé, ce qui permet à ILNP+AH de fonctionner même en présence de NAT).

Autres questions de sécurité en section 11 : les auteurs estiment qu'ILNP n'est pas moins sûr qu'IP. Il ne l'est pas non plus forcément davantage. Un exemple typique est qu'une machine peut mentir sur son identificateur, comme elle peut mentir sur son adresse IP (les solutions sont également les mêmes, IPsec + IKE ou bien les CGA du RFC 3972).

Le principal risque nouveau est celui de faux messages ICMP Locator Update. Ils pourraient provoquer bien des dégâts, par exemple en convaincant un CN d'envoyer tous les paquets d'une machine à un attaquant. C'est pour cela que l'option Nonce est absolument indispensable, même lorsque IPsec est utilisé. À noter que cette option ne protège pas contre un attaquant situé sur le chemin, puisque ce dernier peut alors écouter le réseau et lire le numnique (la situation est exactement la même en IP Classic, par exemple avec les numéros de séquence TCP, qui ne protègent que contre les attaquants hors du chemin). On est donc bien dans un cas « sécurité pas pire qu'avec IP Classic (mais pas meilleure non plus) ». Si on veut aller plus loin en sécurité, il faut IPsec ou un équivalent.

À noter aussi que les autres messages ICMP (Packet too big, Destination unreachable, etc), ne sont pas protégés par le numnique. Ces messages sont en général émis par des équipements intermédiaires, genre routeurs, qui ne connaissent normalement pas le numnique. Comme en IP Classic, ils peuvent donc parfaitement être usurpés (cf. RFC 5927).

La sécurité inclus aussi le respect de la vie privée (section 12). Notre RFC renvoie au RFC 6740 qui discutait cette question dans le cadre d'ILNP.

Enfin, la section 13 contient diverses notes sur des problèmes pratiques. Notamment :

  • Les délais de mise à jour lorsqu'une machine ILNP se déplace trop vite, par rapport à la réjuvénation du DNS. Mobile IP avait déjà ce problème. La mobilité d'un piéton, ça va, celle d'un avion va poser des problèmes.
  • L'absence de garantie qu'on peut réellement joindre une machine via le localisateur indiqué. En effet, ILNP ne teste pas cela. Par exemple, un enregistrement L64 dans le DNS peut être erroné et rien ne l'indique au client ILNP. Comme en IP Classic, on n'est jamais sûr qu'un paquet arrivera et les logiciels doivent en tenir compte.

Comme il n'y a pas encore eu de déploiement, même limité, même de test, d'ILNP, nul doute que la liste des problèmes et questions s'allongera lorsqu'on passera à l'expérience sur le terrain.

Téléchargez le RFC 6741

L'article seul

PostgreSQL et les quantiles, via les « window functions »

Première rédaction de cet article le 9 novembre 2012

Le SGBD PostgreSQL dispose de tas de fonctions utiles. Une relativement peu connue est le système des « window functions » qui agissent sur un découpage d'un ensemble de tuples, s'appliquant à chaque part découpée. Cela permet notamment de travailler sur les quantiles.

Bon, avant de détailler, voyons un cas réel et concret. On a une base de données du personnel et une table stocke les salaires :

   salary INTEGER NOT NULL);

INSERT INTO Salaries (name, salary) VALUES ('John', 3000);
INSERT INTO Salaries (name, salary) VALUES ('Sandy', 2000);

On charge cette table (le fichier complet est disponible). Il est alors facile de trouver des choses comme le salaire moyen :

essais=> SELECT round(avg(salary)) FROM Salaries;
(1 row)

ou de trier selon le salaire, ici du plus payé vers le moins payé :

essais=> SELECT name,salary FROM Salaries ORDER BY salary DESC;
  name   | salary 
 Patt    |   9600
 Robert  |   7000
 Steve   |   4000

Mais on cherche des choses plus subtiles. Par exemple, le salaire moyen plait aux dirigeants pour la communication car il est relativement élevé, tiré vers le haut par quelques gros salaires. En cas de forte inégalité, ce qui est le cas dans l'entreprise de notre exemple, il est nettement moins pertinent que le le salaire médian. Il existe plusieurs méthodes pour calculer ce dernier. Par exemple, la médiane étant par définition le salaire tel que la moitié des employés gagnent davantage, un calcul approximatif (qui ignore les arrondis) est :

essais=> SELECT salary FROM salaries ORDER BY salary DESC LIMIT 
                            (SELECT count(id) FROM salaries) / 2;

Un moyen plus sophistiqué est de travailler sur les quantiles. Les quantiles sont les découpages des données triées en N parties égales. Si N = 100, on parle de centiles, si N = 10 de déciles, etc. Pour la médiane, on va prendre N = 2. Mais, avant cela, un petit détour par les « window functions » de PostgreSQL.

Ces fonctions opèrent sur une partie des tuples retournés par une requête. Le découpage en parties est fait par la clause OVER. Prenons l'exemple d'un découpage en autant de parties qu'il y a de tuples triés, et de la « window function » rank() qui indique la place d'un tuple par rapport aux autres :

essais=> SELECT name,salary,rank() OVER (ORDER BY salary DESC) FROM Salaries 
                              ORDER BY name;
  name   | salary | rank 
 Alfonso |   2300 |   14
 Bill    |   2900 |    8
 Bob     |   2800 |   10
 Chris   |   2900 |    8
 Chuck   |   3800 |    4

Le (ORDER BY salary DESC) après OVER indique que les tuples vont être classés selon le salaire décroissant. rank() va alors s'appliquer à ce classement : Alfonso a le quatorzième salaire (en partant du haut), Bill le huitième, etc. Notez que les ex aequo sont possible (ici, Bill et Chris). row_number() ferait la même chose que rank() mais sans les ex aequo.

Revenons maintenant aux quantiles. La fonction ntile() permet de découper un ensemble de tuples en quantiles (le nombre de quantiles étant l'argument de ntile(), ici on utilise des terciles) :

essais=> SELECT  name,salary,ntile(3) OVER (ORDER BY salary) FROM Salaries;
  name   | salary | ntile 
 Sandy   |   2000 |     1
 Lou     |   2600 |     2
 Peter   |   3400 |     3

Ici, Sandy est dans le tercile le plus bas (ntile() renvoie 1) et Peter dans celui des meilleurs salaires.

On peut utiliser les quantiles de tas de façons. Par exemple :

essais=> SELECT n,min(salary),max(salary) FROM 
              (SELECT name,salary,ntile(3) OVER (ORDER BY salary) as n FROM Salaries) AS q 
              GROUP BY n ORDER BY n;
 n | min  | max  
 1 | 2000 | 2500
 2 | 2600 | 3000
 3 | 3400 | 9600

Ici, on a la plage des salaires pour chaque tercile. Et la médiane que j'avais promise ?

essais=> SELECT n,min(salary),max(salary) FROM 
              (SELECT name,salary,ntile(2) OVER (ORDER BY salary) as n FROM Salaries) AS q  
              GROUP BY n ORDER BY n;
 n | min  | max  
 1 | 2000 | 2800
 2 | 2900 | 9600

Elle est de 2850.

Une autre façon de représenter l'inégalité est de voir quelle part des salaires représente chaque quantile. Passons à des quintiles (N = 5) :

essais=> SELECT n, sum(salary)*100/(SELECT sum(salary) FROM Salaries) AS percentage 
             FROM (SELECT name,salary,ntile(5) OVER (ORDER BY salary) as n FROM Salaries) AS q  
              GROUP BY n ORDER BY n;
 n | percentage 
 1 |         13
 2 |         16
 3 |         18
 4 |         17
 5 |         33

Le quintile supérieur représente le tiers du total des salaires. (On note que c'est le seul des cinq quantiles à représenter plus que sa part, qui serait de 20 % en cas de totale égalité.)

Tout cela ne sert évidemment pas qu'aux salaires. Si on prend des requêtes DNS analysées par DNSmezzo, et qu'on étudie la répartition du trafic par résolveur, on observe que certains résolveurs n'envoient que très peu de requêtes (c'était peut-être un étudiant faisant un ou deux dig), alors que d'autres sont bien plus bavards. Ici, on étudie 447 658 requêtes reçues par un serveur faisant autorité, en IPv6. On observe 3 281 préfixes IPv6 de longueur /48. Quelle est la répartition des requêtes ?

dnsmezzo=> SELECT n,min(requests),max(requests),
       to_char(sum(requests)*100/(SELECT count(id) FROM DNS_packets WHERE query AND family(src_address)=6), '99.9') AS percentage FROM 
        (SELECT prefix,requests,ntile(10) OVER (ORDER BY requests) AS n FROM 
             (SELECT set_masklen(src_address::cidr, 48) AS prefix, count(id) AS requests FROM
                 DNS_packets WHERE query AND  family(src_address)=6          
                GROUP BY prefix ORDER by requests DESC) AS qinternal) AS qexternal 

 n  | min |  max  | percentage 
  1 |   1 |     1 |    .1
  2 |   1 |     1 |    .1
  3 |   1 |     2 |    .1
  4 |   2 |     3 |    .2
  5 |   3 |     4 |    .2
  6 |   4 |     7 |    .4
  7 |   7 |    14 |    .8
  8 |  14 |    32 |   1.6
  9 |  32 |    89 |   3.9
 10 |  89 | 81718 |  92.7

On voit que les cinq premiers déciles ont un trafic négligeable, et que le dixième décile, les clients les plus bavards, fait plus de 90 % des requêtes à lui seul. (En utilisant des centiles et non plus des déciles, on confirme cette grande inégalité : le centile supérieur fait 72 % des requêtes.)

Un bon tutoriel sur les « windows functions » sur PostgreSQL (et qui couvre la clause PARTITION dont je n'ai pas parlé ici), est en ligne. Pour jouer avec les quantiles, il existe aussi une extension de PostgreSQL que je n'ai pas testée, quantile. Elle est notamment censée être plus rapide.

Ces fonctions ne sont pas spécifiques à PostgreSQL, elles sont apparues dans la norme SQL en 2003 sous le nom de « fonctions analytiques ». On les trouve dans plusieurs autres SGBD, par exemple Firebird. On les trouve dans beaucoup de questions sur StackOverflow. Merci à Malek Shabou et Pierre Yager pour leur relecture.

L'article seul

RFC 6726: FLUTE - File Delivery over Unidirectional Transport

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : T. Paila (Nokia), R. Walsh (Tampere University of Technology), M. Luby (Qualcomm), V. Roca (INRIA), R. Lehtonen (TeliaSonera)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF rmt
Première rédaction de cet article le 7 novembre 2012

Peut-on envoyer un fichier d'un ordinateur à un autre lorsque la liaison est unidirectionnelle, c'est-à-dire que les paquets ne voyagent que dans un sens ? Pas question de se servir de FTP ou de HTTP, qui reposent sur le protocole de transport TCP, qui a besoin de bidirectionnalité (car il dépend du retour des accusés de réception). Le protocole FLUTE (File Delivery over Unidirectional Transport) normalisé dans ce RFC, fournit un ensemble de mécanismes pour effectuer ce transfert. La principale application concerne le multicast, où une machine unique diffuse un fichier à plusieurs autres, qu'elle ne connait pas forcément et qui ne peuvent pas lui écrire. Un exemple typique est la distribution des mises à jour d'un gros logiciel à des milliers, voire millions, de machines dans le monde. Parmi les usages possibles, distribuer de la vidéo, une nouvelle version d'un jeu très populaire, etc.

Pour cela, FLUTE s'appuie sur le système ALC (RFC 5775) + LCT (Layered Coding Transport, RFC 5651), qui fait l'essentiel du travail. ALC+LCT sert de protocole de transport d'objets binaires, FLUTE se charge de la sémantique. FLUTE dépend aussi d'autres protocoles de la famille multicast, comme FEC (RFC 5052), qui assure la fiabilité du transport, en permettant au récepteur de détecter les erreurs.

Transférer des gros fichiers sur un réseau ouvert comme l'Internet implique également un mécanisme de contrôle de la congestion, pour éviter que l'émetteur ne noie le réseau sous les paquets, sans se rendre compte que les tuyaux sont pleins. Comme on n'a pas TCP pour limiter la congestion en détectant les paquets perdus, il faut trouver un autre mécanisme. Dans le cas de FLUTE, les récepteurs souscrivent plusieurs abonnements multicast, éventuellement de débits différents, et jonglent avec ces divers abonnements. (Sur des réseaux fermés, le contrôle de congestion de FLUTE peut se faire par encore d'autres mécanismes comme le shaping.)

Les métadonnées (les propriétés du fichier) sont transmises dans un élément XML. On y trouve entre autres :

  • Un identifiant du fichier, un URI. C'est juste un identifiant, et rien ne garantit qu'on puisse récupérer le fichier à cet « endroit ».
  • Un type de contenu, par exemple text/plain.
  • La taille du fichier.
  • Un encodage utilisé pendant le transport, par exemple la compression avec zlib (RFC 1950).
  • D'éventuelles informations de sécurité comme une empreinte cryptographique ou une signature numérique.

L'élement XML <File> qui contient tout cela est mis ensuite dans un élément <FDT-Instance> (FDT = File Delivery Table) qui contient également les informations externes au fichier (comme la date limite pendant laquelle cette information sera valable). Voici l'exemple que donne le RFC, pour le fichier track1.mp3 :

<?xml version="1.0" encoding="UTF-8"?>
<FDT-Instance xmlns:xsi=""

Cet élément XML est transmis avec le fichier. Les informations liées à l'émission du fichier (adresse IP source qui émettra le fichier, début de l'émission, etc) sont récupérées par le destinataire par un moyen non spécifié ici (cf. section 6). Cela a pu être une description SDP (RFC 4566), une ressource sur le Web ou bien d'autres méthodes, même une configuration manuelle. Le point important est que, une fois toutes ces informations en sa possession, le récepteur FLUTE peut se préparer à recevoir le fichier, et peut vérifier sa bonne délivrance (l'émetteur, lui, n'en saura rien, puisque la liaison est unidirectionnelle).

L'envoi unidirectionnel de fichiers soulève des problèmes de sécurité particuliers (section 7, très détaillée). Si le fichier transmis est confidentiel, il doit être chiffré avant, que ce soit par un chiffrement global du fichier (par exemple avec PGP) ou en route par IPsec.

Et si l'attaquant veut modifier le fichier ? On peut utiliser une signature numérique du fichier, avant son envoi ou bien, pendant le trajet authentifier les paquets ALC avec le RFC 6584 ou bien TESLA (Timed Efficient Stream Loss-Tolerant Authentication, RFC 4082 et RFC 5776) ou encore, là aussi, IPsec. À noter que certaines de ces techniques demandent une communication bidirectionnelle minimale, par exemple pour récupérer les clés publiques à utiliser.

Ce RFC est la version 2 de FLUTE, la version 1 était normalisée dans le RFC 3926, qui avait le statut expérimental. Avec ce nouveau document, FLUTE passe sur le chemin des normes IETF. La liste des changements importants figure en section 11. Notez tout de suite que FLUTE v2 est un protocole différent, incompatible avec FLUTE v1.

Je ne connais pas les implémentations de FLUTE mais il en existe plusieurs (pour la version 1) par exemple jFlute, l'ancien MCL v3 (plus maintenue en version libre mais Expway en a une version commerciale fermée) ou MAD-FLUTE fait à l'université de Tampere.

Merci à Vincent Roca pour sa relecture attentive.

Téléchargez le RFC 6726

L'article seul

RFC 6782: Wireline Incremental IPv6

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : V. Kuarsingh (Rogers Communications), L. Howard (Time Warner Cable)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 7 novembre 2012

Parfois, je me dis que si on consacrait tous les efforts qui ont été voués à écrire des RFC à propos d'IPv6 à déployer IPv6 au lieu d'expliquer comment le faire, ce protocole aurait remplacé IPv4 depuis longtemps... Toujours est-il que voici un nouveau RFC, consacré à la synthèse de l'état de l'art en matière de déploiement incrémental d'IPv6 pour un opérateur filaire (FAI ADSL ou câble par exemple).

« Incrémental » car peu d'opérateurs ont la possibilité de déployer un réseau purement IPv6. Par contre, je ne sais pas pourquoi le RFC se limite au filaire, la plus grande partie de son texte peut tout à fait s'appliquer aussi bien à un opérateur mobile (genre 3G).

Plein de textes ont déjà été écrits sur ce même sujet mais les choses changent et il est peut-être bon de temps en temps de refaire une synthèse. Donc, l'idée est de prendre par la main un opérateur qui, en 2012, serait toujours en IPv4 pur (c'est donc un opérateur assez retardé techniquement), pour l'amener (à long terme !) en IPv6 pur (cf. section 3.6). Le point important à garder en mémoire est que chaque opérateur est différent et que, s'il existe plusieurs mécanismes de migration d'IPv4 vers IPv6, ce n'est pas uniquement parce que l'IETF aime écrire beaucoup de RFC, c'est surtout parce qu'il n'y a pas un mécanisme qui conviendrait miraculeusement à tous les cas (cf. le RFC 6180 qui décrivait tous ces mécanismes).

Donc, point de départ, un opérateur Internet qui a des clients en IPv4 (et qu'il n'est pas question de migrer immédiatement), qui veut déployer IPv6 mais en ne cassant pas ce qui existe, en minimisant la quantité de travail nécessaire (donc sans déployer de technologies inutiles). En outre, on veut une qualité de service optimum, donc éviter les tunnels, si possible.

Avec un tel cahier des charges, une migration soudaine de tout le réseau d'un protocole vers un autre est hors de question. Il faut une démarche progressive, où IPv6 arrive petit à petit pendant qu'IPv4 continue de fonctionner correctement. Le problème, c'est que, sur le papier, une telle approche progressive (phased approach) est très sympa mais, en pratique :

  • Par suite de la procrastination d'un grand nombre d'acteurs, les adresses IPv4 sont déjà épuisées,
  • Si IPv6 est mis en œuvre dans tous les logiciels et équipements sérieux, depuis de nombreuses années, il n'a pas toujours été utilisé en production avec la même intensité qu'IPv4 et des bogues traînent donc toujours,
  • Le FAI ne contrôle en général pas les équipements des clients (c'est une des différences entre le FAI filaire et le mobile) et ceux-ci peuvent avoir des vieux systèmes, avec peu ou pas de gestion d'IPv6,
  • Le retour à un réseau multi-protocoles (qui n'est pas une nouvelle chose : dans les années 1980, tous les réseaux locaux étaient multi-protocoles) va poser quelques problèmes opérationnels.

Le RFC rappelle que le client final, le mythique « M. Michu », ne demande pas IPv6. Il ne demande pas IPv4 non plus. Il veut un accès à l'Internet, point. C'est aux professionnels de faire en sorte que son accès fonctionne, aussi bien en IPv4 qu'en IPv6. Les deux protocoles coexisteront sur le réseau local pendant encore longtemps (section 3.1 du RFC).

La section 3 du RFC examine plus en détail ces défis pratiques. La pénurie de plus en plus aiguë d'adresses IPv4 va nécessiter du partage d'adresses IP, avec tous ses inconvénients (RFC 6269, et la section 4.2 de notre RFC). Les autres solutions (gratter les fonds de tiroir à la recherche de préfixes oubliés, acheter au marché gris ou noir des adresses vendues sans garantie) ne suffiront sans doute pas.

Mais IPv6 ne peut pas se déployer en cinq minutes. Sans même prendre en compte l'existence de vieux systèmes ne parlant qu'IPv4, l'opérateur qui va déployer IPv6 va devoir prévoir une période d'assimilation des nouvelles pratiques (IPv6 est très proche d'IPv4 mais pas identique). Souvent, les humains ne sont pas au même niveau en IPv6 qu'en IPv4, et c'est pareil pour les logiciels (pas toujours testés au feu). Si la connectivité IPv4 de l'opérateur va dépendre de sa connectivité IPv6 (comme c'est le cas avec certaines techniques comme DS-LiteRFC 6333 - ou NAT64RFC 6146), un problème IPv6 va également toucher IPv4.

Il faut donc faire attention à ne pas déployer IPv6 sans supervision et de réaction adaptés. Trop souvent, des organisations ont mis un peu d'IPv6, se disant que c'était facile et sans conséquences, puis se sont aperçu après qu'un réseau non géré était moins utile : pannes IPv6 non détectées par le système de surveillance, par exemple.

Certaines des techniques de transition n'ont pas aidé, en proposant des mécanismes qui avaient l'avantage de permettre de faire de l'IPv6 rapidement, et l'inconvénient de fournir aux utilisateurs un vécu de moins bonne qualité. C'est le cas notamment avec les tunnels (tous les tunnels ne sont pas forcément mauvais mais, dans l'histoire d'IPv6, il y a eu beaucoup de problèmes à cause de certains tunnels) : ajoutant une complication supplémentaire, forçant le passage par un chemin qui n'est pas toujours optimum, les tunnels ne devraient être utilisés que lorsqu'il n'y a pas d'autre choix, et en toute connaissance de cause. L'objectif est bien de fournir de la connectivité native.

Avec ces défis en tête, la section 4 du RFC rappelle les techniques de transition et de coexistence possibles. La première citée est la catégorie des tunnels automatiques, 6to4 et Teredo, à mon avis la pire (le RFC 6343 documente certains des problèmes avec 6to4 et le RFC 7526 demande qu'il ne soit plus utilisé). Le problème de fond de ces techniques est qu'elles ne fournissent aucun moyen de contrôler le chemin de retour, ou même de savoir s'il existe. Elles ne devraient à mon avis être utilisées que si on veut décourager les gens de faire de l'IPv6

6rd (RFC 5969) bouche certains des trous de 6to4 et c'est la technique qu'a utilisé Free pour distribuer IPv6 sur son réseau, en attendant un hypothétique accès natif. Son principal avantage est qu'il limite l'investissement initial pour l'opérateur, lui permettant de croître progressivement.

DS-Lite (RFC 6333) tunnele l'IPv4 sur un réseau IPv6. Il est surtout intéressant pour un opérateur qui part de zéro (par exemple parce qu'il vient de se créer) et qui peut donc construire un réseau entièrement IPv6 (ce qui peut être difficile avec certains équipements, encore aujourd'hui), tout en ayant des clients IPv4 à satisfaire. Le CPE doit être capable de faire du DS-Lite donc cette solution marche mieux si le FAI contrôle les CPE.

NAT64 (RFC 6146) est pour le cas où les clients sont bien en IPv6 mais où certains services à l'extérieur ne sont accessibles qu'en IPv4. Elle ne semble donc pas d'une grande actualité aujourd'hui, puisque le réseau local purement IPv6 est encore dans le futur (voir RFC 6586). Elle sera plus utile lorsque les réseaux purement IPv6 devront accéder aux derniers dinosaures IPv4.

La technique de coexistence IPv4/IPv6 qui donne les meilleurs résultats, est la double pile (dual stack) où les machines ont les deux protocoles et deux adresses. Pour permettre l'étape suivante (IPv6 pur), elle nécessite un réseau entièrement IPv6 (y compris les services, par exemple le DNS). Elle ne résout pas le problème de l'épuisement des adresses IPv4 donc, pour un opérateur actuel, le vécu IPv4 restera marqué par le partage d'adresses, le CGN et autres horreurs.

À noter que j'ai fait un exposé comparant toutes ces techniques de transition en 2011 à Grenoble.

Après les défis, et les techniques disponibles, la section 5 présente les différentes phases du déploiement. Une organisation qui va passer à IPv6 peut utiliser cette section comme point de départ pour établir son propre plan de migration. Il est important de noter que ce RFC ne fournit pas un plan tout prêt adapté à tout le monde. Il fournit des lignes directrices, mais chacun doit créer son propre plan, en tenant compte de son réseau, de ses clients, de ses moyens humains et financiers. (Une vision plus technique est dans le RFC 6180.)

La section 5 liste successivement plusieurs phases. J'espère qu'en 2012, plus personne n'en est encore à la phase 0 mais on ne sait jamais... La phase 0 commence par la formation : si personne dans l'organisation (ou bien seulement un ou deux geeks) ne connait IPv6, il faut apprendre. Cela peut se faire par des formations formelles, ou en lisant des livres ou des textes sur le Web. Pour le personnel d'exécution, le RFC rappelle qu'il vaut mieux que la formation soit faite juste avant le déploiement, pour qu'elle ne soit pas oubliée lorsque le moment de s'en servir viendra. Cette phase 0 ne doit pas être purement théorique, et il faut aussi pratiquer, dans un laboratoire dédié à cet effet, à la fois pour que les gens apprennent par la pratique, et pour tester si les matériels et logiciels utilisés dans l'organisation n'ont pas de problème avec IPv6.

Armé de cette formation et de cette expérience en laboratoire, les techniciens peuvent alors commencer à planifier le futur routage IPv6 de leur réseau. Est-ce la même tâche qu'en IPv4 ? On peut argumenter dans un sens ou dans l'autre. Le RFC met plutôt l'accent sur les différences mais on peut aussi considérer que le modèle de routage est tellement proche dans les deux protocoles qu'il ne faut pas dramatiser les différences.

Outre la politique de routage, trois autres points doivent retenir l'attention de l'équipe qui conçoit le plan de migration vers IPv6 :

  • La sécurité, pour laquelle IPv6 peut poser quelques différences (comme pour le routage, je les trouve mineures) : les RFC 4942, RFC 6092 et RFC 6169 contiennent des analyses utiles sur la sécurité d'IPv6 (dommage, à mon avis, que le RFC 6104 ne soit pas cité).
  • L'administration des adresses IP (IPAM adaptés à IPv6) et la gestion du réseau,
  • Et bien sûr les techniques de transition adaptés à cette organisation particulière.

On peut espérer qu'en 2012, la plupart des grosses organisations sérieuses ont au moins franchi la phase 0. Mais pas mal de petites organisations ne l'ont même pas encore commencé.

Étape suivante, la phase 1. Il s'agit cette fois de donner un accès IPv6 à ses clients ou utilisateurs, via des tunnels pour l'instant, car le réseau n'est pas forcément prêt pour de l'IPv6 natif partout. Par exemple, il est courant que le réseau interne d'un opérateur, équipé de routeurs récents, permette IPv6 mais que l'accès aux clients passe par des équipements qu'on ne contrôle pas complètement (par exemple des DSLAM) et qui ne sont pas prêts pour IPv6. (Notez qu'il n'est pas obligatoire de passer par toutes les phases. Si on a un réseau où on peut utiliser du natif tout de suite, nul besoin d'un détour par des tunnels.) La phase 1 peut se faire avec une technologie comme 6rd (RFC 5569), si on contrôle le CPE.

Naturellement, à cette phase 1, il n'y aura pas de miracle : on utilisera des tunnels, donc on aura les problèmes associés aux tunnels comme la MTU diminuée.

Ensuite, place à la phase 2. Cette fois, on fournit de l'IPv6 natif. Tout fonctionne en IPv6 et, surtout, avec le même niveau de qualité qu'en IPv4. C'est un point très important car un certain nombre de fournisseurs qui se vantent de permettre IPv6 ne surveillent pas automatiquement la connectivité IPv6 (laissant les clients faire cette surveillance) et, même lorsqu'on leur signale un problème, le traitent uniquement dès qu'ils ont du temps libre (alors qu'un problème IPv4 est traité immédiatement). Un niveau de service équivalent à celui d'IPv4 est crucial si on veut convaincre les clients de migrer. Si vous faites l'audit du niveau de préparation IPv6 d'un fournisseur d'accès ou d'hébergement, ce sont les meilleurs tests : 1) le monitoring est-il également fait pour IPv6 ? 2) en cas de panne IPv6, y a-t-il le même niveau de mobilisation que pour IPv4 ? (Ou bien, est-ce que le NOC réagira en se disant « ah, IPv6, c'est Richard, on va attendre qu'il revienne de vacances », ce qui est le cas de la majorité des sociétés prétendant faire de l'IPv6 aujourd'hui.)

À ce stade, il faut encore fournir le service IPv4. Compte-tenu de l'épuisement des adresses, il faudra probablement déployer du CGN/NAT444, peut-être avec l'aide de technologies comme DS-Lite (RFC 6333). Au début du déploiement, le CGN peut encore être une grosse machine centrale puis, si son usage croît, être réparti petit à petit sur d'autres machines.

Normalement, l'usage d'IPv4 devrait ensuite suffisamment baisser pour qu'on puisse passer à la phase 3, un réseau purement IPv6. En novembre 2012, au moment où j'écris ces lignes, cela semble une perspective très lointaine, sauf peut-être sur des réseaux très spécifiques. Mais cela arrivera bien un jour.

Même dans ce cas, il est possible qu'il faille fournir une connectivité IPv4 à certains clients. DS-Lite, qui tunnele le trafic IPv4 sur le réseau IPv6, est là encore utile. Si, ce qui est plus vraisemblable, on a juste besoin de permettre l'accès des clients IPv6 à des sites Web qui sont restés en IPv4, NAT64 (RFC 6144 et RFC 6146) sera sans doute la bonne solution. Mais, bon, c'est un problème pour le futur... Le RFC a un ton plutôt pessimiste et, à mon avis, voit le verre IPv6 plutôt à moitié vide.

Téléchargez le RFC 6782

L'article seul

RFC 6783: Mailing Lists and non-ASCII Addresses

Date de publication du RFC : Novembre 2012
Auteur(s) du RFC : J. Levine (Taughannock Networks), R. Gellens (Qualcomm)
Pour information
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 7 novembre 2012

Depuis la sortie du RFC 6530 et de ses petits camarades, il existe désormais une solution normalisée pour avoir du courrier électronique complètement internationalisé, y compris les adresses (arôme@café.fr...). Mais comment est-ce que cela s'applique aux listes de diffusion ? Peut-on avoir des listes où certains membres accepteraient les nouvelles adresses et d'autres non ? Ce RFC, successeur du RFC 5983, se penche sur la question. Pour l'instant, la réponse est pessimiste : il n'y a pas de moyen pratique de faire coexister anciens et nouveaux sur la même liste.

Une liste de diffusion prend un message et le redistribue à N destinataires. Certains de ces N destinataires seront derrière un serveur de messagerie récent, qui gère les adresses internationalisés. Une partie de ceux-ci, en outre, auront des adresses internationalisées. Même si le destinataire, lui, n'a pas une adresse internationalisée, si l'émetteur en a une, ses messages ne pourront pas être remis aux gens qui ont les vieux logiciels.

Il y a donc un problème technique, le fait que des adresses internationalisées soient refusées par certains. Et il y a un problème humain : en communicaton bilatérale, après quelques essais, on peut toujurs trouver une solution technique qui permette la communication. Sur une liste, ce n'est plus possible, l'émetteur ne connait pas les destinataires et réciproquement. Il n'y a pas d'ajustement possible.

Autre problème : idéalement, la liste ne modifie pas le message, à part par l'ajout de certains en-têtes spécifiques aux listes (comme List-Unsubscribe: ou List-Id:, normalisés dans le RFC 2369 et RFC 2919). Toutefois, un certain nombre de listes vont plus loin et, bien que cela soit une source d'ennuis connue, modifient d'autres en-têtes comme Reply-To: voire, pire, From:.

Pour synthétiser, il y a trois services différents qui peuvent marcher ou pas :

  • Avoir une liste dont l'adresse est internationalisée, par exemple évolution-langue@académie-franç,
  • Avoir une liste qui accepte l'abonnement de personnes ayant des adresses internationalisées, par exemple étienne@massé.fr,
  • Avoir une liste qui accepte les messages émis depuis des adresses internationalisées.

Ces trois capacités sont relativement indépendantes (la deuxième et la troisième impliquent des logiciels différents donc l'une peut marcher et pas l'autre).

Le plus simple pour une liste qui veut gérer parfaitement l'internationalisation serait de n'avoir que des abonnés qui eux-même ont la gestion complète des adresses en Unicode (option SMTPUTF8 de SMTP, cf. RFC 6531). Pour cela, le mieux est de tester lors de l'inscription, et de refuser l'abonnement de ceux qui ont le vieux logiciel. Pour ce test, si le candidat à l'abonnement s'abonne avec une adresse Unicode, c'est facile : s'il reçoit le message de confirmation, c'est bon. Et s'il s'abonne avec une adresse ASCII ? Alors, le mieux est de tester en tentant de leur envoyer le message « répondez pour confirmer » depuis une adresse Unicode.

Mais pour la majorité des listes, qui voudront accepter des abonnés SMTPUTF8 et d'autres qui ne le sont pas ? (Fin 2012, très peu de serveurs de messagerie, à part en Extrême-Orient, gèrent SMTPUTF8.) Il n'existe pas (ou plus, cf. RFC 5504) de mécanisme de repli automatique d'un message aux adresses Unicode vers un message traditionnel. C'est donc au MLM (Mail List Manager, le logiciel de gestion de la liste, par exemple Mailman) de faire ce repli.

D'abord, le logiciel de gestion de la liste doit déterminer quels abonnés sont SMTPUTF8 et lesquels ne le sont pas. Il y a plusieurs méthodes :

  • Décider que les abonnés avec une adresse Unicode peuvent recevoir du courrier entièrement internationalisé et que les abonnés avec une adresse ASCII ont un logiciel traditionnel (en pratique, cela privera certains de ces abonnés ASCII des bénéfices du courrier internationalisé),
  • Tester, en envoyant un message depuis une adresse Unicode et en demandant confirmation,
  • Demander à l'utilisateur de se classer lui-même comme, aujourd'hui, on lui demande s'il veut recevoir du texte ou de l'HTML.

Ensuite, il faut décider, pour chaque message entrant vers la liste, s'il est internationalisé ou pas. Cela peut se faire en considérant que, si l'option SMTPUTF8 a été utilisée dans la session, le message sera marqué comme « Unicode ». Ou bien on peut examiner les en-têtes du message, à la recherche d'adresses en Unicode.

Les logiciels de gestion de liste réécrivent en général l'émetteur dans l'enveloppe SMTP du message. Ils mettent leur propre adresse (par exemple pour la liste du groupe de travail EAI, ex-IMA) ou même ils mettent une adresse d'origine différente pour chaque abonné, pour mieux gérer les messages de non-remise (technique VERP). Dans les deux cas, l'adresse d'émetteur, qui recevra les messages de non-remise, contient en général le nom de la liste. Dans ce cas, elle sera une adresse Unicode et les serveurs ne connaissant pas le courrier complètement internationalisé ne pourront donc pas envoyer ces avis de non-remise (bounces).

La section 3 contient les recommandations concrètes. D'abord, pour les en-têtes ajoutés comme List-Id:, la recommandation est de les mettre sous une forme purement ASCII, pour limiter les risques, même si cet en-tête prend comme valeur un URI (comme le fait List-Unsubscribe:) et que cet URI a un plan (scheme) qui permet l'Unicode. Il faut dans ce cas utiliser l'« encodage pour-cent ». Donc, pour une liste pause-café, on aura :

List-Id: Liste de discussion en Unicode <>
List-Unsubscribe: <>
List-Archive: <>

Dans certains cas, cela ne donnera pas un résultat lisible (par exemple le List-Id: d'une liste en chinois encodé en ASCII ne va pas être tellement utile aux lecteurs...) Mais cet inconvénient semble, aujourd'hui, moins grave que le risque de faire arriver de l'Unicode à des gens qui ne s'y attendent pas. Une meilleure solution devra attendre une nouvelle version des RFC 2369 et RFC 2919.

Le RFC n'a pas de recommandation pour le cas où un auteur d'un message a une adresse Unicode et où le gestionnaire de listes essaie de diffuser le message à un abonné n'ayant que des logiciels anciens, ne gérant pas SMTPUTF8. Il n'y a pas de bonne solution technique, juste des petits arrangements : réserver la liste aux gens pouvant recevoir du courrier internationalisé (cf. plus haut la discussion sur de telles listes), proposer aux abonnés d'enregistrer une adresse ASCII et remplacer le From: par cette adresse avant de transmettre ou enfin remplacer le From: par une adresse de la liste. Reste à programmer cela...

Je ne connais pas encore de « grand » gestionnaire de liste de diffusion qui ait des plans précis pour la mise en œuvre des adresses de courrier internationalisées. Sympa, par exemple, en est toujours au stade de la réflexion sur ce point.

Notre RFC ne contient pas de liste des changements depuis le RFC 5983. Il y a eu réécriture complète puisque le repli automatique et les adresses de secours (alt-address) ont été retirées de la norme finale du courrier internationalisé.

Téléchargez le RFC 6783

L'article seul

Le rapport HostExploit 2012 sur les plus grandes sources de Mal de l'Internet

Première rédaction de cet article le 31 octobre 2012
Dernière mise à jour le 12 novembre 2012

Les gérants du groupe HostExploit compilent un rapport régulier sur les plus grosses sources de Mal de l'Internet, c'est à dire les systèmes autonomes hébergeant le plus de centres de commande de botnets, le plus de serveurs de hameçonnage, envoyant le plus de spam... Un Who's who des acteurs de l'Internet, sous l'angle négatif. Dans le dernier rapport, numéroté Q32012, on note un nouveau n° 1 de ce classement, Confluence, et l'arrivée du français OVH dans le sommet.

Avant de commenter ce rapport, il convient d'être prudent et de bien prendre connaissance de la méthodologie. Celle-ci est décrite dans une annexe au rapport (le rapport est fait en Word avec des couleurs et l'annexe en LaTeX...). En gros, HostExploit utilise un certain nombre de sources qui listent des adresses IP qui ont participé à des comportements négatifs, comme héberger un serveur de malware, ou bien un serveur Zeus (voir le Zeus Tracker). De l'adresse IP, on remonte à l'AS et au pays (cette dernière information étant moins fiable). Le tout est pondéré par la taille de l'espace d'adressage annoncé par l'AS (pour éviter que les petits AS hébergant proportionnellement beaucoup de Mal ne se glissent sous la couverture du radar.)

Ces sources ne sont pas parfaites : tout n'est pas signalé, certains le sont à tort.

D'autre part, malgré mon introduction sensationnaliste, il faut bien voir que le fait qu'un AS (donc, en pratique, un opérateur ou hébergeur) soit bien placé dans la liste ne signifie pas que c'est lui qui envoie du spam ou héberge du malware. Il peut être « victime » de ses clients. Des fois, c'est même encore plus indirect : un hébergeur loue des machines, un client en prend une, son site Web se fait pirater, un serveur de hameçonnage est installé dessus et l'AS de l'hébergeur va remonter dans le classement « source de Mal ».

Alors, que contient le classement Q32012 ? Ce classement est peu stable : un opérateur envahi par des zombies va être mis sur des listes noires (et ne sera donc plus intéressant pour les maîtres des zombies) ou bien va prendre des mesures radicales (faire le ménage) et, l'année suivante, rétrogradera loin dans le classement. Cette année, l'AS 40034, Confluence, hébergé dans le paradis fiscal des Îles Vierges, arrive en numéro un du classement général (p. 9 du rapport). Coïncidence amusante, deux jours avant de lire ce dossier, je citais le cas d'un détournement de noms de domaine (l'affaire, fait via une machine chez Confluence. L'AS 16276, le français OVH est numéro 4, en très nette progression. (Sur la liste FRnOG, le directeur d'OVH estime aujourd'hui, je cite, que « avec les differents BETA aux USA que nous avons fait entre juillet et septembre, on a eu une augmentation importante des abuses en tout genre à partir de notre reseau. en gros, les nouveaux "clients" hackers nous ont decouvert puis depuis nous commandent de services. il y a 1 mois on est arrivé au point de non retour: trop marre. et donc il y a 3 semaines on a commencé un grand nettoyage avant l'hiver mais en incluant un echange avec les clients. et si pas de reponse là on hache. vous pouvez donc lire à droite ou à gauche que "mon serveur s'est fait bloqué pour 1 spam". oui si pas de dialogue, pas de serveur. si pas d'action, pas de serveur. sur spamhaus ça sera clean à la fin de la semaine (il reste 14 alertes). et les autres rbl c'est une question de 2 à 3 semaines. » Fin de citation)

Si on regarde le type de Mal hébergé (p. 11), on note que Confluence fait surtout de l'hébergement de Zeus alors qu'OVH est nettement moins spécialisé, on y trouve de tout. Cela semble indiquer qu'il n'y a pas de choix délibéré d'OVH, ni même d'envahissement de ses serveurs par un méchant décidé : la raison du score d'OVH est plus probablement que beaucoup de ses clients sont nuls en sécurité, installent un LAMP sans rien y connaître, se font pirater via une faille PHP, et ne corrigent pas le problème même quand on leur signale.

En attachant les AS à un pays (ce qui est parfois difficile, ainsi Confluence a été classé comme états-unienne malgré son adresse officielle aux Îles Vierges britanniques et, plus drôle, VeriSign a été classé aux Pays-Bas), on voit (p. 16) la Russie en numéro 1, ce qui ne surprendra guère, et le paradis fiscal de l'Union européenne en numéro 4. Grâce à OVH, la France est en huitième position.

Si on classe les AS en prenant chaque cause de Mal séparement, on voit que, pour l'hébergement de serveurs C&C, c'est l'AS 50465, IQhost, qui gagne, devant un autre russe. Pour le hameçonnage, les États-Unis prennent l'avantage avec l'AS 53665, Bodis. Confluence, on l'a vu, gagne nettement pour l'hébergement Zeus. Pour l'envoi du spam, les Indiens sont loin devant avec le record chez l'AS 55740, Tata.

Plus surprenant est le classement des AS où on trouve du malware (p. 26), car l'AS 26415, VeriSign (qui sert notamment pour les serveurs DNS racine exploités par cette société) et l'AS 15169, Google, se retrouvent dans les dix premiers. Le rapport ne propose pas d'explication. Pour Verisign, des explications raisonnables ont filtré mais rien de public encore. Pour Google, si, à première vue, dissimuler du code malveillant dans un Google document n'est pas évident (cela serait possible, via des fonctions de scripting), il y a déjà eu des rapports de hameçonnage où l'appât était un Google document, ce qui explique sans doute ce classement.

Maintenant, qu'est-ce qui devrait être fait ? Un AS a évidemment intérêt à nettoyer ces sources de Mal. Sinon, il va retrouver ses adresses IP dans plein de listes noires dont il est très difficile de sortir. Certains AS ont manifestement choisi de rester dans le business de l'hébergement de délinquants et se moquent de leur réputation (ils sont dans le sommet du classement depuis longtemps comme l'AS 16138, Interia). D'autres ont un problème difficile. (Ceci dit, ils pourraient commencer par traiter le courrier envoyé à abuse.) Nettoyer, OK, mais en respectant un minimum de règles. La différence de classement entre l'AS 16276 (OVH) et l'AS 14618 (Amazon), qui a un business model très proche (louer des machines rapidement et sans formalités, à des tas de clients, pas toujours compétents et pas toujours honnêtes), provient sans doute largement d'une différence d'approche entre l'Europe et les États-Unis. Aux USA, les hébergeurs se comportent comme des cow-boys : au premier signalement de problème (même injustifié), ils coupent et on n'a plus qu'à se chercher un autre hébergeur. Le fameux premier amendement à la Constitution, censé protéger la liberté d'expression, ne les arrête pas : il ne s'impose qu'à l'État. Les entreprises privées, elles, ont tout à fait le droit de s'attaquer à la liberté d'expression. WikiLeaks, qui fut client d'Amazon avant de l'être d'OVH, en sait quelque chose.

Le rapport d'HostExploit exhorte en effet les opérateurs à « agir », à « nettoyer », mais ne fournit aucune piste en ce sens (à part un conseil implicite : « tirez d'abord et enquêtez après »).

Ah, et pour les gens du DNS, à part la curieuse place de VeriSign, une nouveauté de ce rapport est l'étude des résolveurs DNS ouverts (p. 6). Ils sont une grande source d'ennuis, notamment par leur utilisation comme relais pour des attaques DoS avec amplification. Mais ils ne sont pas eux-même le résultat d'un choix délibéré par un méchant : les AS qui hébergent en proportion le plus de résolveurs ouverts (7418, Terra, ou 8167, Telesc) sont largement absents des autres classements et il n'y a donc pas de corrélation entre le nombre de résolveurs ouverts et l'hébergement d'autres sources de Mal.

Merci à Daniel Azuelos et Fabien Duchene pour leurs remarques.

L'article seul

RFC 6778: IETF Email List Archiving, Web-based Browsing and Search Tool Requirements

Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : R. Sparks (Tekelec)
Pour information
Première rédaction de cet article le 31 octobre 2012
Dernière mise à jour le 31 janvier 2014

Ce RFC est le cahier des charges de l'outil d'accès aux archives des innombrables listes de diffusion de l'IETF. Le gros du travail de cette organisation repose sur ces listes de diffusion, dont la plupart sont publiques, archivées et accessibles via le Web. Cette masse d'information est un outil formidable pour comprendre les décisions de l'IETF et les choix techniques effectués. Mais son volume rend l'accès à l'information souvent difficile. L'IETF se vante de sa transparence (tout le travail est fait en public) mais avoir toutes les discussions accessibles ne suffit pas, si l'information est trop riche pour être analysée. D'où l'idée de développer une ensemble d'outils permettant d'accéder plus facilement à ce qu'on cherche. C'est désormais accessible en

Avant, la recherche était particulièrement difficile si une discussion s'étendait sur une longue période et surtout si elle était répartie sur plusieurs listes. Imaginons un auteur d'un RFC, un président de groupe de travail, ou un simple participant, qui veut retrouver toutes les discussions qui ont concerné un Internet-draft donné. Il va trouver des messages dans la liste du groupe de travail mais aussi dans celles d'une ou plusieurs directions thématiques, et peut-être aussi dans la liste générale de l'IETF. Certains ont chez eux des copies de toutes ces listes (copies parfois incomplètes) pour utiliser des outils locaux. (Au fait, personnellement, je me sers surtout de grepmail et je cherche encore un outil qui indexerait les données.)

En l'absence de copie locale, notre participant IETF courageux va compter sur la force brute, ou bien va essayer un moteur de recherche généraliste (mais il est ennuyeux pour l'IETF de devoir compter sur un outil externe pour son propre travail).

Ce n'est pas qu'il n'existait aucun outil à l'IETF. Il y a des solutions proposées sur le site de l'IETF (l'option Email Archives Quick Search). Mais elles ne couvrent pas tous les besoins, loin de là.

Quels sont ces besoins ? La section 2 en donne la liste. D'abord, il faut une interface Web. Elle doit permettre de naviguer dans un fil de discussion donné, ou suivant la date. (Les outils d'archivage classique comme MHonArc permettent déjà tous cela.) Les fils doivent pouvoir être construits en suivant les en-têtes prévus à cet effet (References: et In-Reply-To:) mais aussi en se fiant au sujet pour le cas où les dits en-têtes auraient été massacrés en route, ce qui arrive.

Surtout, il faut une fonction de recherche. Elle doit fonctionner sur une liste, ou un ensemble de listes, ou toutes les listes. Elle doit permettre d'utiliser ces critères :

  • Nom ou adresse de l'expéditeur,
  • Intervalle de dates,
  • Chaîne de caractères dans le sujet ou dans le corps du message,
  • Chaîne de caractères dans un en-tête quelconque. Le plus important est bien sûr le Message-ID: lorsqu'on veut donner une référence stable d'un message (« ton idée a déjà été proposée dans <> »). Le but est de pouvoir faire circuler une référence comme

Et de les combiner avec les opérateurs booléens classiques (AND, OR et NOT).

Il n'y a pas que la recherche dans la vie, on voudrait aussi évidemment avoir des URI stables pour chaque message (stables et beaux). Et cet URL devrait être mis dans le champ Archived-At: du message avant sa distribution (cf. RFC 5064).

À propos d'URI, comme indiqué dans l'exemple de recherche via un Message-ID: montré plus haut, notre RFC demande que les recherches soient représentables par un URI, qui puisse être partagé (et qui soit donc stable). Le RFC ne donne pas d'exemple mais cela aurait pu être quelque chose comme (dans la version publiée, c'est en fait quelque chose comme Naturellement, « stabilité » fait référence à l'URI, pas au résultat, qui peut varier dans le temps (par exemple si des nouveaux messages arrivent).

La plupart des archives à l'IETF sont publiques et doivent être accessibles anonymement mais quelques unes nécessitent une autorisation. Dans ce cas, le cahier des charges demande que le système d'authentification utilisé soit celui de

Difficulté supplémentaire, toutes les listes IETF ne sont pas gérées au même endroit et par le même logiciel. Les listes hébergées à l'IETF le sont avec mailman mais il existe aussi des listes hébergées ailleurs et notre cahier des charges demandent qu'elles puissent être intégrées dans ce système de recherche (par exemple en abonnant l'adresse du programme d'archivage à la liste).

Il y a aussi des cas où des archives de listes de diffusion deviennent accessibles alors qu'elles ne l'étaient pas avant et doivent être incorporées dans le corpus géré par le nouveau système. Le RFC demande qu'au moins le format d'entrée mbox (RFC 4155) soit accepté. Et qu'il serait souhaitable d'accepter aussi le maildir.

En sens inverse, le système doit permettre d'exporter les messages (un système ouvert ne l'est pas si on ne peut pas en sortir l'information pour la garder et l'étudier chez soi ; la fonction d'exportation n'a pas qu'un intérêt technique, elle est aussi un moyen de garantir la pérénnité de l'information publique). On doit pouvoir exporter une liste entière, une liste pour un intervalle de temps donné et, dans le meilleur des cas, le résultat d'une recherche (une vue, pour employer le langage des SGBD). Là encore, l'exportation en mbox est impérative et celle en maildir souhaitée.

Voilà, c'est tout, l'appel d'offres formel de l'IAOC était en ligne. Plus rigolo pour le programmeur de cet ambitieux projet : la section 3 lui rappelle qu'il devrait se préparer à l'arrivée du courrier électronique internationalisé... Le produit final a été livré le 29 janvier 2014 et est disponible en

Téléchargez le RFC 6778

L'article seul

Fiche de lecture : La cybercriminalité en mouvement

Auteur(s) du livre : Éric Freyssinet
Éditeur : Hermes-Lavoisier
Publié en 2012
Première rédaction de cet article le 30 octobre 2012

Un livre utile pour celui qui s'intéresse à la cybercriminalité sous tous ses aspects. En 200 pages, l'auteur, un expert du domaine, réussit à couvrir à peu près tout. Évidemment, cela veut dire que les passionnés de tel ou tel aspect resteront un peu sur leur faim mais, pour celui qui ne connait pas encore bien la cybercriminalité, voici un livre sérieux et bien expliqué.

Quand même, je trouve l'ouvrage mince, surtout pour son prix très élevé (56 €). Mais il couvre pourtant plein de choses. On y trouve tout le panorama de la cybercriminalité actuelle, sans sensationnalisme et avec beaucoup de concret (et plein de références). Ainsi, l'importance du caractère organisé et professionnel de la cybercriminalité est bien expliqué, ainsi que l'organisation complexe du cybercrime : le type qui écrit le malware n'est pas celui qui gère le botnet et celui qui commande une attaque DoS comme on commande un livre à Amazon est encore un autre. C'est tout un écosystème qui s'est ainsi développé. L'auteur parle d'ailleurs de CaaS, « Crime as a Service » pour illustrer le fait qu'on peut louer des services de délinquants. De même, l'auteur explique bien le fonctionnement des botnets, sujet sur lequel il participe au projet

Comme toujours en matière de sécurité (pas seulement de sécurité informatique), les questions politiques de droit et de liberté ne sont jamais loin. J'y apprends par exemple qu'il n'y a pas encore de jurisprudence pour savoir si une attaque DoS peut être assimilée au droit de manifestation. En parlant des Anonymous, l'auteur regrette que le temps passé à les pourchasser soit au détriment d'autres tâches plus utiles. Le reproche-t-il aux Anonymous ou bien aux politiciens qui mettent en avant le danger de la contestation plutôt que celui de la criminalité ? On ne le saura pas.

Globalement, l'auteur, un gendarme, n'hésite pas devant la déformation professionnelle. Il privilégie le point de vue des enquêteurs : disposer de plus de moyens mais aussi de plus de possibilités légales, de plus de données enregistrées, et de plus de contrôles (par exemple des papiers d'identité dans les cybercafés, comme obligatoires en Italie). Et, concernant, l'anonymat, j'ai été surpris de voir qu'il était considéré dans ce livre comme un privilège (pour les opposants aux dictatures féroces, uniquement) et pas comme un droit.

Ah, et puis les défenseurs fervents d'IPv6 noteront que celui-ci est accusé de compliquer les enquêtes, via les techniques de coexistence avec IPv4 qui sont nécessaires.

On peut aussi consulter la critique des Échos, la bonne analyse de Gof dans la Mare (où il reproche notamment à l'auteur de ne pas assez donner son opinion), le blog de l'auteur et le site officiel autour du livre.

L'article seul

Détournement d'un nom de domaine via le domaine des serveurs de noms

Première rédaction de cet article le 29 octobre 2012

Lorsqu'on analyse la sécurité de ses noms de domaine, on pense à des choses comme surveiller l'expiration et ne pas oublier de renouveller, ou bien on pense au piratage du registre ou du bureau d'enregistrement par le premier hacker chinois islamiste pédophile venu (comme vu récemment dans .ie) ou alors on pense à des attaques d'encore plus haute technologie comme l'attaque Kaminsky. Mais on pense rarement à un risque courant : un domaine trébuche parce que le domaine de ses serveurs de noms a trébuché. C'est ce qui vient de se produire dans deux cas, et

Les deux cas ont été publiés et discutés ce mois-ci sur la liste dns-operations de l'OARC. Prenons le deuxième domaine,, domaine de Benedictine University (qui n'a apparemment rien à voir avec la boisson française). Ce domaine a deux serveurs de noms :

% dig NS

; <<>> DiG 9.8.1-P1 <<>> NS
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29134
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

; EDNS: version: 0, flags: do; udp: 4096
;			IN	NS

;; ANSWER SECTION:		37533	IN	NS		37533	IN	NS

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Mon Oct 29 10:11:02 2012
;; MSG SIZE  rcvd: 88

Or, le point important est que ces serveurs sont dans un autre domaine, géré par une autre organisation et passant par un bureau d'enregistrement (BE) qui n'a pas de rapport avec Benedictine University (.edu n'utilise pas de bureaux d'enregistrement). En changeant ce domaine, on peut changer le contenu de C'est apparemment ce qui s'est produit à partir du 25 octobre 2012 (merci à Robert Edmonds pour l'analyse) : au lieu de son adresse IP habituelle,, avait tout à coup (sur certains sites, les autres ayant l'ancienne adresse dans les caches). Le domaine avait expiré (ses serveurs de noms sont passés dans le domaine qu'utilise le BE Network Solutions comme purgatoire pour les domaines non renouvelés), quelqu'un l'a apparemment acheté, a changé les serveurs de noms ( Contrôlant alors le contenu de, il pouvait changer toutes les zones dont les serveurs de noms étaient dans C'est ce qui est arrivé à (qui est aussi l'adresse de est enregistré... aux Îles Vierges, paradis fiscal connu.

Le premier cas, quelques jours plus tôt, était celui de (et, qui vend des équipements pour bateaux. Les serveurs de noms étaient dans le domaine, qui a un BE différent de celui de Ce domaine a expiré le 18 octobre (merci à Andrew Sullivan pour l'analyse). Pour pouvoir supprimer le domaine auprès du registre de .com (les contraintes d'intégrité du registre interdisent normalement de supprimer un domaine qui est utilisé par d'autres), le BE a renommé les serveurs de noms ( est devenu La sortie de la commande whois pour ne montrait pas ce changement, puisque le BE de, différent de celui de, n'était pas au courant... Les nouveaux serveurs de noms n'existant pas dans le DNS, le domaine ne marchait plus (ce qui est moins grave que d'être détourné).

La morale de ces deux histoires ? Lorsqu'on analyse la sécurité d'un nom de domaine, il faut aussi regarder celle du nom utilisé pour les serveurs de noms. Le maillon faible est peut-être là. Essayez avec quelques domaines connus, vous verrez que le domaine sensible est souvent celui du fournisseur, pas celui du titulaire.

L'article seul

Pourquoi donner des instructions alors que donner un URL serait plus simple ?

Première rédaction de cet article le 28 octobre 2012
Dernière mise à jour le 29 octobre 2012

Mais pourquoi voit-on tant de documentations d'un site Web donner des instructions plus ou moins alambiquées pour la navigation (« allez en Aide puis Dépannage ») , alors qu'il serait si simple de donner un URL qui est sans ambiguité, et souvent tout aussi lisible ?

Pour prendre un exemple, la Préfecture de police de Paris (je n'ai rien contre cette organisation, c'est le premier exemple qui m'est tombé sous la main) diffuse des brochures annonçant « [Faites vos démarches] par Internet : Rubriques vos démarches/Services en ligne/Prise de rendez-vous ». Notons que les instructions singent la syntaxe des URL mais n'en sont pas. Le bon URL est

Pourquoi n'avoir pas donné simplement cet URL ? Au téléphone, on peut craindre qu'il ne soit pas bien compris. Mais sur des instructions diffusées sur le papier ? Parfois, c'est parce que les URL ne sont pas lisibles (violation du principe des beaux URL). Mais, le plus souvent, c'est parce que les gens qui rédigent ces documentations ne connaissent pas les URL (ils ne savent pas qu'on peut indiquer autre chose que la page d'accueil du site) ou ne comprennent pas leur rôle.

Ou bien c'est un phénomène purement français, souvenir de l'époque du Minitel, qui n'avait pas d'équivalent des URL ? Le même phénomène se voit-il dans les autres pays ?

En attendant, voici les remarques justifiant ces instructions que j'ai reçues :

  • Par Florian Maury : recopier un URL est de l'écriture, suivre les instructions de la lecture et quelques clics. Or, bien des gens ne tapent pas vite, même en 2012. Comme le note Valentin Lorentz, « Une faute de frappe, et c'est foutu ». Pierre Beyssac a un argument analogue, l'URL ci-dessus est long à retaper... Il suggère des raccourcisseurs d'URL locaux, du genre
  • Par Michel Guillou, la suggestion d'utiliser plutôt un code QR sur la documentation papier.
  • Par plusieurs personnes : car les URL changent, pas la navigation. Je suis très sceptique : non seulement changer les URL est une très mauvaise pratique mais la navigation change aussi, et sans doute plus souvent.

L'article seul

RFC 6733: Diameter Base Protocol

Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : V. Fajardo (Telcordia Technologies), J. Arkko (Ericsson Research), J. Loughney (Nokia Research Center), G. Zorn (Network Zen)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dime
Première rédaction de cet article le 26 octobre 2012

Pendant longtemps, le seul protocole standard d'authentification entre un NAS et sa base d'utilisateurs était Radius. Diameter, normalisé dans notre RFC (qui fait suite au RFC 3588), visait à le remplacer, et est bien plus riche en fonctions.

Traditionnellement, lorsqu'un client PPP ou d'un protocole similaire se connecte à son FAI, sa session est terminée sur un NAS, équipement qui ne possède en général pas de base des utilisateurs autorisés. Il y a plusieurs raisons à cela, comme le fait que le NAS n'est en général pas un ordinateur généraliste, il a peu de moyens, notamment en place disque ou bien comme le fait qu'un FAI a typiquement plusieurs NAS (au moins un par POP), et qu'il souhaite centraliser l'authentification. (Dans le monde 802.11, le NAS est typiquement nommé AP - Access Point.)

Le mécanisme habituel est donc que le NAS soit client d'un protocole d'authentification et que le FAI gère un serveur de ce protocole, serveur qui connaitra les utilisateurs autorisés. Le même protocole assure en général également des fonctions de comptabilisation des accès, d'où le sigle AAA (Authentication, Authorization and Accounting). Le premier protocole standard en ce sens est Radius (RFC 2865), que Diameter vise à remplacer. (Un protocole privé, Tacacs, qui sera documenté dans le RFC 1492, avait également été utilisé.) Diameter avait été normalisé à l'origine dans le RFC 3588. Après une longue gestation (plusieurs années, alors qu'aucun changement de fond n'a été fait, et pas moins de trois « Last Calls » devant l'IETF), il est désormais remplacé par ce nouveau RFC 6733. Le protocole reste le même et les logiciels conformes à l'ancien et au nouveau RFC devraient interopérer.

Que reproche Diameter à Radius ? La section 1 de notre RFC détaille les faiblesses de Radius perçues par les auteurs de Diameter. Une analyse plus détaillée figure dans le RFC 3169 :

  • Utilisation d'UDP, protocole de transport n'assurant pas de fiabilité,
  • Pas de mécanisme de redondance standard,
  • Limites de taille pour certains paramètres (par exemple la longueur d'un attribut n'est codée que sur un octet, ce qui limite les attributs à 256 caractères).

Diameter est donc plus riche et plus complexe que Radius. Diameter reprend aussi plusieurs idées de Radius comme le codage en doublets Attribut / Valeur (AVP pour Attribute-Value Pairs) ou comme l'utilisation des NAI du RFC 7542 pour coder l'identité vérifiée.

Le RFC est bien plus long et compliqué que son équivalent Radius (154 pages !). La section 1 introduit le protocole, et ses usages, et le compare aux exigences listées dans le RFC 2989.

La section 2 précise le protocole, par exemple le mécanisme de transport fait l'objet de la sous-section 2.1, qui impose au minimum TCP et SCTP (les détails sont dans le RFC 3539). Diameter écoute par défaut sur le port 3868. La 2.4 introduit le nouveau concept d'Application Identifier, valeur enregistrées auprès de l'IANA qui identifie un usage particulier de Diameter (plus riche que Radius, Diameter permet davantage d'usages). Par exemple, l'usage en tant que service d'authentification pour un NAS (Application Identifier n° 1) n'est pas dans le cœur du protocole, il est délégué au RFC 4005. D'autres RFC décrivent des applications de Diameter comme le RFC 4740 qui parle de son usage pour SIP. 2.5 parle de la différence entre connexions et sessions, une connexion étant un concept de la couche 4 alors qu'une session Diameter peut impliquer plusieurs connexions. En 2.8, on trouve le bestiaire des agents Diameter, les clients et les serveurs bien sûr mais également les relais ou bien les traducteurs, pour parler à des agents d'autres protocoles, notamment Radius.

La section 3 décrit l'en-tête des paquets Diameter et les codes de commande qu'ils contiennent comme Capabilities-Exchange-Request. Seuls les codes communs à toutes les applications sont définis dans la section 3.1, des codes aussi importants que AA-Request (demande d'authentification, l'équivalent du Access-Request de Radius) sont délégués à d'autres RFC (comme le RFC 4005).

En section 4, nous arrivons aux AVP eux-même, les doublets attributs-valeur qui portent l'information. On notera en 4.1 un concept désormais fréquent dans les protocoles réseaux, l'option Mandatory qui indique pour un AVP, s'il doit absolument être connu de l'implémentation (le dialogue Diameter avorte autrement) ou bien s'il peut tranquillement être ignoré, par exemple par une vieille implémentation qui ne connait pas ce nouvel AVP. La sous-section 4.3 décrit, entre autre, les URI Diameter, de plan aaa:, comme aaa://;protocol=diameter.

Les sections 5 à 8 spécifient les nombreuses machines à état qui doivent être mises en œuvre par les agents Diameter. Au contraire de Radius qui, comme le DNS, est purement requête/réponse, Diameter nécessite un vrai automate dans chaque agent.

La sous-section 5.2 explique comment un agent Diameter peut en trouver un autre. Avec Radius, la configuration (par exemple du serveur d'authentification) devait être manuelle. Avec Diameter, on peut utiliser SLP (RFC 2165) ou NAPTR combiné avec SRV (RFC 2782).

La section 13, sur la sécurité, est très stricte. Un agent Diameter doit pouvoir faire du TLS (mais, contrairement au RFC 3588, IPsec n'est plus qu'une possibilité secondaire).

Une bonne introduction à Diameter a été publié en Il n'existe que trois implémentations de serveur Diameter en logiciel libre, Free Diameter, Open Diameter et OpenBlox Diameter, et, à part la première, elles semblent peu maintenues. (Et je ne suis pas sûr qu'OpenBlox soit vraiment libre.)

Le bilan opérationnel de Diameter est mince : beaucoup plus complexe que Radius, il ne l'a pas réellement remplacé dans son secteur, l'authentification via un NAS. Diameter semble bien être une nouvelle victime de l'effet « Deuxième système ».

Quels sont les changements par rapport au premier RFC Diameter, le RFC 3588 ? La section 1.1.3 en donne un résumé (la liste exacte est trop longue pour être incluse dans ce RFC déjà très long). Si les changements sont nombreux, ils ne sont pas suffisamment importants pour qu'on puisse parler d'un nouveau protocole. C'est le même Diameter et les nouveaux logiciels pourront parler avec les anciens. Les changements sont des clarifications, des abandons de certaines fonctions, et la correction des nombreuses erreurs du RFC précédent (à mon avis, il y a une leçon à en tirer : les spécifications compliquées sont plus difficiles à faire correctement). Certaines fonctions étaient mentionnées dans le RFC 3588 mais même pas décrites complètement. Les principaux changements :

  • Plus de mécanisme pour négocier en cours de session une sécurisation de la session par le chiffrement et introduction d'un nouveau port, le 5868, pour des connexions chiffrées avec TLS dès le début. (En fait, l'ancien mécanisme reste mais uniquement pour assurer la compatibilité.)
  • La demande irréaliste du RFC 3588 d'avoir toujours IPsec a été retirée.
  • Simplification de plusieurs fonctions comme la découverte du pair (pour laquelle il existait un zillion de méthodes dans le RFC 3588).
  • Et bien d'autres clarifications, corrections de bogue dans les machines à état, etc.

Téléchargez le RFC 6733

L'article seul

Surveillance de réseau avec Icinga sur un Raspberry Pi

Première rédaction de cet article le 25 octobre 2012
Dernière mise à jour le 11 novembre 2012

Je vous ai déjà parlé ici de mes essais avec le Raspberry Pi et de mon interrogation : « Bon, d'accord, ce petit ordinateur pas cher est très cool. Mais à quoi peut-il servir en vrai, à part à afficher les messages de boot du système sur mon grand écran de télé ? » Un des usages qui me semblait intéressant, vue notamment la faible consommation électrique du Pi, était de la surveillance de réseau. Cet article décrit la configuration avec le logiciel de surveillance Icinga.

L'article complet

RFC 6769: Simple Virtual Aggregation (S-VA)

Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : R. Raszuk (NTT MCL), J. Heitz (Ericsson), A. Lo (Arista), L. Zhang (UCLA), X. Xu (Huawei)
Pour information
Réalisé dans le cadre du groupe de travail IETF grow
Première rédaction de cet article le 25 octobre 2012

Un des gros problèmes des routeurs de la DFZ, dans l'Internet d'aujourd'hui, est l'augmentation du nombre de routes. Il y a, en octobre 2012, environ 450 000 routes dans cette DFZ et ce nombre croît sans cesse. Ces routes doivent être mises en mémoire et la mémoire d'un routeur du cœur de l'Internet est quelque chose de compliqué, qu'on ne veut pas gaspiller. Des tas d'approches ont été proposées pour traiter ce problème. Ce RFC propose un moyen astucieux de limiter les dégâts, en permettant au routeur d'agréger les routes pour les préfixes IP proches. Ce RFC est donc très court car l'idée est simple.

Attention au terme de « table de routage », trop vague. Un routeur met des routes dans au moins deux tables, la RIB (Routing Information Base, la base constituée par les protocoles de routage, BGP et ses copains OSPF et IS-IS) et la FIB (Forwarding Information Base, typiquement placée dans la CAM car elle doit être très rapide, elle est consultée à chaque paquet). Actuellement, le routeur typique met toutes les entrées de sa RIB dans sa FIB. C'est sous-optimal car la RIB a beaucoup plus d'entrées que le routeur n'a de voisins réseau (des centaines de milliers de routes contre parfois seulement dix ou vingt routeurs voisins). Comme la taille de la FIB est souvent un facteur limitant (ce n'est pas le seul, donc ce RFC ne résout pas tous les problèmes de taille), il serait intéressant d'agréger violemment, en découplant RIB et FIB. Par exemple, si la RIB contient une entrée pour 2001:db8:16::/48 et une autre pour 2001:db8:17::/48, et que les deux vont vers le même voisin (ont le même next hop), mettre les deux entrées dans la FIB est du gaspillage, une seule entrée, pour 2001:db8:16::/47, suffirait. (Et le calcul pour déterminer ce qu'on peut agréger est simple.)

Au passage, on peut agréger dans la FIB mais moins dans la RIB car cette dernière doit être transmise aux routeurs pairs avec qui on échange des routes. Si on agrège, c'est une « compression avec perte » et les pairs ne recevront donc pas toute l'information. Néanmoins, ce RFC permet également de ne pas installer de routes dans la RIB. Celle-ci est typiquement dans une mémoire moins coûteuse mais on souhaite diminuer, non seulement la consommation mémoire mais également le rythme de changement. Moins on aura de préfixes, moins on aura de changements à gérer.

L'avantage de l'approche naïve ci-dessus est qu'elle est déployable unilatéralement : chaque routeur peut le faire dès aujourd'hui sans rien demander à personne. Son principal inconvénient est que la RIB n'est pas statique : si BGP change le next hop (le routeur suivant pour acheminer le paquet) de 2001:db8:17::/48, il faut désagréger en vitesse et mettre deux entrées dans la FIB.

L'approche de ce RFC est donc un peu différente : certains routeurs de l'AS vont annoncer des préfixes virtuels (VA prefix pour Virtual Aggregation prefix). Ils seront transmis, à l'intérieur de l'AS uniquement, par les protocoles de routage habituels et tous les routeurs vont l'avoir dans leur RIB. Ces préfixes virtuels couvrent plusieurs préfixes « réels ». Les routeurs qui veulent économiser de la mémoire ne vont pas installer les préfixes réels couverts dans leur FIB. Notez bien que les préfixes virtuels ne sont pas annoncés en dehors de l'AS. Si cette solution n'est plus déployable par un routeur seul, elle l'est par un AS seul.

Un opérateur réseau va donc typiquement avoir quelques très gros routeurs qui auront dans leur FIB (et dans leur RIB) tous les préfixes. Ils annonceront en plus les préfixes virtuels. Les autres routeurs, moins gros et moins coûteux, garderont tous les préfixes uniquement dans leur RIB et ne mettront pas dans la FIB les préfixes qui sont couverts par un des préfixes virtuels. Le préfixe virtuel pourra même être la route par défaut, entraînant ainsi la non-installation dans la FIB de tous les préfixes ayant le même next hop que la route par défaut.

Un peu de vocabulaire, maintenant (section 1.1) : un FIR (FIB Installation Router) est un des gros routeurs de cœur, qui installe toutes les routes dans sa FIB, et annonce les préfixes virtuels. Un FSR (FIR Suppressing Router) est un routeur situé plus aux marges du réseau et qui n'installe pas dans sa FIB les routes couvertes par un préfixe virtuel, si elles ont le même next hop que le préfixe virtuel. (Le RFC dit « supprimer une route » pour « ne pas l'installer dans la FIB ».) Une troisième catégorie de routeurs est composé des machines actuelles, qui ne connaissent pas ce RFC, et ne peuvent donc ni émettre les préfixes virtuels, ni supprimer des routes couvertes par un tel préfixe.

La section 2 décrit en détail le fonctionnement de ce système. Un FIR doit annoncer les préfixes virtuels en mettant dans les attributs de l'annonce BGP un ORIGIN (RFC 4271, section 5.1.1) à INCOMPLETE (pour dire que la route n'a pas été apprise par un protocole de routage). Il doit mettre NEXT_HOP (RFC 4271, section 5.1.3) à l'adresse du routeur qui gérera toutes les routes du préfixe virtuel. Et il doit ajouter un attribut NO_EXPORT (RFC 1997) pour éviter que ce préfixe virtuel ne sorte de l'AS.

Le FSR, lui, lorsqu'il reçoit de telles routes, les installe dans RIB et FIB. Il peut alors décider de supprimer de sa FIB les routes plus spécifiques ayant le même next hop. Comme vous le voyez, c'est très simple.

La section 3 du RFC se penche sur les problèmes opérationnels pratiques. D'abord, attention au fait qu'une route BGP peut être utilisée pour résoudre un next hop qui n'est pas directement connecté. Il ne faudra donc pas supprimer de la RIB de telles routes.

On l'a vu, les routeurs FSR peuvent économiser de la place non seulement en FIB mais également en RIB, en supprimant de celles-ci les routes couvertes par un préfixe virtuel. Attention, cela peut interagir avec une politique de redistribution de routes aux pairs. Si une telle politique est en place (fondée, par exemple, sur la longueur du préfixe) on peut avoir des cas où la route couverte aurait été redistribuée mais où le préfixe virtuel ne l'est pas. Dans ce cas, il ne faut pas supprimer la route couverte de la RIB (on peut toujours la supprimer de la FIB).

À noter que le groupe de travail grow avait également travaillé sur des mécanismes d'agrégation plus complexes (avec des tunnels MPLS pour joindre les routeurs annonçant les préfixes virtuels) mais que cela n'a pas abouti. Les Internet-Drafts ont été abandonnés. Un bon article de fond sur cette idée d'« agrégation virtuelle » est celui de Paul Francis et Xiaohu Xu (un des auteurs du RFC), « Extending Router Lifetime with Virtual Aggregation ».

Globalement, cela me semble une bonne idée. Avec les préfixes virtuels, ce n'est plus une solution locale au routeur mais c'est local à l'AS et donc ça reste déployable unilatéralement.

Merci à Sarah Nataf pour avoir attiré mon attention sur ce document et à Bastien Pilat et Benjamin Abadie pour leurs corrections.

Téléchargez le RFC 6769

L'article seul

Un exemple de remplacement de clé DNSSEC, avec OpenDNSSEC

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

Si vous avez déjà un peu regardé DNSSEC, vous avez dû noter qu'on vous suggère fortement de remplacer (to roll over) les clés cryptographiques de temps en temps. La nécessité de ces remplacements ne fait pas l'unanimité, notamment en raison de sa complexité. Toutefois, avec les outils modernes, le problème est nettement simplifié. Voici l'exemple pas-à-pas du récent remplacement de la KSK (Key Signing Key) du domaine

Le domaine est hébergé chez moi, le serveur maître est un nsd et les clés sont gérées par OpenDNSSEC, ce qui simplifie beaucoup les choses. Le principe d'OpenDNSSEC est qu'on exprime la politique (taille des clés, remplacement, durée de vie) dans le fichier de configuration et OpenDNSSEC s'occupe de tout. Le fichier de configuration est bien documenté. Voici la configuration de la KSK (Key Signing Key) de mes zones :

   <Algorithm length="2048">8</Algorithm> <!-- 8 = RSA/SHA-256 -->
   <Lifetime>P2Y</Lifetime> <!-- P2Y = two years . Probably useless
   if we have ManualRollover set -->

Il existe évidemment des tas d'autres politiques possibles, configurables dans kasp.xml, par exemple en utilisant des Standby Keys (<Standby>1</Standby>), où la clé est générée mais pas publiée dans le DNS.

À noter que l'utilisation de nsd nécessite un petit bricolage d'intégration avec OpenDNSSEC.

Voyons maintenant l'opération. La KSK avait le keytag 44461. DNSviz affiche l'ancienne configuration : Le 5 octobre vers 1000 UTC, je lance le processus :

# ods-ksmutil key rollover --zone --keytype KSK

La nouvelle clé, la 3445 est créé et aussitôt publiée dans le DNS. (J'ai un moniteur de mes zones qui surveille les clés et leurs remplacements, le code est sur FramaGit, il m'a servi pour un article à la conférence SATIN et m'a prévenu tout de suite de l'arrivée de la nouvelle clé.)

Mais la nouvelle clé n'est pas utilisable tout de suite : il faut attendre la réjuvénation complète dans le DNS, des caches ont encore le vieil ensemble DNSKEY. C'est pour cela qu'OpenDNS affiche pour cette clé 3445 un état publish et pas encore active :

# ods-ksmutil key list --zone  --verbose                   KSK           active    2012-10-05 12:14:02 ... 44461                   KSK           publish   2012-10-06 00:14:03 ... 3445

(Les états d'OpenDNSSEC ont fait l'objet d'un autre article.) Les durées (par exemple le TTL) sont configurées également dans kasp.xml, éléments <TTL>, <*Safety>, etc.

Pas besoin de surveiller en permanence, OpenDNSSEC se charge de vérifier qu'il n'y aura pas d'erreur de timing (cf. RFC 7583). C'est donc seulement trois jours après que j'ai repris le dossier. 3445, toujours publiée, a changé d'état :                   KSK           ready     waiting for ds-seen ... 3445

Le remplacement d'une KSK nécessite une interaction avec le parent. OpenDNSSEC n'a pas à l'heure actuelle de code pour vérifier que l'interaction a été faite (on peut utiliser pour cela le script de Mathieu Arnold) et l'enregistrement DS publié. Il faut donc lui indiquer, une fois la manipulation faite. Les bureaux d'enregistrement le font souvent par EPP (RFC 5910, et cela peut s'automatiser, voir par exemple un script de Mathieu Arnold). Les autres passent en général par un formulaire Web. (Une solution utilisant le DNS a depuis été normalisée dans le RFC 7344 mais n'est pas très répandue encore.) Dans mon cas, la zone parente était .fr donc l'AFNIC, et le bureau d'enregistrement était Gandi. Je demande à OpenDNSSEC le DS :

# ods-ksmutil key export --ds
SQLite database set to: /var/lib/opendnssec/db/kasp.db
;active KSK DS record (SHA1):  3600    IN      DS      3445 8 1 53ad69094ea377347c5538f076d889af5a4f6243
;active KSK DS record (SHA256):  3600    IN      DS      3445 8 2 7cc6f2980fd42b5fbf587cad5b00712bfe568343691135434b719c2bebdf450e

Et je soumets la clé à l'AFNIC, via Gandi (je l'ai fait à la main mais, là encore, Mathieu Arnold a un script pour automatiser cela, via l'API de Gandi) gandi-dnssec.jpg Le second DS a été publié quelque temps après (une vérification technique est systématiquement faite avec Zonecheck, ce qui est particulièrement important pour DNSSEC, plus sensible aux erreurs de configuration). dig montrant que le second DS est bien là (rappelez-vous bien de tester à chaque fois avant de passer à l'étape suivante), je le dis à OpenDNSSEC :

# ods-ksmutil key ds-seen --zone --keytag 3445
SQLite database set to: /var/lib/opendnssec/db/kasp.db
Found key with CKA_ID 02656a5fe158c6e25f7c965eb9a1ca3d
Key 02656a5fe158c6e25f7c965eb9a1ca3d made active
Old key retired

Ainsi prévenu, OpenDNSSEC change l'état de la clé :

# ods-ksmutil key list --zone  --verbose
SQLite database set to: /var/lib/opendnssec/db/kasp.db
Zone:                           Keytype:      State:    Date of next transition: ...      Keytag:                   KSK           retire    2012-10-09 17:52:03      ...      44461                   KSK           active    2013-10-09 13:05:24      ...      3445

L'ancienne clé, la 44461 est toujours publiée dans le DNS à ce stade. Dès que les caches auront tous le nouveau DS, elle sera abandonnée. En effet, le lendemain, elle a disparu :

# ods-ksmutil key list --zone  --verbose 
SQLite database set to: /var/lib/opendnssec/db/kasp.db
Zone:                           Keytype:      State:    Date of next transition:  ...      Keytag:                   KSK           active    2013-10-09 13:05:24       ...      3445

Tout est donc terminé. Il n'a fallu que trois étapes explicites de ma part :

  • Lancer le processus de remplacement avec ods-ksmutil key rollover,
  • Transmettre le DS au registre, via le BE,
  • Prévenir OpenDNSSEC que cette étape a été terminée, avec ods-ksmutil key ds-seen.

Tout le reste est automatique. OpenDNSSEC s'occupe de tout et surveille le timing (ainsi, ods-ksmutil key export n'acceptera pas d'exporter la clé si elle n'a pas été créée depuis assez longtemps).

L'article seul

RFC 6771: Considerations for Having a Successful "Bar BOF" Side Meeting

Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : L. Eggert (NetApp), G. Camarillo (Ericsson)
Pour information
Première rédaction de cet article le 18 octobre 2012

Autrefois, du temps des débuts de l'IETF, les seules réunions ayant un statut officiel étaient les réunions formelles des groupes de travail. Avec le temps, elles sont devenues tellement formelles (et n'ayant plus guère de rapport avec un « groupe de travail ») qu'un type de réunions plus légères est apparu petit à petit, les BOF (Birds Of a Feather). Les BOF étaient au début simples et faciles à organiser, comme l'étaient les groupes de travail des débuts. Mais elles se sont ossifiées petit à petit, devenant aussi formelles qu'un groupe de travail, et ayant même leur propre RFC, le RFC 5434. Continuant cette évolution logique, des participants à l'IETF ont créé un mécanisme léger alternatif aux BOF, les Bar BOF, qui étaient comme leur nom l'indique, des réunions faites au bistrot. Maintenant, on parle de fixer des règles pour les bar BOF...

Les bar BOF sont fréquentes pendant les réunions physiques de l'IETF. Elles se réunissent souvent dans un bar, d'où elles tirent leur nom, et permettent de discuter de manière complètement informelle, de nouvelles idées qui donneront peut-être naissance plus tard à un groupe de travail, voire à un ou plusieurs RFC. Elles ne sont pas mentionnées dans l'agenda officiel et n'ont aucun statut particulier. N'importe qui peut organiser une bar BOF comme il veut (alors que l'organisation d'une BOF est désormais toute une affaire, décrite dans le RFC 5434). Elles ont déjà été mentionnées dans un RFC, le fameux Tao (RFC 6722).

La malédiction se poursuivant, certaines bar BOF sont devenues tellement formalistes qu'on peut se demander si certains ne réclameront pas bientôt statuts et règles pour ces réunions. Ce RFC 6771 essaie de bloquer cette tendance, en plaidant pour que les bar BOF restent complètement an-archiques.

Car ce n'est pas le cas : on voit de plus en plus de bar BOF tenues dans les salles de réunion (et plus au café), avec les chaises organisées comme dans une salle de classe, des orateurs situés sur l'estrade, un tour de parole, des présentations faites avec PowerPoint et, surtout, plus de boissons du tout...

Ce RFC signale que cette évolution peut être due en partie au fait que le terme bar BOF est trop proche de BOF et que les débutants mélangent les BOF (dotées d'un statut, celui du RFC 5434) et les bar BOF. C'est au point que certains participants, voulant aboutir à la création d'un groupe de travail, se sentent obligés de faire une bar BOF uniquement parce qu'ils croient qu'une règle de l'IETF impose cette étape ! Les auteurs du RFC recommandent donc de parler plutôt de « réunion parallèle » (side meeting).

Et, pour que ces réunions parallèles se passent bien, notre RFC 6771 propose quelques conseils. D'abord (section 2), comment gérer les invitations. Une réunion parallèle doit être petite (« uniquement les gens nécessaires et pas plus »). Il ne s'agit pas, comme c'est souvent le cas pour les BOF, de sonner le clairon pour ramener le maximum de gens, espérant ainsi montrer que le sujet est considéré comme important par la communauté. On ne devrait donc pas faire d'annonce publique d'une réunion parallèle (par exemple, sur une liste de diffusion). Si on le fait, on risque de manquer de chaises dans le bar, et de ne pas pouvoir s'entendre d'un bout de la réunion à l'autre, menant à des réunions excessivement formelles, avec tour de parole. (Plusieurs bar BOF ont déjà souffert de ce syndrôme « apéro Facebook ».)

Bref, pas de touristes à une réunion parallèle, uniquement « a few good people », des gens qui vont activement participer au travail (l'IETF ne décide normalement pas sur la base du nombre de participants mais sur le nombre de gens qui vont effectivement bosser). L'implication plus large de la communauté viendra après. La réunion parallèle doit avant tout rester du remue-méninges, chose qui ne se fait pas dans des grands groupes. Par définition, les idées exprimées lors d'une réunion parallèle sont incomplètes et imparfaites et il faut pouvoir les discuter franchement.

De même, on n'est pas obligé d'inviter un membre de l'IESG ou de l'IAB en croyant que cela fera plus sérieux et plus crédible.

Après le Qui, la section 3 couvre la question du Où. Comme leur nom l'indique, les bar BOF se tiennent traditionnellement dans les bars. Mais la tendance récente est de la faire souvent dans les salles d'une réunion IETF, en partie parce que cela fait plus « sérieux ». Notre RFC, qui n'hésite pas à descendre dans les détails concrets, note que les bars sont souvent bruyants, ce qui pose un problème notamment pour les non-anglophones (le bruit gène beaucoup plus lorsque la conversation est dans une langue étrangère). Pour garder la convivialité, en supprimant le bruit, le RFC recommande de choisir un restaurant calme, voire de prendre une arrière-salle du bar. Les salles de la réunion IETF sont en général trop « salle de classe », un environnement qui ne convient pas au remue-méninges entre pairs. Cet environnement est bon pour les présentations, pas pour les discussion.

Toujours concret, le RFC note enfin que se réunir dans un bar ou un restaurant permet souvent de... manger. En effet, certaines réunions IETF se tiennent dans des endroits où le ravitaillement est difficile et la réunion d'Anaheim (IETF 77) a ainsi laissé un souvenir particulièrement cuisant. Sortir est donc souhaitable.

Après le Qui et le Où, le Comment. La section 4 s'insurge contre la tendance de plus en plus marquée à singer les réunions des groupes de travail. On voit ainsi des réunions parallèles ayant un agenda formel, des présentations avec supports, des organisateurs qui se présentent comme bar BOF chair. Les auteurs de notre RFC craignent que ce cirque provoque des réactions pavloviennes chez les participants, les faisant se comporter comme si la réunion parallèle était déjà devenue un vrai groupe de travail. Ces réunions qui caricaturent les réunions officielles ne sont pas très efficaces, et elles entraînent des confusions chez certains participants qui croient qu'il s'agit de réunions officielles, simplement parce qu'elles en ont l'apparence.

Enfin, le Quand, en section 5. La principale recommendation est que les réunions parallèles, comme elles visent à commencer le travail pour résoudre un problème précis, n'ont pas forcément vocation à être toujours parallèles à une réunion IETF, elles peuvent parfaitement se tenir en parallèle d'une réunion RIPE, NANOG ou équivalent.

Et une anecdote amusante : comme obligatoire, ce RFC a une section « Sécurité ». Elle contient l'avertissement qu'on a constaté un oubli fréquent des portables dans les bars, après une réunion parallèle trop arrosée...

Téléchargez le RFC 6771

L'article seul

La cyberguerre n'aura pas lieu

Première rédaction de cet article le 14 octobre 2012

Un concept est très à la mode depuis deux ou trois ans, celui de cyberguerre. Les consultants en sécurité le citent à tout bout de champ, les journalistes le mettent dans leurs titres (moi aussi, vous avez remarqué ?), les politiques le brandissent en classant le risque de cyberguerre dans « l'une des principales menaces auxquelles nous devons faire face ». Y a-t-il une réalité derrière ce concept ?

Il est facile d'ironiser sur cette soi-disant « cyberguerre » en faisant remarquer qu'elle ne fait pas de cybermorts et que personne n'a encore signé de traité de cyberpaix. Il est clair que la cyberguerre n'a pas les caractéristiques habituellement associées à la guerre. La guerre, ce n'est pas seulement la violence physique, directe et organisée, contre l'autre camp (à ce compte-là, criminels et patrons voyous pourraient être qualifiés de guerriers). La guerre, c'est surtout l'engagement massif de moyens, la mobilisation (pas forcément sous l'uniforme) de tas de gens dont ce n'était pas le métier. C'est le risque, en cas de défaite, de changements radicaux (et en général négatifs) dans la vie de millions de gens. On ne parle pas de guerre pour quelques coups de feu de temps en temps, sauf quand on est un politicien malhonnête cherchant à faire parler de lui à la télé en exagérant les problèmes.

Ainsi, l'exemple souvent cité de « première cyberguerre de l'Histoire », l'attaque russe contre l'Estonie ne peut être qualifiée de guerre que par des gens qui n'ont jamais vécu une vraie guerre ! Si la Russie avait envahi l'Estonie, il y aurait eu pour les Estoniens des conséquences autrement plus graves que celui de ne pas pouvoir retirer d'argent à la banque pendant quelques jours ! Le terme de cyberguerre est ici une insulte aux victimes des vraies guerres menées par le pouvoir russe, comme celles contre la Tchétchénie ou contre la Géorgie.

Et les actions ayant des conséquences physiques, comme Stuxnet ? Ce qui fait que Stuxnet ne mérite pas d'être appelé « cyberguerre », ce n'est pas seulement le fait qu'il n'y ait pas eu de morts. C'est surtout le fait que toute action hostile d'un État voyou contre un autre (ici, le sabotage des installations nucléaires iraniennes) n'est pas forcément une guerre ou alors le terme ne veut plus rien dire. À l'extrême rigueur, on pourrait parler de « cyberguérilla » ou de « cybersabotage ». Imaginons que les services secrets israéliens ou états-uniens aient procédé à un sabotage classique, avec dépôt et mise à feu d'explosifs. Parlerait-on de guerre ? Le résultat aurait pourtant été le même.

Et c'est encore plus net pour des opérations comme Duqu ou Flame, où il n'y avait pas d'action, juste de l'espionnage. Certes, l'exploitation de failles de sécurité de MS-Windows change des méthodes de Mata Hari mais c'est simplement le progrès technique. Et ce n'est pas la « cyberguerre » pour autant, ou alors les États sont en guerre en permanence ! (Puisqu'ils s'espionnent en permanence.)

Mais, alors, pourquoi tant de gens utilisent-ils ce terme erroné de « cyberguerre » ? Dans le numéro de novembre 2010 de la revue « Réalités industrielles », on trouve un article de Nicolas Arpagian avec cet aveu touchant : « on peut reconnaître néanmoins l'efficacité [pour toucher un large public] du mot cyberguerre ». Tout est dit : « cyberguerre » est simplement un moyen, pour les consultants, d'obtenir davantage de budget et de missions, pour les journalistes, d'avoir plus de lecteurs et pour les politiques, de faire voter ce qu'ils voudraient.

C'est ainsi que le documentaire « La guerre invisible » fait défiler une longue cohorte d'ex-généraux ou ex-ministres âgés, tous reconvertis dans la cyberpeur, et tous annonçant qu'on peut faire dérailler un train ou empoisonner l'eau via l'Internet. L'un des pires de ces cyberpaniqueurs, Richard Clarke, brandit pendant toute l'émission son livre, pour qu'on n'oublie pas de l'acheter. Il est clairement dans une démarche commerciale et pas dans une tentative de sensibiliser les citoyens à un problème réel.

Pourtant, le problème n'est pas imaginaire. Il y a aura certainement dans les guerres futures, du piratage de drones, des attaques informatiques pour couper les communications de l'ennemi, etc. Mais ce n'est pas de la « cyberguerre », c'est simplement l'utilisation de moyens « cyber » pour la guerre. Si on définit la cyberguerre comme « l'utilisation du cyberespace par des groupes militaires dans le cadre de conflits armés » (Julie Horn), alors on n'a pas avancé dans la terminologie : la guerre utilise forcément les moyens techniques existants. On n'a pas parlé d'« airguerre » avec le développement des avions de combat, ou de « guerre chevaline » lorsque la cavalerie a fait ses débuts...

Est-ce un simple problème de terminologie erronée ? Non, car le terme de cyberguerre n'est pas innocent. Il ne sert pas seulement à justifier le business de quelques consultants incompétents et powerpointeurs. Il vise surtout à conditionner les esprits, à faire croire que nous sommes en guerre, et à habituer les citoyens aux habituelles restrictions, matérielles et surtout de libertés, qui sont la conséquence habituelle de la guerre. Comme le fait remarquer Peter Sommer, interrogé dans le rapport OCDE de janvier 2011, « We don't help ourselves using 'cyberwar' to describe espionage or hacktivist blockading or defacing of websites, as recently seen in reaction to WikiLeaks ». Non, en effet, cette confusion n'aide pas. Mais elle n'est pas due à la paresse intellectuelle ou au manque de sang-froid. Elle est délibérée, cherchant aussi à criminaliser toute opposition en mettant dans le même sac des opérations d'un État puissant et surarmé avec des actions plus ou moins efficaces de groupes informels. Le même Sommer ajoute à juste titre « Nor is it helpful to group trivially avoidable incidents like routine viruses and frauds with determined attempts to disrupt critical national infrastructure,. Mais une telle réserve dans l'analyse ne lui vaudra certainement pas de passer à la télévision...

Quelques bonnes lectures sur ce sujet :

L'article seul

RFC 6749: The OAuth 2.0 Authorization Framework

Date de publication du RFC : Octobre 2012
Auteur(s) du RFC : D. Hardt (Microsoft)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF oauth
Première rédaction de cet article le 13 octobre 2012

Le protocole OAuth a désormais sa seconde version, OAuth 2.0, normalisée dans ce RFC. OAuth permet de à un programme de s'authentifier sur le Web, pour accéder à un jeu limité de services, qu'un utilisateur lui a autorisé.

OAuth est donc un protocole d'authentification d'un tiers, le client, qui veut accéder à une ressource, par exemple un fichier, située sur un serveur et dont le contrôle revient à un propriétaire, le resource owner. (OpenID vise à authentifier un utilisateur humain, OAuth à authentifier la requête d'un programme, agissant pour le compte d'un humain.) Prenons un exemple (vous en trouverez d'autres dans le RFC, comme l'exemple classique de l'impression de photos, mais celui que j'indique a l'avantage d'être un exemple réel) : le service de microblogging Twitter permet à des utilisateurs (les propriétaires, dans la terminologie OAuth) de faire connaître au monde entier leurs pensées profondes en moins de 140 caractères. Le succès de ce service et l'existence d'une bonne (car très simple) API a poussé à l'arrivée de nombreux services tiers qui ont tous en commun de devoir accéder au compte Twitter de l'utilisateur (par exemple, Twibbon ou TwitterCounter). Une façon possible, pour ces services, d'accéder au compte Twitter de l'utilisateur est de lui demander son nom et son mot de passe. On voit les conséquences que cela peut avoir pour la sécurité : le service doit stocker le mot de passe (le fera-t-il de façon sûre ?), le service peut abuser de son privilège, puisqu'il a tous les droits du propriétaire, le serveur doit gérer l'authentification par mot de passe (pas la meilleure), retirer un droit d'accès à un service veut dire changer le mot de passe, retirant ainsi le droit d'accès à tous les services tiers, etc.

OAuth fournit une meilleure solution : le serveur, en recevant la requête du client, demande au propriétaire l'autorisation : twitter-oauth.png Cette demande se fait typiquement via un formulaire HTML.

Le service tiers reçoit alors un token, une autorisation qui lui est spécifique, et ne lui donne que certains droits. Il présentera ce token au serveur pour obtenir l'accès.

Tout se fait par redirections HTTP (RFC 7231, section 6.4 et ce RFC 6749, section 3). Bien sûr, pour que cela soit sûr, il y a de nombreux détails à prendre en compte.

Si OAuth v1 (RFC 5849) était juste l'officialisaton à l'IETF d'un protocole qui avait été développé à l'extérieur, cette nouvelle version 2 marque des changements profonds, et incompatibles avec l'ancienne version. C'est d'abord une refonte de la norme, d'un seul document à un ensemble dont ce nouveau RFC 6749 n'est que le document de cadrage. Les documents décrivant effectivement le protocole ne sont pour la plupart pas encore parus (il y a par exemple un projet de RFC sur les scénarios d'usage, et un entièrement consacré à la sécurité, via une études des menaces portant sur OAuth). Seuls les RFC 6750, sur un type particulier de token, et RFC 6755 sur des URN pour OAuth, accompagnent ce nouveau OAuth. C'est aussi le passage d'un protocole relativement simple à un ensemble de protocoles, partageant un cadre commun mais n'étant plus forcément interopérables (section 1.8), puisque OAuth v2 permet bien des variantes. C'est complètement contraire aux principes posés dans le RFC 6709, sur les extensions aux protocoles. Donc, attention, un service OAuth v1 ne peut pas interagir avec un serveur OAuth v2 (quand ils existeront) ou le contraire. Les programmeurs OAuth sont encouragés à repartir de zéro, vue la différence des deux protocoles.

Une fois que Twitter a adopté ce protocole (notez que, à la date de publication de ce RFC, Twitter utilise OAuth v1 et n'a pas annoncé d'intention de passer à la v2) et documenté son usage, la plupart des services tiers l'ont intégré (par exemple Twibbon).

Lisons maintenant le RFC. Premièrement, les concepts (section 1) et le vocabulaire (section 1.1). Ce qui se jouait autrefois à deux (le client et le serveur) est désormais fréquemment une partie à trois (OAuth Love Triangle, dit Leah Culver), le client (client, Twibbon dans le cas plus haut), le serveur (server, Twitter dans le cas plus haut) et le propriétaire (resource owner, moi). Notez qu'OAuth v2 a transformé le triangle en carré, en passant à quatre rôles, le serveur ayant été séparé en deux, le serveur qui contrôle l'accès à la ressource convoitée, et celui qui donne les autorisations. En pratique, on ne sait pas encore si des serveurs suivront cette séparation.

Pour voir le cheminement complet d'une authentification OAuth, on peut regarder la jolie image de Yahoo (mais attention, elle utilise une ancienne terminologie) ou bien suivre l'exemple de la section 1.2 du RFC. Si le client, le service d'impression veut accéder aux photos stockées sur le serveur, et dont le propriétaire est Jane :

  • Le client et le serveur doivent déjà avoir un accord entre eux, préalable, avec un secret partagé pour s'authentifier. OAuth ne permet pas à un nouveau client inconnu d'en bénéficier.
  • Le client doit avoir lu la documentation du serveur, qui indique entre autre les URL à contacter.
  • Lorsque Jane visite le site du client, ici l'imprimeur, et demande l'impression de ses photos, le client contacte le serveur en HTTP pour demander un token, une suite de nombres aléatoires qui identifie de manière unique cette requête (on peut voir ce token dans la copie d'écran ci-dessus, c'est le paramètre oauth_token).
  • Le client doit alors utiliser les redirections HTTP pour envoyer Jane sur le site du serveur, afin qu'elle donne l'autorisation nécessaire. Les paramètres de la redirection indiquent évidemment le token.
  • Si Jane donne son accord (cela peut être un accord implicite, voir par exemple comment fait Twitter), le serveur signe la demande et renvoie le navigateur de celle-ci vers le client avec, dans les paramètres, une demande approuvée et signée (paramètre oauth_signature).
  • Le client peut alors demander au serveur des autorisations pour les photos, puis demander les photos elle-mêmes.

Un guide complet sur OAuth v1 est disponible en Une autre bonne introduction à OAuth v1 est « Gentle introduction to OAuth ». Parmi les applications amusantes d'OAuth, un curl OAuthisé en Un exemple de programmation OAuth v1 pour accéder à Twitter en Python figure dans mon article. Mais OAuth v2 ne bénéficie pas encore de telles documentations.

OAuth v2 a suscité de nombreuses critiques, notamment sur sa complexité. Mon pronostic est qu'OAuth v2, victime du Second System Effect, ne sera guère déployé, la grande majorité des sites Web restant à la v1.

Une bonne critique qui synthétise la plupart des remarques qui ont été faites sur OAuth v2 est « OAuth 2.0 and the Road to Hell ». Eran Hammer, l'auteur, est marqué dans l'annexe C de ce RFC comme ayant participé à OAuth v2 jusqu'à la version 26 du brouillon (la version publiée est la 31). Il a ensuite cessé sa participation au projet et s'en explique dans cet article. Ses principaux arguments :

  • Le cadre est trop général, ne permettant pas de garantir l'interopérabilité de deux mises en œuvre d'OAuth v2 (ce point est admis dans la section 1.8 de ce RFC 6749). C'est au point qu'un très grand nombre de protocoles incompatibles entre eux pourraient légitimement se nommer « conformes à OAuth »..
  • OAuth v1 était simple et utilisable, issu d'un monde de startups Web qui voulaient une solution « bien assez bonne » et tout de suite. OAuth v2 a été chargé par des exigences de PHB comme de mentionner SAML et autres technologies des « gens de l'entreprise » (par opposition aux « gens du Web »). C'est une tendance analogue qui a tué les Web Services.
  • Étant plus complexe et plus adaptable à des besoins spécifiques, OAuth v2 sera moins sûr.

Téléchargez le RFC 6749

L'article seul

Mesurer le temps de chargement d'un site Web, en ignorant la pub ?

Première rédaction de cet article le 8 octobre 2012

Je suis sûr qu'une partie de mes lecteurs vont apprécier le défi. Le problème a été discuté dans un groupe de travail ARCEP, où il s'agit de mesurer la qualité de l'accès à l'Internet via un FAI. Outre les mesures de bas niveau (les seules sérieuses, à mon avis), on voudrait mesurer un truc plus représentatif de l'utilisation habituelle de l'Internet, l'accès à une page Web. Mais les pages Web « importantes » contiennent souvent des tas d'élements « extérieurs » comme Google Analytics, les publicités, etc. Comment les exclure ?

Je me focalise sur l'aspect technique. Sur la question de fond, il faut se demander si c'est une bonne idée d'exclure quelque chose qui fait partie intégrante du vécu de l'utilisateur...

Le premier algorithme qui vient à l'esprit est d'exclure les contenus externes qui sont désignés par un nom de domaine différent. Prenons la page d'accueil de TF1, Elle référence 31 noms de domaines différents, dont 19 sont en dehors de (par exemple, utilisé pour des statistiques). En examinant ces noms à la main, les choses semblent simples : les noms externes à sont bien pour du contenu « externe », dont l'affichage n'est pas indispensable.

Maintenant, testons un autre média, Libération. La page contient 62 noms de domaine (qui peuvent être des liens à suivre, pas forcément du contenu chargé automatiquement). Mais, cette fois, le problème est que du contenu de la page est chargé à partir de noms en dehors de comme Oui, a le même titulaire que mais allez expliquer cela à un logiciel.

À part des problèmes comme celui-ci, l'examen rapide de quelques sites Web français populaires (bien placés dans Alexa) semble quand même indiquer un gros effort des webmestres pour placer le contenu sous leur nom de domaine. On trouve nettement moins de noms de domaine appartenant à des CDN, par exemple, alors que c'était très courant à une époque. Ce premier algorithme ne semble donc pas catastrophique mais des différences comme vs. le prennent en défaut.

Deuxième algorithme possible, utiliser les listes noires de logiciels comme Ghostery ou Adblock Plus pour éliminer le contenu « externe ».

Et y a-t-il d'autres possibilités ? Vous pouvez indiquer vos suggestions sur SeenThis.

L'article seul

Pourquoi est-ce que les licences « pas d'usage commercial » sont une mauvaise idée ?

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

On trouve souvent des contenus numériques gratuitement accessibles, librement utilisables et réutilisables mais avec une règle supplémentaire : pas d'utilisation commerciale autorisée. C'est par exemple le cas, dans la galaxie Creative Commons, des licences marquées NC (Non Commercial). Mais beaucoup d'autres licences ad hoc reprennent cette idée. En revanche, les logiciels libres comme le projet GNU, ou bien une encyclopédie comme Wikipédia, n'empêchent pas l'utilisation commerciale. Pourquoi est-ce eux qui ont raison ?

A priori, cette interdiction d'utilisation commerciale est le bon sens même. Un auteur (de logiciel, de textes ou d'images, peu importe) travaille dur pour produire un contenu, qu'il permet ensuite au peuple de télécharger et d'utiliser gratuitement et sans formalités. Il ne veut pas que la Fédération du Commerce s'en empare et se fasse du fric avec son travail, alors qu'elle-même n'a rien fait. C'est ce raisonnement que se tiennent un certain nombre d'auteurs. C'est encore plus net s'ils ont des idées politiques de gauche : « je souhaite que ce travail circule en dehors du système capitaliste, et voilà pourquoi j'interdis toute utilisation commerciale ». (Notons que d'autres auteurs, n'ayant pas les mêmes convictions politiques, interdisent l'utilisation commerciale par les autres, mais en font eux-même, par exemple en produisant une version gratuite et une version qu'ils vendent. J'y reviendrai.)

Personnellement, j'ai moi-même partagé ce point de vue et mis ce genre de licences autrefois. Pourquoi ai-je changé d'avis ? La première raison est pratique et c'est pour moi la plus importante. « Utilisation commerciale » est un terme flou et qui est difficile à vérifier en pratique. Comment, vont me retorquer certains, c'est quand même évident : si on le vend, c'est commercial, sinon ça ne l'est pas.

Mais ce test est mauvais. L'archétype des logiciels libres, ceux du projet GNU était vendu à ses débuts, lorsque beaucoup de gens n'avaient pas d'accès à l'Internet (voyez « $150 GNU Emacs source code, on a 1600bpi industry standard mag tape in tar format »). Même chose pour les CD-ROM des premiers systèmes à base de Linux, vendus par ceux qui les faisaient et qui souhaitaient rentrer dans leurs frais. Cette activité « para-commerciale » a beaucoup contribué à rendre Linux accessible à tous, à l'époque où on n'avait pas BitTorrent.

Alors, si l'échange d'argent n'est pas le bon test, peut-on utiliser comme critère le fait que le vendeur fasse un profit ou pas ? Mais ce test n'est pas meilleur. Le statut d'une organisation (avec ou sans but lucratif) ne veut pas dire grand'chose : l'ARC était une organisation sans but lucratif, cela ne les empêchait pas d'être des voleurs. Sans aller jusqu'au vol, des tas d'associations 1901 brassent des fortes sommes d'argent et paient fort bien leurs dirigeants. « Sans but lucratif » n'est pour elles qu'un drapeau qu'on brandit, pas une réalité sur le terrain.

Donc, en pratique, il est très difficile de déterminer si une utilisation est commerciale ou pas. En fait, personnellement, j'ai commencé à changer sur ce point lorsque je me suis fait refuser l'intégration d'un logiciel « sans utilisation commerciale » sur le CD-ROM distribué lors d'une conférence (à l'époque, ça se faisait, l'accès à haut débit n'était pas pour tous). L'inscription à la conférence étant payante (pour couvrir les frais comme la location de la salle), l'auteur avait considéré que c'était une activité commerciale... Encore plus agaçant que le refus, les délais lors des négociations avec les auteurs (surtout lorsqu'il y en a plusieurs) et surtout l'incertitude juridique (suis-je ou ne suis-je pas commercial, telle est la question).

C'est ainsi que le blogueur qui, par exemple, met des publicités sur son site pour gagner sa vie (ou plutôt pour moins la perdre car on ne devient pas riche en bloguant) peut se demander légitimement s'il n'est pas passé commercial et s'il ne devrait pas supprimer tous les contenus sous licence « pas d'usage commercial » qu'il a repris.

C'est pour cela que le monde du logiciel libre, après quelques hésitations au début (les logiciels dans la recherche scientifique, par exemple, ont encore parfois la restriction « pas d'usage commercial »), a fini par ne plus utiliser cette restriction. Malheureusement, les licences Creative Commons ont ramené la question sur le devant en ayant une variante Non Commerciale, par exemple dans la licence Paternité - Pas d'utilisation commerciale - Partage des conditions initiales à l'identique. Beaucoup d'auteurs, voyant cette licence, se disent que c'est une bonne idée et s'en servent pour leurs œuvres, rendant ainsi plus difficile leur réutilisation.

Après le problème pratique (qui est à mon avis le principal), un autre problème des licences « usage commercial interdit » est qu'il s'agit parfois, non pas de rejeter le commerce mercantile par principe (chose que je peux comprendre) mais de le réserver à l'auteur ou à son éditeur. C'est tout à fait légal (l'auteur fait ce qu'il veut avec son œuvre), mais ce n'est pas très progressiste. (Cette démarche est défendue par Calimaq, par exemple.) Un tel usage ne devrait pas être appelé NC (Non Commercial) mais UCR (Usage Commercial Réservé à l'auteur).

Quelques articles et exemples intéressants :

  • « That Blurry Line Between Commercial & Non-Commercial Use Still Troubling For Creative Commons » de Mike Masnick, met également l'accent sur le problème pratique de ces licences « non commerciales ».
  • « Why Not NC (Non Commercial)" » de Kathi Fletcher, est centré sur la question de l'éducation, domaine où malheureusement pas mal de contenu est non-libre, et où une partie est sous une licence restrictive à cause de la clause « non commerciale ». Aux arguments pratiques, elle ajoute un argument plus politique, que le commerce n'est pas une mauvaise chose (on peut être en désaccord).
  • « Use cases for NonCommercial license clause », un très bon texte d'Evan Prodromou où il décrit plusieurs scénarios d'usage de contenu libre et analyse, pour chacun, s'il est commercial ou pas...
  • « Une autre photo de la guerre du Web » de Lionel Maurel, raconte les prétentions exorbitantes d'un lobby de photographes professionnels, qui demande (entre autres !) qu'on oblige les photographes amateurs qui publient sur le Web à utiliser une licence « pas d'usage commercial » afin de préserver le business des « professionnels ». De la même façon, les voleurs de la SACEM, non seulement se sentent autorisés à interdire à leurs membres la licence de leur choix, mais veulent forcer l'utilisation de licences NC, pour que seule la SACEM puisse faire du commerce.
  • « Non à la libre diffusion ! » de Simon « Gee » Giraudot. Il reprend l'argument pratique sur l'ambiguité de la clause « pas d'usage commercial » mais il critique aussi toutes les licences Creative Commons qui restreignent les usages (« non commercial » mais pas seulement, puisqu'il existe d'autres restrictions possibles, par exemple ND « No Derivative »). Le titre provocant fait référence au fait que la libre diffusion (permise par toutes les licences Creative Commons) est bien mais insuffisante.
  • La documentation sur les licences de TuxFamily est très détaillée sur la question des licences « non commerciales ».
  • Dans le domaine de l'éducation, et des livres de cours en informatique, on peut citer trois ouvrages sous Creative Commons, le manuel de Terminale S dans l'option Informatique et Sciences du Numérique, sous licence NC (pas d'usage commercial), le CNP3 (livre universitaire sur les réseaux informatiques), sous licence entièrement libre, ou le « LaTeX appliqué aux sciences humaines », également sans clause NC.
  • L'avis d'Eric Raymond, portant uniquement sur le caractère flou de « commercial ».
  • La question de la clause « non commercial » est mentionnée (avec bien d'autres) dans l'excellent article d'Isa Vodj sur le choix d'une licence. L'auteure estime comme moi que cette clause est bien compliquée en pratique.
  • Et, pour finir, un article de Calimaq favorable à la clause NC (et qui répond en partie à mon article).

Ah, et ce blog que vous êtes en train de lire ? Il est sous licence GFDL donc l'usage commercial est autorisé (ceci dit, personne n'a encore essayé...)

L'article seul

Ethernet OAM (802.1ag) sur Unix

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

Pour tester des équipements réseaux ayant IP, tout le monde utilise les classiques ping et traceroute. Mais pour la couche 2, pour du simple Ethernet, peut-on faire l'équivalent, même si la machine n'a pas d'adresse IP ? Depuis quelques années, oui, une norme existe pour cela, 802.1ag. Elle est surtout mise en œuvre dans les équipements de haut de gamme. On peut l'utiliser depuis une simple machine Unix.

Si vous voulez apprendre 802.1ag, un bon document d'explication et de synthèse a été produit par Fujitsu : « Ethernet Service OAM: Overview, Applications, Deployment, and Issues » (OAM voulant dire Operations, Administration, and Management). Normalisé en 2007, 802.1ag est relativement récent dans l'histoire d'Ethernet. Autrefois, il n'existait pas d'outils de couche 2 pour tester Ethernet, il n'y avait que ceux de couche 3 comme ping et ceux de couche 1 comme les réflectomètres.

802.1ag fournit des services de test classiques, CFM LB (Connectivity Fault Management - Loop Back), équivalent des échos d'ICMP qu'utilise ping, CFM LT (Link Trace), équivalent de ce qu'utilise traceroute, etc.

Il existe une mise en œuvre de cette norme sur Unix, dot1ag. Une bonne introduction à ces outils a été faite dans un exposé de leur auteur (attention, l'outil était loin d'être fini lors de cet exposé). Voici un exemple typique, avec la commande ethping, de ces outils :

# ethping -i eth1 00:23:8b:c9:48:f2
Sending CFM LBM to 00:23:8b:c9:48:f2
64 bytes from 00:23:8b:c9:48:f2, sequence 663084168, 0.014 ms
64 bytes from 00:23:8b:c9:48:f2, sequence 663084169, 0.015 ms
64 bytes from 00:23:8b:c9:48:f2, sequence 663084170, 0.016 ms
64 bytes from 00:23:8b:c9:48:f2, sequence 663084171, 0.014 ms
64 bytes from 00:23:8b:c9:48:f2, sequence 663084172, 0.010 ms

Et voilà, on sait que la machine d'adresse MAC 00:23:8b:c9:48:f2 est bien vivante et joignable. Vous noterez qu'il a fallu indiquer l'interface Ethernet de sortie puisqu'Ethernet ne fait pas de routage.

tcpdump sait décoder ces paquets 802.1ag et on voit passer :

16:26:28.789571 CFMv0 Loopback Message, MD Level 0, length 50
16:26:28.789997 CFMv0 Loopback Reply, MD Level 0, length 50

(Je vous laisse consulter l'article de Wikipédia pour découvrir ce qu'est un MD.) Notez que Wireshark sait également décoder ce protocole.

Si on augmente la bavartitude de tcpdump avec l'option -v, on a :

16:28:38.533399 CFMv0 Loopback Message, MD Level 0, length 50
        First TLV offset 4
          0x0000:  1716 defa 0100 0100 0000 0000 0000 0000
          0x0010:  0000 0000 0000 0000 0000 0000 0000 0000
          0x0020:  0000 0000 0000 0000 0000
        Sender ID TLV (0x01), length 1
        End TLV (0x00), length 0
16:28:38.538023 CFMv0 Loopback Reply, MD Level 0, length 50
        First TLV offset 4
          0x0000:  1716 defa 0100 0100 0000 0000 0000 0000
          0x0010:  0000 0000 0000 0000 0000 0000 0000 0000
          0x0020:  0000 0000 0000 0000 0000
        Sender ID TLV (0x01), length 1
        End TLV (0x00), length 0

Là, pour décoder, il faudrait avoir accès à la norme mais l'IEEE étant un dinosaure très conservateur, cette organisation ne permet pas l'accès libre et gratuit à ses textes, hélas. (Le groupe de travail IEEE a un site Web mais qui contient très peu de choses.) Si vous êtes prêt à remplir un questionnaire (où on vous demande à quel titre vous voulez ce texte...), à indiquer votre adresse de courrier, etc, alors, cette norme fait apparemment partie du petit nombre des normes IEEE qu'on peut obtenir sans frais, en ligne.

Bon, maintenant, on a un client qui marche mais peut-on s'en servir à la maison ou dans une petite entreprise ? Non, les équipements Ethernet bas de gamme (commutateur acheté au supermarché, adaptateur CPL, Freebox) n'ont pas 802.1ag et ne répondent donc pas. Ici, on essaie de tester le commutateur d'une Freebox v6 :

# ethping -i eth1 f4:ca:e5:4d:1f:41
Sending CFM LBM to f4:ca:e5:4d:1f:41
Request timeout for 1340526005
Request timeout for 1340526006
Request timeout for 1340526007
Request timeout for 1340526008

À noter que les outils dot1ag comprennent un démon qu'on peut faire tourner sur ses machines Unix pour les tester. L'intérêt pratique est limité, bien sûr car, si la machine a suffisamment démarré pour lancer ledit démon, elle a probablement aussi acquis une adresse IP.

Et la fonction de trace (l'analogue de traceroute) ? Ici, on voit une machine située à un saut de distance :

# ethtrace -i eth1 00:23:8b:c9:48:f2 
Sending CFM LTM probe to 00:23:8b:c9:48:f2
ttl 1: LTM with id 1207397526
        reply from 00:23:8b:c9:48:f2, id=1207397526, ttl=0, RlyHit

En fait, ce n'est pas tout à fait exact. Il y avait un commutateur Netgear bon marché entre les deux machines. Mais comme ce dernier ne parle pas 802.1ag, il a simplement relayé les trames, comme s'il était transparent.

Merci à Ronald van der Pol pour sa relecture.

L'article seul

RFC 6708: Application-Layer Traffic Optimization (ALTO) Requirements

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : S. Kiesel (University of Stuttgart), S. Previdi (Cisco Systems), M. Stiemerling (NEC Europe), R. Woundy (Comcast Corporation), Y R. Yang (Yale University)
Pour information
Réalisé dans le cadre du groupe de travail IETF alto
Première rédaction de cet article le 30 septembre 2012

Le système Alto (Application-Layer Traffic Optimization), permettant aux machines d'un réseau pair-à-pair de trouver le meilleur pair, par exemple pour obtenir un fichier plus rapidement, avance, lentement, mais sûrement. Ce nouveau RFC spécifie le cahier des charges d'Alto.

Alto peut servir à autre chose qu'au pair-à-pair. Mais le scénario d'utilisation principal est le suivant : une machine veut accéder à un fichier. Celui-ci est offert par plusieurs pairs. Lequel choisir ? En prendre un au hasard risque de ne pas être optimum, ni pour la machine (temps de transfert du fichier plus long qu'il ne pourrait l'être), ni pour son FAI (utilisation de liens externes plus coûteux que son réseau interne). Alto vise donc à permettre à des serveurs Alto de donner à leurs clients (les machines qui veulent accéder aux fichiers) des informations sur lesquelles décider intelligemment, ou même simplement d'indiquer directement le pair à utiliser. Le groupe de travail Alto a été créé en novembre 2008, le RFC 5693, qui définit le problème à résoudre, a été publié en octobre 2009, et voici désormais le deuxième RFC du groupe, le cahier des charges du protocole. (Pour ceux qui ne connaissent pas l'IETF, et qui craignent que le travail sur le protocole ne commence qu'une fois le cahier des charges terminé, je vous rassure, ce n'est pas ainsi que fonctionne l'IETF. Le protocole est déjà bien avancé à l'époque, et a été publié dans le RFC 7285.)

Pair-à-pair ou pas, le but d'Alto est donc d'améliorer simultanément la qualité de la vie pour l'utilisateur (télécharger les chefs d'œuvre de la culture plus vite) et pour le réseau (ne pas gaspiller des ressources chères comme les lignes transocéaniques). Cela ne peut pas se faire par des mesures uniquement faites par les machines terminales. Par exemple, celles-ci peuvent faire des ping mais elles ne peuvent pas déterminer si un lien est de peering (« gratuit ») ou de transit (facturé au 95ème centile de l'usage).

Les serveurs Alto ne feront pas bouger les octets : leur seul rôle est de dire aux pairs « tu devrais plutôt causer avec lui, ça devrait aller vite ». Les pairs sont ensuite responsables de leurs décisions.

L'habituelle section de terminologie, nécessaire pour comprendre le reste du RFC, est la section 2. Attention, le RFC 5693 définissait déjà certains termes (comme client Alto et serveur Alto) qui ne sont pas répétés ici. Les termes les plus importants :

  • Descripteur de groupe (Host Group Descriptor) : c'est l'information qui définit un groupe de machines. Cela peut être un préfixe IP (« toutes les machines en 2001:db8:1337::/32 ») ou un numéro d'AS (« toutes les machines joignables par l'AS 42 »).
  • Attribut d'une machine (Host Characteristics Attribute) : c'est une propriété attachée à une machine comme « accès Internet au forfait ».
  • Critère de classement. On a dit plus haut que le but d'Alto était de sélectionner le « meilleur » pair. Mais quelle est la définition de « meilleur » ? Par exemple, cela peut être « le moins cher » ou « celui avec la plus forte capacité réseau ». Alto est un protocole pour distribuer des choix, pas un mécanisme pour décider quel est le meilleur.
  • Recherche dépendante de la cible (Target-aware Query Mode) se dit d'une requête Alto où le client Alto connait une liste de pairs potentiels, envoie cette liste au serveur Alto (ainsi qu'un critère de classement) et reçoit en retour la liste triée selon le critère. (Plus exactement, le client envoie une liste de descripteurs de groupes, pas d'adresses IP des pairs potentiels.) On notera que ce mode permet au serveur de connaître les pairs potentiels de ses clients. En revanche, c'est ce mode qui permet au client de faire le moins de calculs, ce qui est utile pour les machines aux ressources réduites.
  • Recherche indépendante de la cible (Target-independant Query Mode) désigne une requête Alto où le client télécharge tout ou partie des descripteurs de groupe que connait le serveur, avec leurs attributs, et fait le calcul du meilleur pair lui-même. Préservant la vie privée du client, elle lui impose davantage de calculs.

Les exigences sur le futur protocole figurent en section 3 et sont numérotées AR-n (AR pour Alto Requirment). Elles vont des plus évidentes (exigence AR-1 : les clients et serveurs Alto doivent parler le protocole Alto...) aux plus pointues. Voici les plus importantes, selon moi.

Le protocole devra gérer les descripteurs de groupe : types multiples (AR-3), au moins les types « préfixe IPv4 » et « préfixe IPv6 » (AR-5) et extensible (possitibilité d'ajouter de nouveaux types de descripteurs de groupe dans le futur, AR-6). Les types « préfixes IP » sont, à ce stade, les types recommandés. Donc, en deux mots, les pairs possibles seront identifiés par leur adresse (« j'hésite entre un pair en 2001:db8:1:2::af et un pair en, tu me recommandes lequel ? »). Voir aussi AR-7 et AR-8.

Le protocole devra permettre d'indiquer un critère de classement (AR-11) permettant de comparer les machines entre elles. Alto ne détermine pas comment on fait les calculs : il utilise le résultat (on peut tout imaginer, y compris des tables gérées à la main, par exemple en fonction du fait que les liens sont de transit ou de peering). Alto devra, là aussi, être extensible et permettre d'ajouter d'autres critères dans le futur.

Ces critères doivent être relativement stables (ne pas oublier qu'une fois un transfert de fichiers commencé, il peut durer de nombreuses heures) donc ne pas dépendre, par exemple, de l'état de congestion du réseau (AR-13). À propos de la congestion, les applications qui utiliseront Alto ne doivent pas s'en servir comme remède contre la congestion, elles doivent utiliser un protocole qui dispose de mécanismes d'évitement de la congestion, comme TCP (AR-14, et aussi AR-29).

Le critère de classement doit pouvoir être indiqué au serveur (en mode « recherche dépendante de la cible », car, dans l'autre mode, c'est le client Alto qui classe) afin qu'il l'utilise pour classer (AR-16).

Où va être situé le client Alto ? Le protocole ne l'impose pas et il y aura au moins deux positionnements possibles : directement dans l'application (le client BitTorrent, par exemple) ou bien chez un tiers qui fera une partie du travail pour le compte du client (le tracker BitTorrent, par exemple). Alto devra fonctionner dans les deux cas (AR-18 et AR-19).

Et qui va fournir ses informations au serveur Alto ? Une possibilité évidente est que ce soit le FAI, et qu'Alto devienne un service de base de l'accès Internet, comme le résolveur DNS et le serveur NTP. Mais les exigences AR-20 et AR-21 demandent que le protocole n'impose pas ce choix : il faut que des acteurs tiers puisse jouer le rôle de serveur Alto.

Le protocole doit aussi permettre la redistribution de l'information obtenue (AR-25), en indiquant des conditions de redistribution.

Comment va-t-on trouver son serveur Alto ? Il faudra décrire un mécanisme et AR-37 demande que ce mécanisme soit intégré aux protocoles existants comme PPP ou DHCP (comme c'est le cas pour découvrir un résolveur DNS).

La sécurité étant un enjeu important pour Alto (voir aussi la section 5), il faudra aussi un mécanisme d'authentification des serveurs (AR-40), des clients (AR-41), la possibilité de chiffrer (AR-42), et d'ajuster la taille des requêtes et réponses selon le niveau de confiance du client envers le serveur, ou réciproquement (AR-44). Un client devra donc pouvoir rester intentionnellement vague dans sa demande, au risque évidemment que les informations du serveur soient moins pertinentes.

Et la sécurité ? Outre le RFC 5693 qui couvrait déjà la sécurité d'Alto, la section 5 de notre RFC met l'accent sur le point le plus important, le risque de distribution d'informations sensibles.

Ce risque existe dans les deux sens, du client vers le serveur et du serveur vers le client. Le client ne souhaite pas forcément communiquer au serveur tout ce qu'il sait. Par exemple, lorsque la HADOPI espionne, un client Alto ne va pas dire à un serveur qu'il ne connait pas « je cherche une copie HD du dernier Disney ». Et, en sens inverse, un serveur Alto géré par un FAI n'est pas forcément enthousiaste à l'idée de donner des informations qui permettent de se faire une bonne idée de la configuration de son réseau, de l'identité des opérateurs avec qui il peere et autres informations confidentielles.

Même si le client ne donne pas d'informations aussi évidentes que dans l'exemple ci-dessus, un serveur malin peut déduire plein de choses des demandes que le client lui adresse (la liste des pairs potentiels, par exemple, est une information utile pour repérer les plus grosses sources de contenu en pair-à-pair).

Pour l'opérateur du serveur, le principal risque est en recherche indépendante de la cible, lorsque le client télécharge de grandes quantités d'information. Un serveur prudent ne dira donc pas tout. En outre, même si le serveur accepte de donner ces informations au client, il peut quand même s'inquiéter de ce qu'elles deviendront. Un tiers qui écoute le réseau ne va t-il pas mettre la main sur l'information confidentielle ? Et, même si l'information donnée à chaque client est limitée (par exemple, uniquement une partie des descripteurs de groupes que le serveur connait), ne risque t-on pas de voir des clients coopérer pour récupérer chacun un bout, avant de le mettre en commun ?

Le futur protocole Alto devra donc contenir des mesures pour faire face à ces problèmes : par exemple, permettre au serveur d'être délibérement incomplet ou imprécis (annoncer un préfixe IP plus général que le vrai, par exemple), authentifier clients et serveurs, chiffrer les communications contre l'écoute par TMG, etc. En revanche, le RFC écarte l'idée de DRM dans les données Alto, complexes et facilement contournables. Les acteurs Alto sont donc prévenus que les données échangées ne peuvent pas être 100 % confidentielles. Un client ou un serveur méchant pourra toujours en faire mauvais usage.

À noter que les intérêts du client et du serveur peuvent être contradictoires. Ainsi, les requêtes en mode indépendante de la cible préservent la vie privée du client (il ne dit rien sur ce qu'il va faire des données) mais oblige le servur à diffuser de l'information. Et, pour les requêtes en mode dépendant de la cible, c'est le contraire :le client se dévoile, le serveur ne prend pas de risque.

Téléchargez le RFC 6708

L'article seul

RFC 6730: Requirements for IETF Nominations Committee tools

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : S. Krishnan, J. Halpern (Ericsson)
Pour information
Première rédaction de cet article le 27 septembre 2012

L'IETF dispose d'une institution curieuse, le NomCom (Nominations Committee) qui est chargée de sélectionner des candidats pour des postes à l'IESG, l'IAB ou l'IAOC. Sa tâche d'examen des noms et de sélection nécessite un certain nombre d'outils informatiques, qui n'existent pas forcément tous à l'heure actuelle. Ce RFC est le cahier des charges des outils, pour servir de base aux futurs développements.

Tous les détails sur le NomCom et son fonctionnement sont spécifiés dans le RFC 7437. On peut aussi consulter le site officiel. Le NomCom dispose déjà d'un outil (accessible via le Web pour sa partie publique, mais il a aussi une partie privée, réservée aux membres du NomCom) mais qui est insuffisant. Notre nouveau RFC liste les nouveautés nécessaires pour cet outil. La première exigence, étiquetée META-001 est que le nouvel outil devra reprendre toutes les fonctions de l'ancien.

Ensuite, comme le NomCom travaille avec des données personnelles, la plupart des exigences du cahier des charges concernent la sécurité. Le logiciel stockera des noms, des appréciations, des opinions sur des personnes, etc, toutes choses assez sensibles. Il faudra un système d'authentification (exigences AUTH-001 à AUTH-003), capable de distinguer trois rôles (membre ordinaire de l'IETF, membre du NomCom, président du NomCom). Les membres ordinaires n'ont accès qu'à la partie publique. Ils se servent pour cela de leur compte (cf. RFC 6175, tout le monde peut se créer un compte avec cet outil puisque tout le monde peut participer à l'IETF).

Toutes les communications seront évidemment chiffrées et l'exigence SEC-001 demande que les données stockées le soient de telle façon qu'on minimise même leur exposition accidentelle (même l'administrateur ne doit les voir que sur une action explicite de sa part). Les données seront stockées chiffrées avec la clé publique du NomCom (exigences SEC-002 à SEC-005) et seront détruites à la fin de la sélection (toutes les données ne sont pas concernées, voir plus loin).

Moins cruciales, les autres exigences portent sur le processus de désignation des candidats (exigences NOM-001 à NOM-011) et sur l'enregistrement de l'acceptation ou du rejet car un candidat peut ne pas accepter sa désignation, qui a pu être faite par un tiers (exigences AD-001 à AD-007).

Enfin, l'outil devra gérer les réponses des candidats aux questionnaires qui leur seront soumis (« que ferez-vous si vous êtes élu à l'IAB ? » (exigences QR-001 à QR-007) et surtout les retours des membres sur les candidatures (exigences FB-001 à FB-006). Ces retours, avis, et opinions forment une part essentielle du processus mais, malheureusement, les exigences d'ouverture et de sécurité ne sont pas faciles à concilier. Ainsi, les messages envoyés au NomCom par les membres sont archivés, contrairement aux autres données collectées par le NomCom (exigence FB-005).

On peut finir avec l'amusante annexe A de ce RFC, qui décrit les commandes OpenSSL nécessaires pour la gestion de la cryptographie dans l'outil du NomCom. La configuration (le fichier nomcom-config.cnf) ressemble à :

[ req ]
distinguished_name = req_distinguished_name
string_mask        = utf8only
x509_extensions    = ss_v3_ca

[ req_distinguished_name ]
commonName           = Common Name (e.g., NomcomYY)
commonName_default  = Nomcom12

[ ss_v3_ca ]

subjectKeyIdentifier = hash
keyUsage = critical, digitalSignature, keyEncipherment, dataEncipherment
basicConstraints = critical, CA:true
subjectAltName =
extendedKeyUsage= emailProtection
# modify the email address to match the year.

Et on peut générer le certificat avec :

openssl req -config nomcom-config.cnf -x509 -new -newkey rsa:2048 \
   -sha256 -days 730 -nodes -keyout privateKey.pem \
   -out nomcom12.cert

Téléchargez le RFC 6730

L'article seul

RFC 6721: The Atom "deleted-entry" Element

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : J. Snell
Chemin des normes
Première rédaction de cet article le 26 septembre 2012

Le format Atom, normalisé dans le RFC 4287, est surtout utilisé pour la syndication de contenus Web. Dans ce cas, si une entrée d'un flux Atom n'est plus publiée (remords de l'auteur ou autre raison), le client Atom n'avait pas de moyen de le savoir. Désormais, avec l'extension de ce RFC, surnommée « pierre tombale », on peut indiquer que l'absence d'une entrée est délibérée.

Rappelez-vous qu'un flux de syndication comporte un certain nombre d'entrées mais rarement la totalité des articles d'un site Web (dans le flux de ce blog, par défaut, les articles des quatre derniers mois). On ne peut donc pas dire, lorsqu'un article n'a pas d'entrée dans le flux Atom, si l'article a été supprimé ou simplement s'il n'a pas été inclus dans le flux. Si, par exemple, l'entrée a été gardée dans la mémoire locale du client de syndication, elle risque d'y rester même si l'article original a disparu du site.

Pour éviter cela, ce RFC ajoute un nouvel élément XML à Atom. Il est défini avec la syntaxe Relax NG (l'espace de noms XML abrégé en at est :

deletedEntry =
  element at:deleted-entry {
    attribute ref { atomUri },
    attribute when { atomDateConstruct },
    ( element at:by { atomPersonConstruct }?
    & element at:comment { atomTextConstruct }?
    & element atom:link { atomLink }*
    & element atom:source { atomSource }?
    & anyElement* )

On note donc que la référence de l'article détruit (ref) est obligatoire. Elle correspond à l'attribut id d'un flux Atom, qui a la forme d'un URI. Ainsi, cet article que vous êtes en train de lire a l'id,2006-02:Blog/6721 et une pierre tombale, si je supprimais cet article, comporterait <at:deleted-entry ref=",2006-02:Blog/6721" ....

Comme l'attribut ref, l'attribut when est obligatoire et contient la date et l'heure de destruction (au format du RFC 3339). Il est particulièrement utile si une entrée est détruite puis recréée : en examinant les dates, un client Atom peut savoir quel est l'évènement le plus récent (la suppression ou la création) et ignorer les autres.

Les autres attributs de l'élement at:deleted-entry sont facultatifs. C'est le cas par exemple de comment qui permet d'ajouter une explication en texte libre. Voici, tiré du RFC, un exemple minimal :


et un exemple plus complet :

            <name>John Doe</name>
          <at:comment xml:lang="la">Lorem ipsum dolor</at:comment>

Notez bien que l'élement at:deleted-entry n'est qu'indicatif : on ne peut évidemment pas garantir qu'un client Atom facétieux ne va pas conserver localement (et même redistribuer) des entrées qu'il avait gardé dans son cache et qui ont été détruites dans le flux original.

Autre piège de sécurité : un client Atom ne doit pas croire aveuglément tous les at:deleted-entry qu'il rencontrerait sur le Web ! Car un méchant peut toujours publier des pierres tombales pour un autre site que le sien. Il faut donc vérifier l'origine (la pierre tombale doit être dans le même flux que l'article original, ce qui peut poser des problèmes avec les agrégateurs et autres redistributeurs) et/ou vérifier les signatures cryptographiques attachées (avec XML Signature).

Cette extension est mise en œuvre au moins dans AtomBeat (voir leurs intéressants exemples d'usage).

Téléchargez le RFC 6721

L'article seul

RFC 6707: Content Distribution Network Interconnection (CDNI) Problem Statement

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : B. Niven-Jenkins (Velocix (Alcatel-Lucent)), F. Le Faucheur (Cisco), N. Bitar (Verizon)
Pour information
Réalisé dans le cadre du groupe de travail IETF cdni
Première rédaction de cet article le 26 septembre 2012

Aujourd'hui, les CDN sont partout. Ces serveurs munis de nombreux disques et disposés dans les réseaux des FAI, au plus près de l'abonné, afin de servir du contenu numérique le plus rapidement possible, sont derrière un grand nombre de sites Web (non, ce blog n'utilise pas de CDN) et derrière bien des fournisseurs de streaming. La plus connue des entreprises de CDN est Akamai mais il en existe bien d'autres. Et c'est là que le problème commence : il n'existe aucun mécanisme d'interconnexion des CDN. Chacun utilise ses protocoles spécifiques et pas question de les faire travailler ensemble. L'IETF a donc créé un groupe de travail, CDNI, chargé de réfléchir à l'interconnexion des CDN. Ce RFC est le premier du groupe, et il essaie de définir le problème (les solutions viendront plus tard, le cahier des charges formel a été publié dans le RFC 7337).

L'extension massive des CDN est bien sûr liée à l'augmentation considérable du contenu numérique : présentations PowerPoint ennuyeuses, vidéos de chats mignons, communiqués de presse en PDF qui prennent plusieurs mégaoctets pour ne pas dire grand'chose, publicités débiles, webinars en haute définition et au contenu vide, etc. Sans le CDN, un site Web qui veut distribuer un fichier de N mégaoctets à M clients va voir N*M mégaoctets passer sur sa liaison Internet. Avec le CDN, le fournisseur de contenu (CSP dans le RFC pour Content Service Provider) n'aura à faire passer le contenu qu'une fois, vers le CDN. Le contenu sera ensuite distribué par les serveurs du CDN, situés typiquement chez les FAI (notez aussi que certains FAI ont leur propre CDN). Meilleure latence, meilleure résilience (attaques dDoS et flash crowds), meilleur débit, bref, tous les avantages.

Aujourd'hui, les CDN ne coopèrent pas. Si un fournisseur de CDN est très présent en Europe et en Amérique, mais pas en Asie, un CSP client de ce CDN verra ses clients asiatiques mécontents. Pour les satisfaire, il devra signer un contrat avec un autre CDN, très présent en Asie. Il serait pourtant plus simple que le premier fournisseur de CDN puisse s'appuyer sur l'infrastructure du second et lui transmettre données et instructions. Mais, en l'absence de normes techniques pour l'interconnexion des CDN, cela n'est possible aujourd'hui que par des arrangements privés. C'est l'une des principales motivations pour la création du groupe de travail CDNI. L'idée est que, dans le futur, le premier fournisseur de CDN cité (celui qui est trés présent en Europe et en Amérique) aura juste à signer un contrat avec le second fournisseur et, techniquement, tout se passera tout seul, il utilisera le réseau du second sans que le fournisseur de contenu n'y voit rien.

Avant d'attaquer la question de l'interconnexion, notre RFC 6707 précise qu'il vaut mieux connaître les CDN pour suivre. Si ce n'est pas le cas, il recommande la lecture des RFC 3040 qui décrit les composants d'un CDN, RFC 3466 et RFC 3570, les deux derniers étant le résultat du travail du précédent groupe de travail IETF sur les CDN. Le RFC recommande également la lecture de « A Taxonomy and Survey of Content Delivery Networks ».

La section 2 de notre RFC précise les cas où il est intéressant d'interconnecter les CDN. À la raison donnée plus haut (permettre à des CDN de s'allier pour avoir une meilleure couverture géographique), s'ajoute le désir de permettre l'interconnexion des CDN que gèrent certains FAI : en se regroupant, ils pourraient former un CDN alternatif aux CDN indépendants des FAI comme Akamai. Il y a aussi des cas où un FAI a déployé plusieurs CDN spécialisés et souhaite après les regrouper. Enfin, un dernier scénario envisagé est celui où un CDN doit faire appel temporairement à un autre (suite à une grosse panne, par exemple) et doit le faire vite, sans programmer des scripts spécifiques.

Mais qu'est-ce que veut dire « Interconnecter des CDN » ? Des essais ont déjà été tentés, montrant qu'il y avait des choses qui marchaient et d'autres qui étaient vraiment pénibles en l'absence de normes. La section 3 identifie quatre interfaces par lesquelles on voudrait connecter des CDN, et pour lesquelles il n'existe pas de normes :

  • Interface de contrôle du CDN, par laquelle on démarre et arrête le service, on indique les politiques suivies (« aucun contenu ne doit pas être distribué en dehors des États-Unis », par exemple), on déclenche la copie de contenu, on vire le contenu qui ne doit plus être servi, etc.
  • Interface de routage des requêtes du CDN, qui n'est pas le routage de la couche 3. Il s'agit ici de s'assurer que les requêtes des utilisateur seront routées vers un CDN et un seul (qu'il n'y ait pas de boucles « c'est lui, non c'est lui »).
  • Interface de distribution des métadonnées au CDN. Ces métadonnées sont les données au sujet du contenu : ses caractéristiques techniques (HD ou pas, par exemple, pour permettre la sélection du bon fichier), informations de zonage (tel document ne doit être servi que dans telle région du Monde), etc.
  • Interface de journalisation (logging) du CDN. Elle permet de faire remonter les données de trafic, à des fins de statistiques, de facturation, etc. Sans elle, un CDN hésiterait à s'associer à un autre si cela signifiait qu'il n'aurait plus accès aux données de trafic.

Vous avez noté quelque chose qui manque ? Prenez le temps de réfléchir avant de regarder le paragraphe suivant.

Une interface importante est exclue du projet CDNI : l'interface d'acquisition des données elle-mêmes. Ce n'est pas tout de s'entendre avec un autre CDN pour qu'il contribue à distribuer le contenu de vos clients, encore faut-il mettre la main sur le dit contenu ! Mais notre RFC considère le problème comme déjà largement résolu. Il existe en effet plusieurs protocoles standards, ayant toutes les caractéristiques voulues, et effectivement utilisés par les CDN (HTTP et rsync sont deux exemples typiques). En écartant ce problème des données, le groupe CDNI se focalise sur le contrôle des CDN.

Et pour les quatre interfaces citées plus haut, ne pourrait-on pas trouver des protocoles existants qui résolvent le problème, sans avoir besoin de développer quelque chose de nouveau ? La section 4 reconnait que ce serait très souhaitable, cite des protocoles intéressants (comme XMPP ou APP) et étudie cette question.

  • L'interface de contrôle, dit le RFC, est un problème très ouvert et, bien qu'il soit souhaitable de réutiliser des protocoles existants, le RFC ne s'avance pas à en suggérer certains.
  • Pour l'interface de routage, en revanche, notre RFC considère qu'une simple fonction requête/réponse (par exemple « tu peux gérer ça ? / oui ») suffit et que cette interface peut donc être réalisée avec des protocoles de type Web Services comme XML-RPC ou REST. Le groupe de travail n'aurait alors à normaliser que le format exact de ces services. Il y a toutefois d'autres fonctions, liées à la sélection du CDN le plus efficace pour une requête, pour lequel le RFC suggère d'étudier des techniques comme ALTO (RFC 5693).
  • Même chose pour l'interface d'accès aux métadonnées, où il n'y aura pas non plus de nécessité de développer un protocole entièrement nouveau.
  • L'interface de journalisation pourrait aussi utiliser des protocoles existants comme évidemment SNMP ou syslog. Attention, ils ne sont pas forcément parfaits. Par exemple, dans SNMP, la remise des notifications asynchrones - traps - n'est pas garantie - cf. annexe A.3 - ce qui est un problème pour la facturation.

Des détails sur cette réutilisation de protocoles existants figurent dans l'annexe A. Elle est particulièrement riche pour le cas de l'interface de routage, qui doit permettre des scénarios de redirection complexes (plus complexes que, par exemple, les simples 301 et 302 de HTTP). Pour la journalisation, si le protocole de transport peut être un protocole existant, il restera à spécifier le format des données transportées (les champs, leur syntaxe, leur sémantique, etc).

La traditionnelle section de sécurité (section 6) est longue car une telle interconnexion des CDN soulève plein de problèmes difficiles. C'est d'autant plus vrai que le contenu numérique servi est souvent commercial et que le fournisseur de contenu souhaite en contrôler la distribution. Dans un CDN homogène, c'est relativement facile. Mais comment faire lorsqu'on interconnecte des CDN hétérogènes ? Il va falloir faire confiance aux autres...

En outre, l'interconnexion des CDN différents va introduire des problèmes légaux, puisque les CDN en question seront peut-être gérés par des entreprises différentes, donc soumises à des lois différentes. Ainsi, une loi locale peut obliger à anonymiser plus ou moins les données envoyées sur l'interface de journalisation.

  • Pour l'interface de contrôle, le principal problème de sécurité est le risque qu'un attaquant ne puisse contrôler le CDN par ce biais. Elle devra donc imposer une authentification sérieuse.
  • Pour l'interface de routage, les problèmes sont très proches : imaginez un méchant renvoyant toutes les requêtes vers un CDN qui n'est pas au courant et qui se retrouverait ainsi inondé.
  • L'interface des métadonnées est moins sensible mais, quand même, les informations peuvent ne pas être publiques.
  • L'interface de journalisation reçoit des données confidentielles et qui doivent donc être protégées, par exemple par du chiffrement. Mais elle peut aussi être utilisée pour de la facturation (« j'ai traité ce mois-ci N requêtes de tes clients, voici la note ») et elle doit donc être protégée contre la falsification.

L'annexe B intéressera les concepteurs de protocoles et les étudiants car elle définit les non-buts, ce que le groupe CDNI n'essaiera pas de faire. Par exemple :

  • L'interface entre le fournisseur de contenu et le CDN (on ne s'occupera que de l'interface entre CDN), et les éventuelles transformations de ce contenu (réencodage des vidéos entrantes, par exemple).
  • L'interface entre le CDN et le consommateur (avec éventuellement authentification). Même chose pour les menottes numériques.
  • Comme indiqué plus haut, la synchronisation des données entre les CDN est aussi hors-sujet.
  • Les algorithmes utilisés en interne par le système de routage du CDN pour décider à quel CDN partenaire il envoie des requêtes sont considérés comme une question interne et donc non traitée par le groupe CDNI. Seule l'interface de routage est dans le domaine d'activité de ce groupe.
  • Et, naturellement, tous les aspects commerciaux et juridiques sont également exclus du travail de l'IETF.

Autre partie intéressante de l'annexe B, celle consacrée aux autres groupes de travail IETF qui avaient une importance pour ce sujet :

  • ALTO, bien sûr (RFC 5693), par exemple pour router les requêtes vers le « meilleur » CDN. Comme indiqué plus haut, cela n'a pas d'influence directe sur le travail de CDNI puisque l'utilisation d'ALTO (ou pas) est une décision interne à chaque CDN.
  • DECADE (RFC 6646). Ce groupe travaille à réduire l'usage du « dernier kilomètre » (celui qui connecte Mme Michu à son FAI) en permettant le téléversement de contenu par Mme Michu, sur un serveur mieux placé. Le RFC estime toutefois que le rapport avec les CDN est trop lointain pour que le travail de DECADE soit directement utilisable.
  • PPSP, qui n'a pas encore de RFC, mais qui travaille sur le streaming en pair-à-pair. Son sujet est plutôt l'acquisition de contenu, un point qui a été explicitement exclu de CDNI.

Enfin, pour ceux et celles qui veulent vraiment beaucoup approfondir, les Internet-Drafts qui avaient précédé le RFC contenaient également une annexe (non gardée dans le RFC final) intéressante sur les autres efforts de normalisation des CDN. On y trouve de nombreux projets, parfois toujours actifs, y compris un ancien groupe de travail IETF, CDI, qui avait produit plusieurs RFC intéressants (RFC 3466, RFC 3568 et RFC 3570). Trop ambitieux, ce groupe n'avait pas vraiment réussi à faire avancer l'interconnexion.

Téléchargez le RFC 6707

L'article seul

La traduction d'adresses (NAT) apporte-t-elle vraiment de la sécurité ?

Première rédaction de cet article le 16 septembre 2012

Lors des discussions techniques sur la sécurité des réseaux informatiques, on entend très souvent l'affirmation comme quoi la traduction d'adresses (le NAT) apporterait une certaine sécurité au réseau local, bloquant par défaut les connexions entrantes et protégeant ainsi un peu les machines situées derrière. Cet argument a par exemple été souvent cité lors des débats sur le déploiement d'IPv6 (dans ces débats, l'argument pro-NAT est « Avec IPv4, le réseau local dispose d'une certaine sécurité grâce au NAT, qu'il perdrait lors du passage à IPv6 où le NAT est inutile »). Quelle est la part de vérité dans cette affirmation ?

D'abord, un petit rappel pour ceux et celles qui ne connaissent pas bien le NAT. Le nom est déjà une erreur. En effet, ce qui est déployé chez l'écrasante majorité des particuliers, qui accèdent à l'Internet via une box, ce n'est pas du NAT, c'est du NAPT (voir aussi mon article sur le zoo des NAT). La différence est énorme en pratique car, avec le NAPT, il y a partage d'adresses IP ce qui n'est pas le cas avec le NAT et cela entraîne une rupture du principe « connexion de bout en bout », qui est à la base de l'Internet. NAT signifie Network Address Translation et désigne une technique où les machines du réseau local ont des adresses privées, adresses qui sont dynamiquement remplacées par des adresses publiques lors de la traversée d'un routeur NAT. Celui-ci fait la traduction dans les deux sens, vers l'extérieur (remplacement des adresses privées par des adresses publiques) et vers l'intérieur (remplacement des adresses publiques par des adresses privées). Si le NAT peut perturber certains protocoles (qui indiquent l'adresse IP utilisée dans le paquet transmis, ce qui ne marche plus si un routeur réécrit les adresses), il ne pose pas en soi de problème philosophique fondamental. L'Internet pourrait fonctionner avec le NAT (voir le RFC 6296 pour un bon exemple de NAT bien conçu).

Mais ce qui est déployé actuellement sous le nom de NAT n'est pas du NAT ! La technique que doivent supporter les utilisateurs de base, chez eux ou dans les petites entreprises ou associations est tout autre chose. Son nom exact est NAPT (Network Address and Port Translation) et, contrairement au NAT, le NAPT a deux énormes défauts :

  • Il partage les adresses publiques. Typiquement, en raison de la pénurie d'adresses IPv4, on n'a qu'une seule adresse publique et toutes les adresses privées du réseau interne sont mises en correspondance avec cette unique adresse publique. Cela a des tas de conséquences fâcheuses, détaillées dans le RFC 6269.
  • Comme toutes les adresses internes sont fusionnées en une seule adresse externe, comment le routeur NAPT sait-il, lorsqu'un paquet IP revient, à quelle machine interne il est destiné ? Il regarde pour cela le numéro de port qu'il a mémorisé à l'aller. Cela entraine encore d'autres conséquences désagréables, comme la difficulté pour faire marcher les protocoles sans port (par exemple ICMP).

Bon, mais je m'éloigne du sujet, va-t-on me dire, j'avais promis de parler de la sécurité, pas de faire un éreintement du NAPT. Je reviens donc sur le second point : lorsqu'un paquet sort, le routeur NAPT doit traduire {Adresse IP source privée, port source} vers {Adresse IP source publique, autre port source} et se souvenir de la correspondance qui lui permettra, lorsqu'un paquet de réponse reviendra, de trouver vers laquelle des adresses IP privées il doit le diriger. Résultat, un paquet entrant non sollicité, qui n'est pas la réponse à un paquet sortant, ne sera pas accepté puisqu'il n'y a aucune entrée dans la table pour lui.

C'est ce point qui est souvent présenté comme un avantage de sécurité. Comme un pare-feu à état, le routeur NAPT ne laisse pas passer les nouvelles connexions entrantes. Cela transforme le réseau interne en un réseau purement client, qui ne peut accéder au réseau qu'en consommateur. (Cela perturbe également les services de type pair-à-pair où tout le monde est « serveur », cf. RFC 5128. Vu la diabolisation du pair-à-pair par le puissant lobby de l'industrie du divertissement, ce défaut du NAPT peut plaire à certains...) Mais, disent les partisans de cette configuration minitélienne, cela a des conséquences positives pour la sécurité ; si des machines du réseau interne sont complètement ouvertes à tous vents, pas de problème, le routeur NAPT empêchera le méchant extérieur d'y accéder. C'est d'autant plus important que certains systèmes (Windows...) sont très peu protégés et pourraient être piratés en quelques heures, ne laissant même pas le temps d'installer les patches nécessaires. (Voir l'excellent article « Know your Enemy: Tracking Botnets ».)

Mais les avantages de sécurité du NAPT sont largement exagérés. Voyons en quoi.

Le NAPT a des limites (qui sont aussi celles des pare-feux, malheureusement souvent présentés comme des solutions miracles) :

  • Le NAPT ne protège pas contre les attaques effectuées par le contenu (« charge utile ») comme les chevaux de Troie, le virus contenu dans un courrier, le malware dans une page HTML lue avec IE6...
  • Et il ne protège pas contre les attaques venues de l'intérieur du réseau, pourtant les plus fréquentes. Rappelez-vous que l'attaquant humain peut être à l'extérieur et quand même lancer une attaque depuis l'intérieur, avec des techniques comme le changement DNS.

Il ne manque d'ailleurs pas d'outils automatisant tout cela et permettant à un attaquant de faire une attaque sur un réseau privé situé derrière un routeur NAT.

Aujourd'hui, il y a de moins en moins d'attaques utilisant les connexions réseau, au profit des attaques « charge utile ». C'est logique quand on voit que sur un système récent (j'ai testé avec un Android et un Ubuntu, systèmes conçus pour M. Toutlemonde), il n'y a aucun service qui écoute sur l'Internet par défaut. Testez avec nmap :

# nmap -6 2a01:e35:8bd9:8bb0:6d07:5fdb:89e9:7d00 

Starting Nmap 5.00 ( ) at 2012-09-16 22:00 CEST
Interesting ports on 2a01:e35:8bd9:8bb0:6d07:5fdb:89e9:7d00:
Not shown: 999 closed ports
22/tcp open  ssh

Nmap done: 1 IP address (1 host up) scanned in 1.09 seconds

(le service SSH a été ajouté explicitement après l'installation, il n'était pas activé par défaut). Bien des services tournaient certes sur cette machine Ubuntu mais tous n'écoutaient que sur les adresses locales à la machine ( et ::1) et n'étaient donc pas vulnérables. Le NAPT n'aurait donc protégé contre rien.

Néanmoins, en matière de sécurité, ce n'est jamais tout blanc ou tout noir. Les programmes qui écoutent sur des ports inférieurs à 1024 sont en général particulièrement sensibles et l'idée de les protéger ne me semble pas mauvaise. On peut donc imaginer des règles plus subtiles que celle du NAPT actuel.

Mais le refus de certains d'abandonner le NAT « pour des raisons de sécurité » n'est pas rationnel, puisque le NAT n'empêche pas ces attaques. Même si on tient à la sécurité qui découle de l'usage du NAPT, rien n'interdit de faire pareil si on n'a pas de NAPT, avec un simple pare-feu avec état (c'est ce que recommande le RFC 6092 pour IPv6.)

Cette question de l'utilisation du NAT (ou plutôt, comme on l'a vu, du NAPT) pour améliorer la sécurité a fait couler beaucoup d'électrons. Parmi tous les articles existants, je préfère :

L'article seul

RFC 6709: Design Considerations for Protocol Extensions

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : B. Carpenter, B. Aboba, S. Cheshire
Pour information
Première rédaction de cet article le 15 septembre 2012

Concevoir des protocoles de communication monolithiques qui n'évoluent jamais est une chose. Concevoir des protocoles qui soient extensibles, qui puissent, après leur conception initiale, évoluer par le biais d'extensions, est un exercice plus difficile. Cet excellent RFC de l'IAB décrit comment faire un protocole extensible et comment assurer ainsi une évolution heureuse. C'est un document avant tout destiné aux auteurs de protocoles, mais qui intéressera aussi les étudiants en réseaux informatiques et tous les techniciens curieux, qui veulent savoir comment ça marche.

Parmi les innombrables exemples de protocoles IETF qui ont été étendus, on peut citer les extensions d'internationalisation de SMTP dans le RFC 6531, la recherche floue dans IMAP avec le RFC 6203, ou les capacités BGP du RFC 5492.

Le RFC 5218 (section 2.2.1), qui décrivait les raisons du succès pour un protocole réseau, notait parmi celles-ci l'extensibilité. Beaucoup de protocoles IETF ont des mécanismes pour cette extensibilité, qui est largement reconnue comme un bon principe. Mais, si elle est mal faite, des ennuis peuvent survenir, et cela peut menacer l'interopérabilité, voire la sécurité. Le RFC sur SMTP, le RFC 5321, note ainsi (section 2.2.1) que les protocoles avec peu d'options sont partout et que ceux avec beaucoup d'options sont nulle part. Un RFC comme le RFC 1263 (consacré aux extensions de TCP) critiquait également l'abus des extensions, et ce dès 1991. Malgré cela, d'innombrables RFC normalisent des extensions à tel ou tel protocole, mais il n'existait pas encore de document d'architecture sur le principe des extensions, rôle que ce RFC ambitionne de jouer.

D'abord, une distinction importante (section 2) entre extension « majeure » et « de routine ». Les secondes sont celles qui ne modifient pas le protocole de manière substantielle (et peuvent donc être introduites avec un minimum d'examen), les premières changent le protocole sérieusement et doivent donc être étudiées de près. Le problème est particulièrement aigu si l'extension est faite par d'autres personnes que le protocole originel : les « extensionneurs » risquent de ne pas connaître certaines règles non écrites que les auteurs originaux avaient en tête. Pour éviter cela, la spécification originale d'un protocole devrait toujours expliciter les règles, et décrire comment étendre le protocole proprement.

Comment distinguer une extension majeure d'une extension de routine ? Les extensions majeures sont celles qui peuvent empêcher l'interopérabilité (la capacité de deux pairs à communiquer), perturber le fonctionnement de l'Internet, ou mettre en péril la sécurité. Cela se produit notamment :

  • Si l'extension nécessite que les mises en œuvre existantes soient modifiées. Par exemple, si un protocole a un champ de taille fixe Foobar sur un octet et que, les 256 valeurs étant occupés, on passe à un champ de deux octets, les nouvelles mises en œuvre ne pourront pas parler aux anciennes, tout l'en-tête étant décalé à partir de ce champ (uniquement pour un octet ajouté). Il existe des méthodes pour éviter ces problèmes (par exemple utiliser des TLV au lieu des champs de taille fixe) mais elles ont aussi des inconvénients (de performance, par exemple) et, de toute façon, nécessitent d'avoir été mises dès le début dans le protocole. Un autre exemple est celui d'un protocole où les messages ont un type et où tout type inconnu fait couper la communication. Dans ce cas, ajouter un type de message, même optionnel, représente une extension majeure (là aussi, il existe des solutions, comme de spécifier dès le début que les messages de type inconnu doivent être silencieusement ignorés, cf. section 4.7).
  • Si l'extension change fondamentalement le modèle sous-jacent. C'est d'autant plus difficile à détecter que ce modèle n'est pas toujours explicite. Bien des RFC décrivent au bit près le format des messages mais sont très courts sur la vision de haut niveau du protocole. Le RFC donne l'exemple d'une extension qui ajouterait un état à un protocole qui était précédemment sans état.
  • Des nouveaux usages du protocole peuvent aussi représenter une extension majeure. Par exemple, si des changements purement quantitatifs se produisent (trafic accru, paquets plus gros comme dans le cas d'EDNS ou encore algorithmes qui ne supportent pas le passage à l'échelle d'une utilisation plus intense).
  • Si on change la syntaxe du protocole (par exemple si on inverse deux champs).
  • Si on change le modèle de sécurité.
  • Et, bien sûr, si on crée une extension qui ne « rentre pas » dans le modèle d'extension originellement envisagé.

Et les extensions de routine, alors, elles ressemblent à quoi ?

  • Elle n'ont aucune des caractéristiques citées plus haut, qui identifient les extensions majeures.
  • Elle sont opaques au protocole (les messages avec la nouvelle extension sont traités par le protocole comme ceux d'avant).

Une extension de routine ne nécessitera aucun changement sur les vieux programmes. Seuls ceux qui voudront utiliser la nouvelle extension auront à être modifiés.

Quelques exemples d'extensions de routine : les options spécifiques à un fournisseur de DHCP (RFC 2132), les options spécifiques à un fournisseur de Radius (RFC 2865), les types MIME de l'arbre vnd (vendor), etc. Ce n'est que lorsqu'on est sûr que l'ajout d'une extension ne sera que de la routine qu'on peut avoir des politiques du genre « premier arrivé, premier servi » (RFC 5226), c'est-à-dire peu ou pas d'examen préalable. Et encore, l'expérience a montré que même les extensions de routine pouvaient poser des problèmes inattendus et qu'un examen de toutes les extensions par un expert est souvent une bonne chose.

Une fois posée cette importante distinction entre extensions de routines et extensions majeures, la section 3 de notre RFC s'attache des bons principes architecturaux pour assurer une extensibilité heureuse :

  • Limiter l'extensibilité à ce qui est « raisonnable »,
  • Penser avant tout à l'interopérabilité,
  • Garder les extensions compatibles avec le protocole de base,
  • Ne pas permettre des extensions qui créent un nouveau protocole, incompatible avec le précédent,
  • Permettre de tester les extensions,
  • Bien coordonner les allocations de paramètres (noms, numéros, etc),
  • Faire davantage attention aux extensions aux composants critiques de l'Internet comme le DNS ou BGP.

Premier principe, limiter l'extensibilité. Il faut essayer de ne traiter que les cas les plus courants et ne pas chercher l'extensibilité à tout prix. C'est évidemment plus facile à dire qu'à faire. Comme le note le RFC 5218, un protocole qui rencontre un « succès fou » est utilisé dans des contextes que ses concepteurs n'imaginaient pas. Alors, essayer de déterminer à l'avance les extensions qui vont être vraiment utiles... On peut donc être amené à réviser le mécanisme d'extension en cours de route.

Deuxième principe, l'interopérabilité, c'est-à-dire la capacité de deux mises en œuvre complètement différentes du même protocole à communiquer. Le RFC 4775 (section 3.1) insiste sur ce concept, qui est au cœur de la mission de l'IETF. Une extension qui empêcherait les nouveaux programmes de communiquer avec les anciens casserait cette interopérabilité et serait donc inacceptable.

D'autres familles de protocole que la famille TCP/IP avaient une approche différente : le protocole était tellement bourré d'options très larges que deux mises en œuvre toutes les deux conformes à la norme pouvaient néanmoins ne pas pouvoir communiquer car elles n'implémentaient pas les mêmes options. C'est ce qui est arrivé aux protocoles OSI et la solution adoptée avait été de créer des profils (un ensemble d'options cohérent), créant ainsi autant de protocoles que de profils (les profils différents n'interopéraient pas même si, sur le papier, c'était le même protocole). Notre RFC dit clairement que ces profils ne sont pas une solution acceptable. Le but est d'avoir des protocoles qui fonctionnent sur tout l'Internet (alors qu'OSI avait une vision beaucoup plus corporate où il n'était pas prévu de communications entre groupes d'utilisateurs différents).

En pratique, pour assurer cette interopérabilité, il faut que le mécanisme d'extension soit bien conçu, avec notamment une sémantique claire (par exemple, précisant ce que doit faire un programme qui rencontre un message d'un type inconnu, ou bien un message d'un type qui ne correspond pas à ce qu'il devrait recevoir dans son état actuel).

Le RFC note aussi qu'écrire les plus belles normes ne suffira pas si elles sont mal mises en œuvre. On constate que les problèmes liés aux extensions sont souvent dus à des implémentations qui ne le gèrent pas correctement. Un exemple est celui des options d'IP qui, bien que clairement spécifiées dès le début (RFC 791), ne sont toujours pas partout acceptées en pratique.

Et puisqu'on parle d'interopérabilité, une idée qui semble bonne mais qui a créé beaucoup de problèmes : les extensions privées. Pas mal de programmeurs se sont dit « de toute façon, ce système ne sera utilisé que dans des réseaux fermés, tant pis pour l'interopérabilité sur le grand Internet, je peux, sur mon réseau, ajouter les extensions que je veux ». Mais les prédictions ne sont que rarement 100 % vraies. Les ordinateurs portables, les smartphones et autres engins se déplacent, et les implémentations ayant des extensions privées se retrouvent tôt ou tard à parler aux autres et... paf. Même chose lorsque deux extensions privées rentrent en collision, par exemple à la suite de la fusion de deux entreprises. Imaginons que chacune d'elles ait choisi de mettre du contenu local dans un attribut DHCP de numéro 62, en pensant que, DHCP n'étant utilisé que sur le réseau local, cela ne gênerait jamais. Des années après, une des deux entreprises rachète l'autre, les réseaux fusionnent et... repaf.

Pour résoudre ce problème, on a parfois fait appel à des espaces réservés comme le fameux préfixe « X- » devant le nom d'un paramètre (RFC 822). Le RFC 6648 a mis fin à cette pratique (qui était déjà retirée de plusieurs RFC), notamment parce que les paramètres « privés », tôt ou tard, deviennent publics, et qu'alors les ennuis commencent.

Un problème proche existe pour les paramètres considérés comme « expérimentaux ». Ils ont leur utilité, notamment pour que les programmeurs puissent tester leurs créations. C'est ainsi que le RFC 4727 propose des valeurs pour les expérimentations avec de nouveaux protocoles de transport, des nouveaux ports, etc. Le RFC 3692 décrit plus en détail les bonnes pratiques pour l'utilisation de valeurs expérimentales. Elles doivent être strictement limitées au système en cours de test, et jamais distribuées sur l'Internet. Si l'expérience est multi-site, c'est une bonne raison pour ne pas utiliser de valeurs expérimentales. C'est ainsi que des expériences comme HIP et LISP ont obtenu des paramètres enregistrés, non expérimentaux, pour pouvoir être testés en multi-sites.

À noter que ces valeurs expérimentales ne sont nécessaires que lorsque l'espace disponible est limité. Le champ Next header d'IPv6 ne fait qu'un octet et il est donc logique de bloquer deux valeurs réutilisables, 253 et 254, pour expérimenter avec des valeurs non officiellement enregistrés. Mais ce n'est pas le cas, par exemple, des champs de l'en-tête HTTP, composés d'un grand nombre de caractères et permettant donc des combinaisons quasi-infinies. Si on expérimente avec HTTP, il y a donc peu de raisons de réserver des champs expérimentaux.

Troisième principe architectural, la compatibilité avec le protocole de base. Elle implique un double effort : les auteurs du protocole original doivent avoir bien spécifié le mécanisme d'extensions. Et les auteurs d'extensions doivent bien suivre ce mécanisme. Quelques exemples de protocole où le mécanisme d'extensions est documenté en détail : EPP (RFC 3735), les MIB (RFC 4181), SIP (RFC 4485), le DNS (RFC 2671 et RFC 3597), LDAP (RFC 4521) et Radius (RFC 6158).

Quatrième principe d'architecture, faire en sorte que les extensions ne mènent pas à une scission, avec apparition d'un nouveau protocole, incompatible avec l'original. Des changements qui semblent très modérés peuvent empêcher l'interopérabilité, ce qui serait de facto un nouveau protocole. Un protocole trop extensible peut donc ne pas être une si bonne idée que cela, si cette extensibilité va jusqu'à la scission.

Comme le note le RFC 5704, écrit dans le contexte d'une grosse dispute entre l'IETF et l'UIT, la scission (fork) peut venir de l'action non coordonnée de deux SDO différentes. Mais il n'y a pas toujours besoin d'être deux pour faire des bêtises : le RFC 5421 réutilisait un code EAP, rendant ainsi le protocole incompatible avec la précédente version. L'IESG avait noté le problème (documenté dans la section IESG Note du RFC 5421) mais avait laissé faire.

Cette notion de scission est l'occasion de revenir sur un concept vu plus haut, celui de profil. Il y a deux façons de profiler un protocole :

  • Retirer des obligations (ce qui peut créer de gros problèmes d'interopérabilité),
  • Ajouter des obligations (rendre obligatoire un paramètre qui était facultatif).

Contrairement à la première, la seconde approche peut être une bonne idée. En réduisant le nombre de choix, elle peut améliorer l'interopérabilité. Par contre, retirer des obligations est presque toujours une mauvaise idée. Ces obligations, dans un RFC (les fameux MUST, SHOULD et MAY), sont décrites avec les conventions du RFC 2119 et ce RFC insiste bien sur le fait qu'elles doivent être soigneusement choisies. Par exemple, un MUST ne doit être utilisé que si la violation de cette obligation est effectivement dangereuse, par exemple pour l'interopérabilité. Si ce conseil a été suivi, changer un MUST en SHOULD dans un profil va donc être négatif à coup presque sûr. Et, le RFC rappelle aussi qu'un MAY veut dire « vous n'êtes pas obligés de l'implémenter » mais certainement pas « vous avez le droit de planter si l'autre machine l'utilise ».

Place au cinquième principe, les tests. On a vu que ce n'est pas tout de bien normaliser, il faut aussi bien programmer. Pour s'assurer que tout a été bien programmé, il faut tester. Cela implique d'avoir développé des jeux de tests, essayant les différents cas vicieux (par exemple, essayer toutes les possibilités du mécanisme d'extension, pour vérifier qu'aucune ne plante les programmes ne les mettant pas en œuvre). Sinon, le test sera fait dans la nature, comme cela avait été le cas du fameux attribut 99 de BGP. La norme spécifiait très clairement ce qu'un pair BGP devait faire d'un attribut inconnu, mais IOS n'en tenait pas compte et, lorsque quelqu'un a essayé d'utiliser réellement cette possibilité de la norme, il a planté une bonne partie de l'Internet européen... TLS, étudié plus en détail plus loin, fournit un autre exemple d'implémentations déplorables, bloquant le déploiement de nombreuses extensions.

Sixième grande question d'architecture, l'enregistrement des paramètres. Beaucoup de protocoles ont besoin de registres pour noter les valeurs que peuvent prendre tel ou tel champ (par exemple, il y a un registre des numéros de protocole de transport et un registre des options DHCP). Ces registres et leur bonne utilisation sont une question souvent sous-estimée de l'interopérabilté. Si un champ du paquet identifie une extension et que deux extensions incompatibles utilisent le même numéro, l'accident est inévitable. Cette collision peut être due à l'absence de registre mais on rencontre régulièrement des développeurs qui ne vérifient pas le registre et qui s'attribuent tout simplement un numéro qui leur semble libre. (Le RFC note, de manière politiquement correcte, qu'il ne peut pas « publier les noms sans embarrasser des gens ». Mais cela semble particulièrement fréquent pour les numéros de port et pour les plans d'URI.)

Les concepteurs de protocole devraient vérifier, d'abord si un des registres existants ne suffit pas et, sinon en créer un. Dans ce cas, il faut soigneusement choisir la politique d'allocation des valeurs dans ce registre. Le RFC 5226 décrit les différentes politiques possibles, de la plus laxiste à la plus stricte. Attention : choisir une politique très stricte peut avoir des effets de bord désagréables, par exemple encourager les gens à « s'auto-enregistrer », c'est-à-dire à prendre un numéro au hasard (et tant pis pour l'interopérabilité) parce que la complexité et la lenteur des procédures les ont découragés. Il peut être préférable d'avoir une approche plus ouverte du registre, qui devrait documenter ce qui existe plutôt que d'essayer de contrôler tous les enregistrements.

Enfin, septième et dernier principe architectural à garder en tête pour faire des protocoles extensibles, l'importance particulière des services critiques. Si on arrête BGP, l'Internet ne fonctionne plus. Si on arrête le DNS, il n'y a quasiment plus aucune activité possible (même si vous ne voyez pas de noms de domaine, ils sont présents dans la communication). Même chose pour certains algorithmes comme le contrôle de congestion : si on modifie cet algorithme et qu'on se trompe, on peut mettre l'Internet à genoux. Il faut donc faire dix fois plus attention lorsqu'on étend ces protocoles critiques.

Le RFC cite un exemple BGP. Il existait depuis longtemps dans les IGP comme OSPF la notion de LSA opaque (LSA = Link State Attribute, la structure de données qui contient les informations que s'échangent les routeurs). « Opaque » signifie que les routeurs n'ont pas forcément besoin de comprendre son contenu. Ils peuvent le propager sans l'analyser et cela permet des extensions intéressantes du protocole, en introduisant de nouveaux types de LSA opaques. L'expérience montre que cela marche bien.

Mais l'introduction de nouveaux attributs dans BGP ne s'est pas aussi bien passé puisque des routeurs ont réinitialisé les sessions locales si un attribut, transmis par un routeur lointain, était inconnu ou mal formé. (Cas du fameux attribut 99.)

Une fois ces sept principes en tête, la section 4 se penche sur le protocole de base. Une bonne extensibilité implique un bon protocole de base, conçu pour l'extensibilité. Cela implique :

  • Une spécification bien écrite,
  • Prenant en compte l'interaction avec des versions plus récentes ou plus anciennes du protocole. Cela inclut la détermination des capacités du pair, la négociation des paramètres, le traitement des extensions inconnues (nécessaire pour que les nouvelles implémentations ne plantent pas les anciennes), etc.
  • Décrivant bien les principes architecturaux du protocole, ainsi que sa sécurité (pour éviter qu'une extension ne casse un modèle de sécurité bien fait mais pas assez explicite).
  • Précisant clairement le modèle d'extensions et notamment quelles extensions sont majeures et lesquelles sont de routine.
  • Interagissant le moins possible avec les composants critiques de l'Internet. Par exemple, si un nouveau protocole nécessite des modifications sérieuses au DNS, cela va faire hésiter.

Écrire un protocole bien extensible nécessite aussi de prêter attention à ce qui peut sembler des petits détails. Ainsi (section 4.1), le problème des numéros de versions. Il est courant que le protocole porte un tel numéro, permettant au pair de savoir tout de suite s'il a affaire à une implémentation équivalente (même numéro de version) ou pas (numéro de version plus récent ou plus ancien). Par exemple, voici une session TLS avec l'outil gnutls-cli de GnuTLS :

% gnutls-cli  --verbose  --port 443
- Version: TLS1.2

où on voit que le serveur accepte TLS version 1.2. Un tel versionnement n'est utile que si le protocole de base précise bien ce qu'il faut faire lorsqu'on rencontre une version différente. Par exemple, si un logiciel en version 1.1 rencontre un 2.0 ? Il y a plusieurs sémantiques possibles, par exemple le protocole de base peut préciser que toute version doit être un sur-ensemble de la version antérieure (le logiciel en 2.0 doit accepter toutes les commandes du 1.1). Une autre sémantique pourrait être qu'il n'y a compatibilité qu'au sein d'une même version majeure (entre 1.0, 1.1, 1.2, etc) et que donc les deux logiciels de l'exemple (1.1 et 2.0) doivent renoncer à se parler. Dans les deux cas, cela doit être clairement spécifié.

Un contre-exemple est fourni par la norme MIME. Le RFC 1341 décrivait un en-tête MIME-Version: mais sans dire ce que devait faire une implémentation correcte de MIME si elle rencontrait une version inférieure ou supérieure. En fait, ce RFC 1341 ne précisait même pas le format de la version ! Le RFC 1521 a un peu précisé les choses mais pas au point qu'on puisse prédire le comportement d'une mise en œuvre de MIME face à des versions nouvelles. Notre RFC 6709 estime donc que le MIME-Version: n'a guère d'utilité pratique.

Pour un exemple plus positif, on peut regarder ROHC. Le RFC 3095 décrivait un certain nombre de jeux de paramètres pour la compression. À l'usage, on leur a découvert des limitations, d'où le développement de ROHCv2 (RFC 5225). Ce dernier n'est pas compatible mais ne plante pas les ROHC précédents, ils ont simplement des jeux de paramètres différents et la négociation initiale (qui n'a pas changé en v2) permet à un ROHC ayant les jeux v1 de se comprendre facilement avec un plus récent.

Quelles sont les stratégies utilisées par les protocoles pour la gestion des versions ? Il y en a plein, toutes n'étant pas bonnes. On trouve :

  • Pas de gestion de versions. Le cas le plus célèbre est EAP (RFC 3748) mais c'est aussi le cas de Radius (RFC 2865). Cela les a protégé contre l'apparition de multiples versions à gérer mais, comme la demande d'extensibilité est toujours là, elle s'est manifestée de manière non officielle (voir l'étude de cas de Radius en annexe A.2).
  • HMSV (Highest mutually supported version) : les deux pairs échangent les numéros de version du protocole qu'ils savent gérer et on choisit la plus élevée qui soit commune aux deux. Cela implique que la version plus élevée est toujours « meilleure » (alors que, parfois, une version supérieure retire des fonctions). Cela implique aussi que gérer une version implique aussi de gérer toutes les versions inférieures (si un pair annonce 3.5 et un autre 1.8, HMSV va choisir 1.8 alors que le pair en 3.5 ne sait pas forcément gérer cette vieille version).
  • Min/Max : une variante de HMSV où on annonce non pas un numéro de version (la plus élevée qu'on gère) mais deux (la version la plus élevée qu'on gère, et la moins élevée). Ainsi, il n'y a pas besoin de gérer éternellement les vieilles versions. Dans certains cas, cela peut mener à l'échec de la négociation. Si Alice annonce 2.0->3.5 et que Bob répond avec 1.0->1.8, ils n'auront aucune version compatible (Bob est trop vieux). Au moins, cela permettra d'envoyer un message d'erreur clair.
  • Considérer que les vieilles versions sont compatibles avec les récentes. L'idée est que l'implémentation récente peut envoyer ce qu'elle veut, l'ancienne devant réagir proprement (typiquement en ignorant les nouveaux messages et types). Cela a pour conséquence qu'une nouvelle version du protocole ne peut pas rendre obligatoire un message qui n'existait pas avant (puisque les vieilles implémentations ne le connaissent pas). Avec cette stratégie, qui est par exemple utilisée dans 802.1X, un logiciel n'est jamais dépassé, il peut toujours travailler avec ses successeurs.
  • Majeur/mineur : pour les numéros de versions à deux champs (comme 3.5 et 1.8 plus tôt), on considère qu'il y a compatibilité tant que le champ majeur ne change pas. 3.5 peut communiquer sans problème avec 3.0 mais aussi avec 3.9. Mais 3.5 ne peut pas parler avec 2.4 ou 5.2. Les contraintes de la stratégie précédente (ignorer les types inconnus, ne pas rendre un nouveau type obligatoire) ne s'appliquent donc qu'au sein d'un même numéro majeur.

Et c'est à peu près tout. Le RFC considère qu'il ne faut pas chercher d'autres stratégies de versionnement, qui ont de fortes chances d'être trop complexes pour être mises en œuvre sans erreur.

Autre chose importante à considérer lorsqu'on normalise le protocole de base (la première version) : les champs réservés. On trouve souvent dans les RFC des phrases comme (celle-ci est extraite du RFC 1035) « Reserved for future use. Must be zero in all queries and responses. ». (Dans le cas du DNS, ils ont été utilisés par la suite pour DNSSEC, bits AD et CD. Le bit 9, selon le RFC 6195, section 2.1, avait été utilisé de manière non standard autrefois et semble donc inutilisable désormais.) Certains champs dans l'en-tête sont donc gardés pour un usage futur et, presque toujours, le RFC demande à l'envoyeur de les mettre tous à zéro et au récepteur de les ignorer, ce qui est très important : autrement, on ne pourra jamais déployer d'implémentation d'une nouvelle version du protocole, qui utiliserait ces champs qui avaient été réservés. Dans les diagrammes montrant les paquets, ces champs sont en général marqués Z (pour Zero) ou MBZ (Must Be Zero, voir par exemple le RFC 4656). Notons que bien des pare-feux, fidéles jusqu'à l'excès au principe « tout ce qui est inconnu est interdit », au lieu d'ignorer ces champs, comme l'impose le RFC, jettent les paquets où ce champ ne vaut pas zéro. Ces engins sont une des plus grosses sources de problème lorsqu'on déploie un nouveau protocole. Donc, attention, programmeurs, votre travail n'est pas de vérifier ces champs mais de les ignorer, afin de permettre les futures extensions.

Autre problème douloureux, la taille à réserver aux champs (section 4.4). Certains protocoles utilisent des champs de taille illimitée (paramètres de type texte) ou suffisamment grands pour qu'on ne rencontre jamais la limite, même après plusieurs extensions du protocole. Mais ce n'est pas toujours le cas. Tout le monde se souvient évidemment de l'espace d'adressage trop petit d'IPv4 et de la difficulté qu'il y a eu à passer aux adresses plus grandes d'IPv6 (le champ Adresse étant de taille fixe, les deux versions ne pouvaient pas être compatibles). Dans la réalité, on rencontre :

  • Des champs Version trop petits, par exemple de seulement deux bits (après la version de développement et la version de production, on n'a plus que deux versions possibles).
  • Des champs stockant un paramètre pour lesquels la taille était trop petite pour la politique d'allocation (cf. RFC 5226) qui avait été adoptée. Par exemple, la politique FCFS (First-come, First-served, ou « Premier arrivé, premier servi »), la plus libérale, peut vite épuiser un champ de seulement huit bits (le problème s'est posé pour le champ Method Type d'EAP dans le RFC 2284).

Si un tel problème se pose, si on voit les valeurs possibles pour un champ arriver à un tel rythme que l'épuisement est une possibilité réelle, il y a plusieurs solutions :

  • Changer la politique d'allocation en la durcissant. Mais attention, une politique trop dure peut mener à des comportements comme l'auto-allocation (« je prends la valeur qui me plait et tant pis pour le registre »). C'est ce qui avait été fait pour EAP (RFC 3748, section 6.2) en passant de « Premier arrivé, premier servi » à « Norme nécessaire ». Pour éviter l'auto-allocation, diverses solutions alternatives avaient également été normalisées par ce RFC, comme la suivante :
  • Permettre des valeurs spécifiques à un fournisseur (vendor). Ainsi, chaque fournisseur qui crée une extension privée, spécifique à son logiciel, peut créer ses propres types/messages.
  • Agrandir le champ. La plupart des protocoles IETF ont des champs de taille fixe, pour des raisons de performance (il faut se rappeler qu'il peut y avoir beaucoup de paquets à traiter par seconde, ce n'est donc pas une optimisation de détail). Agrandir le champ veut donc en général dire passer à une nouvelle version, incompatible, du protocole.
  • Récupérer des valeurs inutilisées. C'est très tentant sur le principe (il est rageant d'épuiser un espace de numérotation alors qu'on sait que certaines valeurs ont été réservées mais jamais utilisées) mais cela marche mal en pratique car il est en général très difficile de dire si une valeur est vraiment inutilisée (peut-être qu'une obscure implémentation utilisée uniquement dans un lointain pays s'en sert ?)

Un usage particulier de l'extensibilité concerne la cryptographie (section 4.5). Celle-ci demande une agilité, la capacité à changer les algorithmes de cryptographie utilisés, pour faire face aux progrès constants de la cryptanalyse (c'est bien expliqué dans la section 3 du RFC 4962). Presque tous les protocoles de cryptographie sérieux fournissent cette agilité (le RFC ne donne pas d'exemple mais je peux citer deux contre-exemples, un à l'IETF, le TCP-MD5 du RFC 2385 depuis remplacé par le meilleur RFC 5925 qui est encore très peu déployé et, en dehors de l'IETF, le protocole DNScurve). Le problème est lorsqu'un algorithme noté comme obligatoire (avant d'assurer l'interopérabilité, un ou plusieurs algorithmes sont obligatoires à implémenter, pour être sûr que deux pairs trouvent toujours un algorithme commun) est compromis au point qu'il n'est plus raisonnable de s'en servir.

Soit un algorithme non compromis est déjà très répandu dans les mises en œuvre existantes du protocole et on peut alors le déclarer obligatoire, et noter le vieil algorithme comme dangereux à utiliser. Soit il n'existe pas encore un tel algorithme répandu et on a peu de solutions : déployer du code dans la nature prend beaucoup de temps. Bref, le RFC recommande que, lorsque les signes de faiblesse d'un algorithme face à la cryptanalyse apparaissent (le RFC ne cite pas de noms mais, en 2012, on peut dire que c'est le cas de SHA-1 et RSA), on normalise, puis on pousse le déploiement de solutions de rechange (par exemple SHA-2 et ECDSA dans ces deux cas, algorithmes qui sont aujourd'hui utilisables dans la plupart des protocoles IETF). Il faut bien se rappeler que le déploiement effectif d'un algorithme normalisé peut prendre des années, pendant lesquelles la cryptanalyse continuera à progresser.

Un aspect peu connu des protocoles applicatifs de la famille IP est qu'ils peuvent parfois tourner sur plusieurs transports, par exemple TCP et SCTP (section 4.6). Cela a parfois été fait dès le début, pour avoir le maximum de possibilités mais, parfois, le protocole de couche 7 n'était prévu que pour un seul protocole de couche 4, puis a été étendu pour un autre protocole. Par exemple, utilisant TCP, il ne passait pas à l'échelle, alors on l'a rendu utilisable sur UDP. (Dans ce cas, les concepteurs du protocole devraient lire le RFC 8085 car il y a plein de pièges.)

Cela peut évidemment casser l'interopérabilité. Si le protocole Foobar est normalisé pour tourner sur TCP ou SCTP, deux mises en œuvre de Foobar, une qui ne gère que TCP et une qui ne gère que SCTP (pensez aux systèmes embarqués, avec peu de ressources, ce qui impose de limiter les choix), ne pourront pas se parler. Notre RFC conseille donc de bien réflechir à ce problème. Davantage de choix n'est pas forcément une bonne chose. D'un autre côté, si le premier protocole de transport choisi a de sérieuses limites, on pourra en ajouter un autre comme option mais il sera quasi-impossible de supprimer le premier sans casser l'interopérabilité.

Enfin, dernier casse-tête pour le concepteur de protocoles, le cas des extensions inconnues (section 4.7). Je suis programmeur, je crée un programme pour la version 1.0 du protocole, ce programme sait traiter un certain nombre de messages. Le temps passe, une version 1.1 du protocole est créé, des programmeurs la mettent en œuvre et, soudain, les copies de mon programme reçoivent des messages d'un type inconnu, car introduit dans la 1.1. Que faire ? Première approche, une règle comme quoi les extensions inconnues doivent être ignorées (silently discarded). Je reçois un tel message, je le jette. Un champ qui était à zéro acquiert une signification ? J'ignore ce champ. L'avantage de cette approche est qu'elle permet le maximum d'interopérabilité. On est sûr que les vieilles versions pourront parler avec les nouvelles, même si seules les nouvelles pourront tirer profit des extensions récentes. L'inconvénient de cette approche est qu'on ne sait même pas si les nouveaux messages sont traités ou pas. Dans le cas de la sécurité, on voudrait bien pouvoir savoir si une extension qu'on considère comme indispensable a bien été acceptée par le pair (voir par exemple la section 2.5 du RFC 5080).

Autre approche, mettre un bit Mandatory (aussi appelé Must Understand) dans les messages. Si ce bit est à zéro, une vieille implémentation peut ignorer le message. Sinon, elle doit prévenir qu'elle ne sait pas le gérer (par exemple via un message ICMP). C'est ce que font L2TP (RFC 2661, section 4.1) ou SIP (RFC 3261, section Cette méthode permet d'éviter qu'une extension cruciale soit ignorée par le pair. Mais elle diminue l'interopérabilité : si un programme récent l'utilise, il ne pourra pas parler avec les vieux qui ne savent pas du tout gérer cette extension.

On peut aussi négocier les extensions gérées au début de la session. Cela ralentit son établissement mais cela permet aux deux pairs qui dialoguent de savoir ce que fait l'autre. Typiquement, l'initiateur de la connexion indique ce qu'il sait gérer et le répondeur choisit parmi ces extensions acceptées. IKE (RFC 5996) fait cela, HTTP et SIP aussi, via leurs en-têtes Accept*: et Supported:.

Enfin, le concepteur d'un protocole de base, ou d'une extension à ce protocole doit lire la section 5 sur la sécurité. Elle rappelle qu'une extension à l'apparence inoffensive peut facilement introduire un nouveau risque de sécurité, ou parfois désactiver une mesure de sécurité qui était dans le protocole de base (l'ajout d'une poignée de mains dans un protocole qui était avant sans état peut créer une nouvelle occasion de DoS). L'analyse de sécurité de la nouvelle extension ne peut donc pas se contenter de reprendre celle du protocole de base, il faut s'assurer qu'il n'y ait pas de régression.

L'annexe A de notre RFC est très instructive car elle comprend trois études de cas de protocoles qui ont réussi, ou raté, leur extensibilité. La première concerne Radius (RFC 2865) grand succès mais qui, pour cette raison, a connu de fortes pressions pour son extension, pressions qui ont sérieusement secoué un protocole qui n'était pas vraiment conçu pour cela. L'idée dans le protocole de base était que les extensions se feraient en ajoutant des attributs (le protocole venait avec un certain nombre d'attributs standards dans les messages) dont la valeur pouvait avoir un nombre limité de types.

En pratique, on a constaté que, non seulement beaucoup de fournisseurs ne pouvaient pas s'empêcher de s'auto-allouer des noms d'attributs, mais aussi que bien des attributs ajoutés sortaient du modèle original (comme l'idée d'un dictionnaire, sur lesquels les correspondants se mettent d'accord et qui permet le déploiement de nouveaux attributs sans changer le code : idée astucieuse mais qui n'est pas dans le RFC 2865). La section 1 du RFC 2882, tirant un premier bilan, note qu'une des raisons de la tension est que le monde des NAS, pour lequel Radius avait été conçu, s'était beaucoup diversifié et complexifié, au delà du modèle initialement prévu. Le RFC 2882 notait aussi que certaines mises en œuvre ressemblaient à Radius (même format des messages) mais ne l'étaient pas vraiment (sémantique différente).

Un des cas compliqué est celui des types de données pour les attributs. Il était prévu d'ajouter de nouveaux attributs mais pas de nouveaux types. Il n'existe pas de registre des types définis, ni de moyen pour un client ou serveur Radius que savoir quels types gèrent son correspondant. L'utilisation d'attributs définis avec un type nouveau est donc problématique. Le RFC 6158 (section 2.1) a tenté de mettre de l'ordre dans ce zoo des types mais, publié plus de quatorze ans après la première norme Radius, il n'a pas eu un grand succès.

Radius dispose d'un mécanisme d'extensions spécifiques à un fournisseur (RFC 2865, section 6.2). Ce mécanisme a été utilisé à tort et à travers, notamment par des SDO différentes de l'IETF qui voulaient leurs propres extensions (alors que ces extensions n'avaient jamais été prévues pour être compatibles d'un fournisseur à l'autre). Autre problème, le cas des extensions « fournisseur » inconnues n'avait pas été traité. Or, certaines ont des conséquences pour la sécurité (définition d'une ACL par exemple) et il serait dommage qu'elles soient ignorées silencieusement. Le RFC 5080, section 2.5, estime que la seule solution est que les programmes mettant en œuvre Radius n'utilisent les extensions que lorsqu'ils savent (par exemple par configuration explicite) que l'autre programme les gère.

Autre protocole qui a connu bien des malheurs avec les extensions, TLS (annexe A.3). Son histoire remonte au protocole SSL, v2, puis v3, celle-ci remplacée par TLS. SSL, et TLS 1.0, n'avaient aucun mécanisme d'extension défini. Il a fallu attendre le RFC 4366 pour avoir un mécanisme normalisé permettant de nouveaux types d'enregistrements, de nouveaux algorithmes de chiffrement, de nouveaux messages lors de la poignée de mains initiale, etc. Il définit aussi ce que les mises en œuvre de TLS doivent faire des extensions inconnues (ignorer les nouveaux types, rejeter les nouveaux messages lors de la connexion). Mais, à ce moment, TLS était déjà très largement déployé et ces nouveaux mécanismes se heurtaient à la mauvaise volonté des vieilles implémentations. En pratique, les problèmes ont été nombreux, notamment pendant la négociation initiale. Ce n'est qu'en 2006 que les clients TLS ont pu considérer que SSLv2 était mort, et arrêter d'essayer d'interopérer avec lui. Encore aujourd'hui, de nombreux clients TLS restent délibérement à une version de TLS plus faible que ce qu'ils pourraient faire, pour éviter de planter lors de la connexion avec un vieux serveur (ces serveurs étant la majorité, y compris pour des sites Web très demandés). C'est ainsi que, lors de l'annonce de l'attaque BEAST en 2011, on s'est aperçu que TLS 1.1 résolvait ce problème de sécurité depuis des années... mais n'était toujours pas utilisé, de peur de casser l'interopérabilité.

Dans le futur, cela pourra même poser des problèmes de sécurité sérieux : il n'existe aucun moyen pratique de retirer MD5 de la liste des algorithmes de hachage, par exemple. TLS 1.2 (RFC 5246) permet d'utiliser SHA-256 mais tenter d'ouvrir une connexion en TLS 1.2 avec un serveur a peu de chances de marcher, le mécanisme de repli des versions n'existant que sur le papier.

Morale de l'histoire, dit notre RFC : ce n'est pas tout de faire de bonnes spécifications, il faut aussi qu'elles soient programmées correctement.

Dernier cas intéressant étudié, L2TP (RFC 2661). Fournissant dès le début des types spécifiques à un fournisseur, disposant d'un bit Mandatory pour indiquer si les types doivent être compris par le récepteur, L2TP n'a guère eu de problèmes. On pourrait imaginer des ennuis (RFC 2661, section 4.2) si un programmeur mettait un type spécifique et le bit Mandatory (empêchant ainsi toute interaction avec un autre fournisseur qui, par définition, ne connaîtra pas ce type) mais cela ne s'est guère produit en pratique.

Téléchargez le RFC 6709

L'article seul

RFC 6724: Default Address Selection for Internet Protocol version 6 (IPv6)

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : D. Thaler (Microsoft), R. Draves (Microsoft Research), A. Matsumoto (NTT), T. Chown (University of Southampton)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF 6man
Première rédaction de cet article le 12 septembre 2012

Lorsqu'une machine IPv6 a plusieurs adresses et qu'elle va initier une communication avec une autre machine ayant elle-même plusieurs adresses, quelle adresse choisir pour la source ? Et pour la destination ? Ce RFC donne deux algorithmes (un pour la source et un pour la destination) à suivre pour que la sélection d'adresse par défaut soit prévisible. Naturellement, il sera toujours possible, pour l'ingénieur système ou pour le programmeur, de passer outre ce choix par défaut et de choisir délibérement une autre adresse. Ce RFC remplace le RFC 3484.

Alors, quel est le problème ? En IPv6, il est courant d'avoir plusieurs adresses IP pour une machine (RFC 4291). Par exemple, si un site est multi-homé, les machines peuvent avoir une adresse par FAI. Ou bien il peut y avoir des tunnels, qui viennent avec leurs adresses. Toutes ces adresses peuvent avoir des caractéristiques variables : portée, statut (préférée, abandonnée, cf. RFC 4862), temporaire (pour des raisons de vie privée, cf. RFC 8981) ou pas... Voici un exemple sur une machine Debian ayant six adresses IPv6 :

% ip -6 addr show 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 2605:4500:2:245b::f00/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 2605:4500:2:245b::bad:dcaf/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 2605:4500:2:245b::42/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fed9:83b3/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
    inet6 fe80::5054:ff:fe9f:5bb1/64 scope link 
       valid_lft forever preferred_lft forever

Il faudra donc un mécanisme pour décider de l'adresse source à utiliser.

Quant à la machine de destination, elle peut aussi avoir plusieurs adresses, par exemple plusieurs enregistrements AAAA sont dans le DNS. Il faudra donc aussi choisir l'ordre dans lequel on essaiera les adresses de destination. À noter que ce choix peut inclure le choix entre IPv6 et IPv4. Si les deux machines (source et destination) sont en double pile, va t-on utiliser IPv4 ou IPv6 ? (Notre RFC donne la préférence à IPv6 mais voyez plus loin pour les règles exactes.)

Notez que les deux algorithmes ne rendent donc pas le même type de résultat. Pour la destination, l'algorithme produit une liste d'adresses ordonnées, pouvant mêler IPv4 et IPv6. Pour la source, il produit une adresse, la meilleure, et forcément en IPv6 (la sélection d'une adresse source IPv4 est un problème intéressant mais non couvert par ce RFC).

Soit une application en C qui appelle la routine standard getaddrinfo() (RFC 3493) pour trouver les adresses IP du correspondant. Dans le cas le plus fréquent, elle va essayer toutes les adresses IP renvoyées par getaddrinfo(), dans l'ordre où ce dernier les a renvoyées, et l'application ne spécifiera pas son adresse source (c'est le cas simple : les variantes sont discutées plus loin). Pour mettre en œuvre ce RFC, getaddrinfo() va utiliser l'algorithme de sélection de la destination, pour trier la liste obtenue du DNS, et le noyau du système va utiliser l'algorithme de sélection de la source pour décider de l'adresse IP source, au moment du connect().

À noter qu'essayer uniquement la première adresse IP renvoyée par getaddrinfo() serait une mauvaise stratégie : si elle est injoignable, aucune communication ne sera possible, alors que certaines des autres adresses marchaient peut-être. Essayer les adresses de manière strictement séquentielle n'est pas non plus optimum et le RFC 6555 conseille de le faire en partie de manière parallèle.

Si on veut résumer les deux algorithmes utilisés, on peut dire qu'ils préfèrent former des couples source/destination où les deux adresses ont la même portée, ont la portée la plus étroite possible, sont des adresses préservant la vie privée, et, en fin de compte, partagent le plus de bits de préfixe possibles.

Comme indiqué plus haut, cet algorithme pourra toujours être surmonté par un choix explicite du programmeur comme la directive outgoing-interface d'Unbound (mal nommée puisque prenant comme paramètre une adresse IP et pas une interface) ou comme, avec OpenSSH, l'option -b sur la ligne de commande (ou bien BindAddress dans le fichier de configuration). Ou bien un choix explicite de l'administrateur système qui peut éditer une table des politiques (celle qui dit par exemple que IPv6 est préféré à IPv4, ce qu'on peut changer), modifier la préférence par défaut en faveur des adresses de préservation de la vie privée, et permettre ou pas l'addition automatique de certaines adresses à la table des politiques.

Que contient cette « table des politiques » ? La section 2.1 la détaille. Elle stocke des préfixes d'adresses IP et, comme pour une table de routage, c'est le plus spécifique (le plus long) qui gagne. Sur un système Linux, c'est en général le fichier /etc/gai.conf qui contient la table, fichier que l'administrateur système peut éditer selon ses goûts (section 10.3 du RFC). La table par défaut contient :

Prefix        Precedence Label
::1/128               50     0
::/0                  40     1
::ffff:0:0/96         35     4
2002::/16             30     2
2001::/32              5     5
fc00::/7               3    13
::/96                  1     3
fec0::/10              1    11
3ffe::/16              1    12

La préférence est donnée aux préfixes ayant le champ Precedence le plus élevé. Ainsi, si on a le choix entre les adresses 2001:db8:1::cafe et fec0::90ff:fe92:bd00, la première a une précédence de 40 (en raison de la règle ::/0), la seconde de 1 (en raison de la règle fec0::/10) : rappelez-vous que c'est le préfixe le plus spécifique qui est choisi, pas celui qui est le premier dans la table). On va donc choisir l'adresse publique, 2001:db8:1::cafe (le préfixe fec0::/10 a été abandonné par le RFC 3879).

Autre conséquence de cette table, IPv6 est préféré à IPv4 (représenté par ::ffff:0:0/96, cf. RFC 4291, section Si on veut changer cela, par exemple parce qu'on a une connectivité IPv6 vraiment trop mauvaise (voir le problème des globes oculaires et la section 10.3.1 de notre RFC), on édite gai.conf ou son équivalent et on met, par exemple (syntaxe de gai.conf) une précédence de 100 :

precedence ::ffff:0:0/96  100

D'autres trucs Linux sont documentés dans « IPv6 Source Address Selection on Linux ». Si on travaille sur FreeBSD, la configuration est dans /etc/ip6addrctl.conf et il faut donc regarder la documentation de ip6addrctl.

Notez que cette table peut être dynamique : une implémentation a le droit d'y ajouter des préfixes en cours de route, par exemple pour ses ULA (RFC 4193).

Autre définition importante, la notion de la longueur du préfixe commun. Cette longueur est définie en comparant uniquement les 64 premiers bits de l'adresse. Ainsi, la longueur du préfixe commun à 2001:db8:1::bad et 2001:db8:2::bad est 32 (2001:db8 est la seule partie commune). Mais la longueur du préfixe commun à 2001:db8:1::bad:dcaf et 2001:db8:1::bad:cafe n'est que de 64 et pas de 112 comme on pourrait le croire à première vue. C'est parce qu'on ignore l'Interface ID (les 64 derniers bits). C'est un des gros changements par rapport au précédent RFC, le RFC 3484, motivé par des problèmes comme une mauvaise interaction avec des systèmes de répartition de charge..

Et les propriétés des adresses (section 3) ? On a entre autres :

  • La portée : locale au lien, locale au site, ou globale. Ainsi, fe80::35cd:efc1:e399:3aa9 a une portée inférieure à 2001:4f8:3:2bc:1::64:21.
  • Le fait d'être l'adresse « de référence » (home address) ou l'adresse actuelle du mobile (care-of address) lorsqu'on utilise les fonctions de mobilité du RFC 6275. En pratique, elles sont très peu déployées donc on peut ne pas faire trop attention à cette propriété.

Maintenant, les algorithmes eux-mêmes. D'abord, pour le choix de l'adresse source (sections 4 et 5). Il faut d'abord établir une liste d'adresses candidates pour la destination choisie. La méthode conseillée est que cet ensemble de candidates soit la liste des adresses attachées à l'interface réseau par laquelle les paquets vont sortir. Sur une machine Linux, si on veut écrire à ::1, ce sera l'interface locale (lo) et si on veut écrire à 2001:4860:4860::8888, ce sera la plupart du temps eth0. Cela permet notamment de tenir compte des filtres éventuels des routeurs (un FAI ne laissera pas passer des paquets dont l'adresse source n'est pas chez lui, cf. RFC 2827).

Une fois cette liste établie, il faut choisir l'adresse IP source (notez le singulier), parmi cet ensemble de candidates. Conceptuellement, il s'agit de trier la liste des candidates et, pour cela, il faut une fonction permettant de comparer ces adresses deux à deux. La définition de cette fonction est le cœur de notre RFC. Soient deux adresses SA et SB pour une destination D, ces huit règles permettent de les départager :

  • Si SA = D, choisir SA (préférer une adresse source qui soit égale à la destination, pour les paquets locaux à la machine),
  • Si la portée de SA est différente de celle de SB, choisir l'adresse qui a la même portée que D. En gros, pour une destination locale au lien, on préférera des adresses sources locales au lien. Exemple : destination 2001:db8:1::1, candidates source 2001:db8:3::1 et fe80::1, on choisira 2001:db8:3::1,
  • Éviter les adresses marquées comme « dépassées » (RFC 4862, section 5.5.4), qu'on doit donc classer après celles qui ne sont pas dépassées,
  • Si la machine utilise Mobile IP (c'est très rare), préférer l'adresse de réference (home address) à l'adresse de connexion actuelle (care-of address),
  • Préférer l'adresse correspondant à l'interface de sortie vers D. Notez que cette règle ne servira à rien si on a suivi le conseil de ne mettre dans l'ensemble des candidates que les adresses de l'interface de sortie,
  • Utiliser l'étiquette (label) attribuée dans la table des politiques. On choisit de préférence l'adresse source qui a la même étiquette que l'adresse de destination,
  • Préférer les adresses temporaires du RFC 8981. Si la destination est 2001:db8:1::d5e3:0:0:1 et que les adresses candidates sont 2001:db8:1::2 (publique) et 2001:db8:1::d5e3:7953:13eb:22e8 (temporaire), on choisit 2001:db8:1::d5e3:7953:13eb:22e8. Cette règle est un changement par rapport au prédecesseur de notre RFC, le RFC 3484. Cette préférence doit être réglable (sur Linux, c'est apparemment avec la variable sysctl net.ipv6.conf.*.use_tempaddr qui, mise à 1, alloue des adresses temporaires et, mise à 2, fait qu'elles sont préférées),
  • Et enfin la dernière règle, mais qui sera souvent utilisée (plusieurs des règles précédentes ne s'appliquent qu'à des cas particuliers), la règle du préfixe le plus long. On choisit l'adresse source qui a le préfixe commun avec D le plus long. Si la destination est 2001:db8:1::1 et que les adresses source possibles sont 2001:db8:1::2 (48 bits communs) et 2001:db8:3::2 (32 bits communs), on sélectionne 2001:db8:1::2.
  • Si aucune des huit règles standards n'a suffi, si les deux adresses sont encore ex-aequo, le choix est spécifique à l'implémentation (par exemple, prendre la plus petite).

Une implémentation a le droit de tordre certaine de ces règles si elle dispose d'informations supplémentaires. Par exemple, si elle suit la RTT des connexions TCP, elle peut connaître les « meilleures » adresses et ne pas utiliser la huitième règle (préfixe le plus long).

Maintenant, il faut choisir l'adresse de destination (section 6). Cette fois, le résultat est une liste d'adresses qui seront essayées dans l'ordre. Et, contrairement au précédent, cet algorithme gère IPv6 et IPv4 ensemble (les règles de sélection de la source n'étaient valables que pour IPv6 ; par exemple la règle du plus long préfixe commun n'a guère de sens avec les courtes adresses v4). Le point de départ est la liste d'adresses récupérées en général dans le DNS. Et il y a ensuite dix règles de comparaison entre les destinations DA et DB, en tenant compte des adresses sources, S(DA) et S(DB). Beaucoup de ces règles sont proches de celles utilisées pour la sélection de la source donc je ne les réexplique pas ici :

  • Éviter les destinations injoignables (la machine ne le sait pas forcément mais elle a pu acquérir cette information, par exemple via le RFC 4861, section 7.3),
  • Préférer les portées identiques. Si DA et S(DA) ont une portée identique, et que ce n'est pas le cas pour DB et S(DB), choisir DA. Si les destinations connues sont 2001:db8:1::1 et, avec comme adresses source disponibles 2001:db8:1::2, fe80::1 et, alors le premier choix est 2001:db8:1::1 (source 2001:db8:1::2) puis (source Ce n'est pas une préférence pour IPv6 (elle intervient plus tard, dans la sixième règle) mais une conséquence du fait que l'adresse IPv4 est locale au lien (RFC 3927),
  • Éviter les adresses dépassées,
  • Choisir les adresses de référence en cas de mobilité,
  • Choisir de préférence la destination qui aura la même étiquette que l'une de ses sources possibles,
  • Préferer les destinations avec la plus haute précédence (dans la table des politiques vue plus haut). Avec la table par défaut, c'est cette règle qui mènera à faire les connexions en IPv6 plutôt qu'en IPv4 (section 10.3),
  • Préférer les destinations accessibles par de l'IPv6 natif plutôt que via un tunnel. Cela n'élimine pas tous les tunnels car celui-ci peut être situé plus loin, hors de la connaissance de la machine, comme avec le 6rdRFC 5969 - de Free),
  • Préférer les portées plus spécifiques, on tentera les adresses locales au lien avant les adresses publiques. Si on a le choix entre les destinations 2001:db8:1::1 ou fe80::1, et que les sources possibles sont 2001:db8:1::2 ou fe80::2, on préférera fe80::1 (avec la source fe80::2),
  • Utiliser le plus long préfixe commun entre la source et la destination. Si les destinations possibles sont 2001:db8:1::1 et 2001:db8:3ffe::1, avec comme sources possibles 2001:db8:1::2, 2001:db8:3f44::2 ou fe80::2, le premier choix est 2001:db8:1::1 (pour al source 2001:db8:1::2) puis 2001:db8:3ffe::1 (pour la source 2001:db8:3f44::2),
  • Si on arrive là, ne toucher à rien : contrairement à la sélection de la source, il n'est pas nécessaire de sélectionner une adresse, on peut tout à fait laisser l'ordre inchangé.

Le lecteur subtil a noté que l'interaction de ces règles avec le routage IP normal n'est pas évidente. Le principe de base est qu'une machine sélectionne la route de sortie avant de sélectionner l'adresse source mais la section 7 de notre RFC autorise explicitement une implémentation d'IPv6 à utiliser l'adresse source pour le choix de la route.

Voilà, les deux algorithmes sont là. Mais, si vous voulez les mettre en œuvre et pas seulement comprendre comment ils marchent, la section 8 est une lecture recommandée, car elle donne de bons conseils d'implémentation. Par exemple, comme l'algorithme de sélection de la destination a besoin de connaître les adresses sources possibles, le RFC suggère à getaddrinfo() de demander à la couche 3, pour obtenir la liste des adresses source possibles. Il sera alors capable de renvoyer une liste de destinations déjà triée. Il peut même garder en mémoire cette liste d'adresses, pour éviter de refaire un appel système supplémentaire à chaque fois. (Le RFC dit toutefois que cette mémorisation ne devrait pas durer plus d'une seconde, pour éviter d'utiliser une information dépassée.)

Et la sécurité (section 9) ? Il n'y a que des petits détails. Par exemple, en annonçant des tas d'adresses différentes pour lui-même, un méchant peut, en examinant les adresses source de ceux qui se connectent à lui, apprendre leur politique locale (pas une grosse affaire). Autre cas amusant, en sélectionnant soigneusement les adresses source ou destination, on peut influencer le chemin pris par les paquets, ce qui peut être utile par exemple pour sniffer. Mais c'est une possibilité très limitée.

Quels sont les changements de notre RFC 6724 par rapport à son prédécesseur, le RFC 3484 ? Ils sont détaillés dans l'annexe B. Les principaux (dans l'ordre à peu près décroissant d'importance) :

  • Préférence désormais donnée aux adresses temporaires sur les autres, afin de mieux préserver la vie privée, désormais considérée comme plus importante (c'était déjà le cas dans plusieurs implémentations d'IPv6),
  • Changement de la définition de « longueur du préfixe commun » pour se limiter aux 64 premiers bits (c'est-à-dire, excluant l'Interface ID),
  • Certains changements pour mieux gérer le cas où le réseau de sortie filtre selon l'adresse source (RFC 2827 et RFC 5220),
  • Ajout de la possibilité, pour une mise en œuvre d'IPv6, d'ajouter automatiquement des entrées à la table des politiques,
  • Ajout d'une ligne dans la table des politiques pour les ULA du RFC 4193 (fc00::/7),
  • Ajout d'une ligne dans la table des politiques pour les adresses du défunt 6bone (RFC 3701), avec une faible préférence pour qu'elles ne soient pas sélectionnées.

À noter que les premières versions de ce RFC étaient rédigées simplement sous forme d'une liste des différences avec le RFC 3484. C'était illisible.

Enfin, une anecdote, le prédécesseur, le RFC 3484, avait été accusé d'un problème sérieux. Mais c'est contestable, les responsabilités sont partagées : l'algorithme du RFC 3484 (qui ne concerne qu'IPv6) est certes discutable, l'implémentation de Vista n'est pas géniale (extension du RFC 3484 à IPv4, où les préfixes sont bien plus courts), la configuration de l'auteur de l'article est mauvaise (il dépend de l'ordre des enregistrements, qui n'est pas garanti par le DNS, c'est la même erreur qu'un programmeur C qui dépendrait de la taille d'un int) et, pour couronner le tout, le NAT qui fait qu'une machine ne connait pas son adresse publique.

Une intéressante discussion de certaines objections à ce RFC a eu lieu sur SeenThis.

Téléchargez le RFC 6724

L'article seul

RFC 6716: Definition of the Opus Audio Codec

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : JM. Valin (Mozilla Corporation), K. Vos (Skype Technologies), T. Terriberry (Mozilla Corporation)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF codec
Première rédaction de cet article le 11 septembre 2012

Il y a désormais plus de deux ans que le groupe de travail codec de l'IETF avait commencé un effort inédit de spécification d'un codec audio libre. Ce nouveau RFC est le couronnement de cet effort : Opus, le codec standard et libre est désormais officiel.

Opus n'est pas un format de fichiers, comme MP3. Il est conçu pour l'audio en temps réel (RFC 6366 pour son cahier des charges). Il est prévu pour un grand nombre d'utilisations audio distinctes : téléphonie sur IP, mais aussi, par exemple, distribution de musique en temps réel. Il est prévu pour être utilisable lorsque la capacité du réseau est minimale (dans les 6 kb/s) aussi bien que lorsqu'elle permet de faire de la haute fidélité (mettons 510 kb/s, cf. section 2.1.1). Ses deux principaux algorithmes sont la prédiction linéaire (plus efficace pour la parole) et la transformation en cosinus discrète (plus efficace pour la musique).

Le projet codec avait déjà produit deux RFC : le RFC 6366 était le cahier des charges du nouveau codec, et le RFC 6569 posait les principes de développement et d'évaluation dudit codec. Je renvoie à ces documents pour l'arrière-plan de la norme Opus. Celle-ci a été acceptée sans problèmes par le groupe de travail (c'est plutôt le mécanisme de tests qui a suscité des controverses.)

Opus présente une particularité rare à l'IETF : la norme est le code. Habituellement, à l'IETF, la norme est le texte du ou des RFC, rédigés en langue naturelle. Il existe souvent une implémentation de référence mais, en cas de désaccord entre cette implémentation et le RFC, c'est ce dernier qui gagne et le programme doit être modifié. Pour Opus, c'est tout le contraire. La moitié du RFC 6716 (180 pages sur 330, en annexe A, soit 30 000 lignes de code pas toujours bien commentées et avec plein de nombres magiques) est constituée par l'implémentation de référence (en C, langage que le RFC qualifie de « lisible par un humain », ce qui est parfois optimiste) et c'est elle qui fait autorité en cas de différence avec l'autre moitié, les explications (voir sections 1 et 6 du RFC). Ce point a suscité beaucoup de débats à l'IETF et on trouve trace des critiques, entre autres, dans l'évaluation détaillée qui avait été faite pour GenArt. L'idée de ce choix « le code est la norme » était que l'alternative (faire une spécification en langue naturelle, complète et sans ambiguité), serait bien plus de travail et, dans le cas particulier d'un codec audio, serait peut-être même irréaliste. (À noter que seul le décodeur est normatif. On peut améliorer la sortie de l'encodeur, tant que le décodeur arrive à lire ce qu'il produit.)

Le langage C étant ce qu'il est, il n'est pas étonnant que des bogues aient été découvertes depuis, corrigées dans le RFC 8251.

L'autre moitié du RFC est composé d'explications, avec beaucoup de maths.

Un codec libre est difficile à obtenir, surtout vu le nombre de brevets, la plupart futiles, qui encombrent ce domaine. Plusieurs déclarations de brevet ont été faites contre Opus : #1520, #1524, #1526, #1602, #1670, #1712 et #1741. Une liste mise à jour est disponible à l'IETF.

Comme ces codecs sont très loin de mes domaines de compétence, je ne vais pas me lancer dans des explications détaillées du fonctionnement d'Opus : lisez le code source :-) Notez que le code fait beaucoup d'arithmétique en virgule fixe (et aussi avec des entiers, bien sûr) donc attention si vous le reprogrammez dans un autre langage, les calculs doivent être exacts (voir section 1.1).

Si vous n'avez pas l'ambition de reprogrammer Opus, si vous voulez simplement une idée générale de son fonctionnement, la section 2 est faite pour vous. Opus, comme indiqué plus haut, a deux « couches », LP (prédiction linéaire) et MDCT (transformée en cosinus discrète). L'une ou l'autre (ou même les deux en même temps) est active pour encoder le signal audio, donnant ainsi à Opus la souplesse nécessaire. La couche LP est dérivée du codec Silk. Elle permet le débit variable mais aussi le constant (section 2.1.8). La couche MDCT, elle, est basée sur CELT.

Le codec Opus peut favoriser la qualité de l'encodage ou bien la consommation de ressources (processeur, capacité réseau). Cela permet d'ajuster la qualité du résultat aux ressources disponibles (section 2.1.5). Idem pour la sensibilité aux pertes de paquets : Opus peut être ajusté pour mettre plus ou moins de redondance dans les paquets. Avec le moins de redondance, on augmente la capacité mais on rend le décodage plus sensible : un paquet perdu entraîne une coupure du son.

Le format des paquets est décrit en section 3. À noter qu'Opus ne met pas de délimiteur dans ses paquets (pour gagner de la place). Il compte qu'une couche réseau plus basse (UDP, RTP, etc) le fera pour lui. Une possibilité (optionnelle dans les implémentations) de formatage avec délimiteur figure dans l'annexe B.

Chaque paquet compte au moins un octet, le TOC (Table Of Contents). Celui-ci contient notamment 5 bits qui indiquent les configurations (couches utilisées, capacité réseau utilisée et taille des trames).

Le fonctionnement du décodeur est en section 4 et celui de l'encodeur en section 5. Mais le programmeur doit aussi lire la section 6, qui traite d'un problème délicat, la conformité à la spécification. Je l'ai dit, la référence d'Opus est un programme, celui contenu dans ce RFC. Cela n'interdit pas de faire d'autres mises en œuvre, par exemple à des fins d'optimisation, à condition qu'elles soient compatibles avec le décodeur (c'est-à-dire que le décodeur de référence, celui publié dans l'annexe A du RFC, doit pouvoir lire le flux audio produit par cette mise en œuvre alternative). Pour aider aux tests, des exemples (testvectorNN.bit) et un outil de comparaison, opus_compare, sont fournis avec l'implémentation de référence (les tests sont en Un outil de comparaison est nécessaire car il ne suffit pas de comparer bit à bit la sortie de l'encodeur de référence et d'un nouvel encodeur : elles peuvent différer, mais dans des marges qui sont testées par opus_compare. Si vous avez écrit votre propre encodeur, ou modifié celui de référence, les instructions pour tester figurent en section 6.1.

Autre avertissement pour les programmeurs impétueux que les 150 pages d'explication et les 180 pages de code n'ont pas découragés : la sécurité. Opus est utilisé sur l'Internet où on trouve de tout, pas uniquement des gens gentils. La section 7 met donc en garde le programmeur trop optimiste et lui dit de faire attention :

  • Si on veut chiffrer un flux Opus, il ne faut pas utiliser d'algorithme vulnérable aux attaques à texte clair connu. En effet, bien des parties du flux (comme les trames de silence ou comme les octets TOC) sont très prévisibles.
  • Le décodeur doit être très robuste face à des erreurs (volontaires, ou bien provoquées par des bogues) dans le flux qu'il décode. Une programmation naïve peut mener à des accidents comme le dépassement de tampon ou, moins grave, à une consommation exponentielle de ressources (RFC 4732). L'implémentation de référence est censée être propre de ce point de vue, et résister à presque tout. Elle a été testée avec des flux audio aléatoirement modifiés, ainsi qu'avec des encodeurs faisant du fuzzing. Elle a également été testée avec Valgrind.

Le compte-rendu des tests divers se trouve dans l'Internet-Draft draft-ietf-codec-results.

L'annexe A contient le code source de l'implémentation de référence encodée en Base64 (qu'on trouve également en ligne sur le site Web officiel et qui est distribuée par git en git:// Par défaut, elle dépend de calculs en virgule flottante mais on peut la compiler avec la macro FIXED_POINT pour ne faire que de la virgule fixe (voir le fichier README). Voici un exemple d'utilisation avec la version de développement (il n'y en avait d'autre prête à ce moment)

% export VERSION=1.0.1-rc2
% wget$VERSION.tar.gz
% tar xzvf opus-$VERSION.tar.gz 
% cd opus-$VERSION
% ./configure
% make
% make check
All 11 tests passed

Il n'existe pas à l'heure actuelle d'autre mises en œuvre d'Opus.

Combien de logiciels intègrent actuellement le code Opus pour lire et produire des flux audios ? Difficile à dire. L'excellent client SIP Csipsimple a Opus depuis plusieurs mois. Autre exemple, le logiciel de voix sur IP Mumble l'a promis pour bientôt.

Un bon article en français sur Opus, notamment ses performances : « Un codec pour les dominer tous ». Et un article de synthèse de Numérama sur ce RFC. Pour une comparaison des performances d'Opus avec les autres, voir Pour les nouveautés de la version 1.1 (publiée après le RFC), voir la liste officielle.

Merci à Régis Montoya pour sa relecture.

Téléchargez le RFC 6716

L'article seul

Go Daddy planté, une des plus grosses pannes dans le DNS

Première rédaction de cet article le 10 septembre 2012
Dernière mise à jour le 5 octobre 2012

Go Daddy est de loin le plus gros bureau d'enregistrement de .com et de nombreux autres TLD. Il sert aussi d'hébergeur DNS. Ce soir, tous leurs serveurs de noms sont injoignables, entraînant l'impossibilité de joindre des millions de noms de domaine, et donc les serveurs situés derrière. C'est l'une des plus grandes pannes qu'ait jamais connu le DNS. Elle illustre une nouvelle fois l'importance de s'assurer de la résilience de son service DNS, notamment par le biais de la redondance.

Le lundi 10 septembre, il est 19h00 UTC et la panne dure depuis déjà un certain temps (premier signalement sur la liste outages vers 18h00 UTC). Prenons un hasard un nom de domaine hébergé chez Go Daddy, Tentons une interrogation :

% dig A

; <<>> DiG 9.8.1-P1 <<>> A
;; global options: +cmd
;; connection timed out; no servers could be reached

Pas de réponse. Qu'arrive-t-il aux serveurs de noms ? Demandons au parent (VeriSign) les serveurs de noms de :

% dig NS       

; <<>> DiG 9.8.1-P1 <<>> NS
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38711
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 3
;; WARNING: recursion requested but not available

; EDNS: version: 0, flags: do; udp: 512
;                   IN      NS

;; AUTHORITY SECTION:            172800  IN      NS            172800  IN      NS
;; ADDITIONAL SECTION:         172800  IN      A         172800  IN      A

Ces deux serveurs sont bien chez Go Daddy comme on peut le vérifier avec whois :

% whois
# The following results may also be obtained via:

NetRange: -
NetName:        GO-DADDY-COM-LLC
NetHandle:      NET-216-69-128-0-1
Parent:         NET-216-0-0-0-0
NetType:        Direct Allocation

Et ils ne répondent pas :

%  dig @  A

; <<>> DiG 9.7.3 <<>> @ A
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

Et, surtout, c'est la même chose pour tous les serveurs de noms de Go Daddy. Le domaine de l'hébergeur lui-même, n'est pas davantage accessible :

% dig +nodnssec +nssearch

; <<>> DiG 9.7.3 <<>> +nodnssec +nssearch
;; global options: +short +cmd
;; connection timed out; no servers could be reached

Et comme pas de DNS égal pas de Web, ni d'autres services, on voit l'ampleur de la panne... Celle-ci a duré jusqu'à environ 20h40 UTC, où il y a eu une légère rémission, avant que cela ne re-plante. Finalement, le service a été rétabli quelques heures après (apparemment en migrant une partie de l'infrastructure sur la plate-forme de VeriSign). C'est donc assez long, même en cas de dDoS.

Que s'est-il passé ? Sur le moment, une personne se prétendant Anonymous a revendiqué l'action. Mais n'importe qui peut envoyer un tweet et, comme il ne donnait aucun détail technique, il était donc difficile de savoir si c'est vrai. La première déclaration officielle de Go Daddy incriminait un problème technique interne dans leurs routeurs. L'hypothèse d'une attaque par déni de service distribué aussi réussie contre une infrastructure anycastée était certes possible mais, quand même, cela aurait en effet très difficile à réussir.

Au fait, pourquoi Anonymous aurait-il attaqué Go Daddy ? Peut-être parce qu'ils aiment les éléphants ? Ou parce qu'ils sont choqués des publicités de mauvais goût de Go Daddy, à base de pinups vulgaires en bikini ? Mais Go Daddy est aussi connu pour son soutien à SOPA (voir Wikipédia), et pour être un des hébergeurs les plus rapides à censurer ses clients lorsque le gouvernement ou l'industrie du divertissement le demande (voir l'affaire JotForm ou celle de RateMyCop). Comme disent les policiers, il y a donc beaucoup trop de suspects...

Finalement, le 5 octobre, Go Daddy a publié un rapport technique très détaillé. Le problème (si on prend ce rapport au pied de la lettre mais il semble cohérent avec les faits observés) était bien dans les routeurs. Une combinaison d'incidents avait entraîné l'apparition d'un très grand nombre de routes, dépassant la capacité de la table de routage. Ces routes ont été propagées en interne, plantant ainsi la totalité des routeurs. Même une fois le problème technique analysé, la correction a été longue car chaque fois qu'un des sites de Go Daddy repartait, tout le trafic se précipitait vers lui... et le replantait.

Autres articles :

Une amusante ligne de script shell pour détecter si un de vos sites Web dépend de Go Daddy (merci à climagic). À exécuter dans le répertoire où se trouve la config Apache :

grep ServerName * | grep -io "[a-z0-9-]*\.[a-z]*$" | \
     sort -u | while read -r d; do whois $d | grep -q "GODADDY" &&echo $d; done # site check

L'article seul

RFC 6729: Indicating Email Handling States in Trace Fields

Date de publication du RFC : Septembre 2012
Auteur(s) du RFC : D. Crocker (Brandenburg InternetWorking), M. Kucherawy (Cloudmark)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 7 septembre 2012

Lorsqu'on débogue un problème de courrier électronique en examinant un message reçu, le technicien regarde souvent en premier les champs Received: de l'en-tête. Ceux-ci indiquent les différents MTA qui ont pris en charge le message et sont notamment très utiles en cas de retard inattendu : ils permettent de voir quel MTA a traîné dans la remise du message au MTA suivant. Mais cela ne suffit pas toujours. Aujourd'hui, il est de plus en plus fréquent que les messages soient retardés en raison d'un traitement local à une machine, par exemple le passage par un programme de sécurité qui met très longtemps à vérifier quelque chose. Il n'y avait pas de moyen pratique avec les champs Received: pour indiquer ces traitements. C'est désormais fait avec un nouvel indicateur dans Received: : state qui permet de signaler le passage d'un traitement lent à un autre.

Voici un exemple d'une suite de champs Received:. Rappelez-vous qu'elle se lit de bas en haut :

Received: from ( [])
        by (Postfix) with ESMTP id 5EC103AD82
        for <>; Thu,  6 Sep 2012 18:26:36 +0000 (UTC)
Received: from ( [])
        by (Postfix) with ESMTP id 2268638B64
        for <>; Thu,  6 Sep 2012 20:21:20 +0200 (CEST)
Received: from ( [])
        by (Postfix) with ESMTP id 0844C172094
        for <>; Thu,  6 Sep 2012 20:21:10 +0200 (CEST)
Received: from ([])
        by ( []) (amavisd-new, port
        with ESMTP id 9nO2SZ5sO3KB for <>;
        Thu,  6 Sep 2012 20:21:08 +0200 (CEST)

On note que la machine a renvoyé le message à d'où il venait. Ce n'est pas une erreur, est la machine de filtrage et utilise Amavis pour un certain nombre de tests sur le message (absence de virus, par exemple) avant de le réinjecter. Ici, cet examen a été rapide (deux secondes, si on peut se fier aux horloges des machines) mais, s'il est plus long (et Amavis peut être très long), il serait souhaitable de pouvoir le marquer plus clairement.

Il existe bien des tests/vérifications/etc qui peuvent ainsi ralentir un message : mise en quarantaine, modération, tests anti-spam ou anti-virus, etc. Pour les indiquer plus clairement, notre RFC reprend le champ Received: (défini à la section 4.4 du RFC 5321 et un des outils les plus importants du technicien qui fait fonctionner le courrier électronique). Ce champ comprend plusieurs clauses (dans les exemples ci-dessus, on voit les clauses from, by, with et for, définies dans la section 4.4 du RFC 5321). Notre RFC en ajoute une nouvelle, state (désormais enregistrée, section Additional-registered-clauses), qui ressemble à ça (exemple du RFC car je n'ai pas encore trouvé de clause state dans mes boîtes aux lettres, bien qu'il existe apparemment déjà une mise en œuvre en production) :

Received: from
                  ( [])
              by (8.11.6/8.11.6)
                  with ESMTP id i7PK0sH7021929
                  for <>;
              Fri, Feb 15 2002 18:33:29 -0800
Received: from
                  ( [])
              by (8.11.6/8.11.6)
                  with ESMTP id i9MKZCRd064134
                  for <>
                  state moderation (sender not subscribed);
              Fri, Feb 15 2002 17:19:08 -0800

Ici, le MTA de a décidé de ne pas envoyer le message tout de suite mais de le soumettre à un modérateur (avant-dernière ligne du plus ancien Received:, clause state). Cela suffit à expliquer le délai d'une heure vingt entre les deux Received:, sans imaginer une coupure réseau ou une autre panne. On voit que la clause state indique l'entrée dans un nouvel état (ici, l'état « en attente d'approbation par le modérateur »), la sortie étant marquée par le champ Received: suivant (qui, ici, n'a pas d'état explicite). Rappelez-vous (promis, c'est la dernière fois que je le dis) que les champs Received: se lisent de bas en haut.

La clause state dans l'exemple ci-dessus utilisait le mot-clé moderation. Une liste limitative de tels mots-clés est enregistrée (section Registered-states) et elle comprend notamment :

  • auth : le message attend une authentification,
  • content : le contenu du message va être analysé, par exemple pour s'assurer qu'il ne contient pas de spam ou de malware,
  • moderation : passage par le modérateur,
  • timed : message délibérement gardé, en attendant l'heure de la remise (voir RFC 4865),
  • normal : ce mot-clé est enregistré mais, en fait, c'est celui par défaut, lorsqu'aucune clause state n'est présente,
  • other : il y a toujours des cas où on ne sait pas :-)

À noter que le mot-clé peut être suivi d'une barre oblique et d'une valeur (non enregistrée, on met ce qu'on veut), on peut donc avoir moderation/not-subscribed ou quarantine/spam. D'autres états pourront être enregistrés dans le futur, sous la politique « Premier arrivé, premier servi » (cf. RFC 5226). Ce point avait été le principal sujet de discussion avant la publication du RFC, certains auraient préféré la politique plus restrictive « Examen par un expert ».

Les programmeurs de MTA qui veulent ajouter cette clause aux champs Received: qu'ils écrivent ont tout intérêt à bien lire les sections 4 et 5, qui discutent de quand utiliser la clause state. Elle n'est pas prévue pour des opérations différentes à l'intérieur d'un même agent. Le RFC recommande bien qu'elle ne soit utilisée que lorsqu'on passe à un agent différent, par exemple de Postfix à Amavis. Autrement, on risque de se retrouver avec plein de Received: qui rendront l'analyse plus difficile (et risquent d'atteindre la limite des MTA, qui rejettent les messages ayant trop de Received:, pensant qu'ils bouclent). L'idée est de déboguer les performances et donc cette clause est là uniquement pour les problèmes temporels, pas pour n'importe quelle action ou changement d'état interne à l'agent.

Téléchargez le RFC 6729

L'article seul

Souriez, vous (enfin, votre résolveur DNS) sert à la science

Première rédaction de cet article le 6 septembre 2012

Depuis ce matin, une bonne partie des visiteurs de ce blog participe (involontairement) à une expérience de mesure du déploiement de la validation DNSSEC.

Regardez le code source de chaque page, vers le bas. Vous trouverez un lien <a> vide vers Ce nom est servi par des serveurs DNS un peu spéciaux, qui répondent de manière inhabituelle, de manière à étudier le comportement du résolveur qui les interroge, afin de savoir s'il fait du DNSSEC ou pas (en France, aucun FAI n'a encore activé la validation DNSSEC, à ma connaissance). Si votre navigateur Web met en œuvre le prefetching DNS (la récupération anticipée d'informations DNS, avant tout clic de l'utilisateur), votre résolveur contactera automatiquement les serveurs de J'encourage tous les gérants de sites Web à inclure également ce petit bout de code HTML : <a href=""></a>. (L'ISOC le demande aussi.)

L'expérience est menée par VeriSign et il existe une page officielle avec, notamment, les résultats préliminaires (un peu plus de 3 % de résolveurs validant avec DNSSEC). Attention, comme les serveurs de sont très spéciaux, il peut y avoir des problèmes à accéder à cette page avec certains résolveurs (par exemple Unbound).

Quelques notes sur la protection de la vie privée :

  • Inclure ce code HTML dans sa page n'envoie pas seulement les données du webmestre à VeriSign mais aussi celles des innocents visiteurs. Il faut donc bien réfléchir.
  • La connexion avec VeriSign est uniquement en DNS : le lien est invisible et, même si quelqu'un arrivait à cliquer dessus, l'adresse associée est celle de localhost. Il n'y aura donc jamais d'échange en HTTP avec VeriSign (donc pas de cookies ou de trucs comme ça).
  • Ce n'est pas votre adresse IP que verra VeriSign mais celle de votre résolveur DNS : dans la plupart des cas, un serveur de votre FAI.
  • La requête DNS ne contient rien sur le site Web que vous visitiez.

L'article seul

Quelles machines pinguer pour vérifier sa connectivité Internet ?

Première rédaction de cet article le 5 septembre 2012
Dernière mise à jour le 7 septembre 2012

Lorsqu'on met en place une infrastructure de surveillance de serveurs Internet, il est agaçant de recevoir autant d'alarmes que de serveurs surveillés, alors que c'était simplement la connectivité Internet de la sonde de surveillance qui était en panne. Tous les grands logiciels de surveillance de réseau ont une option pour éviter cela, qui permet de dire que le test d'un serveur dépend du succès d'un test sur un autre composant, par exemple le routeur de sortie (si ce dernier est en panne, il n'y a pas besoin de tester les serveurs et d'alerter si ça rate). Mais quel composant tester pour déterminer qu'on a un accès Internet qui marche ?

Avec les logiciels de la famille Nagios comme Icinga, l'option qui permet d'indiquer la dépendance d'une machine envers une autre se nomme parents . Si on écrit :

define host {
        host_name               freebox

define host {
        host_name    remote-host
        parents freebox

alors on déclare que la connectivité de remote-host dépend de celle de freebox. Si on est connecté à l'Internet par ce seul routeur, c'est logique. Si freebox est injoignable, le reste de l'Internet l'est aussi.

Mais si freebox fonctionne mais ne route plus ? Ou bien si quelque chose déconne dans le réseau de Free bloquant tout accès à l'extérieur ? C'est là qu'il est utile de tester autre chose que le premier routeur. On voudrait en fait tester si on a toujours un accès Internet et pouvoir écrire :

define host {
        host_name    remote-host
        parents Internet

(Les experts Nagios/Icinga auront noté qu'il faudrait plutôt utiliser hostdependency ou servicedependency, pour ne même pas effectuer les tests en cas de panne de la connectivité. Mais c'est un détail ici.) Mais comment faire ce test ? En pinguant des machines distantes, bien évidemment. Il « suffit » de sélectionner des machines stables, qui répondent aux paquets ICMP d'écho, et qui n'ont elles-mêmes que très peu de pannes. Mais lesquelles choisir ?

Il faut bien voir que ces machines sur l'Internet, ces amers ou mires (target en anglais) ne nous appartiennent pas. Si chaque petit réseau local, pour tester sa connectivité, pingue toutes les trois minutes, et qu'il y a dix millions de petits réseaux qui le font dans le monde, recevra 50 000 paquets/seconde, ce qui est une charge sérieuse même pour un gros serveur. (En débit, cela ne fera pas grand'chose car les paquets de test seront de petite taille. Mais pour les routeurs et les serveurs, ce n'est pas que le nombre de bits par seconde qui compte, celui des paquets par seconde est également important, chaque paquet nécessitant un traitement, indépendemment de sa taille.) Utiliser le premier serveur qu'on a choisi pour des tests répétitifs, c'est comme jeter une canette vide par terre : si une seule personne le fait, c'est juste un peu agaçant, si tout le monde le fait, on détruit l'environnement. Ce n'est pas parce qu'un service est publiquement accessible qu'on peut le bombarder de requêtes pour son usage personnel. Dans le passé, il est déjà arrivé qu'un constructeur configure (bêtement) ses machines pour utiliser un serveur public sans autorisation, l'écroulant ainsi sous la charge.

Qu'est-ce que cela nous laisse comme possibilités ? En posant la question, on obtient des réponses (plus ou moins dans l'ordre décroissant du nombre de suggestions) :

  • (ou, à la rigueur,, qui est sans doute moins sollicité), à savoir Google Public DNS. Un service très fiable, qui a très peu de chances de tomber en panne. Mais peut-on l'utiliser ainsi, de manière automatique, dans des tests répétés ? Cela ne figure certainement pas dans les conditions d'utilisation de ce service, et Google pourrait donc décider de couper les réponses ICMP écho du jour au lendemain (ou de mettre en place une limitation de débit).
  • (ou avec l'argument « Si Facebook est en panne, de toute façon, tout l'Internet est fichu ». Cela pose un peu les mêmes problèmes que précédemment.
  • Pinguer un des serveurs DNS de la racine. Ils marchent en permanence (c'est sans doute un des composants les plus robustes de l'Internet), répondent à l'ICMP écho et, n'étant pas gérés dans un but lucratif, on n'est pas à la merci d'un changement soudain de politique commerciale. Mais ces serveurs ne sont pas prévus pour un tel test automatisé. Ils y résisteront, bien sûr, mais est-ce un usage légitime ? Je ne pense pas et les opérateurs des serveurs racine, interrogés, sont également de cet avis. Il faut aussi se rappeler qu'il s'agit d'un service critique : toute perturbation est à éviter.
  • Pinguer un des serveurs de l'AS112 (cf. RFC 7534). Après tout, ils sont censés recevoir du n'importe quoi tout le temps. Un peu de ping ne les dérangera pas. Par contre, ils ne sont pas toujours fiables et, par la magie de l'anycast, ils peuvent être plus près que vous ne croyez, ce qui en fait de mauvaises mires pour tester le grand Internet.
  • Utiliser un ensemble de sites bien connus et qui sont probablement assez stables. Si chacun se fait sa propre liste, cela diminuera la charge sur chacun de ces sites. Mais cela reste un usage non autorisé.
  • Pinguer des équipements du FAI par exemple son serveur Web ou bien les routeurs sur le trajet (après un traceroute pour les repérer). Notez que cela ne détecte pas le cas où la(es) liaison(s) du FAI avec l'Internet sont en panne. Mais la plupart des pannes (comme celle de la Freebox citée plus haut) concernent « le dernier kilomètre » donc c'est peut-être supportable. L'avantage est que tout le monde ne teste pas le même service (les abonnés d'un FAI sont les seuls à tester leur FAI) et que c'est un service qu'on paie. En tirant un peu sur la ficelle, on peut considérer que l'abonnement inclut le droit de pinguer chaque minute. Les FAI ne sont pas forcément d'accord avec cette analyse, et peuvent faire remarquer que les routeurs sont là pour router, pas pour répondre aux pings. Le mieux serait que les FAI fournissent à leurs abonnés une mire à tester, comme le fait OVH avec sa machine (un service qui ne semble pas vraiment documenté) ou Free avec (pas plus documenté).
  • Utiliser une mire publique, prévue pour cela et qu'on a l'autorisation d'utiliser. (Certaines entreprises fournissent peut-être un service de mires privées payantes mais je n'en connais pas. Il existe aussi des mires spécifiques à un système d'exploitation particulier comme qu'utilise Windows.) Je ne connais actuellement que trois mires publiques de ce genre, gérées par Team Cymru (la machine, en HTTP, elle donne plein de renseignements rigolos), par Rezopole ( et par Demarcq ( Elles sont peu documentées, peut-être par manque de temps et peut-être pour éviter d'attirer plein de trafic. Faudrait-il créer des services associatifs pour cet usage, comme le fait pour NTP ? Ou procéder à des échanges avec d'autres acteurs de l'Internet, comme on le fait couramment pour les serveurs DNS secondaires ?

Bref, le débat n'est pas simple. On peut encore le compliquer avec des questions comme « Vaut-il mieux utiliser les paquets ICMP echo de ping ou bien une application comme HTTP ou DNS ? ».

Merci à WBrown pour ses bonnes suggestions sur le pinguage du FAI, à John Kristoff pour m'avoir rappelé le travail que fait Team Cymru, à Jean-Philippe Camguilhem pour les explications sur les dépendances dans Icinga et à Fabien Vincent pour m'avoir appris l'existence de À noter qu'il n'existe pas en France de « service public » de mires accessibles pour ce genre de tests mais que le RIPE-NCC a un service similaire, les Ancres. L'une des ancres a un nom simple à retenir,

J'ai aussi fait un article qui décrit en détail la configuration d'Icinga pour ces mires publiques et l'usage que j'en fait.

L'article seul

RFC 6693: Probabilistic Routing Protocol for Intermittently Connected Networks

Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Lindgren (SICS), A. Doria (Consultant), E. Davies (Folly Consulting), S. Grasic (Lulea University of Technology)
Première rédaction de cet article le 1 septembre 2012

Les protocoles traditionnels de routage (comme, mettons, OSPF) sont conçus dans l'idée que les machines sont connectées et joignables en permanence, sauf rares pannes. Mais il existe des réseaux où cette hypothèse ne se vérifie pas. Par exemple, dans l'espace, domaine traditionnel du groupe de recherche DTN, il est fréquent que la communication soit l'exception plutôt que la règle. Comment router dans ces conditions ? Ce nouveau RFC propose un mécanisme de routage adapté à des connexions intermittente, Prophet.

On n'est plus dans le monde tranquille de l'Internet, avec ses connexions stables et ses problèmes connus. Ici, on est à l'IRTF, l'équivalent de l'IETF pour les recherches avancées. À l'IRTF, on étudie des problèmes comme les connexions entre vaisseaux perdus dans l'espace, ou groupes d'éleveurs samis se déplaçant en Laponie, ou encore entre objets communiquants se déplaçant sans cesse et ne venant que rarement à portée de radio des autres objets. C'est là que Prophet devient utile. (Voir le RFC 4838 pour avoir une meilleure idée des sujets sur lesquels travaille le groupe DTN.). Les protocoles de routage traditionnels (cf. section 1.3), conçus pour trouver le chemin optimum dans le graphe et pour éviter les boucles, n'ont pas réellement de sens ici (par exemple, l'émetteur et le destinataire peuvent ne jamais être allumés en même temps).

Le principe de base de Prophet est d'utiliser l'histoire des rencontres entre deux machines. Si deux engins viennent en contact radio de temps en temps, puis se re-séparent, la mise en œuvre de Prophet se souviendra de ses contacts et pourra se dire « ah, j'ai un bundle (cf. RFC 5050 et RFC 6255) à passer à Untel et, justement, je l'ai vu trois fois dans la dernière semaine, donc je garde le bundle, je devrais le revoir bientôt. » Au moment du contact, les machines Prophet échangent aussi des informations sur les machines qu'elles ont rencontré donc la décision peut aussi être « ah, j'ai un bundle à passer à Untel, je ne l'ai jamais croisé mais Machin l'a souvent fait et, justement, j'ai vu trois fois Machin dans la dernière semaine, donc je garde le bundle, je devrais revoir Machin bientôt, et je lui refilerai le bundle et la responsabilité. »

Une manière courante de résoudre ce problème est d'envoyer le message (dans l'architecture DTN, les messages sont découpés en unités de transmission appelées bundles) à tous ceux qu'on croise, qui le transmettent à leur tour à tous ceux qu'ils croisent et ainsi de suite jusqu'à ce que tout le monde l'ait eu. C'est ce qu'on appelle l'inondation et la mise en œuvre la plus connue de ce principe est dans Usenet (RFC 5537). Mais, dans Usenet, on supposait que tous les nœuds étaient intéressés par le message. Ici, un seul destinataire le veut et, pour ce cas, l'inondation fonctionne mais gaspille pas mal de ressources. Elle marche bien lorsque les ressources ne sont pas un problème mais Prophet se veut utilisable pour des réseaux d'objets communiquants, objets ayant peu de mémoire, de capacité réseau, et de processeur. Prophet adopte donc plutôt une démarche probabiliste : il ne garde que les routes les plus prometteuses, risquant ainsi de ne pas trouver de chemin vers la destination, mais limitant la consommation de ressources. Cet élagage des routes est la principale innovation de Prophet.

Pour échanger les routes (pas forcément les bundles), deux nœuds Prophet, lorsqu'ils se rencontrent, établissent un lien TCP entre eux. La mise en œuvre de Prophet doit donc pouvoir parler TCP et interagir avec le programme de gestion des bundles, pour pouvoir informer les besoins des bundles qu'on souhaite transmettre.

On notera que, comme toujours dans l'architecture DTN (Delay-Tolerant Networking, cf. RFC 4838), la transmission n'est pas synchrone : le message, découpé en bundles, va être bufferisé et pourra mettre « un certain temps » à atteindre sa destination. En outre, il est parfaitement possible que la source et la destination du message ne soient jamais allumés et joignables en même temps : on fait donc du réseautage transitif (le message d'Alice est transmis à René, qui le passe à Rose, qui l'envoit finalement au destinataire, Bob). L'annexe A contient un exemple plus détaillé.

À noter que Prophet est utilisé pour des connexions intermittentes, ce qui ne veut pas dire aléatoires. Elles peuvent au contraire être très prévisibles (cas d'engins spatiaux sur leur orbite, ou cas de déplacement d'objets sur un rythme circadien). D'autre part, Prophet n'est pas seulement utile pour le cas où les nœuds se déplacent mais aussi pour celui où ils sont fixes mais souvent en hibernation, par exemple pour économiser du courant (capteur industriel fixé dans un ouvrage d'art, par exemple). Dans les deux cas, la connectivité est intermittente et ce sont les mêmes solutions qu'on utilise. (Voir « Epidemic Routing for Partially Connected Ad Hoc Networks »).

Les détails pratiques, maintenant. Le RFC est long et il y a beaucoup de détails à prendre en compte. Ce qui suit est donc un simple résumé. La section 2 présente l'architecture de Prophet. À son cœur, la notion de « probabilité de remise [d'un message] » (delivery predictability). Notée P_, définie pour tout couple de machines (A, B), comprise entre 0 et 1, c'est la principale métrique de Prophet. Si P_(A, B) > P_(C, B), alors Prophet enverra les bundles destinés à B via C plutôt que via A. Attention, cette probabilité est asymétrique, P_(A, B) n'a aucune raison d'être égal à P_(B, A). Lorsque deux machines Prophet se rencontrent, elles échangent toutes les probabilités de remise qu'elles connaissent.

Au début, lorsqu'un nœud ne connait rien, la probabilité de remise est indéfinie. À la première rencontre, elle passe typiquement de 0,5 (paramètre P_encounter_first), reflétant l'ignorance encore grande. Au fur et à mesure des rencontres, la probabiité augmente (lentement, pour ne pas se heurter au plafond de 1 trop vite, paramètre delta). Cette augmentation est amortie par un intervalle minimum entre deux rencontres (paramètre P_encounter, pour éviter qu'un lien WiFi très instable ne se traduise par plein de rencontres, qui seraient en fait uniquement des rétablissements du lien). C'est un résumé, la définition complète de ce calcul figure en section 2.1.

Vous allez peut-être vous dire « mais les rencontres du passé ne signifient pas qu'elles vont se reproduire dans le futur ». En effet, si les rencontres sont complètement dues au hasard, le passé n'est pas un bon indicateur. Mais rappelez-vous que, dans les réseaux réels, les rencontres ne sont pas complètement aléatoires.

Ces différents paramètres ne sont pas forcément les mêmes pour tous les nœuds Prophet du réseau mais il est recommandé qu'ils soient proches. La section 3.3 détaille ces paramètres.

Ah, au fait, j'ai dit « quand deux nœuds Prophet se rencontrent ». Mais comment le savent-ils, qu'ils sont en vue l'un de l'autre ? Prophet nécessite que la couche 2 transmette cette information (« new neighbor in sight »). Comme détaillé en section 2.4, si Prophet peut tourner sur des protocoles de niveau 2 différents, il faut néanmoins que tous soient capables de signaler l'arrivée ou le départ d'un voisin, ainsi que l'adresse de niveau 2 pour le joindre.

La section 3 décrit le protocole utilisé entre les nœuds Prophet. Il permet d'échanger avec le pair :

  • La liste des nœuds connus (identifiés par l'EID défini dans le RFC 4838),
  • Les probabilités de remise à ces nœuds,
  • Les bundles à envoyer, et la réponse à ceux reçus depuis le pair.

La section 4 présente le format des messages Prophet. Ce format utilise largement des TLV. Chacun a un type (enregistré à l'IANA, cf. section 7) et, par exemple, le TLV Hello, qui sert en début de connexion, a le type 1. Les structure de données plus complexes, comme la table de routage, sont encodés en SDNV (RFC 6256).

La section 5 fournit ensuite les machines à états du protocole.

Et la sécurité ? Ce sujet obligatoire est traité en section 6. Ce sera vite fait : Prophet n'a à peu près aucune sécurité. Il est très vulnérable car les exigences du cahier des charges (machines avec peu de ressources, connectées seulement de manière très intermittente) rendent difficile toute conception d'un protocole de sécurité.

Prophet ne fonctionne donc que si tous les nœuds participant sont gentils et œuvrent dans le but commun. Un mécanisme de sécurité simple serait donc que tous les nœuds utilisent une authentification et que seuls les membres d'une même tribu soient autorisés à faire du Prophet ensemble.

Que pourrait-il se passer, autrement ? Un nœud peut prétendre de manière mensongère qu'il a des routes, en mettant toutes les probabilités de remise à 1 (attaque du trou noir : les autres nœuds lui confieront des bundles qu'il ne pourra pas transmettre). Il peut annoncer un identificateur qui n'est pas le sien, piquant le trafic destiné à un autre. Il peut aussi générer des tas de bundles et les transmettre à ses malheureux pairs (une attaque par déni de service). Et tout ceci serait encore pire si un réseau Prophet était connecté à l'Internet via une passerelle. Les méchants pourraient alors attaquer l'Internet, cachés derrière les faiblesses de Prophet. Bref, un nœud sadique peut faire beaucoup de dégâts, difficiles à empêcher. D'où l'importance de l'authentification, pour ne jouer qu'avec des copains de confiance.

Les sections 8 et 9 de notre RFC décrivent l'expérience existante avec les mises en œuvre de Prophet. C'est un vieux protocole, bien que le RFC ne sorte que maintenant, et il a déjà été implémenté plusieurs fois. Le première fois, écrite en Java, était pour un environnement original, Lego Mindstorms. Elle est documentée dans la thèse de Luka Birsa. Une autre mise en œuvre, en C++, a tourné sur le simulateur OmNet. Encore une autre, pour Android, est décrite dans l'article « Bytewalla 3: Network architecture and PRoPHET implementation ».

Le tout a déjà été testé dans un environnement réel, dans des montagnes du nord de la Suède, en 2006, et raconté dans « Providing connectivity to the Saami nomadic community » (avec une jolie photo de renne dans l'article).

Téléchargez le RFC 6693

L'article seul

RFC 6725: DNS Security (DNSSEC) DNSKEY Algorithm IANA Registry Updates

Date de publication du RFC : Août 2012
Auteur(s) du RFC : S. Rose (NIST)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 30 août 2012

Lors de la conception d'un protocole cryptographique, il est essentiel de permettre l'agilité des algorithmes, c'est-à-dire de changer d'algorithme pour répondre aux progrès de la cryptanalyse. C'est ainsi que DNSSEC inclut dans les enregistrements DNS de clés et de signatures un numéro qui identifie l'algorithme utilisé. Les numéros possibles sont dûment notés dans un registre IANA et ce nouveau RFC « nettoie » le registre, mettant à jour des entrées inutilisées.

Au passage, les érudits noteront que cette absence d'agilité cryptographique (l'algorithme n'est pas indiqué donc un seul algorithme est possible) est un des inconvénients de DNScurve. Mais ne digressons pas. Quels changements a apportés notre nouveau RFC 6725 ? Les numéros 4, 9 et 11, correspondant à des algorithmes qui n'ont jamais été déployés sont désormais marqués comme « réservés ». C'est tout. On ne peut pas les réaffecter (au cas où il traine dans la nature des mises en œuvre expérimentales utilisant ces algorithmes).

4 était réservé pour un algorithme à courbes elliptiques (on n'a jamais su lequel), 9 et 11 n'étaient pas officiellement affectés mais l'ont apparemment été non-officiellement.

Téléchargez le RFC 6725

L'article seul

RFC 6722: Publishing the "Tao of the IETF" as a Web Page

Date de publication du RFC : Août 2012
Auteur(s) du RFC : P. Hoffman (VPN Consortium)
Pour information
Première rédaction de cet article le 30 août 2012

Le fonctionnement et les particularités de l'IETF étaient traditionnellement décrits dans un RFC nommé Tao, à l'usage des débutants qui débarquaient dans ce monde merveilleux. Le dernier de ces RFC a été le RFC 4677 : désormais, pour évoluer plus facilement, le Tao est une page web ordinaire, régulièrement tenue à jour. Depuis, en juin 2024, le Tao a cessé d'être maintenu (cf. RFC 9592.

Le Tao est le document à lire absolument quand on débute à l'IETF. Il explique son fonctionnement, ses codes, ses rites, son jargon. L'IETF est à ma connaissance la seule SDO à le faire, ce qui est un gage d'ouverture. Le Tao a été d'abord publié comme RFC 1391, puis a connu de nombreuses évolutions jusqu'au RFC 4677. Mais les RFC, statiques et longs à faire publier, ne sont pas le canal idéal pour ce genre de documents, qui doit évoluer en permanence.

Désormais, le Tao est donc une page Web, et contrôlée par l'IESG, qui sera donc l'autorité responsable pour son contenu. Actuellement, cette page est encore très proche du RFC 4677 mais elle va petit à petit s'en éloigner.

Si vous voulez participer à la maintenance du Tao, cela se fait sur la liste de diffusion Un éditeur (actuellement Paul Hoffman) décide ensuite des changements qui seront transmis à l'IESG (cette proposition est visible en ligne). L'IESG accepte ou refuse les changements et le secrétariat n'a plus qu'à éditer la page.

Le Tao est versionné (la version d'aujourd'hui est 20120829) et on peut accéder aux versions précédentes (dès qu'il y en aura plusieurs). On a donc des identificateurs stables pour les précédentes versions (toutes les organisations qui publient des documents devraient en faire autant).

Il existe des traductions du Tao qu'on trouve ici ou là mais le RFC note qu'elles sont toutes non-officielles (et souvent pas à jour). Par exemple, en français, on trouve une traduction du RFC 3160 ou bien la traduction de l'ISOC-Togo.

La section 3 du RFC couvre les propositions alternatives : certains auraient préféré un wiki pour des modifications plus rapides ou plus souples, mais le choix a finalement été de privilégier la sécurité.

Téléchargez le RFC 6722

L'article seul

RFC 6710: Simple Mail Transfer Protocol Extension for Message Transfer Priorities

Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Melnikov (Isode), K. Carlberg (G11)
Chemin des normes
Première rédaction de cet article le 26 août 2012

Des tas d'utilisateurs du courrier électronique souhaiteraient un mécanisme de priorité, permettant de dire que tel message est plus important que tel autre et devrait être traité en premier. Après tout, les ressources (par exemple la capacité disponible dans le réseau) sont souvent insuffisantes et il serait souhaitable que les messages vraiment urgents en profitent avant les informations envoyées par Twitter (« vous avez un nouvel abonné »). Il n'existait pas jusqu'à présent, pour un serveur de messagerie, de moyen standard en SMTP de dire à un de ses pairs quelle était la priorité d'un message. C'est désormais fait grâce à la nouvelle extension SMTP MT-PRIORITY.

Dans les en-têtes du message (le format des messages est normalisé dans le RFC 5322), il existait un en-tête standard, Priority:, décrit dans le RFC 2156. Ce dernier avait à l'origine été écrit pour assurer l'interfaçage avec X.400. Ce système avait été un échec complet mais l'en-tête Priority: garde son utilité (on trouve aussi souvent un en-tête non officiel et n'ayant pas exactement la même sémantique, notamment par le nombre de niveaux et leur représentation, X-Priority:.) Par contre, l'inconvénient de noter la priorité dans le message est que cela oblige les MTA à analyser les en-têtes, ce qui n'est pas normalement leur rôle. De manière cohérente avec l'évolution du courrier électronique depuis quinze ans (meilleure séparation entre le format du RFC 5322 et le transport normalisé dans le RFC 5321), la priorité est désormais exprimable lors de la session SMTP. (Un autre RFC en cours d'écriture, draft-melnikov-smtp-priority-tunneling, utilisera un nouvel en-tête, MT-Priority:, pour le cas où on doive tunneler des messages prioritaires au dessus de MTAs qui ne gèrent pas les priorités.) Par exemple, un MTA dont les files d'attente d'envoi de messages sont grandes, pourra mettre au début de la file les messages de plus forte priorité.

Notez bien que c'est une priorité, donc relative (« ce message est très urgent, celui-ci l'est moins ») pas d'une garantie de délai. Le courrier électronique demeure « au mieux », sans délais certains. Les annexes de ce RFC contiennent des discussions plus en détails sur certaines utilisations de ces priorités. Si on ne se satisfait pas de la délivrance « au mieux », il faut utiliser une autre extension SMTP (DELIVERBY dans le RFC 2852 et section 5.2 de notre RFC 6710) ou regarder du côté de techniques réseaux comme DiffServ (RFC 2474).

Notez aussi que l'une des raisons du peu de déploiement effectif de l'en-tête Priority: est un problème de confiance (comme souvent quand on prétend faire de la qualité de service : tout le monde va demander la qualité maximale). Rien ne garantit que celui qui met dans ses messages Priority: urgent le fait à bon escient, peut-être ajoute-t-il systématiquement cette indication pour que ses messages aillent plus vite. Notre RFC 6710 précise donc bien que le MTA récepteur n'est pas obligé d'honorer les priorités de n'importe qui. Il peut ne le faire que lorsqu'il connait l'expéditeur et lui fait confiance (voir les mécanismes utilisés en sections 4.1 et 5.1).

Maintenant, les détails techniques (section 3) : la nouvelle extension SMTP se nomme Priority Message Handling et est annoncée par le mot-clé MT-PRIORITY lors de la connexion SMTP. Par exemple (S indique le serveur et C le client) :

S: 220 SMTP server here
S: 250-SIZE 20000000
S: 250-DSN

(Le paramètre MIXER est le nom d'une politique de priorités et est expliqué plus loin, section 9.2.) La priorité du message est annoncée par un paramètre de la commande MAIL FROM également nommé MT-PRIORITY. Elle va de -9 (plus faible priorité) à 9 (priorité la plus élevée). Par exemple :

S: 250 2.1.0 <> sender ok
S: 250 2.1.5 <> recipient ok

En pratique, tous les serveurs ne géreront pas forcément 19 niveaux distincts (il n'y en avait que 3 dans le RFC 2156). L'annexe E explique pourquoi ce choix de 19.

Cette extension est utilisable aussi bien pendant la soumission (RFC 6409) que pendant la transmission (RFC 5321), ainsi qu'en LMTP (RFC 2033).

Lorsque le MTA « serveur » gérant cette extension reçoit un message ayant une priorité explicite, il va le traiter en fonction de cette priorité. Par défaut, la priorité est de zéro (d'où le choix d'avoir des priorités négatives, on voit tout de suite si la priorité est plus ou moins importante que celle par défaut, voir annexe E pour les raisons de ce choix). En prime, le MTA va noter cette priorité dans l'en-tête Received: qu'il va ajouter au message. Avant cela, le MTA aura du toutefois vérifier l'émetteur : le RFC précise qu'on peut accepter des priorités négatives de n'importe qui mais qu'on ne devrait accepter des positives (élevant le niveau de priorité) que des émetteurs qu'on a authentifiés d'une manière ou d'une autre, et à qui on fait confiance. Autrement, il serait facile de réclamer systématiquement la plus haute priorité (9), épuisant ainsi les ressources du serveur. Un exemple d'une politique d'autorisation pourrait être « n'accepter de priorités positives que depuis les utilisateurs authentifiés avec la commande AUTHRFC 4954 - ainsi que depuis les MTA dont l'adresse IP a été mise dans une liste blanche, suite à un accord bilatéral avec leur gérant ». (Voir aussi les sections 5.1 et 11.)

Naturellemnt, un MTA peut avoir des politiques plus complexes comme de modifier automatiquement la priorité demandée en fonction de l'émetteur (« maximum 3 pour 2001:db8:666::1:25 »). Il doit dans ce cas prévenir l'émetteur en réponse au MAIL FROM :

S: 250 X.3.6 3 is the new priority assigned to the message

Lorsqu'un serveur transmet un message à un autre serveur SMTP, il inclut la priorité, sauf évidemment si l'autre serveur n'a pas annoncé qu'il gérait les priorités (extension MT-PRIORITY).

Les considérations pratiques liées au déploiement de cette extension MT-PRIORITY figurent dans la section 9. Ainsi, si on a plusieurs serveurs de courrier pour un même domaine (via plisieurs enregistrements MX), le RFC recommande de veiller à ce que tous ou aucun acceptent l'extension de gestion de la priorité. Autrement, des problèmes difficiles à déboguer vont survenir. (De toute façon, avoir plusieurs enregistrements MX est complexe et déconseillé pour les petits domaines, exactement pour ce genre de raisons.)

J'ai parlé un peu plus haut du paramètre « Nom de la politique de priorité » qu'un serveur peut ajouter lorsqu'il indique qu'il gère les priorités. La section 9.2 décrit plus en détail ce que cela signifie. L'idée est que différentes organisations vont avoir des politiques de priorité différentes : nombre de niveaux, notamment. L'idée est de donner un nom à ces politiques afin de permettre à un serveur d'indiquer quelle politiques il suit. Par exemple, si le serveur a une politique qui ne gère que trois niveaux, -1, 0 et 1, un message indiquant qu'il a réduit la priorité demandée de 3 à 1 n'est pas inquiétant. Il est recommandé d'enregistrer les politiques à l'IANA (la section « SMTP PRIORITY extension Priority Assignment Policy »). Ce nouveau registre est rempli selon la règle « Norme nécessaire » du RFC 5226. Il comprend actuellement trois politiques, issues de normes existantes. Par défaut, la politique appliquée est MIXER qui est celle du RFC 2156 et reprise dans l'annexe B de notre RFC 6710 : trois niveaux de priorité seulement (-4, 0 et 4), pas de valeurs numériques définies par défaut pour les tailles maximales des messages ou pour les délais de retransmission.

Deux autres annexes décrivent des utilisations des priorités, avec la politique associée. L'annexe A concerne l'usage militaire (politique STANAG4406, six niveaux, les deux plus urgents étant étiquetés Flash et Override). Et l'annexe C concerne les services d'urgence (RFC 4190 et RFC 4412). Un avis personnel : il n'est sans doute pas sérieux d'utiliser le courrier électronique sur l'Internet public pour des appels aux pompiers ou des messages militaires alors que l'ennemi attaque.

Puisqu'on a parlé de l'IANA, outre ce nouveau registre, les enregistrements suivants ont été faits (section 10) :

  • MT-PRIORITY a été ajouté aux extensions SMTP (la section « SMTP Service Extensions »).
  • Quelques codes de réponse améliorés (RFC 5248) ont été enregistrés, comme X.3.6 pour indiquer que la priorité demandée a été changée ou comme X.7.16 qui signale que le message est d'une taille trop importante pour sa priorité.

Et questions mises en œuvre ? Aujourd'hui, un Postfix typique, par exemple, ne gère pas encore ces priorités (et répond 555 5.5.4 Unsupported option: MT-PRIORITY=3 si on essaie.) Il existe apparemment déjà trois MTA qui ont en interne ce concept de priorité et qui, en l'absence de norme, la déterminaient de manière non-standard. Ils n'ont pas encore été adaptés à ce RFC. Pour cela, l'annexe D donne d'intéressants avis sur les stratégies d'implémentation possibles.

Téléchargez le RFC 6710

L'article seul

RFC 6713: The application/zlib and application/gzip media types

Date de publication du RFC : Août 2012
Auteur(s) du RFC : J.R. Levine (Taughannock Networks)
Pour information
Première rédaction de cet article le 25 août 2012

Encore un RFC qui comble un manque ancien. Les types MIME application/gzip et application/zlib n'avaient jamais été formellement enregistrés. Voici qui est fait.

Ces deux types apparaissent désormais dans le registre IANA avec ce RFC 6713 comme référence. Rien de nouveau, ils étaient déjà utilisés dans de nombreuses applications. (Parfois, des types non officiels étaient utilisés comme application/x-gzip ou encore des trucs comme application/gzipped.)

Pour ceux qui veulent apprendre ces deux techniques de compression, Zlib est spécifié dans le RFC 1950 (et a un site « officiel ») et Gzip est dans le RFC 1952 et a aussi son site. Les deux techniques sont très proches (utilisant l'algorithme Deflate du RFC 1951), la principale différence étant que Gzip inclut un en-tête et une terminaison. Il est donc plus adapté pour les fichiers (et Zlib pour le streaming).

Ah, au fait, soyez prudent : comme le dit l'inévitable section Security Considerations, les données comprimées récupérées sur l'Internet (qui est, comme le dit le sage Beigbeder, « l'empire de la méchanceté, de la bêtise ») peuvent être trompeuses. Elles peuvent prétendre être en Zlib ou en Gzip et comporter des erreurs, des pointeurs ne pointant pas au bon endroit, des champs Longueur qui n'indiquent pas la longueur, et autres choses qui peuvent mener à des accidents comme le dépassement de tampon. Programmeurs, attention.

Téléchargez le RFC 6713

L'article seul

RFC 6703: Reporting IP Network Performance Metrics: Different Points of View

Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Morton (AT&T Labs), G. Ramachandran (AT&T Labs), G. Maguluri (AT&T Labs)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 24 août 2012

Le groupe de travail IPPM de l'IETF a défini de nombreuses métriques, des définitions rigoureuses de grandeurs qu'on peut mesurer sur un réseau. Ce nouveau RFC porte sur un problème un peu différent : une fois qu'on a ces métriques, comment publier les résultats ? Quels sont les pièges de la publication ? Parmi les paramètres de la mesure, que mettre en évidence ? Ce RFC est loin de traiter en détail toutes ces questions, il décrit surtout les conséquences de deux points de vue différents : celui de l'ingénieur réseaux, intéressé surtout par les performances de son réseau, et celui du programmeur, intéressé par les performances de son application.

Il y a bien sûr un lien entre les deux : si le réseau perd beaucoup de paquets, par exemple (RFC 7680 et RFC 6673), les applications auront de moins bonnes performances. Mais, dans certains cas, les deux points de vue ne s'intéressent pas exactement à la même chose. Voyons en quoi. (À noter aussi que ce RFC 6703 ne regarde que les analyses sur le relativement long terme, au moins plusieurs heures. Et il ne se penche pas sur le problème, bien plus difficile, de la publication vers M. Toutlemonde, par exemple pour lui communiquer la QoE.)

Toute présentation de mesures nécessite évidemment de connaître l'audience. On ne va pas communiquer de la même façon vers le management et vers les techniciens, par exemple. Et, même parmi les techniciens, il existe plusieurs catégories. Ce RFC s'intéresse à la différence entre « les gens du réseau » (qui pensent planification des investissements, dépannage, SLA, etc) et « les gens des applications » qui se demandent quel va être l'effet du réseau sur les applications. Les premiers mesurent des métriques comme le taux de pertes de paquets (RFC 7680) ou comme le délai d'acheminement (RFC 7679), avec l'idée de modifier le réseau (par des investissements ou bien des changements de la configuration), si les chiffres sont défavorables. Les seconds vont ajuster les applications pour s'adapter à ces résultats, qu'ils ne peuvent pas changer.

Les recommandations de notre RFC occupent la section 3. Lorsqu'on publie des mesures, on doit notamment :

  • Inclure au minimum le taux de pertes de paquets (RFC 7680) et le délai d'acheminement (RFC 7679). On notera que c'est ce que fait la commande ping, même si elle ne suit pas exactement les métriques IPPM. Notons aussi que la norme UIT Y.1540 donne une définition assez proche de celle de l'IETF.
  • Indiquer la moyenne et la médiane (ce que ping ne fait hélas pas). Les deux statistiques sont utiles (et les deux ont des limites, par exemple aucune des deux ne gère proprement les distributions bimodales).

C'est le minimum. Mais on peut l'enrichir, avec d'autres métriques comme la variation du délai d'acheminement (RFC 3393), le réordonnancement des paquets (RFC 4737), la capacité (RFC 3148 et RFC 5136, le premier RFC décrivant la capacité utile et le second celle mesurée au niveau IP). Et on peut ajouter d'autres statistiques, pour ne pas être bloqués par les limites de la moyenne et de la médiane. Par exemple, minimum, maximum, « 95 percentile ».

Bon, et les deux points de vue différents dont je parlais au début, que deviennent-ils ? La section 4 du RFC examine les différentes métriques selon ces deux points de vue. Par exemple, le taux de pertes du RFC 7680 a un paramètre important : le délai d'attente avant qu'on renonce à attendre un paquet. Le RFC 7680 ne donne pas de valeur quantitative. Intuitivement, on pourrait penser que des durées de l'ordre de la demi-seconde suffisent. Après tout, on n'a jamais vu ping signaler un délai plus long, non ? Mais ce n'est pas idéal. En cas de boucle de routage, par exemple, avant que l'IGP ne converge enfin, un délai de plusieurs secondes est possible (cf. « A Fine-Grained View of High Performance Networking » à NANOG 22 ou « Standardized Active Measurements on a Tier 1 IP Backbone » dans IEEE Communications Mag. de juin 2003). Un délai long est donc recommandé. En modélisant le pire cas dans le réseau, notre RFC arrive à une recommandation de 50 secondes, qui devrait couvrir tous les cas. Revenons maintenant aux deux point de vue. L'homme (ou la femme) du réseau veut déterminer le vrai taux de perte, en étant sûr que les paquets sont vraiment perdus et pas simplement très en retard. Mais la femme (ou l'homme) des applications n'a pas besoin de tels délais d'attente : l'application ne patientera jamais autant. Pour la plupart des applications, si ça n'arrive pas en quelques secondes, c'est comme si c'était perdu.

Faut-il alors faire deux mesures pour nos deux points de vue ? C'est une possibilité. Le RFC en suggère une autre : ne faire qu'une mesure, avec le délai long, mais noter le moment où le paquet arrive et calculer le taux de pertes avec deux délais différents, pour faire deux rapports.

Et le cas des paquets erronés (par exemple car ils ont une somme de contrôle invalide) ? Pour le RFC 7680, ils sont à compter comme perdus (si le paquet est erroné, on ne peut même pas être sûr qu'il était bien pour nous). C'est le point de vue des gens du réseau. Mais les gens des applications ne sont pas toujours d'accord. Certaines applications, notamment dans le domaine de l'audio et de la vidéo temps-réel préfèrent que l'application reçoive les paquets erronés, dont on peut parfois tirer quelque chose. Notre RFC suggère donc de publier deux résultats, un en comptant les paquets erronés comme perdus, l'autre en les acceptant.

Et la métrique « délai d'acheminement des paquets », en quoi les deux points de vue l'affectent (section 5) ? Notre RFC s'oppose surtout à l'idée de présenter les paquets qui, lors de la mesure, n'arrivent pas, avec une valeur artificielle comme un nombre très grand ou comme l'infini. Quel que soit le point de vue, l'infini n'est pas une valeur utile et il vaut donc mieux considérer que le délai, pour un paquet qui n'arrive pas, est « indéfini ».

Maintenant, la capacité (sections 6 et 7). Notre RFC 6703 introduit un nouveau vocabulaire, « capacité brute » (raw capacity) pour celle du RFC 5136 (qui n'intègre pas les effets de la retransmission des paquets perdus ou erronés) et « capacité restreinte » (restricted capacity) pour celle du RFC 3148, qui intègre les actions du protocole de transport (retransmettre les données manquantes, par exemple). La capacité restreinte est donc inférieure ou égale à la capacité brute, et elle est plus proche de ce qui intéresse les utilisateurs.

D'abord, un rappel, la capacité n'est définie que pour un Type-P donné, c'est-à-dire (RFC 2330) un type de paquets (protocole, port, etc). Ensuite, le RFC 5136 définit trois métriques pour la capacité brute : capacité IP maximum (ce que le système peut faire passer), utilisation (ce qui passe effectivement, et qu'on pourrait appeler « débit » mais le RFC évite ce terme, trop galvaudé), et enfin capacité disponible (certaines applications, par exemple, voudraient simplement savoir si la capacité disponible est suffisante - supérieure à une certaine valeur). Les trois métriques sont liées : en en connaissant deux, on peut calculer la troisième. L'utilisation (et donc la capacité disponible) peut varier rapidement sur un réseau réel. Notre RFC 6703 recommande donc de moyenner sur une longue période, par exemple une minute (en notant que cinq minutes est plus fréquent, en pratique, mais peut-être trop long). D'autre part, il suggère de publier plusieurs chiffres : miminum, maximum et un intervalle (par exemple, le pourcentage de temps pendant lequel la métrique vaut entre telle et telle valeur, comme « la capacité est de X Mb/s pendant au moins 95 % du temps »). Maximum et minimum peuvent aussi être publiés sous forme d'un seul chiffre, leur ratio : (max/min = 1) => grande stabilité, (max/min = 10) => forte variabilité, etc.

Pour la capacité restreinte, un autre problème se pose : elle est dépendante des algorithmes de contrôle de congestion. Par exemple, avec certaines mises en œuvre de TCP anciennes, la capacité restreinte (celle réellement accessible aux applications) pouvait être très inférieure à la capacité brute, par exemple parce que TCP réagissait mal en cas de perte de paquets et ralentissait trop son débit. Notre RFC introduit donc un nouveau concept, le « Type-C » qui est l'ensemble des algorithmes du protocole de transport et leurs paramètres (RFC 6349). Il est nécessaire de publier le Type-C utilisé, avec les résultats. (Un exemple, sur Linux, est la valeur du paramètre sysctl net.ipv4.tcp_congestion_control.)

Autre piège, le temps d'établissement de la connexion TCP. Si on mesure la capacité restreinte avec quelque chose comme (sur Unix) time wget $GROSFICHIER, le délai pour la triple poignée de mains qui commence toute connexion TCP peut sérieusement affecter le résultat. Même chose avec le « démarrage en douceur » que fait TCP avant d'atteindre l'équilibre. Il peut diminuer la capacité mesurée (d'un autre côté, l'ignorer serait irréaliste puisque les « vraies » connexions l'utilisent). Bref, toutes ces informations doivent être publiées avec le résultat de la mesure.

Enfin (section 8), deux détails qui peuvent avoir leur importance : la distribution des paquets lors d'une mesure active (Poisson ? Périodique, ce que fait ping ?). Et la taille de l'échantillon (par exemple le nombre de paquets envoyés.) Ces détails doivent également être publiés.

Téléchargez le RFC 6703

L'article seul

RFC 6694: The "about" URI Scheme

Date de publication du RFC : Août 2012
Auteur(s) du RFC : S. Moonesamy
Pour information
Réalisé dans le cadre du groupe de travail IETF appsawg
Première rédaction de cet article le 24 août 2012

Les URI commencent par un plan (scheme en anglais), indiquant leur type. Un plan très répandu en pratique n'avait jamais été normalisé  : « about: ». Il permet de décrire des URI internes au navigateur. Le plus célèbre est le about:blank qui permet d'afficher une page blanche. Ce plan, et ce premier URI utilisant ce plan sont désormais officiellement spécifiés dans ce RFC.

Le plan est souvent appelé par erreur « protocole ». Mais il ne correspond pas toujours à un protocole, comme c'est le cas de notre about:. Celui-ci sert à tout, pages spéciales qui n'ont pas été récupérées sur le Web, accès à la configuration du navigateur et même amusants œufs de Pâques. Il figure désormais dans le registre des plans.

La section 2 indique la syntaxe formelle et la sémantique des URI about:. Un point important est que, contrairement aux URI http:, il n'y a pas de structure. Tout le texte après about: indique la ressource cherchée, sans qu'on puisse détailler des composants dans ce texte. Certains de ces textes sont eux-mêmes normalisés (comme le blank cité plus haut) mais pas tous. Et, comme about: décrit des ressources internes au navigateur, il est courant et normal que ces URI about: soient spécifiques d'un navigateur particulier. Attention donc aux URL about: dans cet article, certains ne marcheront pas dans votre navigateur.

Les noms « bien connus » sont désormais enregistrés (section 5.2). Pour l'instant, le registre IANA ne compte que blank (décrit sommairement en section 3) et invalid (qui vient d'une autre norme, au W3C) mais d'autres pourront s'y ajouter après la publication de ce RFC. Cet enregistrement est recommandé dès qu'au moins deux navigateurs connaissent ce nom. La procédure à suivre (cf. RFC 5226) est « premier arrivé, premier servi ». Ce principe n'a pas fait l'objet d'un consensus immédiat à l'IETF, certains auraient préféré une procédure plus formelle, « Spécification nécessaire ».

Il y a même des questions de sécurité liées aux URI about: (section 4) car ils donnent parfois accès à des informations sensibles comme des mots de passe.

Voici maintenant quelques URI about: à tester dans votre navigateur. N'hésitez pas à me raconter lesquels marchent et à m'en envoyer d'autres. De manière surprenante, il n'est pas toujours facile d'avoir de la documentation stable et fiable sur les about:. Pour Firefox, on peut consulter « Firefox about: pages » et pour Chrome « Google Chrome's about: Pages » ou bien « Behind the Scenes of Google Chrome: Optimizing and Troubleshooting », un bon article sur les réglages de Chrome pour maximiser les performances, qui fait beaucoup appel aux about:. Voici les exemples. Vous noterez que je n'en ai pas fait des liens hypertextes car des navigateurs comme Firefox n'acceptent pas tous les liens about: dans une page Web (sans doute pour des raisons de sécurité). Il faudra donc copier/coller :

Téléchargez le RFC 6694

L'article seul

Fiche de lecture : Breaking the Maya code

Auteur(s) du livre : Michael Coe
Éditeur : Thames & Hudson
Publié en 1992
Première rédaction de cet article le 24 août 2012

Un récit fabuleux sur le décryptage de l'écriture maya. L'un des participants à cette aventure, qui ne s'est terminée que dans les années 1980, a raconté tous les efforts qui ont été nécessaires pour arriver à lire cette écriture oubliée.

Attention, c'est un récit subjectif. Le monde des mayanistes est très divisé (c'est une des raisons pour lesquelles le décryptage a pris tant de temps) et Michael Coe a quelques comptes à régler. Sans compter les chocs entre les cultures différentes des linguistes, des archéologues et des épigraphistes. Bref, il a fallu bien plus longtemps pour lire l'écriture maya que pour les hiéroglyphes égyptiens, ou même que pour les hiéroglyphes hittites. Coe cite plusieurs raisons pour ce retard. Ce n'était pas le manque de documents (il y en avait davantage que pour les hiéroglyphes hittites, malgré la destruction systématiques des textes mayas par les intégristes catholiques, comme De Landa), ni le manque d'une pierre de Rosette (le même De Landa en avait écrite une, mais qui n'avait pas été interprétée correctement). Non, d'après Coe, c'était plutôt des aveuglements volontaires. Persuadés que l'écriture n'avait aucun rapport avec les langues mayas, encore largement parlées aujourd'hui, les premiers décrypteurs n'avaient tout simplement pas pris la peine d'apprendre une seule langue maya... Ensuite, leurs successeurs, ayant décidé une fois pour toutes que les Mayas n'avaient pas d'histoire et n'écrivaient que des réflexions philosophico-astronomiques, n'ont pas su lire les inscriptions même les plus simples (naissance du roi, son arrivée sur le trône, sa mort...)

Cet aveuglement pendant des années est très frappant, a posteriori, et a de quoi faire réfléchir sur la capacité humaine à ne pas se remettre en cause, même face aux plus grosses évidences.

Autre bel aveuglement : le refus acharné par les mayanistes de considérer que l'étude des autres civilisations puisse être utile. Les Mayas étaient considérés comme tellement différents que les compétences des égyptologues ou des assyriologues ne pouvaient pas servir à quoi que ce soit !

Mais il y avait aussi des erreurs techniques : l'une des plus gênantes a été l'attachement à l'idée d'écriture idéographique, c'est-à-dire qui code directement des idées, sans passer par une langue. Coe explique que cette idée est maintenant abandonnée par tous les linguistes (il n'existe pas d'écriture réellement idéographique, même si des termes erronés comme idéogramme sont encore fréquemment utilisés). Mais des gens importants s'étaient accrochés à cette théorie (qui justifiait leur absence de connaissances des langues mayas) et avaient rejeté les premières analyses correctes de l'écriture maya comme syllabaire, par Knorozov.

Il faut dire à la décharge de tous ceux qui se sont plantés que l'écriture maya n'est pas facile, notamment par sa variabilité. Le même texte peut s'écrire de plusieurs façons et les scribes ne manquaient pas d'en profiter.

Bref, plein de fausses pistes, de pistes correctes mais mal suivies (ce n'était pas tout de comprendre que l'écriture maya codait une langue maya, encore fallait-il savoir laquelle), d'expéditions épuisantes sur le terrain, de débats idéologiques vigoureux (c'était en pleine Guerre froide et les théories venues d'Union Soviétique étaient systématiquement rejetées à l'Ouest). Mieux qu'Indiana Jones, et en vrai.

On trouve beaucoup d'images de glyphes mayas libres sur Wikimedia Commons.

L'article seul

RFC 6666: A Discard Prefix for IPv6

Date de publication du RFC : Août 2012
Auteur(s) du RFC : N. Hilliard (INEX), D. Freedman (Claranet)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 21 août 2012

Une technique couramment utilisée en cas d'attaque par déni de service est le RTBH : Remote Triggered Black Hole où la victime demande à son FAI, via un protocole, de jeter des paquets sur tel ou tel critère. On utilise pour cela les protocoles de routage standards comme BGP ou OSPF. Même chose lorsqu'un opérateur réseaux veut propager en interne, entre ses routeurs, la décision de jeter ou de rediriger tel ou tel type de paquets. Pour cela, il est bien pratique de disposer d'un préfixe IP spécial, qui désigne le trou noir (ou l'IDS, si on redirige le trafic vers un équipement d'analyse spécial). Il n'existait pas de tel préfixe pour IPv6, c'est désormais fait avec ce RFC, qui enregistre 0100::/64.

Les RFC 5635 et RFC 3882 décrivent plus en détail cette idée de RTBH dans le cas d'une DoS. On sélectionne les paquets en fonction de leur adresse IP source ou destination et on les jette (trou noir) ou bien on les envoie (par exemple via un tunnel) vers un dispositif d'analyse. Pour configurer cela, il faut des adresses IP (plusieurs, car on peut avoir plusieurs traitements différents selon les attaques, donc une seule adresse IP ne suffit pas). Certains utilisent des adresses privées ou bien les adresses IP réservées pour la documentation (RFC 3849). Ce n'est pas très satisfaisant (et cela peut interférer avec les politiques de filtrage en interne, cf. section 2 du RFC) d'où le nouveau préfixe. Si on voit 0100::/64 dans la configuration d'un routeur, on sait désormais exactement ce que cela implique.

Ce préfixe peut être propagé, à l'intérieur du réseau de l'opérateur, ou bien entre l'opérateur et ses clients, par les protocoles de routage dynamiques habituels comme OSPF. Il ne doit pas être transmis à l'extérieur et il est recommandé de le filtrer en entrée, sur les liens de peering ou de transit. Comme il sert pour gérer des attaques qui peuvent être de taille impressionnante, une fuite de ce préfixe vers un autre opérateur pourrait potentiellement entraîner un reroutage de l'attaque vers cet autre opérateur (sections 3 et 5 du RFC). Prudence, donc !

Ce préfixe 0100::/64 est désormais dans le registre des adresses IPv6 spéciales.

Téléchargez le RFC 6666

L'article seul

RFC 6701: Sanctions Available for Application to Violators of IETF IPR Policy

Date de publication du RFC : Août 2012
Auteur(s) du RFC : A. Farrel (Juniper Networks), P. Resnick (Qualcomm)
Pour information
Première rédaction de cet article le 21 août 2012

Comme toutes les organisations de normalisation, l'IETF a élaboré une série de règles pour gérer le difficile problème de l'appropriation intellectuelle et surtout des brevets. Ces règles existent depuis des années mais ce n'est que récemment, suite à deux affaires spectaculaires, que l'IETF a pris conscience du fait que la question des sanctions, en cas de violation de ces règles, n'avait jamais été sérieusement discutée. Ce RFC corrige ce manque et fait la liste des réactions possibles de l'IETF en cas de violation des règles. Disons-le tout de suite, il n'y en a pas de très dissuasives : l'IETF n'a pas le pouvoir de couper des têtes ou de condamner au bûcher. Un autre RFC, le RFC 6702, discute de l'aspect positif, comment encourager le respect des règles.

Que disent ces règles actuellement ? Documentées dans le RFC 8179, résumées sur le site Web et par l'IESG, et fréquemment rappelées pendant les réunions physiques et sur les listes de diffusion, par les fameux « Note Well », ces règles reposent sur deux piliers :

  • L'IETF peut normaliser des techniques brevetées,
  • Mais encore faut-il le savoir : pour cela, tout participant à l'IETF qui a connaissance, dans le cadre de son activité professionnelle, d'un brevet sur une technique en cours de normalisation doit en avertir l'IETF.

Le but est d'éviter les brevets sous-marins, par lesquels une entreprise pousse à la normalisation d'une technique, pour laquelle elle dispose de brevets, en dissimulant ces brevets pour qu'ils n'effrayent pas les normalisateurs.

La section 2 décrit plus en détail cette politique de l'IETF. D'abord, elle ne s'applique qu'aux contributeurs à l'IETF. Quelqu'un qui n'écrirait aucun document, ne prendrait jamais la parole aux réunions et ne s'exprimerait pas sur les listes de diffusion n'aurait pas à la respecter. C'est d'ailleurs la seule solution pour un employé que sa compagnie n'autorise pas à divulguer l'existence d'un brevet : se retirer du processus IETF (« Aime-la ou quitte-la »).

Cette politique est ensuite souvent rappelée aux participants, par exemple lorsqu'on s'inscrit à une liste de diffusion IETF, on est redirigé vers la page Web d'avertissement (Note Well).

Pour signaler un brevet portant sur une technologie en cours d'examen à l'IETF, cela se fait via un formulaire Web. Les déclarations sont elles-mêmes publiées sur le Web.

Que fait ensuite le groupe de travail IETF de ces déclarations ? L'IETF n'impose pas une politique unique à ses groupes de travail à ce sujet. Le groupe peut décider d'ignorer le brevet (n'oubliez pas que la grande majorité des brevets logiciels sont futiles : technologies évidentes, communes longtemps avant le brevet, etc). Il peut aussi décider de changer la technique en cours de normalisation pour contourner le brevet (et c'est la crainte de ce résultat qui motive certaines entreprises à garder leurs brevets secrets).

Naturellement, il y a des tricheurs. C'est ainsi que RIM ou Huawei (dans le RFC 6468) avaient caché leurs brevets. C'est à cause de ces tricheurs qu'il faut prévoir la possibilité de sanctions, dont la gravité doit être adapté à chaque cas.

Qui va décider de l'action à entreprendre contre les tricheurs (section 3) ? Les chefs du groupe de travail concernés, puisque ce sont eux qui connaissent le mieux tous les détails et, s'ils ne le peuvent pas, le directeur de zone (Area Director) responsable du groupe de travail.

La section 4 liste les sanctions elles-mêmes. Aucune n'est très effrayante, l'IETF n'ayant pas de pouvoirs particuliers. À noter que la liste présentée ici n'est pas exhaustive, d'autres sanctions pourront être imaginées dans le futur. Donc, en gros, par ordre de sévérité croissante, quelques-uns de ces sanctions :

  • Discussion en privé avec le participant,
  • Avertissement en privé,
  • Avertissement public avec les noms (politique nommée en anglais name and shame),
  • Refus d'accepter le tricheur comme auteur d'un document du groupe de travail (ce sont en effet les présidents du groupe de travail qui décident des auteurs), ou exclusion des documents qu'ils éditent actuellement (le droit d'auteur oblige à les mentionner dans la section Acknowledgments, même dans ce cas, il n'est pas possible de reproduire la condamnation d'Érostrate),
  • Rejet complet du document et donc de la technique qu'il normalise,
  • Ajout temporaire ou définitif du tricheur sur la liste noire des gens non autorisés à écrire sur la liste de diffusion du groupe de travail (RFC 3683, ce que le jargon IETF nomme une PR Action pour Posting Rights Action), la section 4.1 décrivant en détail pourquoi cette sanction est acceptable dans ce cas.

Comme toute les décisions à l'IETF, elles sont susceptibles d'appel devant l'IESG (section 5 et la section 6.5 du RFC 2026).

À noter que l'annexe A contient des indications pour ceux qui auront à choisir et appliquer les sanctions. Rien ne sera automatique et les décideurs devront faire preuve de jugement. Parmi les points qu'ils devront examiner avant de décider figurent l'ancienneté de la personne en cause dans l'IETF, le moment exact où le brevet a été révélé, la place de l'individu dans le travail en question (contributeur occasionnel ou principal ?), qualité des excuses présentées, etc.

Téléchargez le RFC 6701

L'article seul

RFC 6702: Promoting Compliance with Intellectual Property Rights (IPR) Disclosure Rules

Date de publication du RFC : Août 2012
Auteur(s) du RFC : T. Polk (National Institute of Standards and Technology), P. Saint-Andre (Cisco)
Pour information
Première rédaction de cet article le 21 août 2012

Les règles de l'IETF concernant la publication des brevets sur les techniques en cours de normalisation ont déjà été violées plusieurs fois, par exemple par RIM. Deux RFC viennent donc d'être publiés pour traiter ce problème : un répressif, le RFC 6701, qui dresse la liste des sanctions possibles contre les tricheurs. Et un préventif, ce RFC 6702, qui expose tous les mécanismes à mettre en œuvre pour encourager tout le monde à respecter les règles. Pour le résumer : la principale (voire unique) méthode envisagée est de rappeler les règles au bon moment, de façon à augmenter les chances qu'elles soient lues.

Que disent ces règles, au juste ? Formulées dans le RFC 8179 et répétées en ligne, elles imposent, en substance, qu'un participant à l'IETF qui connait des revendications de propriété intellectuelle (typiquement des brevets) sur une technique en cours de normalisation doit en informer l'IETF (cela se fait en ligne), qui publiera alors ces revendications. C'est tout. L'IETF n'impose que cette transparence, qui permet ensuite aux groupes de travail de prendre des décisions en toute connaissance de cause (RFC 2026, section 10.4). Le but est d'éviter les brevets sous-marins, où une entreprise fait normaliser une technologie sur laquelle elle a des brevets, qu'elle ne révèle qu'après la publication de la norme, lorsqu'il est trop tard pour chercher une alternative. Pas étonnant que cette obligation de divulgation déplaise aux maneuvriers de l'appropriation intellectuelle. Au moins deux tricheries ont été détectées, une de RIM et l'autre de Huawei (dans le RFC 6468). La seconde a été la goutte d'eau qui a fait déborder le buffer et mené à ces deux RFC qui essaient de redresser la barre. Ils ne définissent pas de nouvelles règles : les anciennes s'appliquent comme avant, ces deux nouveaux RFC disent juste comment le faire.

À noter que, comme l'ont montré l'analyse de ces deux cas, il s'agissait de tricheries délibérées. Mais il y a aussi eu des cas où la négligence ou l'ignorance ont fait que les brevets n'étaient pas annoncés à l'IETF, ou bien l'étaient en retard. Ces deux RFC vont aussi servir pour le cas où la violation des règles s'est faite de bonne foi. Car, même commis de bonne foi, ce manque de divulgation d'un brevet peut avoir des conséquences fâcheuses : un groupe de travail qui ne connaissait pas un brevet risque de négliger une piste alternative, non plombée par des brevets.

En pratique, les méthodes suggérées dans ce RFC concernent surtout les personnes ayant un rôle dirigeant à l'IETF (RFC 2418 et RFC 3669) : président de groupe de travail, directeur de zone (ceux qui forment l'IESG), etc. Ce sont ces personnes qui ont la responsabilité de faire avancer proprement le processus.

La section 3 du RFC décrit les stratégies disponibles. Il s'agit essentiellement de mieux informer les participants à l'IETF pour éviter toute inattention... ou toute fausse excuse. S'appuyant sur les conseils du RFC 3669, les responsables peuvent :

  • Rappeler les règles lorsqu'un Internet-Draft va être présenté à une réunion (le président d'un groupe de travail peut refuser la discussion si le présentateur ne confirme pas que les divulg