Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Ève

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


Lire des paquets capturés sur le réseau en C

Première rédaction de cet article le 23 décembre 2008


Il y a des tas de raisons de vouloir lire soi-même les paquets capturés sur le réseau. Cela peut être par curiosité, par souci de sécurité (ou pour pirater !) ou bien pour faire des statistiques. Pour un rapide coup d'œil, on utilise en général tcpdump, pour un examen interactif détaillé, l'excellent Wireshark mais, pour des études à long terme, il vaut mieux programmer et développer un programme d'analyse spécifique, ce que je fais ici en langage C.

Souvent les articles sur la question parlent ensemble de la capture des paquets et de leur analyse. Ici, je ne mentionne que l'analyse, supposant que la capture a été faite par d'autres moyens, par exemple tcpdump -w FICHIER ou bien pcapdump.

L'outil d'analyse le plus fréquent pour les programmeurs C est libpcap. Il existe un excellent tutoriel d'introduction.

Je commence par un programme trivial, qui lit un fichier au format pcap, capturé par un des outils cités dans « Capturer les paquets qui passent sur le réseau », et qui décode suffisamment d'IPv4 pour afficher le protocole de transport utilisé. L'essentiel du programme est :

/* Ouvrir le fichier pcap */
handle = pcap_open_offline(filename, errbuf);
/* Parcourir le fichier */
while (1) {
    packet = pcap_next(handle, &header);
    /* Décoder l'en-tête Ethernet en convertissant le packet en une
    struct */
    ethernet = (struct sniff_ethernet *) (packet);
    /* Si c'est de l'IPv4 */
    if (ntohs(ethernet->ether_type) == IPv4_ETHERTYPE) {
          /* Décoder IPv4 : convertir le paquet en une struct. Ne pas
	  oublier de décaler de SIZE_ETHERNET octets */
          ip = (struct sniff_ip *) (packet + SIZE_ETHERNET);
          /* Afficher */
          printf ("Paquet IPv4 avec le protocole %d\n", ip->ip_p);

Notons bien qu'il faut utiliser ntohs pour convertir le paquet dans la bonne boutianité. Le code complet du programme est disponible en readfile-ipv4.c. On peut le compiler sur Unix avec :

cc -o readfile -lpcap readfile.c

(Si libpcap est bien présente. Sur une Debian, il aura fallu installer le paquetage libpcap-dev.)

On note qu'il a fallu faire le décodage soi-même, en travaillant au niveaux des bits de l'en-tête du paquet IP. Cela nécessite donc de connaitre le protocole décodé. Pour IPv4, il faut donc lire le RFC 791, section 3.1.

Et pour IPv6 ? Le format est décrit dans le RFC 2460, section 3. Traduisons-le en C :

/* IPv6 header. RFC 2460, section3. 
   Reading /usr/include/netinet/ip6.h is interesting */
struct sniff_ip {
	uint32_t         ip_vtcfl;	  /* version then traffic class
	                                     and flow label */
	uint16_t         ip_len;	  /* payload length */
	uint8_t          ip_nxt;	  /* next header (protocol) */
	uint8_t          ip_hopl;	  /* hop limit (ttl) */
	struct in6_addr  ip_src, ip_dst;  /* source and dest address */
};

Il suffit ensuite de « plaquer » cette définition sur le paquet :

if (ntohs(ethernet->ether_type) == IPv6_ETHERTYPE) {
	ip = (struct sniff_ip *) (packet + SIZE_ETHERNET);

et hop, on a un paquet IPv6 à analyser. On peut par exemple lire ip->ip_nxt qui contient le type du prochain en-tête (en général, la couche transport, mais attention, avec IPv6, d'autres en-têtes intermédiaires peuvent être présents). Le programme complet est en readfile-ipv6.c.

Si on veut décoder des protocoles de plus haut niveau, c'est souvent plus complexe. Prenons le DNS comme exemple. Le format est décrit dans le RFC 1035, section 4.1. Il peut se traduire en :

struct sniff_dns {
	/* RFC 1035, section 4.1.1 */
	uint16_t         query_id;
	uint16_t         codes;
	uint16_t         qdcount, ancount, nscount, arcount;
};

(Cela ne contient que l'en-tête DNS, il existe également des champs ultérieurs pour stocker la requête, la réponse, etc.)

Les codes sont des bits ou des groupes de bits et, pour y accéder, il faut faire de l'arithmétique de bits. Je définis des macros pour cela :

#define DNS_QR(dns)		((ntohs(dns->codes) & 0x8000) >> 15)
#define DNS_OPCODE(dns)	((ntohs(dns->codes) >> 11) & 0x000F)
#define DNS_RCODE(dns)	(ntohs(dns->codes) & 0x000F)

Ainsi, DNS_QR va extraire le bit 15, qui indique si le paquet est une requête ou bien une réponse (on masque avec une valeur où seul ce bit est à 1, 0x8000, puis on décale vers la droite). Une fois le paquet décodé :

if (source_port == DNS_PORT || dest_port == DNS_PORT) {
     dns = (struct sniff_dns *) (packet + SIZE_ETHERNET + 
                                        size_ip + SIZE_UDP);

on peut utiliser ces macros pour afficher le contenu du paquet, par exemple :

DNS_QR(dns) == 0 ? "Query" : "Response"

Le code complet figure en readfile-ipv6-dns.c.

Les programmeurs Python peuvent regarder mon article équivalent pour Python.


L'article seul

RFC 4995: The RObust Header Compression (ROHC) Framework

Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : L-E. Jonsson (Optand), G. Pelletier (Ericsson), K. Sandlund (Ericsson)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF rohc
Première rédaction de cet article le 22 décembre 2008
Dernière mise à jour le 30 mars 2010


Quels que soient les progrès des technologies, il n'y a jamais assez de capacité. Même aujourd'hui, les vieux modems restent en service (y compris dans un pays riche, mais étendu, comme les États-Unis) et certaines technologies récentes offrent une capacité limitée (par exemple sur les téléphones mobiles). Il est donc utile de pouvoir comprimer les données et aussi les en-têtes des paquets émis, qui sont souvent très redondants, ouvrant ainsi de bonnes perspectives pour la compression. Plusieurs mécanismes de compression ont été inventés et le projet ROHC (Robust Header Compression) a été créé pour mettre de l'ordre dans ces mécanismes, en développant un cadre commun. Ce RFC spécifie ce cadre.

La section 1 du RFC, l'introduction, donne quelques chiffres sur les gains qu'on peut tirer de la compression. Par exemple, si on utilise RTP (RFC 3550) pour transporter de la voix sur IP, il faudra transporter les 40 octets de l'en-tête (en IPv6), les 12 octets de l'en-tête UDP et les 8 octets de l'en-tête RTP (sans compter les en-têtes de la couche liaison). Ainsi, un paquet de données de 20 octets (une taille courante en voix sur IP) pourrait nécessiter 60 octets d'en-têtes TCP/IP.

Le RFC originel sur ROHC était le RFC 3095 qui incluait à la fois le cadre général et les profils de compression pour certains protocoles (un profil est un protocole de compression donné, adapté à un certain protocole). Une réforme générale de ROHC a eu lieu et il est désormais normalisé dans plusieurs RFC, notre RFC 4995, à l'origine, pour le cadre général, les RFC 4996 et RFC 5225 pour des profils pour, respectivement, TCP et les protocoles sans connexion comme IP ou UDP, le RFC 4997 pour le langage formel de définition des compressions, etc. (Le RFC 3095 n'est pas officiellement abandonné puisque le protocole est le même, il est juste mieux décrit.) Depuis, le RFC 5795 est sorti, remplaçant notre RFC 4995 en corrigeant quelques bogues.

La section 3 du RFC décrit les bases de la compression. Le principe est que le compresseur ne transmette pas certaines informations, car elles n'ont pas changé, ou bien peuvent être déduites automatiquement. Cela implique que le décompresseur puisse se souvenir de l'état de la compression, ce que ROHC nomme le contexte (la section 2.2 décrit toute la terminologie). Le maintien de ce contexte, même en présence de perturbations sur le réseau, est le principal défi de la compression. Sur des liens de mauvaise qualité (par exemple avec beaucoup de pertes), les mécanismes de compression pré-ROHC se comportaient plutôt mal (voir aussi la section 1).

Naturellement, rien n'est gratuit : le gain en capacité du réseau sera obtenu au détriment de la puissance de calcul, puisque compression et décompression nécessitent des calculs. La vitesse des processeurs des téléphones portables augmentant plus vite que leur capacité réseau, le choix de la compression semble raisonnable.

La section 3.2 rappelle l'histoire de la compression. Le premier grand travail dans le monde TCP/IP avait été la compression des en-têtes TCP par Van Jacobson en 1990 (RFC 1144), dont tous les utilisateurs de SLIP dans les années 1980 et 90 se souviennent (« Tu es sûr d'avoir activé la compression VJ ? »).

La section 4 décrit de manière relativement informelle le fonctionnement de ROHC, notamment (section 4.1), les différentes classes de changement dans les en-têtes, qui permettent leur prédiction par le décompresseur. Ainsi, la classe STATIC décrit les informations qui ne changent pas pendant la durée du flux de données (le numéro de version IP par exemple), la classe INFERRED étant composée des en-têtes qui peuvent se déduire ou se calculer à partir d'autres informations (comme la taille du paquet).

La vraie définition de ROHC est en section 5. C'est là qu'on trouve, par exemple, la description du mécanisme de rétroaction (section 5.2.4) qui permet au décompresseur de tenir le compresseur au courant du succès (ou de l'échec) de son travail. Autre exemple (section 5.1.2), chaque canal de communication ROHC a, parmi ses paramètres, un identificateur du profil utilisé (la liste des identificateurs possibles est dans un registre IANA, voir également la section 8). La section 5.4 normalise ainsi le profil d'identificateur 0x0000, le profil qui ne fait rien (en oubliant une partie, ce qui a été corrigé dans le RFC 5795), les profils « actifs » étant définis dans d'autres RFC.

Des déploiements de ROHC sont déjà faits dans les téléphones portables. Il existe une implémentation libre, RObust Header Compression (ROHC) library (merci à Didier Barvaux pour cela), tirée d'une plus ancienne bibliothèque. La section 6 du RFC 3095 contient une excellent section sur les problèmes concrets de mise en œuvre de ROHC (section qui ne semble pas avoir été reprises dans les RFC plus récents).


Téléchargez le RFC 4995


L'article seul

Lire des paquets capturés sur le réseau en Python

Première rédaction de cet article le 17 décembre 2008


Il y a des tas de raisons de vouloir lire soi-même les paquets capturés sur le réseau. Cela peut être par curiosité, par souci de sécurité ou bien pour faire des statistiques. Pour un rapide coup d'œil, on utilise en général tcpdump, pour un examen interactif détaillé, l'excellent Wireshark mais, pour des études à long terme, il vaut mieux programmer et développer un programme d'analyse spécifique.

Souvent les articles sur la question parlent ensemble de la capture des paquets et de leur analyse. Ici, je ne mentionne que l'analyse, supposant que la capture a été faite par d'autres moyens, par exemple tcpdump -w FICHIER ou bien pcapdump.

L'outil d'analyse le plus fréquent pour les programmeurs C est libpcap (dont je parle dans « .Lire des paquets capturés sur le réseau en C »). Et en Python ? Il existe plusieurs interfaces à la libpcap, notamment pylibpcap et pcapy. pcapy semble de plus haut niveau et c'est celle que j'utilise.

pcapy peut faire la capture et la lecture des fichiers au format pcap. Ses capacités d'analyse sont limitées, on utilise en général la bibliothèque impacket, des mêmes auteurs, ou bien carrément scapy.

Voici un programme simple de lecture d'un fichier pcap, tel que produit par tcpdump :

import pcapy

reader = pcapy.open_offline("mydata.pcap")

while True:
    try:
        (header, payload) = reader.next()
        print "Got a packet of length %d" % header.getlen()
    except pcapy.PcapError:
        break

Il ne semble pas y avoir de moyen de détecter la fin du fichier à part en récupérant l'erreur très générique PcapError.

payload est juste une chaîne non décodée d'octets, représentés en caractères. Si je veux l'analyser, je peux le faire « à la main » avec les fonctions de manipulation binaire de Python. Cela nécessite évidemment de lire les différentes normes pour connaître le format des paquets :


import pcapy

reader = pcapy.open_offline("mydata.pcap")

while True:
    try:
        (header, payload) = reader.next()
        # Ethernet type is two-bytes long and starts at 12 (before, you
        # have the MAC addresses)
        if payload[12:14] == '\x86\xDD': # 0x86DD is the Ethernet type for IPv6
            ip_payload = payload[14:]
            ip_version = (ord(ip_payload[0]) & 0xf0) >> 4
            if (ip_version != 6):
                raise Exception("Packet has ethernet type of IPv6 but internal IP version is %d" % ip_version)
            next_header = ord(ip_payload[6]) # RFC 2460, section 3 to know the offset
            print "Next header (probably the transport protocol) is %d" % next_header
    except pcapy.PcapError:
        break

Ici, on teste le type indiqué dans l'en-tête Ethernet pour ne garder que 0x86DD (IPv6). On saute les quatorze premiers octets (la taille de l'en-tête Ethernet) pour récupérer le paquet IPv6 que l'on décode en suivant le RFC 2460. Le numéro de version fait moins d'un octet, d'où les manipulations de bits avec & et >>.

Mais il peut être plus simple d'utiliser la bibliothèque impacket, conçue pour faciliter le décodage :

import pcapy
import impacket.ImpactDecoder as Decoders

reader = pcapy.open_offline("mydata.pcap")
decoder = Decoders.EthDecoder()

while True:
    try:
        (header, payload) = reader.next()
        result = decoder.decode(payload)
        # https://www.iana.org/assignments/ethernet-numbers
        if result.get_ether_type() == 0x86DD: # IPv6
            print "Got an IPv6 packet of length %d" % header.getlen()
    except pcapy.PcapError:
        break

Ici, plus besoin de connaître la structure de l'en-tête Ethernet, on peut utiliser get_ether_type() au lieu de payload[12:14].

Cela va permettre de s'attaquer à des protocoles de plus haut niveau, souvent plus complexes à décoder. Commençons par UDP :

import pcapy
import impacket.ImpactDecoder as Decoders
import impacket.ImpactPacket as Packets

reader = pcapy.open_offline("mydata.pcap")
eth_decoder = Decoders.EthDecoder()
ip_decoder = Decoders.IPDecoder()
udp_decoder = Decoders.UDPDecoder()

while True:
    try:
        (header, payload) = reader.next()
        ethernet = eth_decoder.decode(payload)
        if ethernet.get_ether_type() == Packets.IP.ethertype:
            ip = ip_decoder.decode(payload[ethernet.get_header_size():])
            if ip.get_ip_p() == Packets.UDP.protocol: 
                udp = udp_decoder.decode(
                    payload[ethernet.get_header_size()+ip.get_header_size():])
                print "IPv4 UDP packet %s:%d->%s:%d" % (ip.get_ip_src(),
                                                        udp.get_uh_sport(),
                                                        ip.get_ip_dst(),
                                                        udp.get_uh_dport())
    except pcapy.PcapError:
        break

Ce programme affiche les paquets UDP sur IPv4 en indiquant les adresses et ports de source et de destination. On note qu'il n'y a pas eu besoin de lire le RFC 768, tout est pris en charge par Impacket (y compris le problème, que j'ai soigneusement évité dans l'exemple du décodage manuel, de l'ordre des octets dans les champs multi-octets). Il faut juste penser, à chaque fois qu'on grimpe d'une couche, à se décaler dans le paquet (du résultat de get_header_size() sur la couche précédente).

Pour le décodage de l'en-tête IP, Impacket ne dispose malheureusement que d'un décodeur IPv4. Pour IPv6, il faut l'écrire soi-même, peut-être plutôt en utilisant Scapy. Ce sera pour un autre article.


L'article seul

Capturer les paquets qui passent sur le réseau

Première rédaction de cet article le 17 décembre 2008
Dernière mise à jour le 27 mars 2009


Lire les paquets qui passent sur le réseau est une activité indispensable pour l'étudiant qui apprend les réseaux informatiques, pour l'administrateur système qui débogue un problème, pour le chercheur qui rassemble des statistiques ou simplement pour le curieux qui veut s'instruire. Mais avant de pouvoir les lire et les analyser, il faut les capturer. Quels sont les outils disponibles ?

Tout le monde connait et utilise tcpdump, qui permet à la fois de capturer et de décoder les paquets. Pour un coup d'œil rapide, c'est parfait. Mais pour des études plus lourdes, il est souvent recommandé de séparer la capture des données (qui doit pouvoir tourner longtemps, sans trop charger la machine) de leur analyse (souvent très consommatrice en ressources et qui peut parfaitement être faite hors-ligne). Cet article se focalise sur les outils de capture, l'analyse étant faite ailleurs, avec un programme d'exploration comme Wireshark ou bien avec un programme qu'on a développé soi-même, par exemple en Python.

Un bon logiciel de capture doit pouvoir :

  • Tourner longtemps, tout en écrivant dans des fichiers, de préférence en sachant passer d'un fichier à l'autre lorsque les fichiers de capture deviennent trop gros, ou bien à l'issue d'un certain délai.
  • Pouvoir filtrer les événements intéressants, de façon à ne pas stocker n'importe quoi sur le disque. À cette fin, tous les logiciels de capture disposent d'un mini-langage permettant de dire quels sont les « événements intéressants ». La puissance expressive de ce langage est un des principaux critères qui distinguent ces logiciels.
  • Ne pas trop charger la machine (c'est une autre raison pour laquelle le filtrage est important mais attention, il peut lui-même consommer beaucoup de ressources), au cas où elle fasse tourner des services de production, et afin d'éviter de perdre des paquets (ce que font les logiciels de capture lorsqu'ils n'arrivent plus à suivre).

Presque tous les logiciels de capture enregistrement au format « pcap », celui de la libpcap.

Voyons les logiciels possibles. L'ancêtre tcpdump, très connu de tous les administrateurs réseaux, reste parfaitement utilisable pour cette tâche. Son option -w permet d'enregistrer les événements, qui pourront ensuite être lus par tout logiciel capable de lire du pcap (y compris tcpdump lui-même, avec l'option -r).

% tcpdump -i eth2 -w mydata.pcap
tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 96 bytes
[Control-C]
41 packets captured
41 packets received by filter
0 packets dropped by kernel

Et mydata.pcap peut être analysé ensuite à loisir. tcpdump dispose de nombreuses options qui peuvent être utiles pour la capture comme -c (s'arrêter après un nombre donné de paquets) ou -C (donne une taille maximale au fichier), même si elles sont moins perfectionnées que celles des logiciels récents.

tcpdump dispose d'un langage de filtrage, nommé BPF et qui permet d'exprimer des choses simples comme « uniquement les paquets venant de 192.0.2.3 » ou « uniquement les paquets à destination du port 80 » ou encore « uniquement les paquets à destination de 2001:db8:1::deca:fbad, et venant du port 53 ». Voici cette dernière :

% tcpdump -i eth2 -w mydata.pcap \
            dst host 2001:db8:1::deca:fbad and \
            src port 53

L'analyseur Wireshark a des mécanismes de décodage des paquets bien plus riches que ceux de tcpdump. Il vient avec un programme en ligne de commande, tshark qui peut être utilisé pour la capture :

 
% tshark -i eth2  -w mydata.pcap 
Capturing on eth2
340 
[Control-C]

Notez l'affichage en temps réel du nombre de paquets capturés, bien pratique. Ses options de capture sont plus perfectionnées que celles de tcpdump, par exemple -a permet de stopper celle-ci après qu'un temps donné se soit écoulé. En mode « plusieurs fichiers », les noms des fichiers sont plus parlants qu'avec tcpdump, etc.

tshark dispose d'un langage de filtrage plus perfectionné, documenté dans Display Filter Reference. Par exemple, si on regarde les requêtes DNS, tshark peut filtrer avec des règles comme « uniquement les réponses ». Mais attention, il ne s'agit que de filtre d'affichage, le langage des filtres de capture est bien plus sommaire, c'est le même que celui de tcpdump (on peut trouver plein d'exemples sur le site de Wireshark). La raison de cette limitation est probablement que la capture doit aller vite, sans nécessiter de copier des paquets depuis le noyau et que le langage BPF, lui, peut tourner entièrement dans le noyau.

Pour des options de capture encore plus riches, on peut regarder pcapdump. Il fait partie d'un groupe de programmes utilisant pcap, développés spécialement pour Debian, mais qui peuvent être compilés sur d'autres systèmes. Par exemple, sur Gentoo, il faut installer la bibliothèque Judy (emerge judy) puis simplement utiliser make pour compiler. Ensuite, on copie les exécutables (dans src/) à la main.

Les forces de pcapdump, un logiciel spécialisé dans la capture, sont notamment ses capacités de tourner en démon (l'option n'est pas évidente à trouver, c'est -P, par exemple pcapdump -P /var/run/pcapdump.opid -C $(pwd)/dns.pcapdump), de changer de fichier sur plusieurs critères, de nommer les fichiers de capture selon un modèle qu'on choisit, d'échantilloner en n'enregistrant qu'un paquer sur N, etc. Il peut aussi lire ces options dans un fichier de configuration, dont voici un exemple qui lit les paquets DNS (port 53) et change de fichier tous les jours :

device=eth0
bpf="udp and port 53"
interval=86400
snaplen=512
promisc=0
filefmt=/var/tmp/pcapdump/eth0.%Y%m%d.%H%M.%S.pcap
mode=0600
owner=smith
group=root

Si on veut des filtres de capture très sophistiqués (tous les logiciels précédents se limitent au langage BPF), il faut les programmer soi-même ou bien utiliser un logiciel spécialisé comme dnscap. Ce programme dispose de filtres de capture spécifiques au DNS, par exemple on peut sélectionner uniquement les réponses et seulement celles qui sont négatives (NXDOMAIN, ce domaine n'existe pas).

dnscap n'a pas de documentation en ligne, tout est dans la page de manuel incluse dans la distribution. Sa compilation n'est pas toujours évidente. Sur Gentoo ou Debian, il faut ajouter dans le Makefile :

PORTLIBS= /usr/lib/libresolv.a
BINDLIB=-lbind9

Voici un exemple d'utilisation de dnscap, pour ne capturer que les paquets de réponses (-sr), et seulement si la réponse est négative (nom de domaine inexistant, -ex) et juste si la question concernait le domaine sources.org :

% dnscap -x 'sources\.org' -i eth0 -sr -g -ex 

Comme pcapdump, il permet de changer automatiquement de fichier de capture en cours de route (par exemple avec -t 86400 pour tourner tous les jours), ce qui le rend utilisable pour des études sur le long terme.

Contrairement aux filtres BPF, le filtrage fait par dnscap est effectué dans l'espace utilisateur, pas dans le noyau. Il a donc fallu copier le paquet dans ledit espace et effectuer des opérations parfois complexes avant de décider de le garder ou pas. Les capacités de capture peuvent donc s'en ressentir.

Une fois les paquets capturés, il existe plusieurs programmes tout faits pour afficher des informations sur ces captures ou pour les modifier. Par exemple, Wireshark est livré avec deux utilitaires en ligne de commande très pratiques. editcap permet de sélectionner une partie d'une capture, en indiquant les numéros d'ordre des paquets qu'on veut garder :

% editcap -r large.pcap small.pcap 1-1000
Add_Selected: 1-1000
Inclusive ... 1, 1000

gardera les mille premiers paquets du fichier large.pcap. capinfos permet d'obtenir des informations sur un fichier de trace :

% capinfos small.pcap 
...
File encapsulation: Ethernet
Number of packets: 1000 
File size: 210439 bytes
Data size: 371542 bytes
Capture duration: 23.338821 seconds
Start time: Mon Mar  2 21:41:57 2009
End time: Mon Mar  2 21:42:21 2009
...

Et si on développe un programme soi-même ? C'est assez facile, dans plusieurs langages de programmation. On peut ainsi choisir les critères de capture à volonté mais il faut prendre garde aux performances : beaucoup de paquets peuvent arriver en très peu de temps.

En langage C, libpcap, maintenue par les responsables de tcpdump, est une solution très répandue, très bien documentée, et qui marche bien. Écrire un programme de capture est assez simple.

Voici un exemple du squelette d'un tel programme (montrant la capture mais pas l'écriture sur disque), sniff-only.c. Il se compile, par exemple, avec :

% gcc -Wall -o sniff -lpcap sniff-only.c

Un bon article d'introduction à la libpcap, et à la définition de filtres de capture est Programming with Libpcap - Sniffing the network from our own application.

Pour la programmation en C, une alternative à pcap est ncap, que je n'ai pas testé. Il semble que son format de stockage soit incompatible avec pcap.

Il existe d'autres programmes de capture que je n'ai pas testés :

  • Grok
  • dumpcap qui, comme tshark, fait partie de Wireshark.

L'article seul

Recherche en plein texte avec PostgreSQL

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


Traditionnellement, les SGBD ne traitaient que des données simples et courtes, comme le nom d'un employé ou son salaire. Les recherches portaient donc sur la totalité du champ. Désormais, il est de plus en plus fréquent de voir un SGBD utilisé pour stocker des textes relativement longs (des articles d'un blog, par exemple) et la recherche dans ces textes devient très longue et peu pratique. Elle nécessite l'indexation et des outils de recherche spécialisés. Qu'en est-il sur PostgreSQL ?

Pendant longtemps, le moteur de recherche plein texte de PostgreSQL était tsearch2. Distribué dans le répertoire contrib/ de PostgreSQL, il devait être installé séparément (ou via un paquetage du système d'exploitation considéré, par exemple databases/postgresql82-tsearch2 sur NetBSD). Désormais, depuis la version 8.3, il est intégré complètement à PostgreSQL, et pourvu d'une excellente documentation, très détaillée.

Le principe est de couper le texte en élements lexicaux, puis en lexèmes, qui sont des versions normalisées des éléments lexicaux. Cela se fait avec la fonction to_tsvector :

essais=> SELECT to_tsvector('les gros chats mangent les rats maigres');
                       to_tsvector                        
----------------------------------------------------------
 'le':1,5 'rat':6 'chat':3 'gros':2 'maigr':7 'mangent':4
(1 row)

Ici, elle a analysé la phrase, trouvé six mots (dont un répété) et réduit (normalisé) ceux qu'elles pouvaient. Ce processus dépend de la langue et donne parfois des résultats surprenants (« mangent » n'a pas été normalisé en « manger »).

On cherche ensuite dans ces éléments lexicaux avec la fonction de correspondance, @@. Elle prend comme paramètres un vecteur (tsvector) comme celui ci-dessus et une requête, créée avec to_tsquery :

essais=> SELECT to_tsquery('chat|rat');
   to_tsquery   
----------------
 'chat' | 'rat'
(1 row)

Le langage des requêtes (vous avez sans doute déjà deviné que | veut dire OU) est évidemment documenté.

En combinant requête, vecteur de mots et opérateur de correspondance, on peut faire une recherche complète :

essais=> SELECT to_tsvector('les gros chats mangent les rats maigres')
                        @@ to_tsquery('chat|rat');
 ?column? 
----------
 t
(1 row)

essais=> SELECT to_tsvector('on ne parle pas de ces animaux ici') 
                        @@ to_tsquery('chat|rat');
 ?column? 
----------
 f
(1 row)

On a trouvé un résultat dans le premier cas et zéro dans le second.

Bien sûr, taper de telles requêtes à la main est plutôt pénible, on a donc intérêt à créer ses propres fonctions.

L'analyse d'une phrase en mots et la normalisation de ces derniers dépend de la langue. Il y a un paramètre à to_tsvector et to_tsquery qui indique une configuration ('french' par défaut, sur mon site). Voyons quelles configurations a une installation typique de PostgreSQL 8.3 (ici, le paquetage Debian) :

essais=> \dF
               List of text search configurations
   Schema   |    Name    |              Description              
------------+------------+---------------------------------------
...
 pg_catalog | finnish    | configuration for finnish language
 pg_catalog | french     | configuration for french language
 pg_catalog | german     | configuration for german language
...

essais=> show default_text_search_config;
 default_text_search_config 
----------------------------
 pg_catalog.french
(1 row)

Prenons maintenant un exemple réel, un moteur de recherche dans la liste des RFC. On commence par créer la base :

-- Un RFC a un numéro, un titre et le corps, du texte brut
CREATE TABLE Rfcs (id SERIAL,
   inserted TIMESTAMP default now(),
   num INTEGER,
   title TEXT,
   body TEXT);

-- Créer son propre type facilite l'utilisation de la fonction search()
CREATE TYPE Results AS (num INTEGER, title TEXT, 
                        body TEXT, rank REAL);

-- Les RFC sont en anglais donc on utilise systématiquement la
-- configuration 'english'
CREATE FUNCTION search (TEXT) RETURNS SETOF Results AS
   'SELECT num, title, 
           body, ts_rank_cd(to_tsvector(''english'', title || body), 
                            to_tsquery(''english'',$1)) 
      FROM Rfcs	
         WHERE to_tsvector(''english'', title || body) @@ to_tsquery(''english'',$1) 
         ORDER BY ts_rank_cd(to_tsvector(''english'', title || body), 
                             to_tsquery(''english'',$1)) DESC;' 
  LANGUAGE SQL;

La fonction search() appelle une fonction ts_rank_cd qui calcule la pertinence d'un texte par rapport à une requête. Il faut aussi remarquer la concaténation des champs (title || body) qui indique qu'on cherche dans les deux colonnes. Testons search() :

essais=> SELECT num,title,rank FROM search('dnssec') ORDER BY rank DESC;
 num  |                         title                      | rank 
------+----------------------------------------------------+------
 4035 | Protocol Modifications for the DNS Security ...    | 10.1
 3130 | Notes from the State-Of-The-Technology: DNSSEC     |  7.4
 4641 | DNSSEC Operational Practices                       |  7.1
...

La recherche peut être plus compliquée, par exemple si on cherche les RFC qui parlent de DNSSEC et LDAP (notons que les pertinences sont bien plus faibles) :

essais=> SELECT num,title,rank FROM search('dnssec & ldap') ORDER BY rank DESC;
 num  |                     title                     |    rank     
------+-----------------------------------------------+-------------
 5000 | Internet Official Protocol Standards          |    0.111842
 4238 | Voice Message Routing Service                 |    0.0170405
 4513 | LDAP: Authentication Methods and Security ... |    0.00547112
...

Chercher dans la totalité de la base à chaque fois peut être assez long. Les moteurs de recherche emploient typiquement l'indexation pour accélerer la recherche. PostgreSQL dispose de plusieurs types d'index. Pour favoriser le temps de recherche (au détriment du temps d'indexation), j'utilise les index GIN :

CREATE INDEX rfcs_idx ON Rfcs USING gin(to_tsvector('english', title || body));

Avec ces index, les recherches sont bien plus rapides. En effet, sans index, il faut balayer toute la table comme l'indique EXPLAIN :

essais=> EXPLAIN SELECT id,num FROM Rfcs   WHERE to_tsvector('english', title || body)  @@ to_tsquery('dnssec');
                                    QUERY PLAN                                     
-----------------------------------------------------------------------------------
 Seq Scan on rfcs  (cost=0.00..186.11 rows=5 width=8)
   Filter: (to_tsvector('english'::regconfig, body) @@ to_tsquery('dnssec'::text))
(2 rows)

(Seq Scan est sequential scan.) Avec l'index, la recherche se fait d'abord dans l'index :

essais=> EXPLAIN SELECT id,num FROM Rfcs   WHERE to_tsvector('english', title || body)  @@ to_tsquery('dnssec');
                                         QUERY PLAN                                          
---------------------------------------------------------------------------------------------
 Bitmap Heap Scan on rfcs  (cost=40.70..57.34 rows=5 width=8)
   Recheck Cond: (to_tsvector('english'::regconfig, body) @@ to_tsquery('dnssec'::text))
   ->  Bitmap Index Scan on rfcs_idx  (cost=0.00..40.70 rows=5 width=0)
         Index Cond: (to_tsvector('english'::regconfig, body) @@ to_tsquery('dnssec'::text))
(4 rows)

Le programme qui prend l'ensemble des RFC et les met dans la base est index-rfcs.py. Un autre exemple pratique est le moteur de recherche de mon blog, documenté dans « Mise en œuvre du moteur de recherche de ce blog.

Sur le même sujet et dans la même langue, on peut lire le très détaillé « Recherche plein texte avec PostgreSQL 8.3 ».


L'article seul

RFC 5398: AS Number Reservation for Documentation Use

Date de publication du RFC : Décembre 2008
Auteur(s) du RFC : G. Huston
Pour information
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 11 décembre 2008


De même qu'il existe des adresses IP et des noms de domaine réservés à la documentation, les numéros d'AS de 64496 à 64511 et de 65536 à 65551 sont désormais réservés pour les auteurs des documentations sur le routage.

Écrire un cours sur le routage (comme mon cours BGP) nécessite de choisir les numéros d'AS qui apparaitront. Prendre des numéros existants est risqués car il y aura toujours un distrait pour copier-coller les configurations de routeurs qu'il a lu dans le cours, créant ainsi des problèmes avec l'AS qui a ce numéro.

Le même problème existe pour les adresses IP (d'où la réservation de 192.0.2.0/24, 198.51.100.0/24 et 203.0.113.0/24, dans le RFC 5737 ou de 2001:DB8::/32 dans le RFC 3849) ou pour les noms de domaine (pour lesquels .example a été réservé par le RFC 2606).

Comme le rappelle la section 1, même les numéros privés (pour les AS, de 64512 à 65534) ne conviennent pas puisqu'ils sont utilisés en production dans certains réseaux. C'est donc logiquement que notre RFC réserve deux plages de seize numéros d'AS pour la documentation : de 64496 à 64511 pour les AS sur deux octets et de 65536 à 65551 pour les AS sur quatre octets (ces derniers ayant été introduits par le RFC 4893, depuis remplacé par le RFC 6793).


Téléchargez le RFC 5398


L'article seul

RFC 5388: Information Model and XML Data Model for Traceroute Measurements

Date de publication du RFC : Décembre 2008
Auteur(s) du RFC : S. Niccolini (NEC), S. Tartarelli (NEC), J. Quittek (NEC), T. Dietz (NEC), M. Swany (UDel)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 11 décembre 2008


Le programme traceroute est un des piliers de l'Internet. Cet outil de déboguage a servi à des dizaines de milliers d'administrateurs réseaux, lors de difficiles sessions de recherche de panne ou de divers problèmes. Né de la nécessité, il n'a jamais eu de modèle de données formel, ni de norme de présentation des résultats. C'est désormais fait avec ce nouveau document.

Cette normalisation permet notamment de stocker les résultats d'un traceroute et de les comparer de manière automatique à un autre (il existe déjà de tels programmes de comparaison, par exemple sous forme d'un moniteur pour le logiciel de surveillance réseau mon, mais tous ne comparent que la sortie texte de traceroute et peuvent donc être perturbés par des changements purement de présentation). La section 1 détaille ce cahier des charges.

La section 3 rappelle le principe de fonctionnement de traceroute : envoyer des paquets UDP (certaines versions peuvent utiliser TCP ou ICMP ; l'annexe A contient une très intéressante description des différentes versions de traceroute) à une machine distante, en mettant délibérement des valeurs trop basses au TTL (ou Hop Count) des paquets IP. Les routeurs qui, après la décrémentation de ce champ, trouveront zéro, signaleront leur existence en envoyant un paquet ICMP TIME_EXCEEDED (RFC 792).

La section 4 liste ensuite les résultats qu'on obtient avec traceroute. Selon la version de ce dernier, on peut trouver :

Enfin, la section 5 définit le modèle de données utilisé pour créer le fichier XML de résultats. 5.1 contient les types de données. Certains sont tirés des schémas du W3C comme Boolean ou DateTime, d'autres tirés d'autres RFC (par exemple le RFC 4001 pour InetAddress, les adresses IP), d'autres enfin définis ici. La section 5.2 donne la liste de tous les élements XML utilisés comme ProbeRoundTripTime (section 5.2.3.8) qui contient le RTT en millisecondes. On peut donc écrire :


<ProbeRoundTripTime>
   <roundTripTime>13</roundTripTime>
</ProbeRoundTripTime>

Cet élement ProbeRoundTripTime peut, alternativement, contenir un élément roundTripTimeNotAvailable.

La section 6 explique le choix de XML, notamment parce que les fichiers XML sont lisibles par un humain et parce qu'il existe un grand nombre d'outils existants. Cette section explique aussi pourquoi des modèles de données proches comme la MIB du RFC 4560 (également discutée en annexe C) ou l'encodage d'IPFIX dans le RFC 7011 n'ont pas été utilisés.

Enfin, une longue section 7 contient le schéma lui-même, défini avec le langage W3C Schema. L'élément ProbeRoundTripTime cité plus haut est ainsi défini comme le choix entre un entier ou la valeur roundTripTimeNotAvailable :


    <xs:element name="ProbeRoundTripTime"
                                 type="_roundTripTime">
    </xs:element>

    <xs:complexType name="_roundTripTime">
       <xs:choice>
  
       <xs:element name="roundTripTime">
           <xs:simpleType>
             <xs:restriction base="xs:unsignedInt"/>
           </xs:simpleType>
         </xs:element>

         <xs:element name="roundTripTimeNotAvailable">
           <xs:complexType/>
         </xs:element>

       </xs:choice>
     </xs:complexType>

Je ne connais pas encore d'implémentation « officielle » de traceroute qui produise ces fichiers XML. Si vous en écrivez une, attention aux caractères spéciaux (speciaux pour XML comme & ou <) dans les noms de machines : rien ne vous garantit qu'une requête DNS inverse ne va pas vous renvoyer des noms avec de tels caractères. Comme toujours quand un programme produit du XML, il ne doit pas se contenter de mettre des <balise> un peu partout, il doit aussi veiller à ces caractères spéciaux.

Il existe à ma connaissance une mise en œuvre expérimentale de traceroute qui produit du XML à ce format (dérivée du traceroute de NANOG). Elle est assez sommaire mais elle marche. traceroute-nanog-xml.c.

Il nécessite libxml2. Pour le compiler, sur GNU/Linux :

cc -DXML -lresolv  $(xml2-config --cflags) $(xml2-config --libs) \
             traceroute-nanog-xml.c -o traceroute-nanog-xml

Sur FreeBSD, même chose sans le -lresolv. Ensuite, on ne lance avec l'option -X pour produire du XML.

Une fois produits, les fichiers XML peuvent être vérifiés, par exemple avec xmllint :

% xmllint --noout --schema traceroute.xsd traceroute.xml
traceroute.xml validates

Voici des exemples de résultats stockés dans ce format, un exemple pris dans le RFC (annexe D) et un autre exemple, produit par mon programme.


Téléchargez le RFC 5388


L'article seul

RFC 5396: Textual Representation of AS Numbers

Date de publication du RFC : Décembre 2008
Auteur(s) du RFC : G. Huston (APNIC, G. Michaelson (APNIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 10 décembre 2008


Après de très longs débats, ce RFC normalise enfin un format pour représenter les numéros de systèmes autonomes de 32 bits. Ils seront affichés dans la notation ASPLAIN, c'est-à-dire sans séparateur interne, par exemple 101234.

Depuis que le RFC 4893, en mai 2007, avait normalisé les numéros de systèmes autonomes sur quatre octets (donc potentiellement supérieurs à 65536), le débat faisait rage, dans la communauté des opérateurs Internet, sur la meilleure représentation textuelle à leur donner. Deux solutions s'affrontaient pour écrire le numéro 101234 : celle qui l'a emportée, nommée ASPLAIN, où le numéro était écrit sans séparateur interne, et une première solution, ASDOT, où on écrivait le numéro en deux parties séparées par un point, ici 1.35698 (1 * 65536 + 35698). La méthode ASPLAIN convenait mieux aux programmes, ASDOT était préféré par les humains.

Il y avait aussi une méthode ASDOT+ où même les numéros inférieurs à 65536 étaient écrits en deux parties, 20768 se notant 0.20768. ASDOT avait semblé avoir le vent en poupe d'abord, mais avait échoué devant l'IESG.

La crainte des adversaires d'ASDOT était que beaucoup de programmes écrits pour gérer les routeurs (car un gros opérateurs ayant des centaines de Juniper ou de Cisco n'édite évidemment pas les centaines de configurations depuis une interface Web, il a un programme pour cela), des gros scripts Perl ou équivalent, n'aient pas été prévus pour des points au milieu d'un numéro d'AS... Pour prendre un exemple cité par Philip Smith :

Well, here is a regexp from a router I have with IOS-XR, just to show how the . notation impacts regexp work:

as-path-set 4byte-asn
   ios-regex '_2\.0_.*_[0-9]+\.[0-9]+_',
   ios-regex '_5\.1_',
end-set

This basically says:

  • "from AS2.0 accept prefixes with 32-bit ASNs in the AS path"
  • "from AS5.1 accept just prefixes originated by AS5.1"

I'm sure some ISPs around here must have similar 16-bit ASN regexps in use at the moment. To handle 32-bit ASNs, they'll need to convert all these to escape the "." as I did above...

Voir aussi http://www.swissix.ch/asn32/doku.php pour d'autres débats sur la question.

Notre RFC 5396 tranche donc en faveur d'ASPLAIN. C'est ce format qui sera utilisé dans la configuration des routeurs, dans les discussions sur les listes de diffusion d'opérateurs comme NANOG, ou dans les IRR par exemple au RIPE-NCC (qui avait failli développer sa propre politique, vue la difficulté de l'IETF à décider). Comme le note la section 3 du RFC, cette notation a l'avantage de refléter l'absence de structure interne du routage BGP (la notation ASDOT pouvait faire croire à une hiérarchie).


Téléchargez le RFC 5396


L'article seul

Thunderbird et la cryptographie, des options pas toujours évidentes

Première rédaction de cet article le 6 décembre 2008


Le MUA Thunderbird permet d'utiliser la cryptographie pour protéger le relevé ou l'envoi du courrier. Mais trouver la bonne option n'est pas facile !

Une fois des serveurs de messagerie configurés pour utiliser le protocole de cryptographie TLS (pour Postfix, voir « Configurer Postfix avec TLS »), il reste à configurer les clients.

Thunderbird est un des plus utilisés. Logiciel libre, à interface graphique, il dispose de nombreuses fonctions, notamment de filtrage des spams par algorithme bayésien. Il dispose également du protocole TLS. Mais il n'est pas évident de choisir l'option à activer, notamment en raison d'un nommage bizarre des protocoles.

Sans Secure connections - Thunderbird, je ne serai jamais arrivé à le configurer en mode « 100 % crypto » (pour IMAP et SMTP). Cela relativise l'argument comme quoi les interfaces graphiques sont forcément simples. Le problème est qu'il est trivial de trouver quoi faire pour activer "TLS" (on clique sur un bouton) mais moins évident de savoir s'il faut choisir "TLS", "TLS, if available" ou "SSL". SSL et TLS sont pourtant la même chose (SSL est l'ancien nom du protocole qui est devenu TLS et est aujourd'hui normalisé dans le RFC 5246).

Les options "TLS" et "TLS, if available" font presque la même chose, et qui est en fait du STARTTLS (commencer en clair puis basculer en chiffré s'il est disponible). La seule différence est que "TLS" tout court impose que STARTTLS soit possible et coupe la communication si cette sécurité n'est pas posisble.

C'est l'option "SSL", très mal nommée, qui permet de faire du TLS directement (sans STARTTLS).

Donc, en SMTP : il faut configurer "TLS" (qui veut dire en fait STARTTLS) et le port 587, le port de soumission du courrier (RFC 6409).

En IMAP, avec la configuration par défaut du serveur IMAP Courier (deux ports, un pour le clair et un pour le chiffré), il faut "SSL" et ne pas cocher "secure authentication" (qui désigne un défi/réponse, mais c'est déjà assez sûr avec TLS) et il faut un certificat correct, le certificat auto-signé généré par Courier par défaut ne marche pas (mais le certificat de ma CA privée fonctionne).

(Courier peut aussi être configuré pour faire du STARTTLS dans IMAP.)

Merci à Erwan David pour ses explications.


L'article seul

Ne jamais avoir de listes noires statiques

Première rédaction de cet article le 6 décembre 2008


Quand on arrive dans un nouvel emploi d'ingénieur système & réseaux, ou bien lorsqu'on fait un petit audit d'un site existant, on tombe souvent sur des listes noires, en général d'adresses IP refusées. Ces listes ont typiquement été créées suite à un incident de sécurité et, malheureusement, sont souvent statiques, c'est-à-dire jamais mises à jour. En général, la date où a été créée une entrée donnée n'est jamais indiquée. Au bout d'un certain temps, ces listes deviennent donc plus dangereuses qu'utiles.

Il ne faut jamais utiliser une telle liste sans avoir une procédure (de préférence automatique, et surveillée, pas un cron que tout le monde a oublié) de mise à jour. Autrement, c'est votre successeur, dans deux ans, qui tombera sur le problème.

Ainsi, l'excellent site Cymru fournit tout ce qu'il faut pour cela. Leurs listes noires de bogons, par exemple, peuvent être automatiquement mises à jour via BGP, le DNS, etc.

Comme, malgré de tels services, la plupart des listes de bogons sont laissées à elles-mêmes, jamais mises à jour, le malheureux qui récupère des adresses dans un préfixe qui vient d'être alloué va souffrir. Certains ont même menacé l'ARIN ou d'autres RIR de procès, pour leur avoir « vendu » des adresses IP inutilisables.

Idem pour les listes noires liées au spam ou d'autres problèmes de sécurité. Si une adresse IP a une fois servi à spammer, elle est gâtée pour toujours. Cela a même mené à une proposition d'évaluation de la valeur des adresses IP selon leur historique.

Certaines de ces listes statiques sont parfois redistribuées et des ignorants les utilisent sans connaitre leurs limites.

Faites le test dans votre organisation : pour chaque liste de bogons, pour chaque liste noire, ou équivalent, existe t-il une procédure documentée de mise à jour ? Si non, supprimez cette liste d'urgence.

Le message attaché est un exemple ultra-classique des problèmes des listes de bogons pas à jour, tels qu'ils sont vus par les opérateurs. De tels messages sont très fréquents (ici, sur la liste SANOG, le groupe des opérateurs réseau d'Asie du Sud) et dureront tant que les gens continueront à utiliser ces listes noires statiques.

Date: Sat, 15 Sep 2007 05:13:48 -0400 (EDT)
From: Sri <jaadhoo@yahoo.com>
Subject: [SANOG] 99/8 IP Block (was Bogons)
To: sanog@sanog.org

Hello all,
I am Sri from Rogers Cable Inc. ISP in Canada. We have IP block
99.x.x.x assigned to our customers. Which happened to be bogons block
in the past and was given to ARIN in Oct 2006. As we have recently
started using this block, we are getting complaints from our customers
who are unable to surf some web sites. After investigation we found
that there are still some prefix lists/acls blocks this IP block.

We got the following blocks:

99.224.0.0/12
99.240.0.0/13
99.248.0.0/14
99.252.0.0/16
99.253.128.0/19

  Here are the few pingable ips 99.246.224.1 & 99.244.192.1
  
Please update your bogons list.

If anyone has any questions, or I can provide any additional
information which anyone may require, please feel free to email me
directly or call our TAC @ 416.935.5700.

Thanks in advance for your support,

Sri


-- 
This is the SANOG (http://www.sanog.org/) mailing list.

L'article seul

Authentifier des serveurs Internet avec X.509 lorsqu'ils ont la même adresse IP

Première rédaction de cet article le 4 décembre 2008
Dernière mise à jour le 16 décembre 2008


On lit souvent qu'il n'est pas possible d'avoir plusieurs serveurs Internet sur la même adresse IP lorsqu'ils sont authentifiés par un certificat X.509. Il faudrait donc donner une adresse IP à chacun. Cette affirmation a des origines réalistes mais est sans doute trop stricte aujourd'hui.

Dans un protocole comme HTTPS, le nom du serveur est transmis une fois la session TLS établie. Il est donc a priori trop tard à ce moment pour choisir un autre certificat. D'où le mème « Un seul certificat par adresse IP ». (Un bon résumé du problème figure dans Name-based SSL virtual hosts: how to tackle the problem.) En fait, il est possible d'avoir une seule adresse IP et néanmoins un certificat différent par Virtual Host Apache, même si les méthodes existantes ont quelques limites.

Il existe trois méthodes pour HTTPS (toutes ne sont pas forcément applicables aux autres protocoles) :

  • La commande HTTP STARTTLS (RFC 2817) qui permet de transmettre le nom du serveur avant la négociation TLS.
  • L'extension X.509 Subject Alternative Name (RFC 5280) qui permet de mettre plusieurs noms dans un certificat. Le client sera alors content si un des noms correspond.
  • L'extension TLS Server Name Indication (SNI) (RFC 6066) qui permet au client d'indiquer le nom du serveur dans la négociation TLS.

Chacune a ses forces et ses faiblesses et des domaines où elle est meilleure que les autres.

La première, STARTTLS, normalisée dans le RFC 2817, est bien décrite par Pierre Beyssac dans « HTTP et TLS, la RFC méconnue... ». Très répandue avec des protocoles comme IMAP ou SMTP, elle a un gros inconvénient pour HTTP : il n'est pas possible d'indiquer dans l'URL que TLS est obligatoire. Un attaquant sur le chemin, ou bien un serveur mal configuré, et on retombe sur du HTTP non protégé.

Mise en œuvre dans Apache depuis la version 2.2, elle n'est présent dans aucun grand navigateur, pour les raisons expliquées par Mozilla dans la bogue #276813.

Une deuxième méthode est le certificat contenant plusieurs noms. Elle est possible grâce à l'extension X.509 Subject Alternative Name, normalisée dans le RFC 2459. Elle est décrite en détail dans mon article « Plusieurs noms dans un certificat X.509 » ou bien dans celui de Franck Davy, « Apache : Hôtes virtuels et SSL (mod_ssl) ». En anglais, on peut lire « Information about setting up the ApacheServer to serve multiple HTTPS sites using one IP address ».

Elle fonctionne avec openssl (aussi bien pour générer le certificat que pour le vérifier) mais il faut que la CA qui signe l'accepte et j'ignore si les grosses CA ayant pignon sur rue le font ou pas. C'est la méthode qui semble la plus déployée et donc celle qui apporte le moins de surprises (CAcert a fait des tests détaillés d'interopérabilité sur les variantes de cette méthode).

La troisième méthode repose sur une extension du protocole TLS et non pas du format X.509. Cette extension, Server Name Indication (SNI), est l'une de celles décrites dans le RFC 6066. Elle envoie le nom du serveur lors de la négociation TLS. Elle est bien expliquée dans l'article de Pierre Beyssac « Adieu RFC 2817, bonjour RFC 3546 ».

SNI (Server Name Indication) ne marche pas avec le module Apache mod_ssl, il faut utiliser mod_gnutls. Il y a un certificat par Virtual Host et elle ne gère donc pas le cas où un Virtual Host a plusieurs noms, avec la directive ServerAlias.

Les serveurs HTTP gérés par le département de recherche & développement de l'AFNIC sont un exemple de déploiement de deux de ces techniques. Le serveur, un Apache, utilise mod_gnutls, avec un certificat par Virtual Host, et peut donc tirer profit de la troisième méthode, SNI. Au cas où le client ne gère pas l'extension SNI, le certificat par défaut (celui qui est utilisé dans la directive <VirtualHost _default_:443>) est un certificat avec plusieurs noms.

Voici un test d'un de ces serveurs avec un logiciel en ligne de commande livré avec GnuTLS (bien entendu, TLS étant une norme - RFC 5246 -, on aurait aussi bien pu tester avec openssl) :

% gnutls-cli -p 443 --x509cafile /etc/ssl/certs/AFNIC-ReD-CA.pem \
       svn.langtag.net                           
Processed 1 CA certificate(s).
Resolving 'svn.langtag.net'...
Connecting to '2001:660:3003:3::1:4:443'...
- Certificate type: X.509
 - Got a certificate list of 1 certificates.

 - Certificate[0] info:
 # The hostname in the certificate matches 'svn.langtag.net'.
 # valid since: Thu Dec  4 10:21:30 CET 2008
 # expires at: Wed Aug 31 11:21:30 CEST 2011
 # fingerprint: F5:78:88:D7:EF:CA:38:92:F3:40:B9:67:D4:B6:48:E6
 # Subject's DN: C=FR,ST=Ile-de-France,L=Saint-Quentin-en-Yvelines,O=AFNIC,OU=R&D,CN=www.generic-nic.net,EMAIL=webmaster@generic-nic.net
 # Issuer's DN: C=FR,ST=Ile-de-France,L=Saint-Quentin-en-Yvelines,O=AFNIC,OU=ReD,CN=AFNIC Research and Development,EMAIL=pki@generic-nic.net


- Peer's certificate is trusted
...

Voilà, tout va bien. Si on est inquiet, on peut vérifier l'empreinte du certificat (ici F5:78:88:D7:EF:CA:38:92:F3:40:B9:67:D4:B6:48:E6). Attention, gnutls-cli affiche l'empreinte MD5 alors que, par défaut, openssl x509 -fingerprint montre l'empreinte SHA-1. Il faut donc, pour regarder le certificat, taper openssl x509 -fingerprint -md5 -in /ou/est/le/certificat.pem.

Vishaal Golam me signale qu'il existe une quatrième méthode, avec des restrictions. Mettre un joker dans le certificat, par exemple *.example.net. Ainsi, tout logiciel client qui accepte les jokers (c'est la grande majorité mais attention, avec des sémantiques différentes car ce point n'est pas vraiment normalisé, cf. RFC 2818, section 3.1) acceptera ce certificat pour www.example.net, svn.example.net, etc. Il faut juste que la CA, l'autorité de certification, accepte ces jokers, qui diminuent ses revenus (je ne sais pas quels CA les acceptent mais, par exemple, Thawte le fait). Et la méthode ne marche que pour des noms qui ont un domaine en commun (ici example.net).

Merci à Pierre Beyssac, Mario Victor-Oscar, Yves Rutschle, Kim-Minh Kaplan et Benoit Deuffic pour des informations stimulantes et utiles.


L'article seul

RFC 5375: IPv6 Unicast Address Assignment Considerations

Date de publication du RFC : Décembre 2008
Auteur(s) du RFC : G. Van de Velde, C. Popoviciu (Cisco), T. Chown (University of Southampton), O. Bonness, C. Hahn (T-Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 4 décembre 2008


Voici un RFC qui s'adresse à l'administrateur système plutôt qu'au développeur. Il s'agit d'expliquer deux ou trois choses sur l'affectation des adresses IPv6 aux machines du réseau local, afin d'aider à la création d'un plan d'adressage.

Les principes de base de l'adressage IP sont décrits dans le RFC 4291. Une adresse est composée de deux parties, celle qui identifie le réseau et celle qui identifie l'interface de la machine, l'interface ID.

La section 1 du RFC rappelle les principales différences avec IPv4 :

  • Il est plus courant d'avoir plusieurs adresses par machine,
  • La taille de l'espace d'adressage fait qu'il n'est typiquement pas nécessaire de faire des économies.

La section 2 s'attaque ensuite à l'adressage de la partie réseau (le préfixe), que ce soit pour les adresses uniques mondialement (section 2.1) ou bien pour les adresses de site du RFC 4193 (section 2.2). Le gros morceau est en 2.4, qui détaille les bénéfices qu'on peut tirer du vaste espace d'adressage IPv6. Des schémas d'adressage « créatifs », par exemple où le préfixe est dérivé du numéro du VLAN sont désormais possibles. La croissance future du réseau peut être permise en laissant des trous dans l'allocation comme l'explique un excellent document, le RFC 3531.

La taille des préfixes est à étudier : le RFC 3177 posait comme principe l'affectation d'un /48 à chaque site, quel que soit sa taille, notamment pour éviter les problèmes en cas de rénumérotation. Mais la section 2.4.2 parle des problèmes d'économie d'adresses v6 (cf. RFC 3194). Et le RFC 6177 ne fait plus de recommandation unique.

La section 3 est dédiée à la question de la taille du préfixe d'un lien donné. Contrairement à IPv4 où on dispose d'une liberté complète, IPv6 suppose un préfixe de lien de /64 (RFC 4291, section 2.5.4). Choisir une autre valeur est théoriquement possible, mais casserait plusieurs protocoles importants comme SEND ou comme les adresses temporaires du RFC 4941. Pire, cela pourrait limiter le déploiement de futurs protocoles qui auraient eux-aussi besoin de 64 bits pour les adresses des machines. (Voir aussi l'annexe B.1 et B.2 ; on y trouve une exception pour les liens point-à-point entre deux routeurs, où un /126 est acceptable, mais pas un /127.)

Ensuite, les adresses des machines sur le lien peuvent être attribuées par plusieurs méthodes (section 4) :

  • Auto-configuration sans état (RFC 4862), section 4.1
  • Adresses anti-traçage du RFC 4941, section 4.2
  • Adresses attribuées manuellement, section 4.3. Dans ce cas, il faut veuiller à ce que les adresses n'entrent pas en conflit avec des adresses bien connues, comme par exemple l'adresse « tout à zéro » qui identifie normalement les routeurs du lien (annexe B.2.5.1). Il faut également veiller à ce que le bit 'u' de l'adresse, le 71ème bit, soit à 0 et le bit 'g', le 72ème, également. En pratique, à l'heure actuelle, se tromper sur ces deux bits n'a pas de conséquences mais cela pourrait en avoir dans le futur (cf. annexe B.2.4). Donc, 2001:DB8:CAFE:1::1 est correct (les deux bits sont à zéro) mais pas 2001:DB8:CAFE:1:0200::1 (le bit 'u' est à un, dans le groupe 0200).

Deux études de cas concrètes, en annexe A, rendent ce RFC un peu plus facile à lire.


Téléchargez le RFC 5375


L'article seul

RFC 3982: IRIS: A Domain Registry (dreg) Type for the Internet Registry Information Service (IRIS)

Date de publication du RFC : Janvier 2005
Auteur(s) du RFC : A. Newton (Verisign), M. Sanz (DENIC)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF crisp
Première rédaction de cet article le 3 décembre 2008


Le protocole IRIS d'accès aux informations dites « sociales » qui sont stockées dans un registre, par exemple un registre d'adresses IP, est défini indépendemment du schéma des données stockées. Il faut donc le compléter, pour chaque registre, par un schéma indiquant comment sont structurées les données. Notre RFC le fait pour les registres de noms de domaine.

Comme tous les schémas IRIS, ce document utilise le langage W3C Schema pour spécifier les éléments XML qui peuvent être présents dans les requêtes au serveur IRIS et dans ses réponses. Le schéma a reçu le nom de DREG (Domain Registry). La section 3 liste en langue naturelle les éléments possibles de DREG, la section 4 contenant le schéma formel.

Par exemple, l'élément <findDomainsByName> (section 3.1.3) permet des interogations analogues à celles de whois en interrogeant le registre sur les données liées à un domaine dont on connait le nom.

Mais il contient aussi des requêtes qui ne sont pas possibles avec tous les serveurs whois comme <findDomainsByContact> (section 3.1.2) qui permet de retrouver tous les domaines d'une personne ou d'une organisation donnée (très intrusive, cette requête ne sera probablement jamais disponible publiquement).

Et les réponses ? La section 3.2.2 décrit la forme d'un élément <domain>. Cet élément contient les informations associées à un domaine comme ses serveurs de noms, sa date de création ou son état (status). Les états possibles sont énumérés, on y trouve, par exemple, reservedDelegation (réservé mais pas publié dans le DNS, un état qui n'existe pas aujourd'hui dans .fr mais qui peut être présent dans d'autres TLD).

Il faut noter que la liste des états possibles n'est pas la même qu'avec EPP (RFC 4931), cela serait trop simple...

D'autres types d'objet peuvent être stockés par le registre et interrogés via IRIS, comme les contacts (les personnes ou organisations responsables d'un domaine), traités en section 3.2.4.

Ce schéma DREG ne semble pas encore utilisé dans aucun serveur IRIS publiquement accessible.

Emprunté à l'annexe A du RFC, voici un exemple de requête IRIS/DREG :


<?xml version="1.0"?>
<request xmlns="urn:ietf:params:xml:ns:iris1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <searchSet>
    <lookupEntity
      registryType="urn:ietf:params:xml:ns:dreg1"
      entityClass="domain-name"
      entityName="example.com" />
  </searchSet>
</request>

et la réponse possible d'un serveur IRIS :


<?xml version="1.0"?>
<iris:response xmlns:iris="urn:ietf:params:xml:ns:iris1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <iris:resultSet>
    <iris:answer>
      <domain xmlns="urn:ietf:params:xml:ns:dreg1"
        authority="iana.org" registryType="dreg1"
        entityClass="domain-handle" entityName="example-com-1">

        <domainName>example.com</domainName>
        <domainHandle>tcs-com-1</domainHandle>

        <nameServer iris:referentType="host" authority="iana.org"
          registryType="dreg1" entityClass="host-handle"
          entityName="research7" />
        <nameServer iris:referentType="host" authority="iana.org"
          registryType="dreg1" entityClass="host-handle"
          entityName="nsol184" />

        <technicalContact iris:referentType="contact"
          authority="iana.org" registryType="dreg1"
          entityClass="contact-handle" entityName="dbarton" />

        <status>
          <assignedAndActive denied="true" />
        </status>

        <registry iris:referentType="registrationAuthority"
          authority="com" registryType="dreg1"
          entityClass="contact-handle" entityName="VGRS" />
        <initialDelegationDateTime xsi:nil="true"/>
        <iris:seeAlso iris:referentType="ANY" authority="iana.org"
          registryType="dreg1" entityClass="local"
          entityName="notice"  />
      </domain>
    </iris:answer>
  </iris:resultSet>
</iris:response>


Téléchargez le RFC 3982


L'article seul

RFC 2026: The Internet Standards Process -- Revision 3

Date de publication du RFC : Octobre 1996
Auteur(s) du RFC : Scott O. Bradner (Harvard University)
Première rédaction de cet article le 1 décembre 2008


Comment sont développées les normes Internet ? Qui les décide ? Comment les changer ? Ce RFC repond à toutes ces questions, en décrivant le processus de normalisation dans l'Internet. Bien sûr, comme pour beaucoup de processus sociaux, la réalité est parfois très éloignée de la description...

La plupart des normes techniques qui régissent l'Internet sont écrites dans des RFC (l'inverse n'est pas vrai : beaucoup de RFC ne sont pas des normes). Ces RFC de normalisation sont développés au sein de l'IETF et on peut trouver une description des activités de l'IETF dans mon exposé IETF à JRES.

Certains RFC ne décrivent pas un protocole ou un format mais des règles à suivre lors du développement des normes et c'est le cas de ce RFC. Son introduction rappelle que toute cette activité se déroule sous la responsabilité de l'ISOC (l'IETF n'est qu'une étiquette, elle n'a pas de personnalité juridique).

La section 1 résume les grands principes : il n'existe pas de « police des normes » (section 1.1) qui ferait respecter les RFC, la conformité à ces normes est volontaire (une norme industrielle n'est pas une loi). Et les normes Internet sont censées représenter une technique qui fonctionne, qui est bien comprise et pour laquelle existent au moins deux mises en œuvre interopérables (contrairement à une légende très répandue, il n'est pas exigé qu'une de ces mises en œuvre soit libre).

Le processus d'élaboration des normes lui-même est résumé en section 1.2. Il est ouvert à tous, est pratiqué par « la communauté » (community, mot fourre-tout dans le discours politique états-unien, qui n'est jamais clairement défini et qui exprime surtout la nostalgie du petit village fermé et regroupé autour de son église) et vise à obtenir un consensus de toutes les parties prenantes. Les procédures de ce RFC doivent être honnêtes, ouvertes et objectives. (Oui, la langue de bois est très présente dans ce RFC.)

Le RFC explique bien la difficulté de la normalisation dans un monde qui évolue aussi vite que celui des réseaux informatiques. La normalisation est forcément lente, à la fois pour des raisons sociales (construire le consensus) et techniques (écrire une norme correcte est un travail difficile), alors que la technique bouge très vite.

La section 2 décrit les documents qui sont produits par le processus de normalisation. Il commence évidemment (section 2.1) par les RFC. Ces textes, bien mal nommés (RFC voulait dire Request For Comments, ce que ne reflète plus leur statut et leur stabilité ; mais le nom est resté) existent depuis très longtemps (le RFC 1 a été publié en avril 1969). Ils sont largement et gratuitement disponibles (pendant longtemps, cela a été une des spécificités de ces normes, et une des raisons du succès de TCP/IP par rapport aux technologies concurrentes). Ils sont publiés par un organisme séparé, le RFC editor. C'est lui qui définit les règles (assez archaïques) de format, le texte brut, obligatoire pour les RFC qui ont le statut de norme.

Car ce n'est pas le cas de tous les RFC. Les normes proprement dites ne sont qu'un sous-ensemble des RFC. Dans l'index, on les reconnait au texte STDnnn qui indique leur numéro dans la série des normes (STanDard ; par exemple, UDP, RFC 768 est STD0006). D'autres RFC n'ont pas ce statut et peuvent être publiés par le RFC editor seul, sans implication de l'IETF. C'est un point important, souligné par le RFC 1796 : Not All RFCs are Standard.

Mais les RFC ne naissent certainement pas tout armés ? Comment évoluent-ils et à partir de quoi ? C'est l'objet de la section 2.2, consacrée aux Internet-Drafts (on dit aussi I-D), les RFC en gestation. Un I-D n'a aucune valeur normative et notre RFC sur les normes rappelle bien qu'il est déconseillé de s'appuyer sur un I-D, par exemple pour un appel d'offres. De même, un vendeur ne devrait pas citer d'I-D dans la liste des fonctions de son produit. En effet, les I-D ne sont pas stables et peuvent changer à tout moment (en outre, même si le RFC 2026 ne le rappelle apparemment pas, n'importe qui peut écrire un I-D et le faire distribuer par l'IETF, il n'y a pas de contrôle).

La section 3 introduit une distinction qui n'a guère été utilisée entre les spécifications techniques (TS pour Technical Specifications) et les consignes d'application (AS pour Applicability Statement), qui expliquent comment appliquer les premières. Même le vocabulaire n'est pas resté et les sigles TS et AS ne semblent plus utilisés à l'IETF.

La section 4 en arrive au chemin des normes (standards track, la route que suivent les RFC vers le nirvana du statut de « norme au sens strict »). À noter que cette partie a été réformée par la suite dans le RFC 6410, qui a réduit le nombre d'étapes à deux. Les détails des anciens trois statuts sont publiés dans la section 4.1. Une fois publiée en RFC, la technique qui a été lancée sur le chemin des normes a le statut de proposition de norme (proposed standard, section 4.1.1). Si tout va bien, lorsqu'elle mûrira, et que deux mises en œuvre distinctes existeront, un nouveau RFC sera publié, avec le statut de projet de norme (draft standard, section 4.1.2). Enfin, après de longs efforts, des tests d'interopérabilité et pas mal d'actions de lobbying, un dernier RFC sera publié, avec le statut de norme au sens propre (Standard ou Internet Standard ou Full Standard, section 4.1.3). C'est par exemple ce qui est arrivé au format ABNF, proposition de norme dans le RFC 2234, projet de norme dans le RFC 4234 et désormais norme complète dans le RFC 5234 (voir la section 6.2 pour des détails, notamment de délais obligatoires). Par contre, si l'expérience montre qu'une technique a des failles et qu'il faut modifier la spécification de manière non triviale, on repart de zéro (section 6.3).

Mais il faut noter que ces trois statuts ne correspondent pas toujours à la réalité. Des techniques très employées sont restées au statut de proposition (par exemple Sieve, RFC 5228), d'autres ont le statut de norme alors qu'elles ne sont plus utilisées (comme chargen du RFC 864). Il faut donc prendre ce classement avec prudence. (Je me souviens d'une réunion où une juriste d'un gros FAI, assez ignorante de tout ce qui concerne la normalisation, avait défendu leur politique de filtrage du courrier en ergotant sur le fait que le RFC 2821 n'était que proposition de norme...) C'est entre autre pour cela que le RFC 6410 a par la suite réduit le nombre de statuts possibles à deux.

Il existe aussi de nombreux RFC qui ne sont pas du tout sur le chemin des normes (section 4.2). C'est le cas des RFC « expérimentaux » (section 4.2.1), statut normalement réservé aux protocoles pas vraiment mûrs et sur lesquels il n'existe pas encore de consensus sur leur inocuité. Ce statut peut aussi être attribué pour des raisons politiques, comme ce fut le cas avec le RFC 4408, bloqué par la volonté de certains gros acteurs.

Le statut « pour information » (section 4.2.2) est notamment celui de tous les RFC qui ne décrivent pas un protocole ou un format mais rendent compte d'une expérience, ou formulent un cahier des charges, ou expliquent les raisons de certains choix. Pour éviter les collisions avec le travail de normalisation à proprement parler, l'IESG a son mot à dire sur ces RFC, pour pouvoir soulever d'éventuelles objections (section 4.2.3).

Enfin, le statut « historique » (section 4.2.4) revient aux RFC qui ont été officiellement considérés comme dépassés par les évolutions techniques et l'expérience acquise. C'est ainsi que, par exemple, le protocole whois++ qui devait remplacer whois, avait été normalisé dans le RFC 1913 qui, n'ayant jamais connu de déploiements significatifs, a été reclassé historique...

À noter que, de même que l'avancement d'une technique sur le chemin des normes nécessite une action délibérée de certains, le reclassement en « historique » demande que quelqu'un fasse le travail de documentation des raisons du reclassement. C'est pour cela que beaucoup de RFC sont simplement tombés en désuétude, sans même que quelqu'un se donne la peine de les faire formellement reclassifier (comme le RFC 1256).

Un statut particulier a droit à une section à lui : BCP (Best Current Practices, « Bonnes pratiques actuelles », section 5). Ces documents ne normalisent pas une technique mais une façon de l'utiliser « correctement ». Ils reçoivent également un numéro commençant par BCP. C'est ainsi que le RFC 2827, sur le filtrage des paquets trichant sur l'adresse source, est également BCP0038 et que le RFC 5226, sur la gestion des registres IANA est aussi le BCP0026. Un autre usage des BCP est de garder un pointeur vers la version actuelle de la norme. En effet, les RFC ne sont jamais modifiés mais remplacés. Si on se réfère à un RFC, on court donc le risque de pointer un jour vers un texte obsolète et il est donc recommandé d'utiliser plutôt le numéro de BCP. Par exemple, BCP0047 désignera toujours le RFC actuel sur les étiquettes de langue (actuellement le RFC 5646).

Le processus d'avancement des normes est décrit complètement en section 6. Je rappelle qu'il n'est pas automatique. Une norme n'avance pas toute seule mais seulement parce qu'un groupe de gens trouvait important de la faire avancer... et a su convaincre l'IESG (section 6.1.2).

L'IETF étant une organisation humaine et le fait de travailler sur des normes techniques ne supprimant pas les passions et les intérêts matériels, les conflits sont fréquents. Il n'est donc pas étonnant qu'il existe une section, la 6.5, sur les conflits et leur résolution. Elle détaille un mécanisme d'escalades successives. D'abord, faire appel aux présidents du groupe de travail considéré, puis au directeur de zone (une zone chapeautant plusieurs groupes), puis à l'IESG puis à l'IAB, ultime arbitre.

Il n'y a pas que l'IETF dans le monde et certaines normes très importantes sur Internet sont issues d'autres organisations (par exemple, HTML vient du W3C, Ethernet de l'IEEE et X.509 de l'UIT). La section 7 décrit donc l'interaction avec les autres SDO. Certaines normes sont qualifiées d'« ouvertes » et d'autres de « autres » mais sans que ces termes soient définis avec précision. Les normes « ouvertes » (ce terme a traditionnellement été utilisé à l'IETF de manière très laxiste, intégrant même des normes comme celles de l'ISO, qui ne sont pas publiquement accessibles) peuvent être référencées par les RFC. Les « autres » sont typiquement découragées mais peuvent être utilisées si nécessaire (section 7.1.2).

Le processus de développement des normes à l'IETF a toujours été ouvert, et les discussions elles-mêmes sont enregistrées et archivées (contrairement à l'ISO où tout, même les votes, est secret). La section 8 décrit les obligations de conservation que s'impose l'IETF.

Ce RFC 2026, dérivé du RFC 1602, lui même issu du RFC 1310, est assez ancien et c'est une autre raison pour laquelle il ne reflète pas toujours bien le processus actuel. Il a parfois été mis à jour (par exemple, sur la question des droits de propriété intellectuelle, qui était traitée en section 10, mais qui est maintenant du ressort des RFC 5377 et RFC 5378) mais de manière incomplète.


Téléchargez le RFC 2026


L'article seul

Tester son courrier électronique avec des auto-répondeurs

Première rédaction de cet article le 30 novembre 2008
Dernière mise à jour le 7 février 2016


Une fois qu'on a bien transpiré et configuré proprement son serveur de messagerie, comment vérifier s'il marche ? En écrivant un message ? Cela ne teste que la moitié du trajet, il serait bien d'avoir aussi une réponse... Si on a des copains patients, on peut leur écrire et solliciter une réponse mais c'est assez abusif. Il vaut mieux compter sur un programme qui répondra à chaque fois, sans se lasser, et qui pourra en prime vous indiquer à quoi ressemblait le message entrant. Quelles sont les adresses qui correspondent à un tel programme ?

Voici une liste partielle. Si vous en connaissez d'autres, n'hésitez pas à me prévenir.

  • echo@generic-nic.net (Accessible en IPv6 et accepte TLS.)
  • echo@nic.fr (Accessible en IPv6 et accepte TLS.)
  • Echo@TU-Berlin.DE (Accepte TLS.)
  • echo@tu-chemnitz.de (Accepte TLS. Répond en allemand.)
  • repondsmoi@crdp.ac-versailles.fr
  • ping@stamper.itconsult.co.uk (analyse SPF et indique le résultat ; en revanche, il ne renvoie qu'une partie du message original ; par ailleurs, cette organisation héberge l'excellent service Stamper.)
  • ping@oleane.net
  • check-auth@verifier.port25.com
  • test@doesnotwork.eu (IPv6 seulement, à n'utiliser que si vous pouvez envoyer et recevoir du courrier en IPv6, il teste les deux et vous envoie donc deux confirmations.)
  • autoreply@dmarctest.org (répond avec votre message testé, notamment pour SPF et DKIM)
  • mailtest@unlocktheinbox.com (répond avec des tests SPF et DKIM détaillés)
  • https://www.mail-tester.com/ qui n'est pas vraiment un répondeur : on regarde une page Web qui vous indique une adresse (à usage unique) à laquelle on écrit et qui vous affiche ensuite le résultat de l'analyse (y compris SPF et DKIM).

Certains, comme echo@generic-nic.net, pratiquent le greylisting (RFC 6647) donc soyez patient : la réponse n'arrivera pas tout de suite, c'est du courrier électronique, pas de la messagerie instantanée.

Tous renvoient également le message tel qu'ils l'ont reçu, ce qui permet de vérifier que tous les détails du courrier sortant sont corrects, par exemple les en-têtes Received:. Par exemple, voici le champ Received: qu'avait le message en rentrant dans le serveur de messagerie de generic-nic.net :

Received: from mail.bortzmeyer.org (bortzmeyer-1-pt.tunnel.tserv10.par1.ipv6.he.net[IPv6:2001:470:1f12:420::2])
        by mail.generic-nic.net (Postfix) with ESMTP id 42B2A9345C2
        for <echo@generic-nic.net>; Sun, 30 Nov 2008 19:26:58 +0100 (CET)

On y voit (la syntaxe complète de Received: est décrite dans le RFC 5322, section 3.6.7) le nom qu'a annoncé l'expéditeur dans la commande EHLO, ici mail.bortzmeyer.org, l'adresse IP dudit expéditeur, ici 2001:470:1f12:420::2 et le nom obtenu à partir de cette adresse IP par résolution inverse dans le DNS, ici bortzmeyer-1-pt.tunnel.tserv10.par1.ipv6.he.net.

Une mention spéciale mérite d'être faite pour check-auth@verifier.port25.com. Outre le simple test d'écho du courrier, il fait en outre une série de tests liés à la lutte anti-spam (présence dans les principales listes noires, score SpamAssassin, etc) ce qui peut être pratique si vos messages ne sont pas délivrés et que vous soupçonnez les logiciels anti-spam d'en être responsables. Voici le genre de rapport qu'envoie ce service :

==========================================================
Summary of Results
==========================================================
SPF check:          permerror
DomainKeys check:   neutral
DKIM check:         neutral
SpamAssassin check: ham
...
[Pour SPF, ici en erreur, les enregistrements SPF et l'identité testée 
sont affichés mais aucune explication détaillée n'est fournie.]
...
SpamAssassin v3.2.5 (2008-06-10)

Result:         ham  (2.0 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
-0.2 BAYES_40               BODY: Bayesian spam probability is 20 to 40%
                            [score: 0.3813]
 2.2 TVD_SPACE_RATIO        BODY: TVD_SPACE_RATIO

Autre mention, les auto-répondeurs de test des adresses internationalisées en http://idn.icann.org/E-mail_test.

Enfin, si vous voulez monter un tel service chez vous, compatible avec le RFC 3834, voici le script procmail qui est derrière echo@generic-nic.net. Il est configuré ainsi dans /etc/aliases :

echo: "|/usr/bin/procmail /etc/procmailrcs/echo"

et /etc/procmailrcs/echo contient :

VERBOSE=off
LOGFILE=/var/tmp/echo.log
MYDOMAIN=YOUR-DOMAIN-NAME-HERE.example
LOOP_TAG=echo@$MYDOMAIN

# Read RFC 3834! Option -t of formail must not be used and Auto-Submitted 
# must be present.
:0Hhb
* !^FROM_DAEMON
* $!^X-Loop: $LOOP_TAG
| (tempfile=`mktemp`; cat - > $tempfile; cat $tempfile | \
     formail -r -k -A'Precedence: junk' \
        -A'Auto-Submitted: auto-replied' \
        -A'MIME-Version: 1.0' \
        -A'Content-type: text/plain; charset=US-ASCII' \
        -A"X-Loop: $LOOP_TAG" \
        -A"From: postmaster@$MYDOMAIN (Echo automatic service)" ; \
	cat /local/lib/echo-reply; \
        echo ""; echo "Your original message:"; echo ""; \
        cat $tempfile; rm $tempfile) \
      | $SENDMAIL -t


L'article seul

DSSSL, le langage de transformation de SGML

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


Le langage DSSSL (Document Style Semantics and Specification Language) est aujourd'hui bien oublié. Il était le langage favori de transformation de SGML. Comme j'ai utilisé ce langage pendant des années, il est temps de documenter un peu avant qu'il ne disparaisse complètement.


L'article complet

RFC 5395: Domain Name System (DNS) IANA Considerations

Date de publication du RFC : Novembre 2008
Auteur(s) du RFC : Donald E. Eastlake 3rd (Motorola)
Première rédaction de cet article le 27 novembre 2008
Dernière mise à jour le 5 janvier 2009


Un RFC un peu bureaucratique, pour détailler les mécanismes utilisés pour l'enregistrement dans les registres de l'IANA des paramètres liés au DNS. Il a depuis été remplacé par le RFC 6195 (qui à son tour a été remplacé par le RFC 6895).

Un certain nombre de paramètres, dans le DNS, sont enregistrés à l'IANA, afin de s'assurer d'une interprétation identique partout. C'est ainsi que l'IANA gère un registre des paramètres DNS où on trouve, entre autres, les types d'enregistrement (A, codé 1, pour une adresse IPv4, AAAA, codé 28, pour une adresse IPv6, LOC, codé 29, pour les positions géographiques du RFC 1876, etc). Cet espace n'étant pas de taille infinie, il faut y enregistrer de nouveaux paramètres avec prudence, selon les règles qui étaient expliquées dans le RFC 2929, que notre RFC modifie.

En effet, les règles du RFC 2929 étaient bien trop strictes à l'usage. Notamment, le processus d'enregistrement d'un nouveau type d'enregistrement était tellement pénible que beaucoup de protocoles (comme SPF à ses débuts) préféraient utiliser le fourre-tout TXT pour y mettre leurs enregistrements. Ce goulet d'étranglement était souvent cité comme un exemple typique des blocages liés à l'IETF.

Notre RFC assouplit donc les règles d'enregistrement des types de ressources DNS (les autres règles sont peu changées). Avant, il y avait deux solutions (voir le RFC 5226 pour plus d'explications), IETF Review (ex-IETF Consensus), un processus long et incertain imposant un RFC sur le chemin des normes, approuvé par l'IESG, ou Specification required, qui impose l'écriture d'une norme (pas forcément un RFC) « stable et permanente ».

Le nouveau système est plus léger (section 3.1.1) : il suffit désormais de remplir un formulaire décrivant le nouveau type d'enregistrement, de le soumettre sur la liste namedroppers@ops.ietf.org et d'attendre le jugement d'un expert, désigné parmi les noms fournis par l'IESG, qui décidera, sur la base du formulaire soumis, d'allouer ou pas la requête. Un tel processus est utilisé pour d'autres enregistrements à l'IANA, par exemple pour les nouvelles étiquettes de langue.

Le nouveau processus a été testé pour la première fois pour le type d'enregistrement ZS (Zone Status) qui a été accepté, sous un autre nom, NINFO, et figure désormais dans le registre IANA.

Notre RFC a depuis été remplacé par le RFC 6195, qui ne change que des points de détail (puis par le RFC 6895).


Téléchargez le RFC 5395


L'article seul

Déboguer les zones DNS signées avec DNSSEC

Première rédaction de cet article le 26 novembre 2008
Dernière mise à jour le 10 juin 2009


La sécurité est un aller et retour permanent entre trop et pas assez. Trop de sécurité et on ne peut plus rien faire, pas assez et les ennuis nous tombent dessus. Le DNS n'échappe pas à cette dialectique fondamentale. Pour se protéger de l'empoisonnement des résolveurs DNS, on pense à déployer DNSSEC. Oui, mais qui va déboguer les innombrables problèmes que cela va causer et comment ?

La vulnérabilité du DNS aux empoisonnements avec des données fausses est bien connue depuis longtemps (voir par exemple le RFC 3833). Elle est particulièrement prise en compte depuis la révélation de la faille Kaminsky. Pour faire face à cette vulnérabilité, un certain nombre d'experts prônent le déploiement d'une technique de signature cryptographique, DNSSEC, normalisée dans les RFC 4033, RFC 4034 et RFC 4035.

Il existe une longue expérience de déploiement de la cryptographie sur l'Internet et l'une des leçons apprises est que des ennuis se produisent inévitablement. Bogues dans les logiciels et erreurs de procédures de la part des humains font que la cryptographie fonctionne souvent comme une serrure : elle gêne les méchants mais elle peut aussi bloquer les gentils. Normalement, le DNS est très résistant aux erreurs de configuration : il faut vraiment le faire exprès pour rendre une zone complètement inatteignable. Avec DNSSEC, on perd cette robustesse : une erreur et la zone, quoique atteignable, ne sera pas validée et les résolveurs refuseront de transmettre les données. Il est donc crucial d'apprendre à déboguer DNSSEC.

Commençons par un cas banal à l'heure actuelle. On a un résolveur DNS qui valide avec DNSSEC (dans BIND, cela se fait avec l'option dnssec-validatation yes;) et, un matin, une zone DNS n'est plus accessible. Le résolveur, interrogé avec dig dit juste Server failure :


% dig +dnssec SOA example.net

; <<>> DiG 9.5.0-P2 <<>> +dnssec @dnssec SOA example.net
; (1 server found)
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 31180
                                       ^^^^^^^^
                                       Ici
...

Si on a accès aux journaux de ce résolveur et s'il est configuré en mode suffisamment bavard, on pourra y trouver des détails sur la cause du problème. Mais il faut noter que les résolveurs Unbound et (surtout) BIND ont en commun que les messages ainsi journalisés sont peu compréhensibles, et nécessitent souvent la lecture des RFC pour être décodés.

À l'autre extrémité du spectre de la complexité, une solution entièrement cliquodromesque est le vérificateur du registre de .se, http://dnscheck.iis.se/. Si la zone est disponible publiquement, il peut l'analyser en détail et produire des diagnostics compréhensibles par exemple :

DNSSEC signature expired: RRSIG(example.net/IN/DNSKEY/8850)
Expired signatures will be ignored by validating resolvers.

Cet outil est également distribué, sous une licence libre, pour ceux qui veulent le faire tourner chez eux. Un autre excellent outil de vérification du DNS, Zonecheck, peut faire des tests DNSSEC depuis sa version 3.

Et entre les deux ? Si on est prêt à utiliser quelques outils Unix mais qu'on n'a pas accès au journal du résolveur, ou bien qu'on ne comprend rien à ses messages ? Mark Andrews, responsable de la version actuelle de BIND, aime dire qu'on peut « déboguer DNSSEC uniquement avec dig et date ». Est-ce vrai ?

Voyons ce qu'on peut obtenir avec dig. Par défaut, la plupart des résolveurs validateurs ne distribuent aucune donnée lorsque la signature est invalide. Cela rend difficile le déboguage aussi faut-il demander gentiment au résolveur d'envoyer quand même les données invalides, avec l'option +cd :

% dig +dnssec +cd SOA example.net
...
;; ANSWER SECTION:
example.net.            86400   IN      SOA     ns1.example.net. hostmaster.example.net. 2008102101 3600 900 3600000 900
example.net.            86400   IN      RRSIG   SOA 5 2 86400 20081120064157 20081021064157 8850 example.net. QWzZD+N2Y3qCoosWI7T/x3Rlqr06bZXyZhDv6h/L7PxxPXedV63gTz+b q5Rw8p/46rqkBa+YTwAH/050iZMfrKDQALh+0aLI1CJpRaiAUPyXN/hf Dc5kapJmgIW9eSD17hmbKz8Qp29WriqefPTToll4MC1TtBJm1M7QSE2e Y6Q=

Le premier enregistrement, le SOA est ce que nous avions demandé, le second, RRSIG est la signature cryptographique. La majorité est du binaire, que je ne chercherai pas à lire mais certaines données sont en clair, notamment le key ID (ici 8850) et les dates de validité de la signature.

En effet, pour empêcher un attaquant de « rejouer » de vieux enregistrements, les RRSIG ont une date de début et une date de fin de validité. (La période de validité est de un mois, par défaut, si on signe avec l'outil dnssec-signzone de BIND.) dig affiche cette date dans un format quasiment lisible, décrit par les section 3.2 et 3.1.5 du RFC 4034 : YYYYMMDDHHmmSS en UTC. Ici, la date de fin de validité est 20081120064157, donc le 20 novembre 2008 à 06h41 UTC. Comme nous sommes le 26 novembre, pas besoin de chercher plus loin : la signature a expiré. (Pour afficher la date du jour au format identique à celui de dig, sur un Unix qui a GNU date comme Debian, on peut faire date -u +%Y%m%d%H%M%S.)

En effet, puisque les signatures ont une durée de vie limitée, il faut re-signer la zone périodiquement. Les futures version de BIND le feront automatiquement. Mais, en attendant, il faut mettre dans son crontab quelque chose comme :

dnssec-signzone -N increment example.net

À noter qu'il existe aussi des appliances DNSSEC comme celle de Secure64 qui, normalement, vous dispensent de cette tâche.

Mais, pour l'instant, il faut bien dire que la signature expirée est la cause la plus fréquente de problèmes DNSSEC. Tellement qu'elle vaut la peine d'une surveillance spécifique. Par exemple, le script check-sig vérifie un nom de domaine et affiche un message d'erreur si sa signature est expirée ou bien si elle le sera bientôt (sept jours par défaut) :

% check-sig example.net
% 

% check-sig SOA example.net
Name example.net has an expired signature (20081120064157)
%

% check-sig example.org
Name example.org has a signature that will expire in less than 7 days (20081201224442)
%

Il peut donc être mis dans une crontab pour donner l'alarme lorsqu'une signature risque d'expirer. (Merci à Erwan David, Thomas Parmelan, Pierre Beyssac, Phil Regnauld et tlhackque pour sa mise au point.)

Et la cause suivante, en nombre d'erreurs ? Probablement les incohérences dans la délégation. DNSSEC repose, comme le DNS, sur un modèle hiérarchique. Une racine délègue à des zones qui délèguent à des sous-zones et ainsi de suite. Chacune de ces délégations, matérialisées par un enregistrement DS (RFC 4034, section 5), est évidemment signée. La principale différence avec le DNS est que la racine de signature peut être différente de la racine tout court, grâce à DLV (RFC 5074). Ainsi, à l'heure actuelle, la plupart des zones signées sont délégués depuis le registre DLV de l'ISC.

Or, des problèmes peuvent survenir lors des délégations puisque elles impliquent deux organisations différentes. Par exemple, un administrateur de zone décide de signer car c'est à la mode puis arrête de le faire mais oublie qu'un enregistrement DLV pointe vers lui (et donc garantit que la zone devrait être signée). Ou bien l'administrateur modifie sa clé et oublie de prévenir la zone au-dessus. De telles contradictions entre la zone parente et la zone fille sont fréquentes dans le DNS d'aujourd'hui mais, avec DNSSEC, elles ne pardonnent pas.

Supposons donc que la zone example.net ne fonctionne pas : nous ne récupérons que le Server Failure. Regardons sa clé (l'option +multi rend l'affichage des clés plus agréable) :

% dig +dnssec +cd +multi DNSKEY example.net
...
;; ANSWER SECTION:
example.net.              366 IN DNSKEY 257 3 5 (
                                AwEAAc4x/KbNECb+dpDDBSvyxfTlvUxXyC3EAqCnXDp4
                                +IxjfmwCm1QfB/VIMfqQ2bSsEu51BPk/38dBG01COvE5
                                tYit/Ux8gIuDgZiJx+ldZ9OAJ3Lnm7v/q5+gy2LSzW46
                                p6U45WHmGnDZ4c3uhzcfooXmQsW4UmIw+zDc2ePADy3M
                                bkr3Srll3XDny1OHoW6Ch4o8qC+ezzRDSEnhrtpon+r9
                                4sqXF50k6OLaqCRB3q9iaGUgviTVfZWJIlvZOwvxxpbH
                                SDd6QThM/CZBzcx/8JHAwP7MJcUQYS8XvBwRdaAfVDuE
                                FjUj6IF+vgn8PI1ipQUrF8L0OAHf1dHBou1XjuE=
                                ) ; key id = 17398

Sa clé est la 17398. Est-elle bien chez le parent ? On demande à celui-ci :

% dig @addr-server-parent +dnssec +cd +multi DS example.net.
...
;; ANSWER SECTION:
example.net.              1800 IN DS 6732 5 1 (
                                BBDDDD272C4D81EF941C722CEF79A848B543502D )

Oui, il y a bien un enregistrement DS mais pour une autre clé, la 6732. La chaîne de confiance est cassée là. Sans doute un changement de clé effectué sans prévenir le parent.

Attention, il est courant d'avoir plusieurs clés et il faut donc les regarder toutes.

Avec DLV, même principe. Ma zone sources.org est signée et enregistrée dans DLV à l'ISC, ce qu'on peut voir avec :

% dig @ns-ext.isc.org +multi DLV sources.org.dlv.isc.org
...
;; ANSWER SECTION:
sources.org.dlv.isc.org. 3600 IN DLV 22107 5 2 (
                                AF12A23DFBCDB5609DCEC2C2FBD3CD65AEEFE49CBE07
                                51C65C71C983986B7DE5 )
sources.org.dlv.isc.org. 3600 IN DLV 14347 3 1 (
                                31FF6986A07DAC3642C18606FC992F6ED403A873 )
sources.org.dlv.isc.org. 3600 IN DLV 14347 3 2 (
                                0D5D5B209264BBA5EDAEC9B95843901073BF27F01702
                                B144FFC1389D747DAB7F )
sources.org.dlv.isc.org. 3600 IN DLV 22107 5 1 (
                                EA78D532118A6C2B3C95447A7E520FF3B16FE775 )

Il y a deux clés, les 14347 et 22107, utilisant deux algorithmes différents, d'où les quatre DLV. Ici, tout va donc bien.

Et si la recherche d'une clé dans la zone ne donnait rien ? C'est que la zone n'est pas signée. Actuellement, c'est l'écrasante majorité. Sauf s'il existe une délégation DNSSEC depuis le parent (la zone serait alors invalide), ces zones ne doivent pas être refusées, sauf extrême paranoïa. Si elles déclenchent un Server Failure, c'est qu'il y a une raison non-DNSSEC à cela.

On peut tester ces techniques avec la zone test.dnssec-tools.org où se trouvent de nombreux enregistrements DNSSEC cassés volontairement. Par exemple, futuredate-A.newzsk-ns.test.dnssec-tools.org a une date des signatures valide seulement dans le futur... Même chose avec un autre domaine cassé exprès, dnssec-failed.org.

Bien sûr, un million d'autres choses peuvent tomber en panne. Par exemple, DNSSEC dépend d'EDNS0, puisque les réponses DNSSEC sont typiquement plus grosses. L'expérience prouve qu'un certain nombre de pare-feux bogués interceptent les paquets avec EDNS0 ou bien qu'un certain nombre d'administrateurs incompétents configurent leur pare-feu pour rejeter les paquets DNS de taille supérieur à 512 octets. Il faut donc également être prêt à déboguer la configuration réseau.

On trouve de nombreuses indications pratiques sur le déboguage de DNSSEC dans le DNSSEC HOWTO, a tutorial in disguise ou bien dans les transparents DNSSEC in 6 minutes. Merci à Mohsen Souissi pour le déboguage du texte et à Mark Andrews pour ses exemples de déboguage sur la liste bind-users.


L'article seul

Que sont les dinosaures devenus ?

Première rédaction de cet article le 25 novembre 2008


Sur mon site Web se trouvaient il y a très longtemps des jolies photos de dinosaures numérisées à partir d'un vieux livre. N'étant pas sûr de la situation légale de ces photos, j'ai préféré les retirer.

Ce qui est curieux, c'est que les adresses Web ne meurent jamais. Des années après, ces photos, qui étaient très populaires et bien référencées (et on parle d'une époque où Google n'existait pas) continuent à être demandées à leur ancienne adresse, http://www.internatif.org/bortzmeyer/dinos/. La leçon à en tirer est qu'il ne faut pas changer les adresses des ressources Web : on ne peut pas changer les milliers d'endroits où elles sont enregistrées.

Le moteur de recherche de Yahoo, par exemple, s'obstine à demander ces images. Il n'a jamais accepté qu'elles disparaissent :

72.30.87.98 - - [25/Nov/2008:09:26:47 +0100] "GET /dinos/index.fr.html HTTP/1.0" 410 457 "-" "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)" www.bortzmeyer.org

J'ai modifié la configuration d'Apache pour renvoyer le code d'erreur 410 (« Parti définitivement » alors que la classique 404 peut être temporaire ; les deux codes sont décrits respectivement dans les sections 6.5.9 et 6.5.4 du RFC 7231). Dans le .htaccess :

Redirect gone /dinos

Apache envoie alors un message d'erreur sans ambiguïté. Mais cela n'a rien changé, Yahoo continue à s'acharner.

Parfois, l'examen du champ Referer: tel qu'il est enregistré dans le journal d'Apache indique que le visiteur vient d'une page de liens comme http://www.lauriefowler.com/dinopix.html, page qui n'est plus mise à jour depuis longtemps. Le Web est d'une stabilité étonnante...

Au cas où cette inertie ne suffise pas, vous pouvez aussi utiliser le remarquable service de Internet Archive pour voir une version archivée de ces photos.


L'article seul

Vers une programmation réseau orientée vers le nom de machine

Première rédaction de cet article le 25 novembre 2008


Aujourd'hui, une des raisons pour lesquelles il est difficile de déployer de nouveaux protocoles réseaux est la dépendance des applications aux adresses IP, utilisées comme identificateurs. D'où la proposition radicale de Christian Vogt : que les machines aient une pile réseau centrée sur le nom de machine, sans accès facile à l'adresse IP, de façon à permettre de changer celle-ci, voire de changer son format ou sa sémantique.

Christian Vogt est l'auteur de plusieurs RFC sur la mobilité et un participant actif du groupe de recherche RRG de l'IRTF. C'est un chercheur très concret, toujours soucieux de proposer des solutions réalistes.

Dans son article Towards A Hostname-Oriented Network Protocol Stack for Flexible Addressing in a Dynamic Internet, Vogt propose que les applications n'aient plus accès trop facilement aux adresses IP, comme c'est le cas actuellement avec l'API de très bas niveau des prises. Il propose qu'on remplace cette API, qui lie les applications au concept d'« adresse IP comme identificateur » par une nouvelle API qui comprendrait essentiellement deux primitives :

  • ConnectToHostname(host) qui prendrait comme paramètre le nom de la machine où on veut se connecter et,
  • AcceptFromHostname() qui accepterait les connexions.

Derrière, le système d'exploitation devrait faire la résolution de nom en adresse, bien sûr, mais aussi gérer le changement d'adresse IP en cours de session, si utile à la mobilité et au multihoming, et que des protocoles comme SCTP (RFC 3286) permet.

Certaines API existantes (par exemple celles de bibliothèques comme libcurl ou comme le WSAConnectByName de Microsoft) permettent un mécanisme du genre ConnectToHostname mais qui ne gère pas le changement d'adresse en cours de session.

L'adoption d'une telle API permettrait donc de résoudre le problème du « portage » des applications de IPv4 vers IPv6, qui est une aberration en soi. Normalement, un changement de format des adresses dans la couche 3 n'aurait dû avoir aucun impact sur les applications.

Mais cette API permettrait aussi de pouvoir un jour déployer des protocoles plus avancés, où l'adresse IP n'est pas exposée, comme LISP ou HIP (RFC 4423).

Hélas, l'expérience des migrations précédentes n'incite pas à l'optimisme. Les API sont très stables, voire immobiles, et il est très difficile d'obtenir un changement des habitudes. Il suffit de voir, par exemple, qu'on trouve encore des universités où on enseigne la résolution de noms via gethostbyname(), méthode spécifique à IPv4 et abandonnée depuis le RFC 2133 il y a plus de dix ans...


L'article seul

Le fantôme est dans le navigateur

Première rédaction de cet article le 23 novembre 2008


Une part de plus en plus importante de l'activité Internet de beaucoup d'utilisateurs se fait via un navigateur Web. Cet outil devrait donc être digne de la plus grande confiance. Loin de là.

Comme le montre l'étude de Google (Niels Provos, Dean McNamee, Panayiotis Mavrommatis, Ke Wang et Nagendra Modadugu), The Ghost In The Browser - Analysis of Web-based Malware, les navigateurs Web se font bien trop facilement infecter par le malware. Un excellent article, plein de données précises. Un article qui rappelle donc qu'il n'y a rien de ridicule à couper Javascript ou bien à naviguer derrière un relais comme Privoxy.


L'article seul

Le Web et la version originale des documents

Première rédaction de cet article le 23 novembre 2008


Aujourd'hui, beaucoup de sites Web sont disponibles en plusieurs langues. Par exemple le site de Barcelone, http://www.barcelona.cat/, est en catalan, en espagnol et en anglais. Celui de Katmandou, http://www.kathmandu.gov.np/, est en népalais et en anglais, etc. Mais comment choisit-on sa version ? Le problème est plus compliqué qu'il n'y parait.

La norme du protocole HTTP, le RFC 2616, fournit une solution simple, la négociation de contenu (en-tête Accept-Language, RFC 2616, section 14.4). Le navigateur Web est configuré par son utilisateur avec une liste de langues préférées (par exemple, je préfère le breton, sinon le français, sinon l'anglais), il indique cette liste au serveur et le serveur envoie la page dans la langue préférée dont il dispose. Un logiciel comme Apache a ce qu'il faut pour cela. C'est très simple pour l'utilisateur, qui n'a pas à répéter son choix à chaque fois. S'il utilise un navigateur comme Konqueror, il n'aura même rien à faire, le navigateur utilisant les préférences globales de l'environnement KDE. Pour les autres navigateurs, on peut suivre l'excellente documentation de Debian.

Mais cette méthode est très peu utilisée. C'est dû en grande partie à la profonde ignorance de la plupart des webmestres : très rares sont ceux qui ont lu le RFC 2616. Mais il y a d'autres raisons : avec Apache, mettre en action cette option interfère avec d'autres options comme la sélection des formats des pages. Enfin, cette technique ne permet pas au lecteur de changer, par exemple s'il veut voir à quoi ressemblent les versions dans d'autres langues. Il faut donc toujours au moins fournir un échappement manuel. Par exemple, le site de Debian, http://www.debian.org/, traduit en des dizaines de langues, y compris le finnois et le coréen, fonctionne automatiquement avec la négociation de langue mais permet également, par des liens en bas de chaque page, de modifier ce choix.

La grande majorité des sites Web multilingues ignorent donc les préférences de langue exprimées via le navigateur. À la place, ils fournissent un mécanisme manuel où l'utilisateur doit, pour chaque site, trouver le lien permettant de sélectionner la langue, trouver sa langue (un problème difficile en soi, surtout avec les sites qui s'obstinent à utiliser de petits drapeaux) et la sélectionner.

Ce système ne tire pas profit des possibilités de HTTP et est pénible pour l'utilisateur. Souvent, en outre, le code qui le met en œuvre est bogué, comme c'est le cas sur le site de Katmandou cité plus haut. Mais il est le seul à donner un contrôle complet à l'utilisateur, sur tous les aspects du choix de langue.

En effet, le mécanisme du RFC 2616 a une grosse limite : il ne traite pas le cas où les textes sont de qualité différentes selon les langues. Ce cas est fréquent (il suffit de comparer http://www.microsoft.com/en/us/ et http://www.microsoft.com/fr/fr/) : bien que ma langue maternelle soit le français, si je demande systématiquement la version française, je me retrouve en général avec des mauvaises traductions, incomplètes et/ou dépassées. Parfois, la langue d'origine est le français et le problème est le même : la version anglaise est loin d'être équivalente.

Maintenir plusieurs versions du même site, en différentes langues, et les garder synchrones et de qualité équivalente à travers les changements et les réorganisations qu'affectent les services de communication est en effet une tâche herculéenne. Très peu d'organisations le font réellement.

Au cinéma, je ne cherche pas systématiquement des films en français, ni d'ailleurs systématiquement des films en anglais. Je préfère des films en version originale, la langue dans laquelle ils ont été faits. Pour les romans, où il n'y a pas de sous-titres, je préfère des versions originales si c'est une langue que je comprends, puis une traduction française et, s'il n'y a pas d'autre choix, une traduction anglaise.

Malheureusement, HTTP n'a pas cette notion de version originale et donc, en pratique, la sélection automatique de langue n'a que peu d'intérêt. J'ai donc cessé de l'utiliser (alors que je trouvais cette idée très astucieuse).

Voir aussi sur ce sujet l'article International Web Usability. L'entièreté du problème de choix de la langue est couvert très en détail (configuration d'Apache, pièges, moyens de les éviter) dans la section 10.5 du livre de Patrick Andries « Unicode en pratique ».

Le même problème se pose évidemment pour le courrier électronique, pour lequel une solution a été normalisée, dans le RFC 8255.


L'article seul

Configurer l'accès Subversion par HTTP avec Apache

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


Le VCS Subversion est probablement désormais le plus utilisé des VCS centralisés, une position qui avait été longtemps tenue par CVS. Une de ses particularités est la possibilité d'accéder au dépôt Subversion par différents protocoles réseaux. Pour HTTP, le moyen le plus courant est d'utiliser Apache.

Le client Subversion désigne en effet un dépôt par un URL. Cet URL peut désigner un fichier local (il commence alors par file://, cf. RFC 8089), un accès via un compte distant atteint en SSH et il commence alors par svn+ssh:// ou bien un dépot distant accédé en HTTP, méthode la plus courante dès que le dépôt est utilisé par plusieurs utilisateurs.

Subversion utilise pour cela le protocole WebDAV, une extension à HTTP, normalisé dans le RFC 4918, plus des extensions spécifiques à Subversion. On va utiliser Apache, comme documenté en http://svnbook.red-bean.com/en/1.5/svn.serverconfig.httpd.html. Mettons qu'on veuille un dépôt accessible par l'URL https://svn.example.net/, qui permette les accès anonymes mais qui réserve certains répertoires à des utilisateurs bien identifiées (via LDAP). Apache ne demandera une authentification que pour les parties du dépôt où c'est nécessaire. La configuration va ressembler à :


# Module Apache pour WebDAV
LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so
# Module Apache pour les extensions Subversion à WebDAV
LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so
# Module Apache pour l'authentification par répertoire dans le dépôt
# (ce qu'Apache ne sait pas faire tout seul)
LoadModule authz_svn_module /usr/lib/apache2/modules/mod_authz_svn.so

# Uniquement en httpS, pour des raisons de sécurité, donc port 443
<VirtualHost *:443>
    ServerAdmin webmaster@example.net
    ServerName svn.example.net
 
    # Pour le chiffrement, on utilise GNU TLS (et pas OpenSSL)
    GnuTLSEnable  on
    GnuTLSCertificateFile /etc/ssl/certs/ssl-cert-www.example.net.pem
    GnuTLSKeyFile /etc/ssl/private/ssl-cert-www.example.net.key
    GnuTLSPriorities NORMAL:!AES-256-CBC:!DHE-RSA

 <Location />
 
  # Le dépôt
  DAV svn
  SVNPath /home/Subversion-Repository

  # Couper l'authentification ordinaire et activer celle par
  # LDAP. Naturellement, d'autres méthodes que LDAP sont
  # possibles. Voir 
  # <http://svnbook.red-bean.com/nightly/en/svn.serverconfig.httpd.html#svn.serverconfig.httpd.authz>
  AuthUserFile /dev/null
  AuthBasicProvider ldap
  AuthType Basic  
  AuthName "Example & co Subversion Repository"
  AuthLDAPURL ldap://ldap.example.net/ou=People,dc=example,dc=net?uid?sub?(objectClass=*)

  # Le fichier où se trouvent les autorisations par répertoire
  AuthzSVNAccessFile /etc/apache2/subversion-access

  # On utilise "Satisfy any" car on veut permettre les accès anonymes aussi
  Satisfy any
  require valid-user

  </Location>

</VirtualHost>

Et ce fichier /etc/apache2/subversion-access, qui stocke les autorisations, que contient-il ? Il est documenté en http://svnbook.red-bean.com/en/1.5/svn.serverconfig.pathbasedauthz.html. Le principe est qu'on définit des groupes d'utilisateurs, puis on indique des permissions (droit de lire et d'écrire) à des répertoires du dépôt. Tous les répertoires ne sont évidemment pas listées systématiquement. Lorsqu'un répertoire n'est pas indiqué, Subversion utilise les permissions du parent, puis du grand-parent, etc. L'ordre des directives dans le fichier n'est donc pas vital mais la plupart des administrateurs mettent les répertoires du plus général au plus spécifique. Voici un exemple :

# Definition des groupes d'utilisateurs 
[groups]
# La compagnie
staff = smith,jones,muller
# Des partenaires sur un projet
foobar = @staff,durand,li

# Par défaut : tout le monde peut lire, la compagnie peut lire et écrire
[/]
* = r
@staff = rw

[/Business]
# Inaccessible aux extérieurs. Comme les permissions sont normalement
# héritées du parent, il faut explicitement couper l'accès de "*" (tous).
* = 
@staff = rw

[/FooBar]
# Un projet public, sur lequel nos partenaires travaillent
* = r
@foobar = rw

[/Secret]
# Projet très réservé
* =
smith = rw

À noter qu'il n'existe apparemment pas de moyen simple pour donner des droits à tous, sauf aux anonymes. Il faut lister tous les authentifiés explicitement (* inclus les anonymes).

Voici un accès à ce répertoire par un utilisateur anonyme, qui utilise le client Subversion en ligne de commande :

% svn co https://svn.example.net/
...
A    svn.example.net/FooBar/src/main.d
...
Checked out revision 7979.

Si, maintenant, je vais dans un des répertoires qui demandent une authentification :

% cd svn.example.net/FooBar/src
% emacs util.d
% svn add util.d
A         util.d
% svn commit
Authentication realm: <https://svn.example.net:443> Example & co Subversion Repository
Password for 'smith': 
Adding         FooBar/src/util.d
Transmitting file data .
Committed revision 7980.

Apache demandera l'authentification, puisque l'anonyme n'a pas le droit d'écrire dans ce répertoire (notez que le client Subversion a affiché le domaine d'authentification, tel que configuré par AuthName).

L'un des inconvénients de l'utilisation d'Apache et de WebDAV est qu'il n'y a pas de rapport simple entre les actions Subversion (checkout, commit, etc) et les requêtes HTTP. L'examen du journal d'Apache n'est donc pas très utile. Un simple commit va produire une dizaine de requêtes dont :

88.189.152.187 - smith [22/Nov/2008:18:40:56 +0100] "PUT //!svn/wrk/8f2454bd-4a5c-0410-af3f-ad2595489424/FooBar/src/util.d HTTP/1.1" 204 - "-" "SVN/1.4.4 (r25188) neon/0.26.3" svn.example.net
88.189.152.187 - smith [22/Nov/2008:18:40:56 +0100] "MERGE /FooBar HTTP/1.1" 200 709 "-" "SVN/1.4.4 (r25188) neon/0.26.3" svn.example.net
88.189.152.187 - smith [22/Nov/2008:18:40:56 +0100] "DELETE /!svn/act/8f2454bd-4a5c-0410-af3f-ad2595489424 HTTP/1.1" 204 - "-" "SVN/1.4.4 (r25188) neon/0.26.3" svn.example.net

L'article seul

Connecter un serveur dédié à IPv6 avec un tunnel manuel

Première rédaction de cet article le 20 novembre 2008
Dernière mise à jour le 25 novembre 2009


Il existe beaucoup de façons de connecter une machine ou un réseau qui n'a pas d'IPv6 natif au monde IPv6. Je présente ici le tunnel manuel, que j'ai utilisé pour qu'une de mes machines soit joignable en IPv6.

L'épuisement proche des adresses IPv4 rend nécessaire de pousser les feux du déploiement d'IPv6. La machine utilisée pour cet article est hébergée chez Slicehost, qui ne fournit pas de connectivité IPv6. Mais on peut quand même le faire via un tunnel.

Je me suis créé un compte chez Hurricane Electric, qui est présent à Chicago, à douze milli-secondes de ma machine.

Ma nouvelle adresse IP est donc 2001:470:1f10:3aa::2. Je crée un fichier de démarrage pour Gentoo :

start() {
        ebegin "Starting IPv6 connection through Hurricane Electric"
        (
             modprobe ipv6
             ifconfig sit0 up
             ifconfig sit0 inet6 tunnel ::209.51.181.2
             ifconfig sit1 up
             ifconfig sit1 inet6 add 2001:470:1f10:3aa::2/64
             route -A inet6 add ::/0 dev sit1
        )
        eend $?
}

Sur une Debian, avec /etc/network/interfaces, ce serait (pour le cas d'une machine ayant un autre point d'attachement) :

auto 6in4
iface 6in4 inet6 v4tunnel 
   # Le POP d'Hurricane Electric au Panap
   endpoint 216.66.84.42
   address 2001:470:1f12:420::2
   netmask 64
   # "gateway" n'a pas l'air de marcher ?
   up route -A inet6 add ::/0 dev 6in4

Si on a un pare-feu, il faut penser à laisser passer les paquets IPv6 encapsulés dans IPv4 (protocole 41). Avec Shorewall, cela se fait dans /etc/shorewall/tunnels :

# Hurricane Electric in Chicago
6to4     net    209.51.181.2

Et tout fonctionne :

% traceroute6 2001:470:1f10:3aa::2
 ...
 9  10gigabitethernet1-4.core1.ams1.he.net (2001:470:0:47::1)  17.663 ms  17.468 ms  17.376 ms
10  10gigabitethernet1-4.core1.lon1.he.net (2001:470:0:3f::1)  18.894 ms  19.454 ms  18.78 ms
11  10gigabitethernet2-3.core1.nyc4.he.net (2001:470:0:3e::1)  87.946 ms  89.41 ms  87.904 ms
12  10gigabitethernet1-2.core1.chi1.he.net (2001:470:0:4e::1)  115.003 ms  112.809 ms  112.441 ms
13  1g-bge0.tserv9.chi1.ipv6.he.net (2001:470:0:6e::2)  112.213 ms  111.927 ms  112.223 ms
14  bortzmeyer-1-pt.tunnel.tserv9.chi1.ipv6.he.net (2001:470:1f10:3aa::2)  118.001 ms  118.153 ms  118.031 ms

J'ai donc modifié la zone bortzmeyer.org pour ajouter un enregistrement AAAA pour la machine en question. Je peux maintenant me vanter de ma certification IPv6.

À noter que la création du compte chez Hurricane Electric ne s'est pas passé toute seule : il y avait une bogue dans le formulaire HE, j'écris et une heure après la bogue est réparée. Ça change des boîtes françaises !

Hurricane Electric fournit aussi un /64 routé, 2001:470:1f11:3aa::/64 dans mon cas, et on peut donc configurer sa machine pour gérer ces adresses. Sur Gentoo :

route -A inet6 add 2001:470:1f11:3aa::/64 dev eth0
ifconfig eth0 add 2001:470:1f11:3aa::bad:dcaf

Sur Debian :

iface eth0 inet6 static
   address 2001:470:1f13:420::bad:dcaf
   netmask 64

Je n'ai pas pu utiliser le tunnel broker de Renater car il a aussi une bogue dans son formulaire, qui refuse mon inscription.

Une autre possibilité aurait été Sixxs mais l'inscription et la création du tunnel sont effectués manuellement et j'étais trop impatient.


L'article seul

Évaluer la valeur d'une adresse IP

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


Voici une nouvelle avancée du marché dans un monde qui ne le connaissait pas : une proposition pour un service de rating des adresses IP.

Pour les noms de domaine, cela se fait depuis longtemps (voir le fameux sex.com ou bien ce que fait Sedo). Mais cela n'était pas encore le cas pour les adresses IP, alors qu'elles feront très probablement bientôt l'objet d'un marché.

Mais pourquoi certaines adresses IP valent-elles moins que d'autres ? C'est parce qu'elles sont « gâtées », par exemple parce qu'elles avaient été utilisées par des spammeurs. Une fois que cela est fait, impossible de sortir des listes noires (voir, par exemple, « Go Daddy blocks links to EC2 »).

Cela casse la légende entretenue par les RIR comme quoi toutes les adresses IP se valent...


L'article seul

RFC 5405: Unicast UDP Usage Guidelines for Application Designers

Date de publication du RFC : Novembre 2008
Auteur(s) du RFC : L. Eggert (Nokia), G. Fairhurst (University of Aberdeen)
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 18 novembre 2008


La grande majorité des applications Internet tourne sur le protocole de transport TCP. Mais son concurrent UDP, normalisé dans le RFC 768, prend de l'importance avec le multimédia et les jeux en ligne pour lesquels il est souvent bien adapté. Mais, contrairement à TCP, UDP ne fournit aucun mécanisme de contrôle de la congestion. C'est donc aux applications de fournir ce contrôle, suivant les règles expliquées par ce RFC. (Il a depuis été remplacé par le RFC 8085.)

UDP est apprécié pour certaines applications car il est simple et léger et le fait qu'il ne garantisse pas l'acheminement de la totalité des paquets n'est pas forcément un problème dans les applications multimédia : si on perd quelques secondes d'une communication téléphonique RTP, il vaut mieux passer à la suite que de perdre du temps à la retransmettre comme le ferait TCP. Mais UDP ne fournit pas non plus de contrôle de la congestion. C'est pourtant nécessaire (RFC 2914 et RFC 7567), à la fois pour assurer que le réseau continue à être utilisable et également pour assurer une certaine équité entre les différents flux de données, pour éviter qu'une seule application gourmande ne monopolise le réseau pour elle.

UDP ne le faisant pas, il faut bien que l'application le fasse et, pour cela, qu'elle mette en œuvre les conseils de ce RFC. (Notre RFC contient également des conseils pour d'autres aspects de l'utilisation d'UDP que le contrôle de congestion : mais c'est le plus important.)

Le gros du RFC est dans la section 3 qui détaille ces conseils (la section 5 contient un excellent résumé sous forme d'un tableau des conseils à suivre). Le premier est qu'il vaut peut-être mieux ne pas utiliser UDP. Beaucoup de développeurs d'applications pensent à UDP en premier parce qu'il est simple et facile à comprendre et qu'il est « plus rapide que TCP ». Mais, rapidement, ces développeurs se rendent compte qu'ils ont besoin de telle fonction de TCP, puis de telle autre, ils les mettent en œuvre dans leur application et arrivent à une sorte de TCP en moins bien, d'avantage bogué et pas plus rapide. Notre RFC conseille donc d'abord de penser aux autres protocoles de transport comme TCP (RFC 793), DCCP (RFC 4340) ou SCTP (RFC 4960). Ces protocoles sont d'autant plus intéressants qu'ils ont souvent fait l'objet de réglages soigneux depuis de nombreuses années et qu'il est donc difficile à un nouveau programme de faire mieux. D'autant plus qu'il existe souvent des réglages spécifiques pour les adapter à un usage donné. Par exemple, on peut dire à TCP de donner la priorité à la latence (paramètre TCP_NODELAY de setsockopt) ou bien au débit.

Si on ne suit pas ces sages conseils, et qu'on tient à se servir d'UDP, que doit-on faire pour l'utiliser intelligemment ? La section 3.1 couvre le gros morceau, le contrôle de congestion. Celui-ci doit être pris en compte dès la conception de l'application. Si cette dernière fait de gros transferts de données (section 3.1.1, c'est le cas de RTP, RFC 3550), elle doit mettre en œuvre TFRC, tel que spécifié dans le RFC 5348, donc faire à peu près le même travail que TCP. Et ce mécanisme doit être activé par défaut.

Si l'application transmet peu de données (section 3.1.2), elle doit quand même faire attention et le RFC demande pas plus d'un datagramme par RTT, où le RTT est un cycle aller-retour avec la machine distante (calculé selon le RFC 2988 ; si le calcul n'est pas possible, le RFC demande une durée de trois secondes). L'application doit également détecter les pertes de paquet pour ralentir son rythme si ces pertes - signe de congestion - sont trop fréquentes.

Le cas où l'application est un tunnel au dessus d'UDP est également couvert (section 3.1.3).

En suivant toutes ces règles, l'application gère proprement la congestion. Et le reste ? La section 3.2 fournit des pistes sur la gestion de la taille des paquets (rester en dessous de la MTU, utiliser la découverte de MTU spécifiée dans des RFC comme le RFC 4821, etc). La 3.3 explique la question de la fiabilité : par défaut, UDP ne retransmet pas les paquets perdus. Si c'est nécessaire, c'est l'application qui doit le faire. Elle doit aussi gérer l'eventuelle duplication des paquets (qu'UDP n'empêche pas). Le RFC note que les retards des paquets peuvent être très importants (jusqu'à deux minutes, normalise le RFC) et que l'application doit donc gérer le cas où un paquet arrive alors qu'elle croyait la session finie depuis longtemps.

La section 3.4 précise l'utilisation des sommes de contrôle (facultatives pour UDP sur IPv4 mais qui devraient être utilisées systématiquement). Si une somme de contrôle pour tout le paquet semble excessive, et qu'on veut protéger uniquement les en-têtes de l'application, une bonne alternative est UDP-Lite (RFC 3828), décrit dans la section 3.4.1.

Beaucoup de parcours sur l'Internet sont encombrés de « middleboxes », ces engins intermédiaires qui assurent diverses fonctions (NAT, coupe-feu, etc) et qui sont souvent de médiocre qualité logicielle, bricolages programmés par un inconnu et jamais testés. La section 3.5 spécifie les règles que devraient suivre les applications UDP pour passer au travers sans trop de heurts. Notamment, beaucoup de ces « middleboxes » doivent maintenir un état par flux qui les traverse. En TCP, il est relativement facile de détecter le début et la fin d'un flux en observant les paquets d'établissement et de destruction de la connexion. En UDP, ces paquets n'ont pas d'équivalent et la détection d'un flux repose en général sur des heuristiques. L'engin peut donc se tromper et mettre fin à un flux qui n'était en fait pas terminé. Si le DNS s'en tire en général (c'est un simple protocole requête-réponse, avec en général moins de deux secondes entre l'une et l'autre), d'autres protocoles basés sur UDP pourraient avoir de mauvaises surprises. Elles doivent donc se préparer à de soudaines interruptions de la communication, si le timeout d'un engin intermédiaire a expiré alors qu'il y avait encore des paquets à envoyer. (La solution des keepalives est déconseillée par le RFC car elle consomme de la capacité du réseau et ne dispense pas de gérer les coupures, qui se produiront de toute façon.)

La section 3.6 fera le bonheur des programmeurs qui y trouveront des conseils pour mettre en œuvre les principes de ce RFC, via l'API des prises (sockets, RFC 3493). Elle est largement documentée mais en général plutôt pour TCP que pour UDP, d'où l'intérêt du résumé qu'offre ce RFC, qui ne dispense évidemment pas de lire le Stevens. Par exemple, en l'absence de mécanisme de TIME_WAIT (la prise reste à attendre d'éventuels paquets retardés, même après sa fermeture par l'application), une application UDP peut ouvrir une prise... et recevoir immédiatement des paquets qu'elle n'avait pas prévus, qui viennent d'une exécution précédente.

Le protocole ICMP fournit une aide utile, que les applications UDP peuvent utiliser (section 3.7). Mais attention, certains messages ICMP peuvent refléter des erreurs temporaires (absence de route, par exemple) et ne devraient pas entraîner de mesures trop drastiques.

Après tous ces conseils, la section 4 est dédiée aux questions de sécurité. Comme TCP ou SCTP, UDP ne fournit en soi aucun mécanisme d'intégrité des données ou de confidentialité. Pire, il ne fournit même pas d'authentification de l'adresse IP source (authentification fournie, avec TCP, par le fait que, pour établir la connexion, il faut recevoir les réponses de l'autre). L'application doit-elle mettre en œvre la sécurité seule ? Le RFC conseille plutôt de s'appuyer sur des protocoles existants comme IPsec (RFC 4301) ou DTLS (RFC 6347). En effet, encore plus que les protocoles de gestion de la congestion, ceux en charge de la sécurité sont très complexes et il est facile de se tromper. Il vaut donc mieux s'appuyer sur un système existant plutôt que d'avoir l'hubris et de croire qu'on peut faire mieux que ces protocoles ciselés depuis des années.

Pour authentifier, il existe non seulement IPsec et DTLS mais également d'autres mécanismes dans des cas particuliers. Par exemple, si les deux machines doivent être sur le même lien (un cas assez courant), on peut utiliser GTSM (RFC 3682) pour s'en assurer.

Voilà, un rappel, ce RFC n'est plus d'actualité, il a été remplacé par le RFC 8085.


Téléchargez le RFC 5405


L'article seul

Épuisement des adresses IPv4

Première rédaction de cet article le 16 novembre 2008
Dernière mise à jour le 20 juin 2014


Depuis plus de deux ans, cet article avait été automatiquement mis à jour pour suivre l'allocation des adresses IPv4 et le temps qui restait avant leur épuisement. Eh bien, c'est désormais fait, il ne reste plus de préfixes IPv4 libres à l'IANA.

Les chiffres et dates contenus dans cet article étaient automatiquement mises à jour à partir de la liste officielle des allocations. Le nombre d'adresses IPv4 étant une ressource finie et non renouvelable, l'épuisement futur ne faisait aucun doute (même si quelques négationnistes arrivaient à nier ce fait). La dernière adresse IPv4 ayant été allouée par l'IANA, il faut, ou bien arrêter toute croissance de l'Internet, ou bien passer à IPv6, comme cela aurait dû être fait depuis longtemps. Une autre « solution » sera d'accepter un Internet limité, où les clients résidentiels, puis les petites entreprises et les associations, n'auront plus d'adresses IP publique du tout et devront passer des bricolages comme le NAT, qui limitent le nombre de services auxquels ils auront accès (par exemple le pair-à-pair).

Il reste certes un tout petit peu de temps avant que l'épuisement des adresses v4 ne touche tout le monde. Les RIR ont reçu des préfixes de l'IANA qui n'ont pas été épuisés tout de suite. Chaque RIR avait encore un à deux ans de réserve, avant de ne plus pouvoir rien donner aux FAI. Le premier à tomber à cours a été l'APNIC, le 15 avril 2011. Le RIPE-NCC a suivi le 14 septembre 2012 puis se furent ARIN en avril 2014 et LacNIC en juin 2014. Aujourd'hui, seul AfriNIC a encore sa réserve normale d'adresses IPv4. Notez que chaque RIR garde en réserve un /8 spécial, pour être attribué selon une politique très restrictive (c'est donc déjà le cas de tous les RIR sauf un). Ensuite, ce seront les FAI qui ne pourront plus rien donner aux clients. Bref, on peut avoir l'illusion que la pénurie n'existe pas encore vraiment mais il faut pour cela fermer très fort les yeux et avoir un optimisme en béton.

Pour faire des statistiques sur ce nouvel épuisement (celui des réserves des RIR), je manque de temps mais on peut regarder :


L'article seul

RFC 5386: Better-Than-Nothing-Security: An Unauthenticated Mode of IPsec

Date de publication du RFC : Novembre 2008
Auteur(s) du RFC : N. Williams (Sun), M. Richardson (SSW)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF btns
Première rédaction de cet article le 15 novembre 2008


Le protocole BTNS (Better Than Nothing Security), expliqué dans le RFC 5387, est normalisé dans ce RFC 5386. Il permet d'utiliser IPsec sans authentification des autres machines, ce qui pourrait simplifier son déploiement.

BTNS ne change pas le protocole IPsec (RFC 4301), ni les protocoles associés comme IKE (RFC 4306). Sur le câble, ce sont les mêmes paquets qui passent, les changements se concentrant sur les machines terminales, dans la PAD (Peer Authentication Database, section 4.4.3 du RFC 4301) et la SPD (Security Policy Database, section 4.4.1 du RFC 4301).

Ce RFC reste assez court car il ne normalise pas encore toutes les idées prévues dans le RFC 5387 comme par exemple la liaison entre une SA (Security Association) IPsec et une connexion dans les couches hautes (cf. section 4.1) ou comme la mémoire des SA précédentes, pour n'avoir à faire confiance à un inconnu que la première fois (cf. section 4.2, qui propose un futur mécanisme analogue à celui de SSH).

La section 2 décrit BTNS par rapport à l'IPsec traditionnel. Le principal changement est que, après l'examen de toutes les entrées de la PAD, une implémentation de BTNS peut simplement accepter un pair uniquement pour sa clé publique, ou même pour n'importe quelle clé (cas où on accepte les connexions de tout le monde).

La section 3 décrit quelques exemples de scénarios avec BTNS. Ainsi, 3.3 décrit un serveur NFS qui veut protéger le trafic NFS avec IPsec, tout en acceptant n'importe quel client NFS (accepter au niveau IPsec : les couches hautes peuvent toujours imposer une authentification). La PAD (Peer Authentication Database) ressemblera à :

         Rule Remote ID        IDs allowed  SPD Search by
         ---- ---------        -----------  -------------
          1   PUBLICKEY:any    ANY          by-IP

(Une seule règle, accepter tout le monde. Une telle règle n'était pas possible en IPsec avant BTNS.) Et la SPD (Security Policy Database) pourra être :

        Rule Local Remote Next Layer BTNS  Action
               addr  addr   Protocol   ok
         ---- ----- ------ ---------- ----  -----------------------
          1    [C]    ANY      ANY      yes  PROTECT(ESP,transport,
                     with                               integr+conf)
                     port
                     2049

          2    [C]    ANY      ANY      N/A  BYPASS

(Utilisation IPsec, avec protection ESP pour le port 2049 (NFS) et ne pas toucher aux autres applications.)

La section 4 revient sur les problèmes de sécurité déjà étudiées dans la section 5 du RFC 5387. BTNS est notamment vulnérable aux attaques d'un attaquant situé au milieu.


Téléchargez le RFC 5386


L'article seul

RFC 5387: Problem and Applicability Statement for Better Than Nothing Security (BTNS)

Date de publication du RFC : Novembre 2008
Auteur(s) du RFC : J. Touch (USC/ISI), D. Black (EMC), Y. Wang (Microsoft)
Pour information
Réalisé dans le cadre du groupe de travail IETF btns
Première rédaction de cet article le 15 novembre 2008


En matière de sécurité, le mieux peut être l'ennemi du bien. Un protocole très exigeant peut, en partie à cause de ces exigences, ne pas être déployé et laisser donc l'Internet aussi vulnérable qu'avant. C'est en partie ce qui est arrivé à IPsec et a justifié le travail sur le mécanisme « Mieux que rien » qui fait l'objet de plusieurs RFC dont notre RFC 5387 qui décrit les motivations et le domaine d'application de ce nouveau mécanisme ou dont le RFC 5386 qui normalise le nouveau protocole.

C'est une banalité que de dire que l'Internet n'est pas sûr. N'importe qui peut envoyer un paquet avec une fausse adresse IP, il est très facile d'écouter ce qui passe sur le réseau et il est facile de s'insérer dans une session déjà commencée. On peut se demander pourquoi le problème n'a pas encore été traité. Il l'a été, pourtant. Par exemple, IETF a depuis 1998 un protocole, IPsec (actuellement RFC 4301), qui permet de sécuriser n'importe quelle connexion Internet contre l'écoute ou la modification, en utilisant la cryptographie. IPsec est exigeant : pour établir une SA (Security Association, association de sécurité entre deux machines, qui leur permettra de communiquer en toute sécurité), il faut s'authentifier, ce qui veut dire un secret partagé (un mot de passe) ou bien une signature reconnue par une autorité commune. Si IPsec peut utiliser plusieurs identités dans sa base , les adresses IP, noms de domaine et bien d'autres, toutes doivent être authentifiées (voir aussi la section 2.1). C'est lourd et compliqué et cela a pesé sérieusement dans le peu de déploiement d'IPsec (section 1 du RFC).

Alors, faut-il supprimer l'obligation d'authentification ? Après tout, si IPsec est utilisé entre deux pairs BitTorrent, quel besoin ont-ils de s'authentifier ? La plupart du temps, les pairs acceptent de servir n'importe quelle autre machine. Même chose pour un serveur Web public. Mais ce n'est pas si simple (section 1.1) car l'authentification sert aussi à empêcher les attaques de « l'Homme au Milieu », un attaquant situé entre les deux machines et qui se fait passer pour leur correspondant. Si un tel intermédiaire est présent, la cryptographie ne servira à rien puisque les clés utilisées sont connues du méchant.

C'est pourtant la voie que suit (avec prudence) le nouveau protocole BTNS (Better Than Nothing Security ou « Mieux vaut un peu de sécurité que pas de sécurité du tout - ce qui arrive si on impose des contraintes trop élevées. »).

Ainsi, le protocole telnet était bien connue pour son extrême vulnérabilité, puisque les mots de passe passaient en clair, mais, pendant longtemps, les seules solutions proposées étaient horriblement compliquées comme Kerberos (RFC 1411 pour un telnet « kerberisé »). Elles n'avaient donc jamais été déployées sérieusement avant la sortie de SSH en 1995. SSH, lui, remplacera telnet en quelques années, bien que certains experts en sécurité aient froncé le sourcil lors de son lancement en l'estimant insuffisamment blindé.

Une des solutions qu'utilise BTNS pour limiter les risques est de dépendre d'une authentification faite dans les couches hautes (IPsec travaille dans la couche 3). La section 1.3 décrit comment de tels mécanismes rendent BTNS moins dangereux qu'il n'en a l'air.

On peut se demander quel est l'intérêt de BTNS si un protocole comme TLS s'occupe de toute la sécurité. Mais BTNS est IPsec, donc protège également contre certaines attaques dans les couches basses, contre lesquelles TLS ne peut rien. Ainsi, un paquet TCP RST (Reset, qui va couper la connexion) imité peut couper une session TLS, puisque TLS n'authentifie et ne protège que la couche application. Une telle attaque, pratiquée par exemple par Comcast contre ses propres clients ou par la censure chinoise contre ses citoyens (voir aussi la section 2.2.1), ne marcherait pas avec BTNS.

Les sections 2 et 3 du RFC décrivent plus en détail le problème que BTNS résoud et la manière dont il le résoud (en permettant les connexions non authentifiées). La section 4, elle, revient sur le domaine d'application de BTNS. BTNS n'a pas d'intérêt pour les connexions très sécurisées, par exemple entre deux organisations qui veulent établir entre elles un VPN aussi solide que possible. Pour celles-ci, le IPsec actuel est une bonne approche. Mais BTNS est utile si :

  • Un serveur public veut accepter tous les clients mais souhaite protéger les connexions après leur établissement,
  • Un serveur sait authentifier ses clients après l'établissement de la connexion.

La section 4.1 explique les bénéfices de BTNS dans ce cas (pas d'infrastructure d'authentification à gérer) et la 4.2 ses faiblesses (le risque d'établir la connexion avec un imposteur).

Enfin, la section 5 analyse plus complètement les questions de sécurité parfois subtiles qui naissent de ce tournant dans IPsec. BTNS protège la connexion établie, mais pas l'établissement. Il est donc proche des autres protocoles TOFU (Trust On First Use ou, plus méchamment, leap of faith, « acte de foi ») comme SSH. Contrairement à SSH, BTNS ne se souvient pas forcément des clés précédemment présentées, et ne peut donc pas détecter l'arrivée d'un imposteur (cf. section 5.7).

BTNS est donc vulnérable aux attaques de l'homme au milieu (section 5.3) mais aussi à certaines attaques DoS comme tout protocole de cryptographie. En effet (section 5.4), une machine qui établit une connexion IPsec avec vous (ce qui est plus facile avec BTNS puisqu'il n'y a plus d'authentification) peut vous faire exécuter des calculs de cryptographie assez coûteux.

À l'heure actuelle, je ne connais pas d'implémentation de BTNS dans les grands projets IPsec comme Openswan.


Téléchargez le RFC 5387


L'article seul

Plusieurs noms dans un certificat X.509

Première rédaction de cet article le 14 novembre 2008


X.509 est l'énorme usine à gaz qui permet au secrétaire général de l'ITU de se vanter de la contribution de son organisation à l'Internet. Un de ses principes est que le client, par exemple HTTP, est censé vérifier que le nom dans le certificat présenté par le serveur coïncide avec le nom demandé par le client. Et si le serveur a plusieurs noms ?

Ne demandons pas à l'ITU d'avoir prévu un cas aussi simple que celui où une machine est connue par plusieurs noms, comme par exemple www.example.org et www.example.net. Il faut pour cela utiliser des extensions à X.509 telles les Subject Alternative Name du RFC 5280. Ces extensions sont correctement gérées par certains logiciels tels que OpenSSL mais pas forcément par toutes les autorités de certification.

Comment mettre de tels noms supplémentaires dans une demande de signature (CSR pour Certificate Signing Request) ? Avec OpenSSL, il faut éditer openssl.cnf pour y ajouter ces noms (je ne trouve pas de moyen de les indiquer en ligne de commande, ou de faire qu'OpenSSL les demande interactivement :

x509_extensions = v3_req   
...
[ v3_req ]
...
subjectAltName          = @alt_names

[alt_names]
# www.example.net sera donné interactivement
DNS.1   = www.example.org

Et il faut vérifier que la CSR est correcte :

% openssl req -text -in www.example.org.csr
...
           X509v3 Subject Alternative Name: 
                DNS:www.example.org
...

La CA qui signe doit elle-même gérer ces extensions. Si elle utilise OpenSSL, elle doit s'assurer d'avoir dans son openssl.cnf :

copy_extensions = copy

Rien de cela n'est spécifique à HTTP. Par exemple, si on protège ses connexions POP avec TLS, un MUA comme Thunderbird vérifie les noms et proteste si sa configuration lui dit de se connecter à mail.example.org alors que le certificat X.509 ne contient que mail.example.net. L'utilisation de noms supplémentaires résoud le problème, Thunderbird ne râle plus.

Une autre solution à ce problème est possible pour les protocoles qui ne commencent pas TLS tout de suite, qui envoient une requête STARTTLS et qui transmettent le nom du serveur (pour permettre à celui-ci de déterminer le certificat à utiliser). C'est le cas de HTTP (RFC 2817) comme le rappelle Pierre Beyssac dans un article qui cite les mises en œuvre possibles (mod_gnutls le gère apparemment).

Pour les protocoles comme POP ou IMAP (RFC 2595), qui ne transmettent pas le nom du serveur, je pense que cette autre solution ne marche pas. Une approche possible serait la Server Name Indication des extensions TLS normalisées dans le RFC 6066, section 3 (merci à Mathieu Arnold pour l'idée). Cette technique permet de transmettre le nom du serveur dans le premier message TLS et fournit donc une solution générale (là encore, elle est mise en œuvre dans GnuTLS). Voir Adieu RFC 2817, bonjour RFC 3546 pour un exemple de mise en œuvre.


L'article seul

Fiche de lecture : Blackwater

Auteur(s) du livre : Jeremy Scahill
Éditeur : Nation books
978-1-84668-652-8
Publié en 2008
Première rédaction de cet article le 12 novembre 2008


Autrefois, les sociétés de mercenaires, qui louaient leurs services aux États pour des coups tordus divers, notamment en Afrique, étaient de petites sociétés européennes ou sud-africaines, comme Sandline ou Executive Outcomes. Pas de bureaux connus, peu de frais de fonctionnement, pas de paperasses, pas de scrupules excessifs. En France, avec Bob Denard, on avait même des organisations complètement informelles, juste un groupe de brutes qui se connaissaient bien et pouvaient répondre à un coup de téléphone en cinq minutes. Mais les États-Unis sont rentrés sur ce marché et ils l'ont sérieusement professionnalisé. La plus importante société de mercernariat privée au monde, Blackwater, marque l'entrée du mercenariat dans l'ère corporate : bataillons d'avocats, service de propagande (pardon, de « communication ») étoffé, et activités de lobbying et de marketing intenses.

Le journaliste Jeremy Scahill a enquêté pendant des annnées sur Blackwater et en a sorti ce livre, la référence sur le monde des « sociétés militaires privées » (il s'agit de la seconde édition). Suivant la mode idéologique du moment, développement de la sous-traitance et réduction du rôle du service public, ces sociétés s'attaquent à ce qui semblait le dernier bastion de la puissance publique, la violence armée. En Irak, il y a déjà d'avantage de mercenaires que de soldats réguliers. Et cela devrait continuer puisque, comme le dit franchement le PDG de Blackwater, « Quand vous voulez envoyer un colis, vous ne faites pas confiance à la Poste, vous le passer à FedEx. C'est pareil pour les questions de sécurité. ».

Si, au début, les tâches des mercenaires (appelés « sous-traitants civils » désormais) se limitaient à des missions peu glorieuses de gardiennage, désormais, ils sont parfois engagés dans des combats, jusqu'à commander des troupes régulières. S'ils se limitaient aux terres lointaines et exotiques, ils sont maintenant également utilisés sur le sol national, comme à la Nouvelle-Orléans après Katrina.

Scahill décrit en détail ce monde, les budgets considérables dont il dispose, les liens étroits entretenus avec le gouvernement de Washington, la façon dont il s'est rendu indispensable au fur et à mesure du dégraissage de l'armée régulière. Blackwater réussit à payer ses hommes bien plus chers que l'armée (mais sans retraite et sans aucun avantage social), tout en se prétendant moins cher qu'elle (mais les budgets sont tellement opaques qu'il est difficile de savoir ce qu'il en est).

Dans des pays comme l'Irak, les « sous-traitants » opèrent dans la plus totale impunité. N'étant pas aux États-Unis, ils ne sont pas soumis aux lois de ce pays. N'étant pas des militaires d'active, ils ne sont pas soumis aux lois militaires ; si indulgentes soient-elles pour les tortionnaires d'Abou Ghraib, il faut noter que plusieurs soldats ont été poursuivis devant la justice militaire pour des crimes contre des civils irakiens, ce qui n'a jamais été le cas des mercenaires, même après des massacres comme celui de la place Nisour.

La puissance de cette armée privée (qui dispose même désormais de son aviation) est d'autant plus inquiétante que ses dirigeants ont un autre but dans la vie que de gagner de l'argent. Tous professent un christianisme intégriste et guerrier, et voient leur rôle comme une composante d'une croisade. Peut-être y a t-il une part de marketing dans cette attitude. Ce serait encore le moins effrayant.

Ce ne serait pas la seule contradiction de Blackwater : les lois du capitalisme sont rudes et la concurrence (DynCorp, Triple Canopy) est très présente. Après avoir clamé bien fort son patriotisme et son chauvinisme, Blackwater a fini par embaucher des chiliens et des salvadoriens car ils coûtent moins cher que les états-uniens et leur famille ne risque pas de faire un procès s'ils meurent en Afghanistan.

Peu d'hommes politiques aux États-Unis se risquent à regarder de près ce que fait le Pentagone avec les mercenaires. Scahill épingle ainsi l'inactivité de Clinton au Sénat et note qu'Obama a été plus inquisiteur... mais aussi que le recours au mercenariat est tellement présent partout qu'il sera difficile au nouveau président de revenir en arrière.

Un excellent livre, donc, sur ce monde dangereux et fermé. Il a été composé à partir d'articles parus dans la presse et il y a donc souvent des redites (parfois mot pour mot) mais c'est un reproche mineur, l'important est d'avoir des informations soigneusement vérifiées et à jour sur ce milieu.


L'article seul

RFC 5377: Advice to the Trustees of the IETF Trust on Rights to be Granted in IETF Documents

Date de publication du RFC : Novembre 2008
Auteur(s) du RFC : J. Halpern (Self)
Pour information
Réalisé dans le cadre du groupe de travail IETF ipr
Première rédaction de cet article le 11 novembre 2008


Une fois les droits de publication, et de modification, offerts par le(s) auteur(s) d'un RFC à l'IETF trust, quels droits ce dernier va t-il transmettre aux lecteurs d'un RFC ? Le RFC 5378 spécifiait les droits « entrants » à l'IETF trust, et notre RFC 5377 spécifie les droits sortants : que puis-je faire avec un RFC ? Ai-je le droit de le lire ? De le redistribuer ? De le traduire ?

Pendant longtemps, l'IETF avait été réputée plus généreuse que les autres SDO car ses RFC étaient distribués librement (alors que l'ISO ou l'ITU faisaient payer une somme considérable, qui n'était même pas justifiée par les frais de distribution puisque ces dinosaures interdisaient la reproduction et la redistribution). Mais les temps ont changé : d'autres SDO ont suivi ce chemin, à commencer par le W3C, certaines organisations traditionnelles se sont ouvertes, comme l'ITU. L'IETF est désormais dans la moyenne, plus ouverte que l'ISO mais beaucoup moins que le W3C ou OASIS.

Compte-tenu de cette tendance à l'ouverture, et du développement du logiciel libre, accompagné d'un mouvement en faveur de formats ouverts, l'IETF devait donc libéraliser sa politique de licence, qui était spécifiée dans le RFC 3978. Celle-ci spécifiait notamment que les RFC étaient distribués et redistribués librement mais que toute modification était interdite. Ce problème n'était pas purement théorique : du texte issu de RFC se retrouve souvent verbatim dans des documentations de logiciel ou dans des manuels en ligne comme la page getaddrinfo (RFC 3493) sur beaucoup d'Unix. Le texte du RFC n'étant pas modifiable, ce logiciel devenait non libre. Pire, les RFC comportent souvent du code (définitions des MIB, exemples de code, schémas XML, implémentation du protocole, etc) et celui-ci n'était pas non plus modifiable et ne pouvait donc pas être inséré dans un logiciel libre !

Il était donc nécessaire de libéraliser. Mais une partie de la « vieille garde » de l'IETF s'est opposé à toute évolution et ce RFC 5377 ne représente donc finalement qu'une libéralisation très modérée. La principale innovation par rapport au RFC 3978 est la séparation du RFC entre code et texte, avec des règles différentes, plus ouvertes pour le code.

La section 1 du RFC rappelle un point important : c'est désormais l'IETF trust qui décide. Le RFC 5377, publié par l'IETF, n'est qu'indicatif et ne fixe que des grands principes. Le texte exact de la licence des RFC est écrit par l'IETF trust (http://trustee.ietf.org/license-info/ et il existe aussi une FAQ sur ces textes.) La section 2 revient d'ailleurs sur les raisons de ce choix (pouvoir s'adapter aux changements légaux aux ÉUA, pays de l'IETF trust et de l'ISOC).

On pourra trouver ce texte standard, ce boilerplate, sur le site du Trust.

La section 2 du RFC décrit les buts que suit l'IETF en publiant des RFC (cf. RFC 3935). Clairement, l'élaboration d'une licence doit se faire en gardant ces buts à l'esprit : faire fonctionner l'Internet le mieux possible.

La section 3 explique l'articulation de ce RFC avec le RFC 5378 : les droits sortants (ceux que l'IETF trust accorde aux utilisateurs) doivent être inférieurs ou égaux aux droits entrants (ceux que l'auteur a accordé à l'IETF trust). Autrement dit, l'IETF ne peut pas donner de droits qu'elle n'a pas. Si l'auteur d'un RFC interdit toute modification à son texte, le RFC publié ne permettra pas de modifications (et ne pourra d'ailleurs pas être publié sur le chemin des normes).

La section 4 s'attaque aux droits que l'IETF trust devrait donner aux utilisateurs :

  • Droit de publier et de republier (section 4.1), une très ancienne politique de l'IETF,
  • Droit (évidemment) d'implémenter la technique décrite dans le RFC (section 4.3). C'est ici qu'apparait la distinction entre code et texte. Par un mécanisme non spécifié dans le RFC (cela a été choisi par la suite comme une liste publiée par l'IETF trust), le code sera marqué spécialement et l'implémenteur aura d'avantage de droits sur le code, notamment le droit de modification. Cela ne résoud pas, et de loin, tous les problèmes. Par exemple, cela ne permet pas de modifier du texte d'un RFC qui est inclus dans la documentation d'un logiciel.
  • Droit de modifier le texte ? Non, ce droit est exclu par la section 4.4. La montagne a donc accouché d'une souris : si ce RFC représente une libéralisation, elle reste très modérée et limitée au code.

Les discussions sur le groupe de travail IPR ont été longues et passionnées. Elles opposaient surtout la vieille garde IETF, attachée à ne rien changer et effrayée par les changements survenus avec le développement du logiciel libre, mais aussi du Web (avec ses mashups, son Wikipédia et autres preuves de l'importance du droit de modification) aux partisans du logiciel libre comme Simon Joseffson ou Lawrence Rosen. Notons que Joseffson a écrit quatre RFC, comportant souvent du code. Je cite ce point car un des arguments les plus vicieux d'un débat qui en a compté beaucoup était que les partisans d'une libéralisation n'avaient jamais écrit de RFC et donc devaient se taire !

Pourquoi donc cet acharnement à refuser les modifications ? La raison la plus souvent invoquée était le désir d'éviter l'apparition de « RFC non officiels », incompatibles avec les « vrais », qui pourraient semer la confusion. Ainsi, un « méchant » pourrait créer un document mettant à jour le RFC 5321 en remplaçant EHLO par GDAY. Outre que cette « attaque » reste très théorique, plusieurs participants ont fait remarquer que les nouvelles règles ne l'empêchent pas et que la seule protection contre ce genre de problèmes serait dans le droit des marques, par exemple en faisant déposer la marque RFC pour empêcher le document du méchant de se présenter comme RFC. Or, ce point n'a jamais été considéré...

Notons enfin que beaucoup de participants à l'IETF n'ont pas du tout suivi ce qui se passait dans ce petit groupe, en général par manque d'intérêt pour les questions politiques et juridiques.


Téléchargez le RFC 5377


L'article seul

RFC 5378: Rights Contributors provide to the IETF Trust

Date de publication du RFC : Novembre 2008
Auteur(s) du RFC : S. Bradner (Harvard University), Jorge Contreras (WilmerHale)
Réalisé dans le cadre du groupe de travail IETF ipr
Première rédaction de cet article le 11 novembre 2008


Pendant longtemps, l'IETF a vécu avec l'illusion qu'elle était une organisation purement technique, vouée uniquement à produire les meilleures normes possibles, sans considération pour les questions « vulgaires » comme le droit. Désormais, l'IETF est rattrapée par la judiciarisation croissante de la société, surtout aux ÉUA, où se trouve la majorité des structures formelles qui comptent pour l'IETF (notamment l'ISOC, l'IETF elle-même restant informelle et non enregistrée). Avec l'enthousiasme des néophytes, une partie de l'IETF s'est donc engagée dans la voie d'un travail sur les questions de propriété intellectuelle (un terme d'ailleurs très contestable, puisque mêlant des choses aussi différentes que le droit d'auteur, les brevets et le droit des marques). Ce RFC décrit les « droits entrants », c'est-à-dire ceux dont l'IETF a besoin, et qui doivent lui être accordés par les participants aux travaux et notamment par les auteurs de RFC (la convention de Berne faisant que les auteurs ont automatiquement certains droits sur leur œuvre).

Si des notions de « propriété intellectuelle » apparaissaient déjà dans le RFC 2026 en octobre 1996, le premier RFC fournissant un cadre complet à ces questions a été le RFC 3667 en février 2004, remplacé par le RFC 3978 puis par notre RFC 5378. Le principal changement (section 10) est la séparation plus claire entre les droits « entrants » (ce que le contributeur donne à l'IETF) et les droits « sortants » (ce que l'IETF donne aux utilisateurs), décrits dans le RFC 5377.

Ce dernier RFC, écrit par un « grand ancien » de l'IETF (dont l'activité récente est essentiellement consacrée aux questions de propriété intellectuelle) et un avocat (qui, logiquement, pousse toujours l'IETF vers d'avantage de judiciarisation), est donc la version actuelle de la politique de l'IETF. Il détaille les droits que les contributeurs (participants au processus IETF) doivent transmettre à l'IETF trust, l'organisme (largement indépendant de l'IETF et étroitement contrôlé par l'ISOC et CNRI) qui est censé administrer la propriété intellectuelle de l'IETF (voir RFC 4748).

L'IETF trust ne peut en effet pas donner aux utilisateurs des RFC des droits qu'il n'a pas lui-même reçu. Pour pouvoir distribuer un RFC, le traduire, ou en extraire des parties, les droits automatiquement donnés par l'auteur (comme le droit de citation ou comme le fair use) ne suffisent pas. Il faut que les auteurs donnent explicitement d'avantage de droits.

La section 5 décrit les droits en question. 5.3 porte sur les droits donnés à l'IETF trust : droits de publication (évidemment), de traduction, d'utilisation des marques que contient le document, etc. 5.5 explique que ces droits n'impliquent pas de licence d'utilisation des technologies présentées dans le RFC (l'IETF, contrairement au W3C ou, dans certains cas, à OASIS, accepte de normaliser des technologies brevetées).

Pour que tout le monde puisse connaître ses droits, la section 6 explique le mécanisme de publication de ceux-ci par le biais d'un boilerplate, officiellement appelé legend. Ce boilerplate, un texte légal attaché à chaque RFC, ne figure pas dans notre RFC 5378. En effet, l'évolution des lois états-uniennes, les changements d'interprétation, peuvent nécessiter une évolution du texte, alors qu'un RFC n'est pas facile à changer. L'IETF trust reçoit donc un quasi-chèque en blanc pour rédiger le texte en question et le tenir à jour sur son site Web (c'est le second grand changement par rapport au RFC 3978).

La section 3 du RFC explique le raisonnement derrière les choix effectués (on peut aussi consulter la FAQ du trust). Par exemple, 3.3 explique que l'auteur doit donner le droit de faire certaines modifications (derivative works) car l'IETF doit pouvoir faire évoluer le RFC suivant l'évolution de la technologie. Elle explique aussi pourquoi cette règle peut comporter des exceptions, par exemple lorsque l'IETF re-publie sous forme de RFC une norme d'une autre organisation.

Comme le travail a été plutôt bâclé, un gros problème n'est survenu que plus tard lorsque des auteurs se sont aperçus que le nouveau texte interdisait de réutiliser du texte d'anciens RFC... La chasse aux auteurs de ces anciens RFC a donc commencé, pour les convaincre d'abandonner leurs droits (voir l'article IETF Shoots Itself in the Foot).


Téléchargez le RFC 5378


L'article seul

Spectacle Le Mur

Première rédaction de cet article le 10 novembre 2008


En août 2008, à Morlaix, lors du Festival des Arts de la Rue, j'ai assisté au spectacle « Le Mur » de la compagnie 1 Watt.

C'est une extraordinaire spectacle, délirant, sur la construction d'un mur par deux voisins qui ne savent pas pourquoi ils le construisent. Les mouvements des acteurs sont fabuleux (par exemple le balayage du sol avec le dos).

La question reste ouverte : « Qu'est-ce qui vous anime ? », demandent-ils plusieurs fois aux spectacteurs ? « Le sexe ? Le pouvoir ? Le poulet ? »


L'article seul

Un portage d'un site Web Mason vers Apache 2

Première rédaction de cet article le 10 novembre 2008


J'ai passé une bonne partie de la journée à porter un site Web Mason vers une nouvelle machine. Comme la première avait Apache 1 et mod_perl 1 et que la seconde machine avait les versions 2, cela n'a pas été tout seul.

J'utilisais pas mal Mason à un époque. C'est un environnement de développement en Perl pour faire des sites Web dynamiques. Il est utilisé notamment pour amazon.com. Il s'appuie sur l'intégration de Perl dans Apache, mod_perl.

On trouve pas mal de récits d'expérience d'une telle migration sur le Web. Curieusement, tout le monde n'a pas eu les mêmes bogues et ce n'est pas la même solution qui marche pour tous. Voici donc les deux points qui ont été les plus bloquants pour moi.

J'avais un fichier index dans chaque répertoire et une directive DirectoryIndex index dans la configuration d'Apache. En Apache 1, cela marchait mais, en Apache 2, la directive DirectoryIndex semble complètement ignorée dans un répertoire géré par Mason. Résultat, lorsque le client HTTP demandait un URL qui se terminait par un répertoire, pas un fichier, le serveur renvoyait un code 404 et notait dans son journal [error] [client 192.134.4.69] Attempt to serve directory: /var/www/www.generic-nic.net/dyn/whois/.

La solution qui a marché pour moi est de chercher le fichier index via une règle de réécriture Apache :

RewriteEngine on
RewriteRule ^(.*)/$ $1/index

Cette règle dit que si l'URL se termine par /, on ajoute index à la fin. Ce n'est rien, mais j'ai dû essayer pas mal de fausses solutions avant, souvent très complexes.

Le second problème concernait l'appel d'une méthode dans les fichiers Mason. Pour donner un titre aux pages, le site utilisait une technique Mason très classique :


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>        
<title>Generic NIC: <& SELF:title &></title>

<& SELF:title &> signifiait qu'on appelle la méthode title. Celle-ci est définie dans chaque page :


<%method title>Technical details on the domain information</%method>

Mais cette technique ne marche plus avec mod_perl 2, la méthode n'est plus dans l'espace SELF mais dans REQUEST. Il faut donc réécrire le fichier qui contient l'en-tête HTML ainsi :


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>        
<title>Generic NIC: <& REQUEST:title &></title>


L'article seul

Pourquoi les RFC sont-ils encore en texte brut ?

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


Les RFC, documents qui incluent les normes de l'Internet, sont publiés en texte brut, sans aucune fioriture ou marquage. Pourquoi un tel conservatisme ?

Le RFC 2223, le RFC qui normalisait les RFC (il a été remplacé depuis par le RFC 7322), précise que le seul format faisant autorité est la version en texte seul, encodée en ASCII. Malgré de nombreuses tentatives, il n'a pas encore été possible de faire évoluer cette règle. Il y a des bonnes et des mauvaises raisons à cela. (Depuis la parution de cet article, le texte brut est en voie d'abandon, cf. le RFC 7990.)

Le premier RFC, le RFC 1, a été publié en avril 1969. À l'époque, même le jeu de caractères ASCII était une nouveauté. Bien sûr, ce RFC n'a plus d'utilité de nos jours. Mais plusieurs RFC très anciens restent des normes en vigueur. Même si on écarte le RFC 20 qui normalise le texte en ASCII, le plus ancien RFC encore en service semble être le RFC 768, qui normalise UDP, et qui date d'août 1980, il y a vingt-huit ans.

Cela nous donne la première explication : la permanence. Une norme, surtout celles utilisées par un réseau aussi essentiel que l'Internet, doit pouvoir être encore lisible des années après, longtemps après que les tendances en matière de format aient changé. Si le RFC 768 avait été écrit avec le traitement de textes à la mode chez les managers de l'époque, il ne serait plus lisible aujourd'hui. Le format « texte brut » (RFC 3676) est le seul qui aie traversé cette époque.

Mais il y a d'autres critères : l'accessibilité en est un. Tout le monde, quelle que soit la plate-forme informatique utilisée, peut lire et écrire du texte brut. Cela garantit la participation maximale. Si, au lieu de distribuer les RFC en texte brut, on utilisait le format privé d'un éditeur de logiciels états-unien particulier (au hasard, Microsoft Word puisque beaucoup de blaireaux envoient systématiquement leurs documents dans ce format, sans s'être demandé si leurs destinataires pouvaient le lire), les RFC cesseraient d'être universels. Le texte brut est le PGCD des formats.

Il présente également un intérêt pour le programmeur : écrire un programme qui cherche dans les RFC ne nécessite pas de lire des spécifications compliquées d'abord (comme c'est le cas avec l'ultra-difficile PDF, pour lequel il existe très peu de mises en œuvre distinctes). Un simple grep (ou outil équivalent) suffit.

Mais le texte brut en ASCII n'a t-il pas également des limites ? Bien sûr. Il rend difficile de représenter les noms des auteurs, s'ils sont chinois, allemands ou arabes (par exemple Martin Dürst qui, dans le RFC 3987 doit expliquer comment écrire proprement son nom ou Bill de hÓra dans le RFC 5023 ce dont son co-auteur s'est plaint). Il rend pénible les exemples Unicode comme dans les RFC 3490 ou RFC 5198. Il ne permet pas de représenter les formules mathématiques, même relativement simples, comme celles des RFC 5905 ou RFC 5348. Il ne permet pas d'inclure des images autres que l'art ASCII encore que ce point soit discutable : la plupart des images contenues dans les RFC sont des diagrammes assez formels, qui seraient mieux représentés dans un langage spécialisé comme Cosmogol. L'ASCII ne permet même pas de mettre en évidence un mot en l'indiquant en gras ; pire, il semble que le RFC editor refuse les conventions ASCII courantes qui consistent à entourer le mot de * ou de _. Ainsi, distinguer une variable d'un litéral dans une spécification est souvent problématique (alors qu'un format comme Docbook le fait trivialement avec l'élément <replaceable>). Avec l'ASCII pur, il faut deviner que, lorsqu'une norme parle de http://example.com/, que http est un litéral et example.com une variable, juste un exemple.

Face à ces limites, les tentatives de faire évoluer la règle du RFC 2223 n'ont pas manquées. Ainsi, le RFC 7749 propose un format XML. XML est une norme ouverte, présente depuis suffisamment d'années pour qu'on puisse avoir confiance dans sa stabilité. Si les outils d'édition sont un peu rudes, ce n'est normalement pas un problème pour les auteurs de RFC, qui sont tous des techniciens pointus. Hélas, ce format n'a jamais été adopté officiellement, en partie à cause de l'opposition virulente de Microsoft, en partie par simple conservatisme. Le RFC editor (une organisation séparée de l'IETF, sur laquelle l'IETF n'a pas de pouvoir) est en effet très conservateur. C'est dans son travail (qui est de rendre les normes accessibles à tous pendant très longtemps) mais la déformation professionnelle devient parfois excessive. (Depuis, la sortie du RFC 7990 a marqué le début de la fin pour le texte brut.)

À la rigueur, serait-il possible d'autoriser au moins le jeu de caractères Unicode (après tout, « texte brut » n'implique pas forcément ASCII) ? C'est ce qui a été proposé de nombreuses fois, par exemple dans l'Internet-Draft draft-hoffman-utf8-rfcs, actuellement en cours de discussion. Mais le RFC editor continue à s'y opposer. (Les partisans d'Unicode ont finalement eu gain de cause avec le RFC 7997.)


L'article seul

Obsolescence des ordinateurs

Première rédaction de cet article le 6 novembre 2008


Comme la question de l'« obsolescence programmée » des ordinateurs est souvent mentionnée lors de discussions sur le développement durable, j'ai fait deux petites expériences avec des « vieux » ordinateurs, pour voir s'ils pouvaient encore servir pour le travail quotidien.

J'ai d'abord sorti de mon placard un vieux portable Compaq Armada 1570. Je l'avais acquis en 1999 (d'occasion : il a en fait quelques années de plus). Il a un processeur Pentium 200 Mhz, 32 Mo de mémoire et (quand même) plus d'un giga-octet de disque dur. J'ai utilisé le logiciel qu'il avait à l'époque, Debian et les paquetages de ce temps.

Ce qui marche très bien sur cet appareil :

  • un SGBD relationnel complet, PostgreSQL (bien plus riche que, par exemple, MySQL).
  • des langages de programmation dits « de script », pourtant généralement considérés comme lents et gourmands, comme Python ou Perl.
  • L'éditeur emacs, longtemps réputé lent et lourd (Eight Megabytes And Constantly Swapping, ce qui fait rire aujourd'hui quand on voit la taille qu'occupent les traitements de texte modernes).
  • le formateur LaTeX, souvent présenté comme gourmand (mais infiniment moins qu'OpenOffice). On peut donc écrire des textes sophistiqués.

Ce qui nécessite des adaptations :

  • le Web est utilisable via le navigateur lynx. Le seul navigateur graphique qui marche de manière acceptable est Dillo. Konqueror tourne mais swappe (manque de mémoire).
  • le courrier est utilisable via le logiciel client mutt.

Ce que je n'ai même pas essayé :

  • l'audio.
  • la vidéo.

Notons que la matériel fonctionne aussi bien qu'au premier jour, sauf la batterie, qui ne se charge plus.

Souvent, une certaine adaptation de l'utilisateur est nécessaire. Ainsi, l'éditeur Emacs et le SGBD PostgreSQL tournent bien tous les deux, mais séparément. Si on passe de l'un à l'autre très vite, le swapping devient insupportable. Il faut donc adapter son style de travail, taper plus longtemps dans l'éditeur avant de tester ses programmes, etc.

Une autre expérience a porté sur un portable bien plus récent, un Dell Inspiron 7500, acheté (d'occasion) en juillet 2005. 256 Mo de mémoire, un Pentium de 400 Mhz. Contrairement au premier, il a été testé avec un système d'exploitation actuel, le dernier Ubuntu.

En plus des applications qui marchent bien sur le plus vieux des PC, il peut en outre exécuter Firefox, OpenOffice et bien d'autres applications modernes. La taille des applications modernes fait qu'il n'est pas plus rapide que son ancêtre. Mais il peut quand même faire tourner les services actuels. Il reste trop lent pour la vidéo (Youtube défile à deux images par seconde) mais ce n'est pas un problème pour la bureautique.

La conclusion est mixte : on peut travailler avec ces ordinateurs, bien sûr. Des millions de gens l'ont fait et s'en trouvaient très bien. Mais cela peut nécessiter des logiciels différents de ceux d'aujourd'hui (trop gaspilleurs) et des comportements différents de la part de l'utilisateur (ce qui est, après tout, souvent le cas en matière de développement durable).


L'article seul

RFC 2047: MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text

Date de publication du RFC : Novembre 1996
Auteur(s) du RFC : Keith Moore (University of Tennessee)
Chemin des normes
Première rédaction de cet article le 2 novembre 2008


La série de RFC sur MIME, qui a introduit les caractères composés (et les écritures non-latines), ainsi que les objets multimédia, dans le monde du courrier électronique, comprend, entre autres, ce RFC qui normalise une méthode pour mettre des caractères non-ASCII dans les en-têtes du courrier, ces métadonnées situées avant le corps du message et structurées en nom: valeur.

Normalement, le courrier, tel qu'il était normalisé par le RFC 822 (aujourd'hui RFC 5322), ne permettait que le jeu de caractères ASCII dans les en-têtes. C'est ainsi qu'il fallait écrire :


From: Stephane Bortzmeyer <bortzmeyer@sources.org>
Subject: Du cafe bien fort !

au lieu de la forme correcte en français :


From: Stéphane Bortzmeyer <bortzmeyer@sources.org>
Subject: Du café bien fort !

Notre RFC 2047 vise tout simplement à fournir une solution à ce problème, en encodant les caractères non-ASCII, en Quoted-Printable ou en Base64. Les en-têtes ci-dessus apparaitront donc sur le réseau comme :


From: =?iso-8859-1?q?St=E9phane?= Bortzmeyer <bortzmeyer@sources.org>
Subject: Du =?iso-8859-1?q?caf=E9?= bien fort !

Ainsi, le message pourra passer à travers toute l'infrastructure du courrier qui n'accepte que l'ASCII. Ce sera au MUA de les remettre sous une forme lisible (voir par exemple mon article Décoder les en-têtes du courrier électronique).

L'approche de notre RFC est donc conservatrice : on ne demande pas à tous les logiciels sur le trajet de connaître MIME, autrement ce dernier n'aurait jamais été déployé. (MIME n'utilise même pas, par prudence, certaines fonctions du RFC 822 qui auraient pu aider mais qui sont trop souvent boguées, cf. section 1.) Aujourd'hui où l'infrastructure du courrier est très différente, une méthode plus radicale pourrait être réaliste et c'est l'approche du bien plus récent RFC 6532.

La section 2 du RFC donne la grammaire exacte : un terme encodé est précédé de =? suivi de l'encodage des caractères. (Pour le corps du message, tel que normalisé dans le RFC 2045, l'encodage est indiqué dans un en-tête, Content-Type. Pour les en-têtes eux-mêmes, il a fallu trouver une autre solution.) Puis on trouve le surencodage appliqué par MIME, Q pour Quoted-Printable et B pour Base64 puis le terme lui-même, ainsi encodé. Le tout est terminé par un ?=. Voici le résultat, produit par un programme Python avec le module email :


% python
>>> from email.header import Header
>>> h = Header('niçoise', 'iso-8859-1')
>>> print h
=?iso-8859-1?q?ni=E7oise?=

Notons que l'encodage utilisé est appelé charset (jeu de caractères) par MIME, ce qui n'est pas vraiment le terme correct (« utf-8 » est un encodage, le jeu de caractères est Unicode). La section 3 normalise ce paramètre, pour lequel les valeurs standard de MIME sont utilisées.

La section 4 décrit en détail les surencodages possibles, Quoted-Printable et Base64. Le premier (RFC 2045) convient mieux lorsque le texte comprend des caractères latins, avec quelques caractèrs composés. Le second (RFC 4648) est préférable si le texte est composé de caractères non-latins. La section 4.2 détaille quelques spécificités de Quoted-Printable et notamment l'utilisation du _ à la place de l'espace comme dans :


% python
>>> from email.header import Header
>>> h = Header("réveillés dans une Citroën niçoise", "ISO-8859-1")
>>> print h
=?iso-8859-1?q?r=E9veill=E9s_dans_une_Citro=EBn_ni=E7oise?=

Pour le même genre de tâches, les programmeurs Perl peuvent utiliser Encode::MIME::Header.


Téléchargez le RFC 2047


L'article seul

Configurer un serveur relais pour accéder à des sites Web filtrés

Première rédaction de cet article le 1 novembre 2008
Dernière mise à jour le 3 novembre 2008


Il arrive que certains sites Web soient filtrés et interdits d'accès, soit par l'État (cas de Dubaï), soit par une entreprise qui ne veut pas laisser ses employés aller sur certains sites. Une technique courante pour contourner ces filtres est le relais HTTP.

Avant de voir comment en configurer un, un sérieux avertissement. Les gens qui filtrent n'aiment pas qu'on contourne leurs filtres. Si le filtrage est le fait de l'État, le contourner peut être illégal et vous valoir de gros ennuis, notamment dans des pays comme la Chine ou la Tunisie. Si le filtrage est le fait de votre patron, celui-ci a pu indiquer dans le réglement intérieur ou bien à un endroit similaire que les tentatives de contournement étaient également interdites et pouvaient vous valoir un licenciement. Donc, soyez prévenu...

Il existe plein de façons de configurer un relais HTTP et plein de logiciels pour cela. Je ne vais pas me lancer dans la comparaison détaillée de toutes ces méthodes, simplement indiquer comment je l'ai fait pour moi.

Il faut d'abord une machine, le relais, allumée en permanence et connectée à Internet, proxy.bortzmeyer.org dans les exemples qui suivent. Aujourd'hui, de telles machines se trouvent pour moins de dix € par mois.

J'ai choisi le logiciel Apache, qui était déjà installé sur la machine. Il faut qu'il inclue l'option de relayage (proxy) ce qui, sur ma Gentoo, est le cas si, dans /etc/make.conf, on a dans la définition de APACHE2_MODULES les modules proxy proxy_ajp proxy_balancer proxy_connect proxy_http (avant de compiler Apache, bien sûr).

Il faut ensuite configurer Apache en relais. Pour simplifier, je mets les directives nécessaires dans un fichier de Virtual Host, ici /etc/apache2/vhosts.d/proxy.conf :


<IfDefine PROXY>
Listen [::1]:8080
<VirtualHost [::1]:8080>
ProxyRequests On
<Proxy *> # Do not delete!
Order Deny,Allow
Deny from all
Allow from ::1
</Proxy>
</VirtualHost>
</IfDefine>

Ici, on dit à Apache, si la variable PROXY est définie (sur une Gentoo, c'est dans /etc/conf.d/apache2), il doit écouter sur le port 8080 et autoriser le relais.

Attention, les lignes qui suivent (celles qui commencent par <Proxy *>) restreignent l'usage du relais à la machine locale et elles sont indispensables sinon votre relais est un relais ouvert (n'importe qui peut l'utiliser) et les méchants détectent en quelques heures un relais ouvert - c'est ce qui m'est arrivé - et l'exploitent pour cacher leurs traces.

Rechargez Apache et, pour tester si tout va bien, depuis la machine Apache, par exemple avec curl :

% curl -v --proxy localhost:80 http://www.ras.eu.org/ > /dev/null
...
< HTTP/1.1 200 OK
< Date: Sat, 01 Nov 2008 12:36:03 GMT
< Server: Apache
...

Ici, tout s'est bien passé. Depuis une autre machine, testez que l'accès est refusé :

% curl -v --proxy proxy.bortzmeyer.org:80 http://www.ras.eu.org/ > /dev/null 
...
< HTTP/1.1 403 Forbidden

(On a testé le port 80 car, précaution supplémentaire, le Virtual Host Apache qui fait le relais n'écoute que sur l'adresse locale ::1.) La documentation d'Apache insiste bien sur la nécessité de ne pas ouvrir complètement le relais (Controlling access to your proxy).

Mais, si le relais n'est accessible que depuis la machine relais elle-même, comment l'utiliser depuis ma machine située derrière le filtre ? Comme on souhaite en plus que le fait que l'accès au relais soit discret (rappelez vous les avertissements au début), on va chiffrer la communication. L'idéal serait que les clients HTTP puissent accéder au relais avec TLS. Mais, apparemment, ni Firefox, ni Opera, ni wget ne savent le faire. Donc, on va créer un tunnel ssh depuis la machine de l'utilisateur, vers le relais :

% ssh -f -N -v -L localhost:6666:\[::1\]:8080 proxy.bortzmeyer.org

(si on trouve cette commande trop longue à taper à chaque fois, on peut utiliser un alias, ou bien la mettre automatiquement en route à la connexion, par exemple dans le fichier ~/.xsession ; on peut aussi utiliser autossh). Cette commande fait suivre tout message envoyé au port 6666 de la machine locale vers le relais, puis au port 8080 de ce dernier (notez l'utilisation de la syntaxe du RFC 2732, [::1]:8080, pour distinguer l'adresse IP du numéro de port). -f fait s'exécuter la commande de manière non-interactive.

Il ne reste plus alors qu'à dire au navigateur Web d'utiliser http://localhost:6666/ comme relais. Ici, avec curl et la variable d'environnement http_proxy :

% export http_proxy=http://localhost:6666/
% curl -v http://www.ras.eu.org/ > /dev/null

Avec Firefox, il est sans doute préférable d'utiliser l'extension FoxyProxy, qui permet de jongler facilement avec les différentes options pour les relais.

Merci à Pascal Courtois, Thomas Quinot et Bertrand Petit pour leur aide.

Il existe une alternative à la solution « tunnel SSH + logiciel relais HTTP » présentée ici (avec Apache comme logiciel relais). Cette solution m'a été proposée par Samuel Tardieu, Ollivier Robert, Yannick Palanque ou Eon Knight : elle consiste en un tunnel SSH plus le protocole Socks pour éviter d'installer un relais explicite derrière le tunnel. On lance le tunnel SSH avec l'option -D pour relayer le Socks :

% ssh -f -N -v -D localhost:6667 proxy.bortzmeyer.org

et on peut alors dire aux navigateurs Web d'utiliser le relais Socks localhost:6667. Par exemple, avec curl :

curl -v --socks5 localhost:6667 http://www.ras.eu.org/

Mais attention : tous les logiciels ne parlent pas forcément le Socks. curl ou Firefox le font, mais ni wget, ni lynx. Même chose pour les bibliothèques d'accès au Web comme httplib qui nécessitent du code supplémentaire pour utiliser Socks :

proxy = socks.socksocket()
proxy.setproxy(socks.PROXY_TYPE_SOCKS5, 'localhost', 6667)
conn = httplib.HTTPConnection("www.ras.eu.org", 80)
conn.sock = proxy

On peut certes utiliser une bibliothèque comme tsocks pour « socksifier » les applications non-Socks mais ma solution avec Apache me paraît plus claire.

Au fait, petit avertissement à propos de Socks et Firefox (merci à Yannick Palanque). Par défaut, Firefox fait la résolution DNS en local (cf. réglage network.proxy.socks_remote_dns). Il faut y penser si on veut rester discret en utilisant un tunnel SSH.


L'article seul

KCM, gérer des clés cryptographiques sans autorité de certification

Première rédaction de cet article le 28 octobre 2008


Dans tout système utilisant la cryptographie, la gestion des clés est la principale plaie. La cryptographie garantit qu'un tiers ne pourra pas modifier, ni même écouter la communication mais comment savoir si l'interlocuteur auquel on parle n'est pas justement celui dont on veut se protéger ? Dans le monde physique, on reconnait sa voix et son visage, mais une clé cryptographique n'a pas de voix. Le mécanisme KCM (Key Continuity Management) s'attaque à ce problème.

Prenons pour simplifier le cas du courrier électronique. Pour authentifier un message et pour s'assurer de sa confidentialité, on le chiffre avec la clé publique du destinataire. Mais comment savoir si c'est la bonne ? Les deux normes les plus répandues de chiffrement du courrier, PGP (RFC 3156 et RFC 4880) ou S/MIME (RFC 3850) utilisent deux approches opposées.

PGP utilise des clés qui sont signées par qui le veut, souvent à l'occasion de sessions de signature. Si une clé a été signée par quelqu'un à qui on fait confiance, on l'utilise. Sinon, on prend un risque, celui d'utiliser une clé qui est peut-être celle d'un imposteur. C'est donc à l'utilisateur de prendre des décisions de sécurité (« La clé de Jeanne est signée par Paul, et celle de Paul par moi. Mais Paul signe t-il après des vérifications sérieuses ? ») Le mécanisme est simple, ne nécessite pas d'autorité de certification centrale et marche bien... au sein de petites communautés solides. Il n'a jamais fonctionné pour l'ensemble de l'Internet.

S/MIME, au contraire, repose sur X.509 et dépend donc d'autorités de certification qui signent les messages. L'utilisateur n'a plus de décisions à prendre. Mais ces autorités de certification sont chères, complexes et il n'est pas évident qu'elles fournissent effectivement une bonne sécurité.

En se tournant vers d'autres protocoles, on peut trouver d'autres idées. Ainsi, SSH (RFC 4251) utilise par défaut un mécanisme dit TOFU pour « Trust On First Use ». Les clés des machines auxquelles on se connecte ne sont quasiment jamais vérifiées lors de la première connexion mais elles sont stockées dans le fichier ~/.ssh/known_hosts et, si elles changent par la suite, SSH interrompt la connexion. Si on a la chance que le méchant ne soit pas en train de mener un détournement du DNS ou de BGP juste au moment de la première connexion, on peut être tranquille pour la suite. (Le terme plus formel pour TODU est « leap of faith » qu'on trouve souvent dans la littérature sur la sécurité des réseaux. On parle aussi du mécanisme « bébé-oie » par allusion au fait que l'oie sortie de l'œuf considère le premier être vu comme sa mère) Ce mécanisme de TOFU a des limites (et il existe des projets pour l'améliorer comme Perspectives) mais marche « suffisamment bien » pour l'instant.

Peut-on l'étendre au courrier ? Oui, répondent Simson Garfinkel et Robert Miller dans leur article Johnny 2: A User Test of Key Continuity Management with S/MIME and Outlook Express. L'idée de base est simple : à chaque configuration d'une nouvelle identité de courrier, le logiciel crée automatiquement une nouvelle paire de clés et envoie la clé publique avec le message. Au premier message reçu de cette adresse, il faudra décider si on l'accepte ou pas mais, ensuite, la clé est conservée et, si elle change, cela indique probablement qu'un usurpateur tente d'utiliser cette adresse, sans avoir la bonne clé.

Le mécanisme a été testé lors d'une experiénce nommé « Johnny 2 » (ainsi nommée en référence au célèbre article « Why can't Johnny encrypt? » qui concluait que les problèmes d'utilisabilité étaient au cœur des difficultés de déploiement de la cryptographie). Le résultat est très positif, montrant que les utilisateurs se débrouillent bien avec les différents cas de figure (premier message d'un correspondant, message suivant, message d'un usurpateur).


L'article seul

Exposé DNSwitness à la réunion RIPE de Dubaï

Première rédaction de cet article le 28 octobre 2008


Le 28 octobre, à Dubaï, j'ai eu le plaisir de faire un exposé lors de RIPE 57, l'une des réunions RIPE, réunions rassemblant les acteurs de l'Internet européen (comme vous pouvez le voir, l'Europe du RIPE s'étend assez loin...) L'exposé portait sur DNSwitness, le logiciel de mesures des données DNS que j'ai développé à l'AFNIC. Cet exposé a été fait au sein du groupe de travail DNS.

Voici les documents produits à cette occasion :


L'article seul

Censure à Dubaï

Première rédaction de cet article le 27 octobre 2008


Plusieurs pays filtrent le contenu diffusé sur le Web et ne laissent pas leurs citoyens y accéder. On connait le cas de la Chine, de la Tunisie, de l'Arabie Saoudite. Mais cela arrive aussi dans des pays moins souvent cités comme les Émirats arabes unis.

Voici, depuis Dubaï, ce qu'on obtient si on essaie d'accéder à un site interdit : uae-web-blocked.jpg

La redirection du port 80 est faite automatiquement, donc on ne peut pas la contourner sur sa machine locale (on peut bien sûr utiliser un relais à soi, accessible en HTTPS quelque part ; par contre, Tor ne marche pas.)

Notons que tout n'est pas si noir aux Émirats : au moins, on est prévenus franchement (il semble qu'en Tunisie, le filtre est hypocrite : il ne répond pas, faisant ainsi croire à une erreur réseau.).

(Tiens, c'est amusant, Bruce Schneier blogue sur le même sujet une semaine après.)


L'article seul

Le budget de l'IETF et le coût d'un RFC

Première rédaction de cet article le 27 octobre 2008


Combien coûte le travail de normalisation ? Ce travail implique en général plusieurs acteurs, donc les coûts sont difficiles à calculer. Mais certaines SDO sont suffisamment ouvertes pour publier un budget détaillé, donc, on peut savoir, par exemple, combien chaque RFC a coûté à l'IETF.

Les RFC sont écrits par des volontaires de diverses sociétés et organisations. Attention, j'ai écrit « volontaire », pas « bénévole ». La plupart sont en effet payés par leur société pour ce travail, et cela n'apparait pas dans le budget. Ce qui y apparait, ce sont les dépenses directes de l'IETF, comme les versements effectués au RFC editor, une fonction séparée de l'IETF, actuellement exercée par l'ISI.

Quel est le budget de l'IETF ? Il est surveillé par l'IAOC, un organisme créé par le RFC 4071. L'IAOC publie toutes les informations utiles sur son site Web. On y trouve par exemple le budget 2007 ou celui (pas encore exécuté) de 2008.

Les montants ne sont pas négligeables pour une organisation fondée sur le volontariat. Pour 2007, on trouve pas moins de 744 500 dollars pour le RFC editor.

Comme il y a eu 321 RFC publiés en 2007 (cf. http://www.rfc-editor.org/rfc.html), cela ferait 2 300 dollars par RFC, uniquement pour le travail du RFC editor, sans compter celui des auteurs, relecteurs, etc...


L'article seul

Portabilité des données d'un site Web ?

Première rédaction de cet article le 25 octobre 2008


Aujourd'hui, un grand nombre de sites Web sont techniquement gérés par un CMS ou un moteur de blog. Cela présente bien des avantages, notamment la séparation du contenu (placé dans la base de données) et de la présentation. Mais cela pose le problème de la portabilité des données. Si j'ai passé trois ans à remplir mon blog avec Wordpress, puis-je passer sur Dotclear ? Si j'ai tout mis dans SPIP, que se passe t-il si je migre vers un site à base de Drupal ?

Avec les premiers sites Web, faits en HTML (à la main ou via un logiciel d'édition HTML comme nvu), c'était simple, HTML étant un format standard et ouvert, la portabilité des pages était automatiquement assuré. Mais HTML souffre d'autres inconvénients, notamment parce que la structure de la page (titre, menu, case pour le moteur de recherche, etc) et son contenu (spécifique à chaque page) sont mélangés. Si on veut mettre à gauche le menu qui était à droite, on n'a pas de solution simple, il faut reprendre toutes les pages. Donc, il est logique que des outils comme les CMS ou les moteurs de blog se soient imposés. Mais, à l'occasion, on a perdu la portabilité. Désormais, changer de logiciel devient difficile. Dans tous les cas, les gabarits sont perdus, parfois les informations sur les auteurs (qui peut écrire, qui peut modifier) mais peut-on au moins récupérer le contenu, ces articles qu'on a passé tant de temps à taper ? A priori, cela ne marchera pas : le schéma de la base de données est différent et le langage dans lequel sont décrites les données est également différent.

Cela a mené à la prise de conscience du problème de la portabilité des données, sous-ensemble du problème général de la préservation des ressources numériques. À l'heure actuelle, les utilisateurs sont, trop souvent, prisonniers d'un logiciel particulier car en changer signifierait la perte d'un contenu significatif.

Commençons par les langages. La plupart des CMS ou moteurs de blog n'utilisent pas du tout HTML mais un langage de formatage spécifique. Quels langages existent ? Textile, par exemple (Textpattern l'utilise), le langage de MediaWiki, rendu populaire par Wikipédia, des nouveaux formats normalisés comme Atom (RFC 4287), etc. Il n'y a rien qu'on puisse appeler « standard » dans ce domaine. Rien que dans le monde du wiki, il existe de nombreux langages différents. Heureusement, ces langages sont en général plutôt simples, ce qui facilite l'écriture de programmes de conversion.

Ensuite, il y a la structure des données dans la base, différente d'un logiciel à l'autre, souvent mal documentée et toujours changeante.

Y a t-il des programmes tout faits ? Oui, souvent, dès que le format qu'on veut importer est utilisé par un logiciel populaire. Par exemple, Wordpress dispose d'importeurs pour beaucoup de ses concurrents. On peut les trouver sous l'onglet Import de l'interface d'administration. On peut lire de nombreux récits d'importation de données... plus ou moins réussies. Wordpress lui-même dit prudemment que ces importeurs permettent de récupérer « la plupart » des informations associées aux articles de l'ancien blog.

En sens inverse, l'importance de Wordpress fait que beaucoup de moteurs de blog ont un moyen d'importer du Wordpress. Par exemple, pour Textpattern, on peut voir http://forum.textpattern.com/viewtopic.php?id=23243 qui explique que Click on administration->import, enter the database-information for the wordpress installation and click button. That will import the content.. De tels programmes d'importation ad hoc doivent être écrits pour chaque couple de CMS entre lesquels on veut échanger des données et il n'est donc pas étonnant qu'ils soient fragiles et ne respectent pas toujours toutes les données.

Et cela laisse ouvert le cas des logiciels « rares », pour lesquels de tels programmes ne sont pas disponibles.

Plusieurs personnes ont donc réfléchi à ce problème de portabilité des données. Ainsi, la création, en janvier 2008, du consortium DataPortability.org par quelques acteurs de poids comme LinkedIn, Six Apart ou Flickr a suscité beaucoup d'intérêt (mais il semble qu'il n'y ai pas encore grand'chose de produit).

Quelques conseils pratiques, pour finir :

  • Avant d'écrire des milliers de pages ou d'articles, demandez-vous comment vous les récupérerez en cas de changement de logiciel ?
  • Si un programme de conversion semble disponible, testez-le d'abord, de preférence sur des données réelles. Beaucoup de ces programmes de conversion sont très sommaires et ne gèrent pas certains cas.

J'ai rassemblé quelques ressources Web sur ce thème en http://del.icio.us/bortzmeyer/dataportability.


L'article seul

RFC 5389: Session Traversal Utilities for (NAT) (STUN)

Date de publication du RFC : Octobre 2008
Auteur(s) du RFC : J. Rosenberg (Cisco), R. Mahy (Plantronics), P. Matthews (Avaya), D. Wing (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 25 octobre 2008


Le NAT a toujours été une des plaies de l'Internet, entre autres parce qu'il perturbe les applications qui veulent transmettre une référence à leur adresse IP. STUN, décrit dans ce RFC, est un des protocoles qui permet de limiter les dégâts.

Pour plusieurs raisons, dont le manque d'adresses IPv4, de nombreuses machines sont connectées à l'Internet derrière un routeur qui fait du NAT. Leur adresse étant alors privée, elles ne peuvent pas la transmettre à l'extérieur, ce qui est une gêne considérable pour tous les protocoles qui reposent sur la référence à des adresses IP, comme SIP. SIP lui-même (RFC 3261) marche à travers le NAT mais les données audio ou vidéo transmises (typiquement par RTP) le sont à une adresse IP que l'appelant donne à l'appelé et, si cette adresse est privée, le flux multi-média n'arrivera jamais.

La bonne solution serait de déployer IPv6, qui fournit des adresses en quantité illimitée, ou à la rigueur de permettre un meilleur contrôle du routeur NAT avec MIDCOM (RFC 3303) mais, en attendant, STUN est une solution simple et qui marche souvent. STUN avait à l'origine été normalisé dans le RFC 3489, que ce RFC met à jour, avec des changements assez importants, mais qui n'empêchent pas la compatibilité des anciens clients avec les nouveaux serveurs (ou réciproquement, sauf si le client utilise les nouvelles possibilités, comme la possibilité de fonctionner sur TCP et plus seulement UDP).

STUN s'inscrit donc dans la catégorie des protocoles de « réparation » du NAT, catégorie décrite dans le RFC 3424.

STUN résoud partiellement le problème des NAT de la manière suivante : un serveur STUN doit être installé quelque part sur l'Internet public (il existe des serveurs STUN publics) et reçoit des demandes envoyées en UDP (ou TCP, voir la description de cette nouveauté en section 7.2.2) au port 3478. Le serveur STUN peut alors connaitre l'adresse publique, celle mise par le routeur NAT et, en répondant au client, il pourra informer celui-ci « Voilà à quoi tes paquets ressemblent, vus de l'extérieur ». stun

Le nom du serveur STUN est typiquement configuré dans le client, puis le serveur recherché dans le DNS via les enregistrements SRV (RFC 2782), comme détaillé dans la section 9. (Le client Unix en ligne de commande ne connait pas encore les SRV.)

Le principe est simple, mais le RFC est plus compliqué que cela, notamment en raison des problèmes de sécurité (la section 16 du RFC est très détaillée sur ce point). Par exemple, le client STUN doit en fait commencer par une connexion TCP pour obtenir un mot de passe temporaire. (d'autres méthodes d'authenfication sont possibles.)

Un autre problème est qu'il y a en fait plusieurs sortes de NAT (voir par exemple le RFC 2663). Par exemple, certains routeurs NAT (Symmetric NAT pour le RFC 3489) n'attribuent pas l'adresse externe uniquement en fonction de la source mais aussi en fonction de la destination. Ceux-ci ne fonctionnent pas avec STUN, qui a besoin de NAT cone, c'est-à-dire où les paquets d'une même machine auront toujours la même adresse IP externe.

Voici une démonstration d'un client STUN qui, en se connectant à un serveur STUN public va apprendre son adresse IP publique :

% ifconfig -a
hme0: [...] inet 172.19.1.2
(Adresse privée, probablement NATée...)

% ./client  stun.ekiga.net -v |& more
STUN client version 0.96
...
MappedAddress = 213.41.181.9:32143
(Voici mon adresse telle que vue de l'extérieur, à noter que ce RFC,
contrairement à son prédécesseur la nomme désormais ReflexiveAddress)
...

Une fois l'adresse extérieure détectée, tout n'est pas terminé car rien n'indique, par exemple, que les paquets vont effectivement passer. C'est pour cela que la section 14 insiste que STUN n'est qu'un outil, devant s'insérer dans une solution plus gobale, comme ICE (pas encore normalisé). À lui seul, STUN ne permet pas la traversée de tous les NAT. La section 14 décrit en détail ce concept d'utilisation de STUN et les règles que doivent suivre les protocoles qui utilisent STUN.

La section 6 décrit le format des paquets. Un paquet STUN doit comprendre l'indication d'une méthode, qui indique le genre de services que désire le client. Notre RFC 5389 ne décrit qu'une seule méthode, Binding, qui permet d'obtenir son adresse IP extérieure mais TURN (RFC 5766), par exemple, en définit d'autres. Après la méthode et un identificateur de transaction (qui sert au serveur STUN à séparer ses clients), suivent les attributs, encodés en TLV (la liste des attributs figure en section 15). Les numéros des attributs sont compris entre 0x0000 et 0x7FFF s'ils doivent être reconnus par le serveur (autrement, la requête est rejetée) et entre 0x8000 et 0xFFFF si leur compréhension est facultative (cette notion d'attributs obligatoires ou facultatifs facilite les évolutions ultérieures du protocole). Une partie de l'identificateur de transaction de la version précédente de STUN a été transformé en magic cookie, une valeur fixe (0x2112A442) qui sert à reconnaitre les agents STUN conformes à la nouvelle version.

Les sections 2, 12 et 19 décrivent en détail les changements par rapport à la norme précédente, le RFC 3489, notamment le fait que STUN (qui a changé de nom au passage, en gardant le même sigle) n'est plus présenté comme une solution complète mais comme un outil pour une solution plus générale (qui doit, notamment, tester que la connectivité fonctionne, comme le fait ICE). Même la découverte du comportement du NAT est désormais effectuée par des protocoles plus riches comme celui du RFC 5780. Parmi les autres changements, il faut noter que STUN encode désormais les adresses IP (par un simple XOR, section 15.2) pour les masquer, empêchant ainsi des stupides routeurs NAT de les réécrire (oui, certains routeurs NAT, profitant de l'absence de mécanisme de responsabilité pour le logiciel embarqué, examinaient toutes les données transitant par eux pour réécrire les adresses IP afin d'y mettre l'adresse publique ; le RFC parle poliment de misguided attempt at providing a generic ALG function mais le terme correct est « débilité monstrueuse »).


Téléchargez le RFC 5389


L'article seul

La racine DNS ORSN se termine officiellement

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


C'est par un message de Paul Vixie sur la liste dns-operations que la majorité des acteurs du DNS ont appris l'arrêt officiel de la racine ORSN (Open Root Server Network).

ORSN était de très loin la plus sérieuse des racines alternatives, ces groupes de serveurs de noms qui font concurrence aux serveurs racines « officiels ». La plupart de ces racines alternatives sont créées et maintenues par de complets zozos, voire par des escrocs purs et simples. ORSN était une des rares qui géraient le même espace de nommage que la racine gérée par le gouvernement US, espace auquel elle se contentait d'ajouter des innovations techniques (comme IPv6, pour lequel il a fallu attendre des années pour que l'ICANN le mette dans la racine officielle). ORSN était géré par plusieurs opérateurs sérieux.

Si mettre en route une racine alternative est trivial (n'importe quel étudiant en informatique avec trois PC peut le faire), la faire fonctionner régulièrement pendant des années, en surveillant que tout se passe bien, est beaucoup moins simple. ORSN avait souvent eu de sérieux problèmes mais, cette fois, ses responsables ont eu au moins la franchise de reconnaître qu'ils ne pouvaient plus assurer. ORSN est donc officiellement arrêtée, ne laissant pas d'autre racine utilisable que l'officielle.

(Depuis, ORSN est apparemment reparti, en juin 2013.)


L'article seul

Générer une version statique d'un site Web

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


On a souvent besoin de générer une version statique d'un site Web, c'est-à-dire de simples pages HTML, utilisables sans logiciel derrière, juste avec un serveur de fichiers, voire pas de serveur du tout, par exemple lorsque la version statique a été mise sur un CD-ROM. Mais comment faire avec les outils existants ?

Ces versions statiques sont très pratiques lorsqu'on veut pouvoir transformer un gros site Web nécessitant pour fonctionner un ensemble complexe de programmes en Java, en PHP ou autre, sans compter le SGBD qui l'accompagne. Cette transformation en site statique permet de consulter par la suite le site sur n'importe quelle plate-forme, même non connectée à l'Internet (ou bien mal connectée, un cas fréquent). france.fr aurait dû utiliser un tel mécanisme (puisque son contenu, quoique géré par des techniques dynamiques - Drupal - était entièrement statique), celà lui aurait épargné le ridicule.

Un autre cas qui m'a servi était celui où le moteur du site, un CMS, était bien vieux, plus maintenu, rempli de failles de sécurité et où personne n'avait le temps et l'envie de le mettre à jour. Le transformer en version statique a permis de continuer à le publier, même si on ne pouvait plus changer le contenu (http://www.web1901.org/). Cela avait l'avantage de supprimer beaucoup de risques de sécurité notamment les spam dans les commentaires.

Maintenant, comment faire pour produire cette version statique ? Si on a accès aux « cuisines », à la base de données où tout est stocké (ce qui est le cas des sites qu'on contrôle entièrement mais aussi de sites très ouverts comme Wikipédia), alors, il faut écrire un petit programme de conversion en HTML.

Si non, on peut toujours utiliser un client HTTP doté de la capacité de récupérer les pages, mais aussi de les modifier pour les adapter à cette nouvelle tâche. Il en existe deux en logiciel libre, wget et httrack.

Pour wget, l'utilisation de base est :

wget  --mirror --no-parent --convert-links http://www.LESITE.fr/

Le --convert-links est indispensable si certains liens sont absolus. Il faut alors les convertir en liens relatifs. Cette commande laisse un ensemble de fichiers HTML dans un répertoire nommé www.LESITE.fr, ensemble qu'on peut copier sur un CD-ROM ou une clé USB, archiver, etc.

Si le site est d'accès restreint, pas de problème :

wget --http-user MOI --http-passwd MONSECRET \
        --mirror --no-parent --convert-links  http://www.LESITE.fr/

wget a une limite que je trouve très gênante : si certains URL comportaient des ?, il laisse des fichiers avec un point d'interrogation dans le nom. Un navigateur comme Konqueror ne peut alors pas suivre les liens locaux (même sur Unix, il faut utiliser l'option --restrict-file-names=windows pour résoudre cela). Cela illustre l'importance de tester le résultat, surtout si on s'apprête à le graver sur un support stable.

Mais le vrai problème est que wget ne renomme pas les fichier en un nom finissant par .html. En local, le navigateur Web ne dispose pas de l'information donnée par le protocole HTTP et permettant de connaître le type du fichier récupéré. L'extension est donc indispensable (lynx avec -force_html ne résoud pas le problème car cette option n'agit que sur le premier fichier auquel on accède).

Le deuxième logiciel utilisable, et qui n'a pas ce défaut, est httrack. Si wget a beaucoup d'options (lisez son manuel en ligne), httrack en a une quantité astronomique. Mais on utilisation de base est aussi simple :

httrack http://www.LESITE.fr/

En outre, son affichage pendant l'exécution est bien plus agréable.

httrack réécrit les URL « dynamiques » en URL simples : index.html?art=55 devient ainsi quelque chose comme index6d76.html. De tels fichiers sont bien plus facilement manipulables en local.

Les fichiers de httrack ne marchent toujours pas avec lynx (car les liens dans les fichiers ne sont pas toujours modifiés) mais c'est bon avec Konqueror qui gère intelligement les points d'interrogation. Ceci dit, l'option -%q0 règle cela et j'utilise donc désormais httrack pour ces tâches.

Pour un autre article sur le même sujet, on peut consulter http://blog2doc.over-blog.com/article-1387761.html.


L'article seul

RFC 5358: Preventing Use of Recursive Nameservers in Reflector Attacks

Date de publication du RFC : Octobre 2008
Auteur(s) du RFC : J. Damas (ISC), F. Neves (registro.br)
Première rédaction de cet article le 20 octobre 2008


L'ampleur des attaques DoS menées avec l'aide de serveurs DNS récursifs ouverts a mené à ce RFC qui résume les bonnes pratiques : un serveur DNS ne doit pas être récursif pour le monde entier.

L'accroissement du nombre d'attaques début 2006 a provoqué une prise de conscience, qui s'est manifesté par de nombreux avertissements aux administrateurs réseaux (comme celui de l'AFNIC). La vitesse de publication d'un RFC étant ce qu'elle est, c'est seulement maintenant qu'un RFC met par écrit cette règle simple (le RFC est très court). Un serveur DNS ne doit être récursif que pour ses clients connus, pas pour tout l'Internet.

En effet, s'il est récursif ouvert, il peut servir de base à une attaque par amplification. Il n'y a aujourd'hui aucune raison technique légitime de laisser un serveur récursif ouvert (vous pouvez tester le vôtre avec l'interface Web de the Measurement Factory et trouver des informations sur la configuration de votre logiciel dans le document, malheureusement ancien, Securing an Internet Name Server).

La section 4 détaille les configurations qui peuvent limiter l'accès à la récursion : par exemple, pour un boîtier SOHO qui sert également de résolveur DNS, discriminer selon l'interface (n'accepter les requêtes DNS que si elles viennent du réseau local). Ou bien, pour les machines en déplacement (un des arguments les plus souvent présentés par ceux qui voulaient maintenir la récursion ouverte à tous), utiliser un résolveur local à la machine, ou bien monter un VPN avec un résolveur de confiance.

À noter que notre RFC parle également beaucoup de BCP 38 (actuellement le RFC 2827) comme étant la « vraie » solution au problème. Mais c'est exagéré : BCP 38 ne résoud pas tous les problèmes, notamment les attaques entres clients d'un même opérateur.

Une technique non mentionnée par le RFC est de limiter le trafic du résolveur.


Téléchargez le RFC 5358


L'article seul

RFC 5382: NAT Behavioral Requirements for TCP

Date de publication du RFC : Octobre 2008
Auteur(s) du RFC : S. Guha (Cornell U.), K. Biswas (Cisco), B. Ford (MIT), S. Sivakumar (Cisco), P. Srisuresh
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 17 octobre 2008


Comme son compagnon, le RFC 4787, qui concerne UDP, ce RFC décrit les règles que doit suivre un routeur NAT pour être utilisable sans trop de problèmes par les applications TCP.

La lecture préalable du RFC 4787 est recommandée, car il fixe le vocabulaire et les principes généraux. Notre RFC les complète ensuite pour le cas de TCP.

TCP a beaucoup évolué depuis le début (cf. le RFC 7414 pour une bonne description de cette évolution) mais le mécanisme de connexion initial, le fameux « Three-Way handshake », n'a pas changé, des tentatives comme T/TCP (cf. RFC 1644) ayant échoué. C'est cette connexion initiale qui est le plus gênée par le NAT.

Les exigences de notre RFC pour un routeur NAT sont principalement :

  • Indépendance par rapport à la destination : la table de correspondance entre un port et un couple (adresse IP, port) ne doit dépendre que de la source,
  • Le routeur doit accepter la totalité de la machine à états de TCP (décrite dans le RFC 793) et notamment, ce que beaucoup de routeurs NAT ne font pas, l'ouverture simultanée (où deux machines tentent une connexion TCP à peu près en même temps),
  • Les éventuels délais avant qu'une session TCP « inactive » soit coupée doivent être d'au moins deux heures (aujourd'hui, il est courant que des routeurs NAT suppriment une connexion de leur table au bout de quelques minutes, car leurs concepteurs n'ont pensé qu'aux sessions HTTP, jamais à SSH, où il est courant qu'une session dure des jours et n'envoie pas de paquets tout le temps).

Depuis la sortie de ce RFC, le RFC 7857 a apporté quelques compléments.


Téléchargez le RFC 5382


L'article seul

Normalisation synthétique du DNS : un nouvel échec

Première rédaction de cet article le 16 octobre 2008


Le DNS est très compliqué pour les implémenteurs, car il existe de nombreux RFC, qui se mettent partiellement à jour. Les deux RFC de départ, le RFC 1034 et RFC 1035, sont, selon les critères actuels, plutôt mal écrits, et ils sont précisés, modifiés, etc, par bien d'autres RFC, mais qui ne les rendent pas obsolètes pour autant. Écrire une mise en œuvre correcte du DNS aujourd'hui nécessite de lire beaucoup de documents.

Régulièrement, un groupe de participants à l'IETF se dit que c'est intolérable, qu'il faut faire quelque chose, et décident, soit de réécrire les RFC 1034 et RFC 1035 en propre, en intégrant les mises à jour, soit, pour les moins courageux, d'écrire un RFC de guide parmi les RFC, sur le modèle de ce qu'est le RFC 7414 pour TCP.

La dernière tentative de produire un document qui détaille les RFC sur DNS, leur importance, et leurs relations, suivait cette seconde méthode. Elle se nommait DNS profile. Cette fois, j'étais un des participants au projet. Il vient d'échouer et d'être officiellement abandonné le 15 octobre.

Comme les projets précédents, il a échoué par manque de temps (la faille Kaminsky est tombée en plein milieu du projet), manque d'intérêt, manque de financement (le travail à l'IETF est fondé sur le volontariat). Le DNS restera donc en l'état.


L'article seul

RFC 3879: Deprecating Site Local Addresses

Date de publication du RFC : Septembre 2004
Auteur(s) du RFC : C. Huitema (Microsoft), B. Carpenter (IBM)
Chemin des normes
Première rédaction de cet article le 14 octobre 2008


L'IETF n'a jamais apprécié les identificateurs à portée purement locale, comme le TLD .local ou comme les adresses IP privées du RFC 1918. Ces identificateurs locaux, dont la signification est spécifique à un site donné, soulèvent plusieurs problèmes, par exemple une question pratique : que faire si deux organisations fusionnent et qu'elles utilisent toutes les deux de tels identificateurs, qui sont en collision ?

Les RFC successifs sur l'adressage IPv6 prévoyaient des identificateurs « site-local », spécifiques à un site, dans le préfixe FEC0::/10 (RFC 3513, section 2.5.6, ce RFC ayant depuis été remplacé par le RFC 4291). Toute organisation pouvait piocher librement dans ces adresses, tout en faisant attention à ne pas les laisser sortir de son site. Cela a permis à beaucoup d'organisations de commencer à expérimenter avec IPv6.

Mais ces identificateurs posaient des problèmes, en général communs avec tous les problèmes des identificateurs locaux. La section 2 du RFC les détaille :

  • Si des applications se passent des adresses IP, comme le font FTP ou SIP, elles doivent connaitre les frontières de site pour savoir si elles peuvent passer des adresses privées (section 2.2).
  • Commes les domaines privées, les adresses IP privées tendent à « fuir », à être transmises en dehors du site (par exemple dans les en-têtes Received: du courrier électronique ou via des requêtes DNS comme celles qu'absorbe l'AS112). Comme elles perdent toute signification en dehors du site d'origine, cela sème la confusion (section 2.3).
  • Elles nécessitent un traitement spécial par les routeurs (section 2.4).
  • Selon le RFC 3879, le concept de « site » lui-même n'est pas clairement défini (section 2.5). Est-ce une entité administrative unique ? Un site géographique unique ? Un AS ? Je dois avouer que cette section est la moins convaincante de tous et qu'elle donne l'impression que les auteurs ont voulu charger la barque. Puisque les adresses « site-local » sont spécifiques à un site, rien n'empêchait chaque site d'avoir sa propre définition.

Du point de vue pratique, pour l'opérateur d'un réseau, ces inconvénients pouvaient sembler légers et, de toute façon, un mécanisme de remplacement était nécessaire. C'est au développement de ce mécanisme que s'attaque la section 3 qui réclame un mécanisme alternatif assurant l'unicité des adresses « locales ». Cela ne supprimera pas, par exemple, les fuites, mais cela les rendra plus facile à déboguer. Ce mécanisme, les ULA (Unique Local Addresses) a finalement été créé par le RFC 4193.

Un détail important : la section 5, consacrée à la sécurité, rappelle que, contrairement à ce que croient beaucoup d'administrateurs réseaux débutants, le fait d'avoir des adresses privées n'offre à peu près aucune protection (par exemple parce que des techniques comme le changement DNS permettent d'attaquer de l'intérieur). La bonne technique est l'emploi de filtres et elle s'applique aux adresses privées comme aux publiques.

Il ne faut cependant pas considérer que les identificateurs locaux sont systématiquement une mauvaise idée. Ils sont nécessaires lorsque l'obtention d'identificateurs globaux, valables partout, est difficile ou coûteuse. C'est le cas des adresses IPv4 privées du RFC 1918 : vue la pénurie d'adresses IPv4 et les obstacles financiers et bureaucratiques à franchir pour en obtenir, il est logique d'utiliser ces adresses privées. C'était également le cas à l'époque pour les adresses IPv6 privées. Pendant longtemps, il était complètement impossible d'en obtenir (par diplomatie, pour éviter de vexer les RIR, le RFC 3879 évite de rappeler cet épisode). Il est donc déplorable que ce RFC aie été publié avant que son successeur, le RFC 4193, soit prêt. Désormais, les ULA de ce RFC fournissent une meilleure solution, qui évite notamment les collisions entre deux sites qui fusionneraient. On peut donc enterrer FEC0::/10 sans remords.


Téléchargez le RFC 3879


L'article seul

Les Japonais aussi pètent parfois les plombs

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


Personne en Europe ne comprend vraiment le Japon, c'est une banalité. Mais tout espoir n'est pas perdu, pense Keiko Ichiguchi, auteure de mangas, résidente à Bologne depuis des années et qui a décidé de faire un modeste effort pour expliquer le Japon aux européens. Ce petit livre, la suite de « Pourquoi les Japonais ont les yeux bridés », illustré par l'auteure, fait partie de ce projet.

Notre Japonaise Bolonaise s'est donc lancé dans des explications : est-ce que les japonais gardent toujours leur calme ? (Non, mais les manifestations de la colère ne sont pas les mêmes qu'en Europe.) Pourquoi les héros du Shinsengumi sont-ils si populaires ? Existe t-il des gros mots en japonais ? (Oui, mais pas beaucoup.) Les adolescentes japonaises sont-elles bizarres ? (Oui, d'après l'auteure, une quadragénaire.)

Le tout oscille entre article de Marie-Claire, cours d'histoire (la révolution Meiji est traitée en trois chapitres), plaidoyer antiraciste (dans le chapitre « Je suis une extra-communautaire ») compensé par des bouffées de nationalisme (« Je suis une Japonaise dangereuse  »).

C'est léger, cela fait réfléchir et c'est édité chez Kana (Dargaux/Lombard).


L'article seul

La licence restrictive de Broadcom surprend les utilisateurs Linux des serveurs Dell

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


Depuis longtemps, la difficulté à obtenir les spécifications des périphériques d'ordinateurs comme les cartes Ethernet handicape sérieusement les développeurs (et donc les utilisateurs) de logiciel libre. Si beaucoup de choses (Wifi, cartes graphiques, notamment 3D, ACPI) fonctionnent si mal sur Linux ou sur FreeBSD, ce n'est pas à cause de la paresse ou de l'incompétence de leurs développeurs, mais à cause de la volonté délibérée des fabriquants de ne pas aider, notamment en ne communiquant pas les spécifications, ou bien en ne le faisant qu'en échange d'un NDA très restrictif. Parfois, ces fabricants fournissent un pilote ou une partie de pilote (le firmware) mais pas toujours sous une licence libre. (Les firmwares ne sont fréquemment livrés qu'en binaire.) Et parfois, la licence change...

C'est ce qui vient d'arriver aux utilisateurs des serveurs Dell Poweredge comme le 2950 ou le 2970, équipés d'une carte Ethernet Broadcom détectée par Linux comme Broadcom NetXtreme II BCM5708 1000Base-T (B2) PCI-X 64-bit 133MHz. Cette carte fonctionnait sans problèmes avec les noyaux Linux jusqu'au 2.6.23, avec le module bnx2. Sur un Dell Poweredge 2970, sous Debian lenny (version actuellement en test), je mets à jour le noyau, je redémarre et plus de réseau !

La licence n'est en effet plus libre : comme bien d'autres, Debian n'acceptait de tels ajouts au noyau que temporairement et a fini par durcir sa position. Il faut désormais, pour que le pilote Linux fonctionne, charger un blob binaire (et, apparemment, penser à faire un update-initramfs -u). Plusieurs utilisateurs en ont fait l'expérience. Sur Debian, ce firmware est disponible dans les dépôts de logiciel non-libre, sous le nom de firmware-bnx2. Sa licence est en /usr/share/doc/firmware-bnx2/copyright.

Son installation a nécessité pour moi une clé USB puisqu'il n'y avait plus de réseau. Il vaut donc mieux, si on est le malheureux propriétaire de telles machines, penser à le faire avant le prochain redémarrage... Et penser à le faire remarquer à Dell, qui utilise de tels composants dans ses machines.

Un bon article en français sur la gestion du firmware sur Debian est « Firmwares manquants dans Debian ? Apprenez à gérer le problème ».


L'article seul

Trouver si un domaine a des jokers

Première rédaction de cet article le 10 octobre 2008


Le DNS permet à un domaine d'avoir des jokers, des enregistrements qui feront que le serveur DNS répondra systématiquement à tous les noms de domaine, qu'ils « existent » ou pas. Comment tester, sans accès aux données entrées, si un domaine a de tels jokers ?

Les jokers (wildcards) sont un des points les plus contestés du DNS. Certains TLD les utilisent de façon à rabattre du trafic (essentiellement des fautes de frappe) vers un serveur de publicité (c'est ce que fait aujourd'hui .tk ou ce qu'à fait, avec beaucoup plus de publicité, .com, dans l'affaire connue - bien à tort - sous le nom de Sitefinder ; le registre de .fr, s'est par contre engagé à ne pas le faire).

Pire, certains FAI peu scrupuleux utilisent une technique similaire sur les résolveurs DNS qu'ils mettent à la disposition de leurs clients, malgré l'avertissement du RFC 4924 (voir aussi le communiqué de l'AFNIC).

Comment détecter qu'il y a des jokers ? En lisant le RFC 1034, cela semble simple. Les jokers sont représentés par le caractère * et, si on veut tester example.org, on fait une requête DNS pour *.example.org et on voit si le domaine existe ou pas (attention à échapper le caractère * pour le shell Unix) :


% dig ANY \*.example.org
...
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 48646
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

Le NXDOMAIN (No Such Domain) indique que le domaine n'existe pas et qu'il n'y a donc pas de jokers. Avec .tk, par contre :


% dig ANY \*.tk         
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63123
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 7, ADDITIONAL: 1
...
;; ANSWER SECTION:
*.tk.                   86400   IN      MX      20 MX-HOST.DOT.tk.

Ici, le domaine existe : .tk a bien des jokers.

Mais le monde est plus compliqué que cela : on trouve des domaines qui ne répondent pas pour * mais qui ont quand même des jokers, et aussi le contraire. Il faut donc utiliser un algorithme plus perfectionné. Voici celui que j'ai développé (avec l'aide de Joe Abley et de plusieurs autres) :

  • Envoyer une requête pour *.DOMAINE.example,
  • Envoyer trois requêtes pour des noms choisis aléatoirement dans DOMAINE.example,
  • Vérifier que les réponses coïncident.

Notez qu'aucun algorithme de recherche de jokers n'est parfait. Celui-ci a des faux négatifs (par exemple si la malchance fait que les noms choisis au hasard existent réellement) et des faux positifs (par exemple si les serveurs DNS ont des réponses variées - plusieurs serveurs avec des adresses IP différentes à chaque requête).

Le code de mise en œuvre en Python, utilisant dnspython, est disponible. Voici quelques tests :


% python DNSwildcards.py fr
fr does not have A wildcards
% python DNSwildcards.py -t TXT fr
fr does not have TXT wildcards

% python DNSwildcards.py tk       
tk has A wildcards (['193.33.61.2', '195.20.32.103', '209.172.59.196', '217.119.57.22'])

% python DNSwildcards.py elastoplast.fr
elastoplast.fr has wildcards but no data for type A
% python DNSwildcards.py -t MX elastoplast.fr 
elastoplast.fr has MX wildcards ([<DNS IN MX rdata: 10 mail1.beiersdorf.com.>, <DNS IN MX rdata: 50 mail2.beiersdorf.com.>])

Et, si on indique explicitement le résolveur (ici, celui d'OpenDNS, un service de résolution qui renvoie de fausses réponses avec de la publicité) :


# Avec le résolveur standard, cela marche
% python DNSwildcards.py bortzmeyer.org                  
bortzmeyer.org does not have A wildcards

# Avec OpenDNS, on récupère toujours l'adresse du serveur de publicités
% python DNSwildcards.py -r 208.67.222.222 bortzmeyer.org
bortzmeyer.org has A wildcards (['208.69.34.132'])


L'article seul

RFC 5357: A Two-way Active Measurement Protocol (TWAMP)

Date de publication du RFC : Octobre 2008
Auteur(s) du RFC : K. Hedayat (Brix Networks), R. Krzanowski (Verizon), A. Morton (AT&T Labs), K. Yum (Juniper Networks), J. Babiarz (Nortel Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 7 octobre 2008


Aujourd'hui, l'administrateur réseau qui teste ses problèmes de performance utilise en général ping pour mesurer le RTT, le temps d'aller-retour avec la machine visée. Demain, utilisera t-il un programme nommé twping et le vieux ping sera t-il dépassé ? C'est en tout cas ce que visent les auteurs de ce protocole de mesure de RTT. (ping restera utile pour les tests de bon fonctionnement.)

ping, qui repose sur l'envoi de paquets ICMP echo request et echo reply (cf. RFC 792) a en effet des limites, décrites dans le RFC 2681, section 2.6 : notamment, il est difficile de savoir si les paquets ICMP ont été traités rapidement ou pas par la machine qui répond (un routeur Cisco renvoie la réponse très lentement, car elle doit passer par le processeur généraliste du routeur). En outre, il n'est pas possible de réserver l'usage de ces paquets echo à certains, sauf à filtrer par adresse IP (TWAMP, lui, permet l'authentification).

TWAMP (Two-way Active Measurement Protocol) hérite directement d'OWAMP (One-way Active Measurement Protocol, RFC 4656). Il reprend beaucoup de ses concepts, notamment la séparation en deux protocoles, celui de contrôle et celui de test. Notre RFC 5357 est d'ailleurs largement écrit sous forme de différences entre OWAMP et TWAMP, on ne peut donc pas implémenter ce dernier sans avoir lu le RFC 4656.

TWAMP met donc en œuvre la métrique décrite dans le RFC 2681 pour les mesures bidirectionnelles. Ces mesures ont l'avantage de ne pas dépendre de la présence d'une horloge correcte sur les deux machines et l'inconvénient de ne pas pouvoir séparer les contributions du trajet aller et du trajet retour. Un des deux est peut-être bien plus lent que l'autre mais les mesures bidirectionnelles ne pourront pas le détecter.

Comme l'explique la section 1.2, un système TWAMP peut comprendre jusqu'à quatre machines mais on peut supposer que, la plupart du temps, il n'y en aura que deux, la Control-Client/Session-Sender et la Server/Session-Reflector. Le programme sera lancé sur la première, qui émettra les paquets qui seront renvoyés par la seconde, permettant de calculer le RTT.

La section 2 décrit le protocole : le Control-Client établit une connexion avec le Server sur le port 862, ils se mettent d'accord sur le test, puis le Session-Sender envoie les paquets au Session-Reflector.

La section 3 décrit le protocole de contrôle, très proche de celui d'OWAMP. La section 4 est consacrée au protocole de test, dont la différence avec son prédécesseur est plus marquée, puisqu'il faut désormais renvoyer les paquets reçus. La procédure exacte suivie par le Reflector est décrite en 4.2. Le réflecteur renvoie la date d'arrivée, celle d'émission de la réponse et d'autres informations (section 4.2.1). Comme la réponse contient le TTL tel qu'il était à l'arrivée, une implémentation de TWAMP doit pouvoir accéder aux en-têtes IP, ce qui n'est pas pas toujours simple. Comme avec OWAMP, le diable est dans les détails et l'implémentation doit être faite très soigneusement pour limiter les erreurs et imprécisions.

TWAMP a depuis, bénéficié d'extensions au protocole de base, décrites dans le RFC 6038.

À noter que ce RFC est, je crois, le premier RFC qui normalise la prononciation du sigle du protocole (section 1.3) : « ti-ouampe ».

Il n'existe pas actuellement de mise en œuvre de TWAMP en logiciel libre. Compte-tenu de la proximité du protocole avec OWAMP, le meilleur moyen d'en écrire une serait sans doute de partir du programme owamp.

Pour une critique vigoureuse de ce RFC (pas du protocole, mais de la rédaction du RFC), voir « How NOT to Write a Protocol Specification », de Dustin D. Trammell.


Téléchargez le RFC 5357


L'article seul

RFC 5321: Simple Mail Transfer Protocol

Date de publication du RFC : Octobre 2008
Auteur(s) du RFC : J. Klensin
Chemin des normes
Première rédaction de cet article le 1 octobre 2008


Ce RFC normalise la version actuelle de SMTP, le protocole de transfert de courrier électronique qui est un des grands succès de l'Internet et toujours une de ses applications les plus populaires, malgré les attaques des spammeurs et la concurrence des blogs et de la messagerie instantanée.

Ce protocole a été successivement normalisé par les RFC 788 (qui avait lui-même été précédé par des RFC décrivant des protocoles qui étaient très proches de SMTP), RFC 821, RFC 2821 et désormais notre RFC 5321. Le RFC 788 datant de novembre 1981, SMTP a donc vingt-sept ans.

Parmi ses caractéristiques principales, on trouve la simplicité, qui lui vaut son nom (écrire un client SMTP est simple), le fait qu'il permette le relayage du courrier par des serveurs intermédiaires et le fait qu'il ne spécifie que le transport du message, pas son contenu, qui fait l'objet du RFC 5322.

Il est intéressant de noter que, s'il a gagné en fonctions, SMTP en a aussi perdu dans certains cas. C'est ensuite que les fonctions de messagerie instantanée (voir annexe F.6) ont disparu avec le RFC 2821, le routage par la source également (annexe F.2) ou que la simple soumission du courrier par le logiciel client est désormais traitée par le RFC 6409, le SMTP complet étant réservé aux communications entre serveurs de messagerie.

La section 2 du RFC traite en détail du modèle de fonctionnement de SMTP. Le principe est que l'émetteur trouve le serveur distant (en général grâce aux enregistrements MX du DNS) puis ouvre une connexion TCP avec ce serveur distant, connexion sur laquelle on transmet l'adresse de l'expéditeur, celle du destinataire et le message (ces deux adresses forment donc ce qu'on appelle l'enveloppe, qui ne fait pas partie du message ; elles ne sont pas forcément identiques aux adresses qu'on trouve dans les champs From: et To: du message). (L'annexe B revient également sur certains aspects de la séparation entre l'enveloppe et le message. Ainsi, faire suivre un message en se fiant aux en-têtes To: du message, au lieu d'utiliser l'enveloppe, va très probablement produire des boucles sans fin.)

Le serveur distant n'est pas forcément la destination finale, il peut être un simple relais (un relais utilise SMTP des deux côtés) ou une passerelle (la passerelle parle SMTP d'un côté mais utilise un autre protocole, par exemple un protocole privé, de l'autre côté, cf. section 2.3.10).

En théorie (et la section 2.1 insiste sur ce point), le serveur qui a accepté un message doit le délivrer ou bien prévenir l'expéditeur. Aujourd'hui, avec la prolifération du spam et des joe jobs, ce principe n'est plus tenable et cette partie du RFC est donc celle qui est la plus ignorée. Une discussion sur ce point figure dans le RFC, aux sections 6.1, 6.2 et 7.8, qui admettent que « In today's world, [...] those principles may not be practical. » en rappelant toutefois qu'il faut être prudent, contrairement à beaucoup d'opérateurs de serveurs de messagerie qui jettent de nombreux messages sans garder de trace, ce qui jette un sérieux doute sur la fiabilité du service de courrier.

SMTP est simple, mais extensible. La section 2.2 résume le modèle d'extensibilité de SMTP, qui avait été intégré à partir du RFC 2821. Il repose sur une nouvelle commande pour s'annoncer au serveur distant, EHLO, qui remplace l'ancien HELO, et qui permet d'annoncer les extensions que l'ou ou l'autre MTA accepte. La section 2.2.1 insiste toutefois sur le fait que l'une des forces de SMTP est sa simplicité et qu'il ne faut donc peut-être pas trop le charger d'extensions, si elles ne sont pas clairement utiles.

La (longue) section 2.3 est consacrée à la terminologie. Elle rappelle notamment la distinction entre enveloppe et message, signalée plus haut. C'est ainsi que la définition des en-têtes du message comme Subject: ou bien Date: est laissée au RFC 5322, alors que celle du corps du message est du domaine de MIME (RFC 2045).

C'est également dans cette section de terminologie que sont définis des termes comme MTA ou MUA même si le RFC note (section 2.3.3) que, dans ce monde peu organisé, il ne faut pas toujours prendre les mots trop sérieusement.

La section suivante, 2.4, couvre les principes de base de la syntaxe SMTP, comme le fait que les commandes sont du texte, pas du binaire, qu'elles sont insensibles à la casse, et que les réponses à ces commandes sont des nombres de trois chiffres, conçus pour être interprétés par un programme (par exemple, 500 signifie « Erreur de syntaxe »).

Place ensuite, en section 3, aux procédures SMTP. Le cœur du protocole est là, notamment dans la section 3.3 qui explique l'enchaînement des commandes. Quatre sont particulièrement importantes, EHLO pour se connecter (section 4.1.1.1), MAIL FROM pour indiquer l'expéditeur (section 4.1.1.2), RCPT TO pour le destinataire (section 4.1.1.3) et DATA pour envoyer le message (section 4.1.1.4).

Voici un exemple d'une session SMTP, telle que l'affiche, pour nous aider au déboguage, le client SMTP msmtp, lorsqu'il est lancé par echo TEST | msmtp --from=foobar@example.org --debug stephane@bortzmeyer.org (les lignes préfixées par <-- sont envoyées par le serveur SMTP de réception, celles commençant par --> par celui d'émission) :


<-- 220 relay1.nic.fr ESMTP Postfix
--> EHLO bortzmeyer.nic.fr
<-- 250-relay1.nic.fr
<-- 250-PIPELINING
<-- 250-SIZE 10240000
<-- 250-VRFY
<-- 250-ETRN
<-- 250-ENHANCEDSTATUSCODES
<-- 250-8BITMIME
<-- 250 DSN
--> MAIL FROM:<foobar@example.org>
--> RCPT TO:<stephane@bortzmeyer.org>
--> DATA
<-- 250 2.1.0 Ok
<-- 250 2.1.5 Ok
<-- 354 End data with <CR><LF>.<CR><LF>
--> TEST
--> .
<-- 250 2.0.0 Ok: queued as 92859A1D95D
--> QUIT
<-- 221 2.0.0 Bye

On voit, et c'est une des caractéristiques importantes de SMTP, que l'émetteur peut indiquer ce qu'il veut comme expéditeur. Cela permet les usurpations d'identité mais il n'est pas évident de résoudre ce problème de sécurité sans supprimer en même temps bien des usages utiles du courrier. Si le serveur SMTP initial peut à la rigueur authentifier ses clients, les serveurs suivants n'ont guère le choix, sinon de tout accepter.

Et voici ce qu'affiche un programme Python qui utilise la bibliothèque smtplib. Notons que les commandes de la bibliotèque portent le nom des commandes SMTP. Ici, on n'utilise que la commande de bienvenue initiale, EHLO :


% python
...
>>> import smtplib
>>> s = smtplib.SMTP("mail.example.org")
>>> s.set_debuglevel(True)
>>> s.ehlo("mail.foobar.example")
send: 'ehlo mail.foobar.example\r\n'
reply: '250-horcrux\r\n'
reply: '250-VRFY\r\n'
reply: '250-ETRN\r\n'
reply: '250-STARTTLS\r\n'
reply: '250-ENHANCEDSTATUSCODES\r\n'
reply: '250-8BITMIME\r\n'
reply: retcode (250); Msg: mail.example.org
VRFY
ETRN
STARTTLS
ENHANCEDSTATUSCODES
8BITMIME
(250, 'mail.example.org\nVRFY\nETRN\nSTARTTLS\nENHANCEDSTATUSCODES\n8BITMIME')

On trouve d'ailleurs des mises en œuvre de SMTP pour tous les langages de programmation, pour Emacs Lisp, pour Haskell...

En théorie, le serveur SMTP ne devrait pas du tout toucher au message qu'il convoie. Mais il existe quelques exceptions. Par exemple, la section 3.7.2 couvre le cas des en-têtes Received: dans le message (également discutés en section 4.4). Très utiles au déboguage, ceux-ci doivent être ajoutés par chaque serveur SMTP qui a relayé le message. Pour le premier exemple ci-dessus, l'en-tête Received: ressemblera à :


Received: from bortzmeyer.nic.fr (batilda.nic.fr [192.134.4.69])
        by relay1.nic.fr (Postfix) with ESMTP id 92859A1D95D
        for <stephane@bortzmeyer.org>; Sun, 28 Sep 2008 03:56:11 +0200 (CEST)

Enfin, la section 4.1 décrit une par une toutes les commandes SMTP et leur syntaxe. La section 4.2 décrit, elle, les réponses. Composées de trois chiffres, le premier indique si la réponse est positive, négative ou incomplète (ainsi, 2xy indique que le serveur qui répond est satisfait, 5xy qu'il ne l'est pas et 4xy qu'il y a eu un problème temporaire). Le second chiffre, lui, indique le genre de la réponse : x0z pour ce qui concerne la syntaxe, x2z pour le réseau, etc. On peut donc en déduire que 421 signifie un problème temporaire avec le réseau, forçant à fermer la connexion (section 3.8).

Tout cela est bien beau, mais cela ne fait que spécifier le dialogue avec un serveur distant qu'on a déjà trouvé. Et comment le trouver ? Si je suis un MTA et que je veux transmettre un message envoyé à postmaster@gmail.com, comment est-ce que je trouve l'adresse du ou des serveurs responsables de gmail.com ? Si on refaisait SMTP en partant de zéro aujourd'hui, j'utiliserai sans doute les enregistrements SRV du RFC 2782. Mais le courrier électronique a été normalisé longtemps avant ce RFC et il utilise donc une sorte d'enregistrements SRV spécifique, les enregistrements MX. Le MTA regarde donc dans le DNS les MX de gmail.com :

% dig MX gmail.com.
gmail.com.		3600	IN	MX	5 gmail-smtp-in.l.google.com.
gmail.com.		3600	IN	MX	10 alt1.gmail-smtp-in.l.google.com.
...

et sait donc qu'il doit contacter gmail-smtp-in.l.google.com. La section 5 du RFC est consacrée à ce mécanisme.

Que faire s'il n'y a pas d'enregistrement MX ? La question a toujours été chaudement discutée chez les passionnés de SMTP, mais particulièrement lors de la rédaction de ce RFC 5321. En effet, l'ancienne règle (section 5 du RFC 2821) était qu'on utilisait, s'il était présent, un enregistrement A (une adresse IPv4), qualifié de « MX implicite ». Ce mécanisme est très critiqué : les domaines ont souvent un enregistrement A pour le Web (afin de pouvoir taper http://example.net/ et pas seulement http://www.example.net/) et la machine qu'il indique n'a pas forcément de serveur de courrier. En outre, que faut-il faire s'il n'y a pas d'enregistrement A mais un AAAA (une adresse IPv6) ? Notre RFC s'éloigne donc du RFC 2821 ici et décide de garder l'ancienne convention du MX implicite (au nom de la continuité), en l'étendant à IPv6 (voir la discussion en section 5.2). Les termes de « A RR » (A resource record, enregistrement de type A) ont ainsi disparus au profit de address RR qui regroupe A et AAAA.

On note qu'il n'existe pas de moyen normalisé de dire « Je ne veux pas recevoir de courrier » ; ne pas avoir de MX ne suffit pas, en raison de la règle maintenue d'un MX implicite ; la méthode la plus courante, mais non standard, est de publier un MX délibérement invalide, pointant par exemple vers . (la racine) ou vers localhost.

Notons que la section 5 précise qu'un émetteur SMTP doit essayer d'envoyer à toutes les adresses IP, pas uniquement à tous les MX (un serveur peut avoir plusieurs adresses).

La section 6 est consacrée aux problèmes et à tout ce qui peut aller mal. Par exemple, la sous-section 6.4 parle des rapports avec les implémentations qui violent la norme. Elles sont très nombreuses (historiquement, Lotus Notes semble avoir la médaille des problèmes). Depuis que le courrier existe, il y a des polémiques entre les « éradicateurs » qui demandent que les serveurs SMTP refusent de compenser ces violations et stoppent tout dialogue avec les logiciels trop bogués et les « conciliateurs » qui, après avoir fait trois génuflexions vers la statue de Jon Postel et cité son « principe de robustesse » (« Be conservative in what you send and liberal in what you accept »), demandent qu'on essaie malgré tout de parler avec les programmes ratés. Le problème est d'autant plus difficile que tous les développeurs ne sont pas égaux : on peut difficilement refuser de parler aux serveurs de messagerie d'AOL, quelles que soient les curieuses pratiques qu'ils utilisent. Même chose avec des logiciels très répandus comme Microsoft Exchange.

Une autre partie du problème est que certains MUA ont des capacités limitées et qu'on ne peut pas trop exiger d'eux. Ainsi, les serveurs SMTP ont pris l'habitude de réparer les messages, en rectifiant par exemple les champs Date: invalides (une bogue très fréquente). Ces réparations devraient, dit le RFC, être limitées aux clients locaux, que l'on connait, et ne pas s'étendre aux machines d'autres domaines. Cette approche est cohérente avec le RFC 6409 (qui sépare la soumission d'un message depuis un MUA vers le premier MTA, de l'envoi d'un message entre MTA) mais avec certains logiciels, comme Postfix, elle ne peut pas être configurée.

Toute aussi brûlante est la question de la sécurité du courrier électronique, qui fait l'objet de la section 7. D'abord (section 7.1), il y a le problème de l'authentification : un serveur SMTP peut toujours prétendre que le courrier vient de pape@nic.va, il n'y a aucun moyen de vérifier. (De très nombreux projets ont visé à traiter ce problème, voir par exemple les RFC 7208 et RFC 6376 mais il est bien plus compliqué qu'il n'en a l'air, notamment parce qu'il n'existe pas de système d'identité international et reconnu.) Le RFC recommande donc d'authentifier ses messages, par exemple avec le RFC 4880.

La section 7.9, elle, couvre les questions opérationnelles liées à la sécurité. Par exemple, certains fournisseurs de courrier (notamment AOL, qui s'en vante bruyamment), refusent le courrier de certains sites, sur des critères décidés unilatéralement et sans prévenir leurs propres utilisateurs. D'une certaine façon, c'est compréhensible, puisque l'ampleur du spam nécessite des mesures souvent radicales. Mais cela peut, si on poursuit cette logique, mener à un système de courrier qui serait réservé à un oligopole de quelques fournisseurs qui s'acceptent entre eux (le projet du MAAWG).

C'est la même section qui mentionne les relais ouverts, en des termes étonnamment prudents (la pratique générale est de les supprimer). Comme autre exemple de code Python pour faire du SMTP, voici un programme pour tester si un serveur est un relais ouvert.

Ce RFC ne marque guère de changements par rapport à son prédécesseur, le RFC 2821. Le but principal était de le faire avancer sur le chemin des normes, vers son nouveau statut de « Projet de norme ». Les changements ? Eh bien, le principal étant l'extension du « MX implicite » à IPv6.

Ce RFC a été longtemps retardé par une amusante et exaspérante « querelle des exemples » et a même fait l'objet d'un appel contre l'obstruction de l'IESG. Celle-ci estimait en effet que le RFC aurait dû utiliser, pour ses exemples, uniquement les noms de domaines du RFC 2606, malgré le fait que le RFC 2821 aie déjà utilisé des noms comme isi.edu (l'université de Jon Postel) ou generic.com depuis des années.

Des propositions d'architectures radicalement nouvelles, en général fondées sur un modèle où le récepteur « tire », comme avec Atom, plutôt que sur le modèle traditionnel du courrier où l'expéditeur « pousse » ont déjà été faites, par exemple par Dan Bernstein ou par Wietse Venema mais n'ont jamais débouché sur des protocoles finalisés, et encore moins sur des implémentations. Ces propositions visent en général à traiter le problème du spam en forçant l'expéditeur à garder le message chez lui, jusqu'au moment de la récupération par le destinataire. Cela résoudrait la question du stockage du spam, mais pas du tout celle de son traitement puisqu'il faut bien notifier le destinataire qu'il a un message, et qu'il doit bien le récupérer pour décider si c'est du spam ou pas.


Téléchargez le RFC 5321


L'article seul

RFC 5322: Internet Message Format

Date de publication du RFC : Octobre 2008
Auteur(s) du RFC : P. Resnick (Qualcomm)
Chemin des normes
Première rédaction de cet article le 1 octobre 2008


Vieux de désormais trente et une années (la première norme était le RFC 724 en mai 1977), le format des messages électroniques vient donc de recevoir une nouvelle spécification. Pas de grands changements mais beaucoup de petites erreurs corrigées, elle marque l'avancée de la norme au statut de « projet de norme ».

Le courrier électronique d'Internet repose sur deux piliers : un protocole d'échange des messages, SMTP, normalisé dans le RFC 5321 et un format des messages, que traite notre RFC 5322. Les deux sont relativement indépendants, notamment dans le sens où on peut transporter des messages sur d'autres protocoles que SMTP, comme par exemple UUCP. Autre exemple, les adresses traitées par les deux RFC sont différentes (même si leur syntaxe est la même), SMTP gérant l'enveloppe du message et le format gérant son contenu (section 1). Cela justifie deux RFC séparés.

Que contient le RFC 5322 qui vient de remplacer le RFC 2822 ? Moins qu'on ne pourrait le croire. Des pans énormes de l'utilisation du courrier sont en dehors de ce RFC comme l'important format MIME (RFC 2045) ou comme les extensions d'internationalisation (RFC 6532).

Il reste donc un RFC sur l'envoi de messages textuels en ASCII. Mais, sans même prendre en compte des extensions comme MIME, c'est déjà assez complexe. La section 2 définit les règles lexicales des messages. Les messages sont découpés en lignes composées ce caractères. Le nombre maximal de caractères par ligne est de 998 caractères (section 2.1.1, qui recommande d'accepter également des longueurs plus grandes, mais sans générer soi-même de lignes plus longues).

La section 2.2 définit les en-têtes qui composent le début du message. Un message au format RFC 5322 ressemble, sur le câble, à :


Date: Tue, 9 Sep 2008 09:33:17 +0200
To: ubuntu-fr@lists.ubuntu.com
Message-ID: <20080909073317.GA23390@sources.org>
Subject: [Son] Silence complet sur mon ESS ES1978 Maestro 2E
From: Stephane Bortzmeyer <stephane@sources.org>

Le son, avec Linux, c'est vraiment p=E9nible.

J'ai un Dell Inspiron 7500 dont le son ne marche pas du tout. Silence
complet.

...

Le début, avant la ligne vide, est composé de cinq en-têtes (il y en a bien d'autres, non affichés ici. Avec mutt, c'est la commande h qui permet d'afficher tous les en-têtes). Chaque en-tête a un nom, suivi du deux-points et d'un corps. Si les premiers MUA affichaient directement les noms des différents champs, cela ne se fait plus guère aujourd'hui. En général, ce que voit l'utilisateur est bien différent de ce qui passe sur le câble, notamment à des fins de localisation (afficher « Objet » et pas « Subject », par exemple). Le corps du champ peut être non structuré (section 2.2.1, on y met ce qu'on veut, c'est le cas du champ Subject:) ou bien structuré (section 2.2.2, il obéit à une mini-grammaire spécialisée, c'est le cas de Date: ou de From:). Les champs peuvent être très longs et il est donc prévu (section 2.2.3) de pouvoir les plier sur plusieurs lignes. C'est un des points les plus souvent oubliés des auteurs d'analyseurs de ce format. Il faut donc rappeler qu'on ne peut pas utiliser d'outil orienté ligne comme grep sur un message électronique. (Une solution est d'utiliser l'excellente commande formail, dans le paquetage procmail, avec son option -c qui replie les lignes.)

Enfin, il y a le corps du message, après les en-têtes. Précédé d'une ligne vide, ce corps n'a pratiquement pas de structure dans notre RFC 5322 (section 2.3) mais d'autres normes comme MIME (RFC 2045) se chargent de combler ce manque et permettent, par exemple, de transporter plusieurs fichiers, y compris binaires, dans un seul message.

La section 3 décrit la syntaxe d'un message. La grammaire est très riche et très complexe. Pire, en raison de l'ancienneté de ce format, un grand nombre de productions grammaticales sont désormais abandonnées mais doivent toujours être reconnues par un analyseur, au cas où un logiciel les génère encore. Elles ont un nom commençant par obs- pour qu'on puisse les reconnaitre plus facilement. (La section 4 décrit cette grammaire abandonnée plus en détail. On y trouve, par exemple, un format pour les années sur deux chiffres, non compatible avec l'an 2000.)

Parmi les subtilités de cette grammaire :

  • La syntaxe des dates, dans le champ (structuré) du même nom (section 3.3). Elle est très souvent violée : en pratique, on voit des dates de toutes les formes, même lorsque le logiciel est un programme payant et cher. Un exemple correct est Date: Tue, 30 Sep 2008 11:49:07 +0200 (le format du courrier est bien plus ancien que la norme ISO 8601). Ce champ est décrit en 3.6.1.
  • Les adresses (section 3.4). C'est, encore plus que les dates, un des aspects les plus mal compris du courrier. Le Web abonde de programmes écrits dans des langages qui encouragent l'approximation (comme PHP ou Javascript) et qui refusent des adresses parfaitement légales. À leur décharge, il faut dire que la grammaire de la section 3.4.1 n'est pas triviale ! Un exemple d'adresse (on les utilise notamment dans les champs From: et To:) est stephane+blog@bortzmeyer.org. On notera que des normes comme NAI (RFC 7542) ou bien XMPP (RFC 7622) utilisent une syntaxe proche.

Enfin, la section 3.6 décrit tous les en-têtes. Citons entre autres :

  • L'expéditeur, From:, Sender: et Reply-To:, section 3.6.2.
  • Les destinataires, To: et Cc: (ceux qui reçoivent une copie), section 3.6.3.
  • Message-ID:, section 3.6.4, un champ structuré qui contient un identificateur unique du message, par exemple <17b4fdcd0809290041i4323797al964ccf5a344b1c47@mail.gmail.com>.
  • Subject:, section 3.6.5, qui indique l'objet du message et n'est pas structuré. Pour qu'il puisse contenir autre chose que des caractères ASCII, il faut utiliser l'encodage du RFC 2047 (ou le plus récent RFC 6532).
  • Received:, section 3.6.7, qui sert à indiquer par quels relais est passé un message. Par exemple, Received: from rv-out-0708.google.com (rv-out-0708.google.com [209.85.198.250]) by mx1.nic.fr (Postfix) with ESMTP id 98D821714088 for <bortzmeyer@nic.fr>; Mon, 29 Sep 2008 09:41:22 +0200 (CEST). C'est un excellent outil de déboguage pour l'administrateur réseau.

La liste des en-têtes n'est pas figée, on la trouve dans un registre IANA (créé à l'origine par le RFC 4021) décrit en section 6.

Notre RFC 5322 remplace le RFC 2822, par rapport auquel il y a peu de changements. Le RFC 2822 remplaçait le RFC 822 qui est resté en service très longtemps, accompagnant l'essor du courrier électronique, et qui a été tellement influent que son numéro sert souvent à désigner le format (comme dans l'ancien module Python rfc822, remplacé depuis par email). L'annexe B donne la liste des changements par rapport au RFC 2822, essentiellement des corrections de bogues.


Téléchargez le RFC 5322


L'article seul

RFC 3406: Uniform Resource Names (URN) Namespace Definition Mechanisms

Date de publication du RFC : Octobre 2002
Auteur(s) du RFC : L. Daigle (Thinking Cat), D. van Gulik (Web Weaving), R. Iannella (IPR Systems), P. Faltstrom (Cisco)
Première rédaction de cet article le 1 octobre 2008


Le RFC 2141 définissait une syntaxe pour les URN, un membre de la grande famille des URI. Dans cette syntaxe, immédiatement après la chaîne de caractères urn:, on trouve l'espace de noms (namespace), une chaîne de caractères qui identifie le domaine d'une autorité d'enregistrement. Notre RFC 3406 expliquait les procédures de création d'un nouvel espace de noms dans le registre des espaces de noms que tient l'IANA. Ces deux anciens RFC ont dépuis été remplacés par le RFC 8141.

Comme expliqué dans la section 1, ce mécanisme d'espaces de noms suppose que, dans chaque espace, il existe une autorité d'enregistrement qui accepte (ou refuse) les enregistrements et que, d'autre part, il existe une autorité qui enregistre les espaces de noms (en l'occurrence l'IANA). Tout le RFC 3406 est consacré aux procédures de cette dernière autorité et aux mécanismes pour enregistrer un identificateur d'espace de noms (NID pour namespace identifier). (La résolution des URN en autres identificateurs n'est par contre pas couverte.) Des exemples d'autorité d'enregistrement dans un espace de noms donné sont le gouvernement néo-zélandais (RFC 4350) ou l'OGC (RFC 5165).

La section 2 du RFC détaille ensuite ce qu'est un espace de noms (un ensemble d'identificateurs uniques géré, c'est-à-dire que tous les noms syntaxiquements corrects n'en font pas partie, uniquement ceux qui ont été enregistrés). Par exemple, les ISBN forment un tel espace (dont l'utilisation dans des URN a fait l'objet du RFC 3187). À l'intérieur d'un espace de noms, les règles d'enregistrement et le travail quotidien du registre ne sont pas gérés par l'IETF ou l'IANA mais par l'autorité d'enregistrement de cet espace.

La section 3 introduit les différents types d'espaces de noms. Il y a des espaces expérimentaux (section 3.1), qui ne nécessitent pas d'enregistrement auprès de l'IANA, et qui se reconnaissent à leur NID commençant par x- (leur usage est désomais découragé, cf. RFC 6963). Il y a les espaces informels (section 3.2), dont le NID commence par urn- et est composé de chiffres et les espaces formels (section 3.3) dont le NID est composé de lettres et qui, contrairement aux informels, sont censés fournir un bénéfice aux utilisateurs de l'Internet (les espaces informels ont le droit d'être réservés à une communauté déconnectée). Contrairement encore aux informels, l'enregistrement des espaces formels doit faire l'objet d'une spécification écrite, typiquement un RFC.

Un des principes des URN est la durabilité : un URN devrait être stable dans le temps. Mais cette stabilité dépend essentiellement de facteurs non-techniques, comme la permanence dans le temps du registre (une organisation privée et fermée comme l'IDF est, par exemple, typiquement un mauvais choix pour assurer la permanence). Toutefois, si on ne peut pas garantir la stabilité d'un espace de noms, on connait en revanche des facteurs qui diminuent la probabilité de permanence et l'IETF peut donc analyser les spécifications à la recherche de tels facteurs (c'est une variante du problème très riche mais bien connu de la stabilité des identificateurs).

Enfin, avec la section 4, on arrive au processus d'enregistrement lui-même. Il faut en effet un peu de bureaucratie pour s'assurer que le NID est bien enregistré et que le registre des NID soit lui-même stable. Les procédures sont différentes selon le type d'espace de noms. Les expérimentaux (section 4.1) ne sont pas enregistrés du tout. Les informels (section 4.2) ont leur propre registre, avec un processus d'enregistrement léger, mais très peu utilisé.

Le gros morceau est constitué des espaces de noms formels (section 4.3). Cette fois, le processus d'enregistrement est plus complexe, un RFC est nécessaire, mais on obtient un « vrai » NID comme MPEG (RFC 3614), OASIS (RFC 3621) ou 3gpp (RFC 5279).

Le formulaire d'enregistrement complet est disponible dans l'annexe A du RFC. Bon courage aux futurs enregistreurs. N'oubliez pas de lire tout le RFC.

Notre RFC succède au RFC 2611, les changements étant détaillés dans l'annexe C. Ils incluent une meilleure formalisation des différents types d'espace (expérimental, informel et formel) et une description plus détaillée des formalités d'enregistrement. Depuis, il a lui-même été remplacé par le RFC 8141.


Téléchargez le RFC 3406


L'article seul

RFC 5353: Endpoint Handlespace Redundancy Protocol (ENRP)

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : Q. Xie, R. Stewart, M. Stillman (Nokia), M. Tuexen (Muenster Univ. of Applied Sciences), A. Silverton (Motorola)
Expérimental
Réalisé dans le cadre du groupe de travail IETF rserpool
Première rédaction de cet article le 30 septembre 2008


Complétant la série des RFC sur la famille de protocoles Rserpool, famille dont le cahier des charges était le RFC 3237, ce document normalise le protocole ENRP (Endpoint Handlespace Redundancy Protocol) qui est le protocole utilisé entre les serveurs qui font la traduction des identifiants, les handles, en adresses IP.

Rappelons brièvement le fonctionnement de Rserpool (le RFC 5351 fournit une description plus détaillée) : un client, le PU (Pool User) veut accéder aux services fournis par un groupe (pool) de serveurs d'application, les PE (Pool Elements). Le client ne connait que l'identifiant du groupe, le PH (Pool Handle). Pour le traduire en adresses IP, le client utilise le protocole ASAP (RFC 5352) pour demander aux serveurs ENRP cette traduction. Les PE utilisent également ASAP pour s'enregistrer auprès des serveurs ENRP. Et comment les serveurs ENRP se synchronisent-ils ? Avec le protocole ENRP de notre RFC 5353. Grâce à lui, les serveurs ENRP forment un registre distribué et résistant aux pannes.

Notons qu'ENRP n'est conçu que pour fonctionner au sein d'un même domaine administratif, où toutes les machines sont configurées par la même équipe et peuvent donc, après authentification forte, se faire confiance (la section 6 détaille ces exigences de sécurité et impose TLS avec authentification réciproque). La conception d'un tel protocole pour l'Internet entier est encore un défi.

C'est la section 3 qui décrit le fonctionnement du protocole. Au démarrage, un serveur ENRP doit (section 3.2) générer son identifiant ENRP (un entier de 32 bits), trouver un mentor, le pair qui lui donnera les autres informations (la section 3.2.21 explique comment), obtenir la liste de ses pairs (et la garder à jour, cf. section 3.4) puis les tenir au courant des enregistrements/départs de PE (section 3.3) qu'il voit (chaque PE ne parle qu'à un serveur ENRP, son home server).

La section 3.5 détaille la procédure plus compliquée de remplacement (take over), qui permet à un pair de remplacer un pair en panne et de signaler aux PE (via le protocole ASAP) qu'ils doivent changer leur serveur ENRP.

La section 2 du RFC décrit les messages ENRP (s'appuyant sur la base fournie par le RFC 5354). Par exemple, ENRP_PRESENCE (section 2.1) permet à un serveur ENRP d'annoncer à un de ses pairs ENRP qu'il est toujours là. ENRP_HANDLE_TABLE_REQUEST (section 2.2) est utilisé lorsqu'un pair ENRP rejoint les autres et réclame une copie complète de la table des handles et des adresses IP associées. ENRP_HANDLE_UPDATE (section 2.4) servira ensuite aux mises à jour, au fur et à mesure que des PE s'enregistreront ou bien partiront.

ENRP_LIST_REQUEST (section 2.5) est également utilisé à l'initialisation d'un pair ENRP : il lui permet de demander une liste des pairs ENRP actuellement actifs.

Il existe au moins une mise en œuvre d'ENRP dans http://tdrwww.iem.uni-due.de/dreibholz/rserpool/.


Téléchargez le RFC 5353


L'article seul

RFC 5351: An Overview of Reliable Server Pooling Protocols

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : P. Lei (Cisco), L. Ong (Ciena), M. Tuexen (Muenster University of Applied Sciences) , T. Dreibholz (University of Duisburg-Essen)
Pour information
Réalisé dans le cadre du groupe de travail IETF rserpool
Première rédaction de cet article le 30 septembre 2008


Il existe de très nombreux cas où une application cliente peut utiliser plusieurs serveurs parmi un groupe (le pool). L'idée de la suite de protocoles Reliable Server Pooling ( RSerPool) est de fournir un moyen standard de faire ce choix. Ce RFC explique les concepts de base de ce protocole, normalisé dans d'autres RFC.

La section 1 du RFC résume les raisons pour lesquelles on veut disposer d'un groupe, un pool, de serveurs plutôt que d'un serveur unique, par exemple, pour atteindre des objectifs de haute disponibilité ou de répartition de charge. Les nouveaux protocoles devront fournir notamment les services suivants :

  • indépendance par rapport à l'application,
  • liaison directe entre le client et le serveur, sans machine intermédiaire,
  • séparation des fonctions de disponibilité et de changement en cas de panne, des fonctions propres à l'application.

Comment sont structurés les protocoles de la famille RSerPool ? (Le cahier des charges était le RFC 3237 et prévoyait un protocole relativement léger, interne à un domaine administratif, moins ambitieux, donc, que les grilles.) Le groupe (pool) a un identificateur, le PH (Pool Handle). Les serveurs du groupe se nomment les PE (Pool Element). Chaque PE s'enregistre auprès d'un serveur ENRP (Endpoint haNdlespace Redundancy Protocol) en utilisant le protocole ASAP (Aggregate Server Access Protocol), décrit dans le RFC 5352. Le client se nomme, lui, le PU (Pool User). Il utilise également ASAP pour parler au serveur ENRP, obtenant ainsi la correspondance entre le PH et l'adresse IP du serveur effectif. Le PU parlera ensuite directement au PE, utilisant un protocole spécifique à l'application. Enfin, le serveur ENRP peut se synchroniser avec d'autres serveurs ENRP (RFC 5353) pour fournir également un service à haute disponibilité.

Ces protocoles sont décrits dans différents RFC, le RFC 5352 pour ASAP, le RFC 5353 pour ENRP, le RFC 5354 pour le format des paramètres, le RFC 5356 pour les politiques de sélection des serveurs et le RFC 5355 pour l'analyse des risques de sécurité.

La section 2 décrit ASAP (Aggregate Server Access Protocol), le protocole de communication entre le PU et le serveur ENRP, ainsi qu'entre ce dernier et les PE, les membres du groupe. ASAP est normalisé dans le RFC 5352. Il permet aux PE de s'enregistrer auprès du serveur ENRP (section 2.2) et au PU d'obtenir l'adresse d'un membre du groupe (section 2.3). Dès qu'un PE s'enregistre sous un identificateur de groupe (un PH), ce groupe existe et, lorsque le dernier PE se désenregistre, le groupe disparait (section 2.1).

Comme la communication entre le PU, le client et le PE, le serveur, est directe (ce qui permet au protocole d'être indépendant de l'application), il n'y a pas d'état et il peut donc être difficile de passer d'un PE à un autre en cas de panne, le nouveau PE ne se souvenant pas du contexte de l'application. La famille de protocoles RSerPool fournit donc quelques mécanismes limités pour conserver un état (section 2.5). Ainsi, la section 2.5.1 permet un système de petits gâteaux, envoyés par le PE au PU et que celui-ci doit renvoyer lorsqu'il change de PE, permettant ainsi de garder trace de l'état de l'application.

La section 3 décrit ENRP, Endpoint haNdlespace Redundancy Protocol, le protocole de communication entre les serveurs ENRP. Ce protocole, normalisé dans le RFC 5353, permet aux serveurs ENRP d'un domaine de se synchroniser et de garder trace des PE enregistrés dans tel ou tel groupe.

La section 4, enfin, donne des exemples d'usage de la famille RSerPool. L'exemple de la section 4.1 est relativement simple, RSerPool y est utilisé pour sélectionner un serveur. La résolution d'un PH en adresse IP d'un serveur est donc le seul service invoqué. Cette section décrit les modifications nécessaires au code source de l'application :

  • Spécifier un PH (identificateur de groupe) au lieu d'un nom (ou d'une adresse IP),
  • Au lieu d'utiliser la fonction classique de résolution de nom, getaddrinfo, utiliser une fonction RSerPool de résolution,

À noter qu'il n'existe pas d'API standard pour les protocoles de la famille RSerPool. À noter également que, dans un exemple aussi simple, RSerPool n'était pas forcément nécessaire, les enregistrements DNS SRV du RFC 2782 auraient suffi.

L'exemple de la section 4.2 est plus complexe, faisant appel à toutes les fonctions de RSerPool, y compris pour la transmission de données entre le client, le PU et le serveur, le PE.

Il existe au moins une mise en œuvre de RSerPool. Elle est disponible en http://tdrwww.iem.uni-due.de/dreibholz/rserpool/. Elle est décrite dans la thèse Reliable Server Pooling -- Evaluation, Optimization and Extension of a Novel IETF Architecture. La page de l'auteur contient beaucoup d'autres informations sur la famille Rserpool.


Téléchargez le RFC 5351


L'article seul

RFC 5352: Aggregate Server Access Protocol (ASAP)

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : R. Stewart, Q. Xie, M. Stillman (Nokia), M. Tuexen (Muenster University of Applied Sciences)
Expérimental
Réalisé dans le cadre du groupe de travail IETF rserpool
Première rédaction de cet article le 30 septembre 2008


Membre de la famille Rserpool (décrite dans le RFC 5351, ASAP (Aggregate Server Access Protocol) est le protocole de communication entre un client (le PU, pour Pool User) et le serveur ENRP (RFC 5353), ainsi qu'entre un élément du groupe de serveurs d'application (le PE pour Pool Element) et le serveur ENRP. ASAP permet aux PE de s'enregistrer auprès du serveur ENRP et aux PU de trouver l'adresse d'un PE avec lequel ils vont travailler.

Le groupe de serveurs de l'application, le pool, est identifié par un handle nommé PH (pool handle). ASAP permettra de résoudre cet handle en une ou plusieurs adresses IP. Le fait d'interposer cet intermédiaire entre le client et le serveur de l'application permet d'assurer des fonctions de répartition de charge ou de résistance aux pannes. Comme le rappelle la section 1.3, un handle n'a qu'une signification locale à une organisation, il ne prétend pas être unique pour tout l'Internet.

Les deux fonctions essentielles d'ASAP sont donc :

  • Pour un PE, un des serveurs de l'application, de signaler sa disponibilité (message ASAP_REGISTRATION, section 2.2.1),
  • Pour un PU, un client final, de trouver l'adresse IP d'un ou plusieurs serveurs du groupe, afin de le contacter (message ASAP_HANDLE_RESOLUTION, section 2.2.5).

ENRP, quant à lui (RFC 5353), est utilisé entre les serveurs ENRP, pour assurer leur synchronisation.

Une façon simple de décrire ce que fournit ASAP est de lire la section 6 qui décrit, en pseudo-code, les primitives d'ASAP. Par exemple, l'enregistrement d'un serveur dans le groupe est (section 6.1) :

         
Format: registration.request(poolHandle,
                             User Transport parameter(s))

La section 2 détaille le format des messages que portera ASAP. Le format de base est défini dans le RFC 5354. Ainsi, ASAP_REGISTRATION (section 2.2.1) porte le handle du groupe que le PE veut rejoindre. La réponse, ASAP_REGISTRATION_RESPONSE (section 2.2.3) comprendra un champ Reject qui, mis à 1, indiquera l'échec éventuel (un 0 signifiant le succès).

L'autre message important est ASAP_HANDLE_RESOLUTION (section 2.2.5) et sa réponse, ASAP_HANDLE_RESOLUTION_RESPONSE. Le premier permet de résoudre un handle en une adresse IP (ou une liste d'adresses IP, pour donner du choix au client, et lui permettre d'essayer d'autres serveurs en cas de défaillance, voir par exemple la section 6.8.1 et le RFC 5356).

Le principal protocole de transport utilisé par ASAP (sections 2.1 et 5) n'est pas TCP mais SCTP (RFC 4960), entre autres parce qu'il fournit déjà une certaine résistance aux pannes (plusieurs adresses IP peuvent être utilisées pour la même association). Le port par défaut est 3863 (3864 avec TLS). Notons qu'ASAP n'est pas purement requête-réponse : le serveur ENRP peut envoyer des messages non sollicités, par exemple si un pool change.

Il existe une implémentation d'ASAP en logiciel libre dans rsplib.


Téléchargez le RFC 5352


L'article seul

ISO 5218, une norme indispensable

Première rédaction de cet article le 28 septembre 2008


L'ISO ne laisse rien au hasard et aux choix individuels. Comme son nom l'indique, elle normalise. C'est ainsi qu'il existe une norme « Représentation des sexes humains », la 5218.

Le texte est une des très rares normes ISO à être publiquement disponible, en http://standards.iso.org/ittf/PubliclyAvailableStandards/c036266_ISO_IEC_5218_2004(E_F).zip. Il fait 24 pages serrées, qui, en retirant les avertissements juridiques et le délayage, se résument à :

Data elements  Code
Not known      0 (zero)
Male           1 (one)
Female         2 (two)
Not applicable 9 (nine)

Donc, on sait désormais que les hommes sont représentés par Un et les femmes par Deux (convention qui avait déjà été adoptée dans des systèmes comme le NIR).

Notons quand même cet avertissement, qui prouve que l'ISO pense à tout : No significance is to be placed upon the fact that "Male" is coded "1" and "Female" is coded "2". This standard was developed based upon predominant practices of the countries involved and does not convey any meaning of importance, ranking or any other basis that could imply discrimination. .

Et pour ceux qui ont aimé, voici une discussion surréaliste sur la liste PostgreSQL, sur le même sujet (comment représenter le genre dans une base de données) : http://www.mail-archive.com/pgsql-general@postgresql.org/msg89107.html. La proposition que j'ai préférée était celle d'utiliser 1 pour les hommes et 0 pour les femmes, méthode qui a l'avantage d'être auto-documentée (regardez la forme du chiffre, si vous n'avez pas compris). Et, bien sûr, si on utilise une base de données qui accepte l'Unicode, on peut mettre directement les caractères U+2642 (♂) et U+2640 (♀)...


L'article seul

Geoff Huston et le futur marché des adresses IPv4

Première rédaction de cet article le 26 septembre 2008


Geoff Huston est l'auteur de nombreuses études sur l'épuisement prochain des adresses IPv4. Ces études ont contribué à la prise de conscience du fait qu'il ne restait plus que deux ou trois ans avant l'allocation de la dernière adresse. Dans un article récemment publié, The Changing Foundation of the Internet: Confronting IPv4 Address Exhaustion, Huston se demande ce qui se passera après.

Huston commence par revenir sur l'état actuel de la transition vers IPv6 : elle est à peine commencée. L'épuisement des adresses IPv4 ne peut donc plus désormais être évitée. Même si tout le monde s'affolait enfin et déployait IPv6 en urgence, il serait trop tard.

À propos de cette transition, d'ailleurs, l'auteur tord le coup à la légende comme quoi l'IETF aurait été insouciante en ne prévoyant pas de plan de déploiement d'IPv6. Il y en avait bien un : le dual stack où, pendant la transition, chaque machine aurait eu deux adresses, une v4 et une v6. Il était décrit à l'origine dans le RFC 1933 en avril 1996, il y a douze ans (aujourd'hui, RFC 4213, section 2). Mais il n'a pas marché.

Huston analyse ensuite les raisons de cet échec, largement dû à la dérégulation qui a créé un marché très atomisé où aucune décision collective n'était possible « A more likely explanation for the current situation is an inability of a highly competitive deregulated industry to be in a position to factor in longer term requirements into short term business logistics. ».

Bref, nous sommes maintenant proches du mur et n'avons plus le temps de freiner. Que se passera t-il ensuite ? Huston considère qu'il y aura forcément un marché des adresses IP. « A more likely scenario is that addresses will change hands in exchange for money. ». Il ne fait pas preuve d'un grand enthousiasme pour cette solution (au contraire de certains adorateurs du marché comme Milton Mueller dans Scarcity in IP addresses: IPv4 Address Transfer Markets and the Regional Internet Address Registries) mais il la pense inévitable.

Et il appelle à l'organiser « The corollary of this approach is the use of markets to perform the address distribution function, creating a natural pricing function based on levels of address supply and demand. ».

Joli article qui part d'un échec du marché pour arriver à la conclusion qu'il faut créer un nouveau marché...

Un autre article très détaillé sur le sujet, et assez partagé sur la question du marché, est Running on Empty: the challenge of managing Internet addresses de Lehr, Vest et Lear. Sinon, on peut noter dans le dernier numéro des Enjeux / Les Échos un dossier « Pénuries », où on trouve, outre le pétrole, l'eau et l'uranium... les adresses IP (avec, chose étonnante, uniquement des informations exactes). Ça, c'est un signe des temps.


L'article seul

Stack Overflow, un site de Q&A pour programmeurs

Première rédaction de cet article le 26 septembre 2008
Dernière mise à jour le 5 juin 2009


Joel Spolsky a annoncé le 15 septembre le lancement de Stack Overflow, un très intéressant site Web de questions & réponses pour programmeurs, avec système de réputation.

À l'usage, Stack Overflow s'avère très riche en information de qualité. Le principe est que toute personne qui veut écrire doit s'authentifier (les simples lecteurs peuvent être anonymes) et que les actions de cette personne (poser une question, proposer une réponse) lui vaudront petit à petit une réputation, déterminée par les votes des autres utilisateurs. Stack Overflow rejoint donc la grande famille des réseaux sociaux.

Les réponses aux questions sont classées, non pas dans l'ordre chronologique comme sur un blog mais dans l'ordre décroissant des votes, ce qui permet à l'information la plus reconnue d'émerger hors du bruit.

Pour ceux que ça intéresse, ma réputation est aujourd'hui de 2169 ce qui me permet, par exemple, d'éditer les messages des autres, ou de voter contre une contribution (il faut une réputation de 15 pour voter pour).

Stack Overflow permet d'afficher sa réputation sur son site, pour frimer. Je n'ai pas encore osé le faire sur l'ensemble de mon blog (non, en fait, la vraie raison est qu'il y a une mauvaise interaction entre l'HTML de Stack Overflow et celui de mon blog).

Comment se fait l'authentification ? Il faut s'enregistrer ? Non, pas du tout, la seule authentification utilisée est OpenID (donc, http://www.bortzmeyer.org/ pour moi). Une excellente idée qui permet d'éviter de se créer encore un compte de plus.

Parmi les questions, on note que les langages couramment utilisées sur Windows comme Java ou Visual Basic se taillent la part du lion. Pour le programmeur Unix, lire les questions sur la page d'accueil n'est donc pas passionnant mais Stack Overflow permet d'étiquetter les questions et chercher ensuite selon ces étiquettes. Ainsi, http://stackoverflow.com/questions/tagged/elisp donnera accès aux questions sur Emacs Lisp et http://stackoverflow.com/questions/tagged/haskell aux questions sur Haskell.

Stack Overflow contient déjà énormément d'informations de qualité, ce qui semble indiquer que le système fonctionne. Quelques bons exemples, sur des questions assez pratiques :

Et sur des questions plus conceptuelles, moins susceptibles de recevoir une réponse simple et univoque :

Les données de Stack Overflow sont désormais publiques, ce qui permet en outre de lancer plein d'analyses sur le fonctionnement du site.

Stack Overflow a désormais un site frère pour l'administration systèmes et réseaux, Server Fault.

Le meilleur article sur Stack Overflow est « Anthropology: The Art of Building a Successful Social Site ». À lire absolument pour voir tout ce qui fait la réussite de Stack Overflow.


L'article seul

RFC 5348: TCP Friendly Rate Control (TFRC): Protocol Specification

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : M. Handley, S. Floyd (ICIR), J. Padhye (Microsoft), J. Widmer (University of Mannheim)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dccp
Première rédaction de cet article le 25 septembre 2008


Tout protocole sur Internet doit gérer la congestion et réagir proprement à celle-ci, sans aggraver le problème par un comportement égoïste. Si ce protocole fonctionne sur TCP, c'est fait automatiquement pour lui. Mais s'il fonctionne sur des protocoles sans notion de connexion, comme UDP, c'est plus complexe. Ce RFC spécifie un mécanisme que les protocoles peuvent utiliser pour assurer un contrôle de congestion compatible avec celui de TCP. Il s'applique aussi bien aux protocoles de la couche transport comme DCCP qu'aux protocoles de la couche application, si la couche transport ne fournit pas de contrôle de congestion.

Il est difficile de demander à chaque application de faire ce contrôle, qui est très complexe. Celles utilisant TCP ou bien DCCP (RFC 4340) voient ce contrôle fait automatiquement pour elles. Le protocole de notre RFC 5348, TFRC, peut être utilisé par DCCP, son principal client (RFC 4342), ou bien par une application utilisant UDP (section 1 du RFC). TFRC n'est d'ailleurs pas un protocole complet, spécifié dans les moindres détails, puisque certains points dépendent du protocole qui l'utilise (le RFC 4342 donne un exemple d'utilisation de TFRC).

Le nom de TFRC vient de son désir d'être « civil » envers TCP lorsqu'un flot de données TCP et un flot de données DCCP sont en compétition sur le même câble. Normalement, chacun des deux flots doit obtenir une part à peu près égale de la capacité disponible. (Un protocole « incivil » enverrait le plus de paquets possible, sans ralentir, malgré la congestion.)

TFRC met en œuvre ses mécanismes chez le récepteur des données (sections 3, 5 et 6). Celui-ci mesure le pourcentage de données perdues et en informe l'émetteur (par des paquets décrits en section 3.2.2), qui devra alors ralentir l'envoi (pour calculer le ralentissement nécessaire, l'émetteur dispose également du RTT, qu'il a mesuré à cette occasion). L'équation exacte est donnée dans la section 3.1 et est très proche de celle dite Reno.

Le contrôle de congestion est un problème complexe, très mathématique, et qui mène facilement à des textes longs, comme ce RFC. Les nombreuses formules qu'il contient sont d'autant plus difficile à lire que, comme tout RFC, il est en texte brut.

La section 4 décrit plus en détail ce que doit faire l'émetteur, notamment s'il ne reçoit pas les paquets d'information du récepteur (l'émetteur doit alors diviser son débit par deux, mesure drastique justifiée par le fait que, si aucun paquet d'information ne passe, c'est probablement que la congestion est sévère).

Notons qu'une variante de TFRC fonctionne avec des mesures du taux de perte de paquets faites par l'émetteur et pas par le récepteur. Elle est décrite en section 7.

TFRC avait été normalisé à ses débuts dans le RFC 3448. La section 9 résume les changements, peu importants. Le principal est que, dans l'ancien RFC, l'émetteur était tenu par le taux d'envoi que lui imposait le récepteur. Si l'émetteur envoyait peu, parce qu'il n'avait pas grand'chose à dire (data limited), le récepteur lui retournait un taux d'envoi faible. Ce problème a été traité.


Téléchargez le RFC 5348


L'article seul

RFC 2681: A Round-trip Delay Metric for IPPM

Date de publication du RFC : Septembre 1999
Auteur(s) du RFC : Guy Almes (Advanced Network & Services, Inc.), Sunil Kalidindi (Advanced Network & Services, Inc.), Matthew J. Zekauskas (Advanced Network & Services, Inc.)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 25 septembre 2008


Les mesures de performances sur l'Internet sont un sujet passionnant mais complexe. Comme il faut bien commencer par définir précisement ce qu'on mesure, ce RFC ne spécifie pas un protocole mais uniquement une métrique, une grandeur qu'on veut mesurer et qui doit faire l'objet d'une définition rigoureuse. Cette métrique est le temps d'aller-retour (RTT) d'un paquet IP.

Cette mesure du RTT est connue grâce à l'outil ping. Mais ping a, entre autres défauts, celui de ne pas reposer sur une métrique rigoureuse, ce qui rend souvent difficile de savoir ce qu'il mesure exactement. Notre RFC s'attache donc à une définition précise d'une telle métrique. Il s'appuie pour cela sur le cadre et les définitions du RFC 2330, et suit de près le RFC 2679, qui décrivait une telle métrique pour les allers simples.

La section 1.1 du RFC commence par expliquer pourquoi une telle métrique est utile : notamment parce que certaines applications, notamment les plus interactives, fonctionnent mal si le RTT est trop élevé, que sa valeur minimale donne une idée des caractéristiques intrinsèques du lien et que des augmentations de ce RTT peuvent indiquer une congestion du lien. Elle est donc pertinente dans beaucoup de cas.

Mais pourquoi, continue cette section 1.1, mesurer le temps d'aller-retour et pas seulement celui d'aller simple comme le fait le RFC 2679 ? En effet, le RTT a plusieurs défauts : en cas de routage asymétrique, le temps de parcours aller peut être très différent du temps retour (et le RTT ne permet pas de voir cette différence). Même chose si des mécanismes divers (par exemple l'asymétrie des débits en ADSL) font qu'une direction a des caractéristiques très différentes d'une autre. C'est vrai, mais le RTT a aussi des avantages, notamment le fait qu'il est beaucoup plus facile à mesurer que l'aller simple, puisqu'il ne nécessite pas que les horloges des deux machines soient synchronisées (c'est sur ce principe que fonctionne ping).

Les lecteurs étant désormais convaincus de l'intérêt de cette métrique, la section 2 passe donc à sa définition : baptisée du nom scientifique de Type-P-Round-trip-delay, le temps d'aller-retour a pour paramètre les adresses IP de la source et de la destination, le temps T de la mesure, pour unité la seconde et pour définition (section 2.4) le délai entre la mise du premier bit de la question sur le câble et la réception du dernier bit de la réponse. Type-P signifie simplement qu'il peut dépendre du type du paquet (par exemple TCP vs. UDP, ou bien le numéro de port, tout ce qui fait qu'un routeur peut traiter ce paquet rapidement ou pas). Ainsi, les mesures de ping ont pour Type-P « ICMP avec des paquets echo ». Ce terme de Type-P est défini dans la section 13 du RFC 2330.

Cette définition est donc très simple sur le papier. En pratique, elle pose quelques problèmes, signalés par la section 2.5 : le temps T de la mesure dépend, lui, d'une bonne synchronisation des horloges, la définition n'indique pas à partir de quand on renonce à attendre un paquet perdu (le résultat de la mesure est alors indéfini), etc.

Ce n'est pas tout : même lorsque la métrique est parfaite, les ordinateurs sont des machines physiques ayant plein de limitations, qui limitent la précision de la mesure. Il est symptomatique du mauvais état de la métrologie sur Internet qu'on voit souvent citer des résultats sans indiquer les marges d'erreur ou d'incertitude. La section 2.7 cite certaines de leurs causes :

  • Les faiblesses des horloges (section 2.7.1) sont à prendre en compte. Si la mesure du RTT ne nécessite pas de synchronisation de celles-ci (sauf pour déterminer le temps T de la mesure), elle demande par contre un peu de stabilité. Une dérive (skew) très forte ou, plus probable, un changement brusque de l'heure par l'opérateur ou par un logiciel peut fausser un résultat. De même, la résolution des horloges peut être trop mauvaise pour la rapidité des réseaux modernes.
  • La définition du RTT est lié au concept de « mise sur le câble » des bits (section 2.7.2). Un programme typique n'a pas accès à l'information sur l'instant exact où le bit est envoyé. Le temps qu'il mesure est celui de la machine, pas celui de la carte réseau. (Mon programme echoping, qui mesure le RTT, n'essaie même pas de déterminer ce wire time, je ne pense pas qu'il existe une méthode portable sur Unix pour cela.)
  • Le temps de réaction de la machine visée est souvent difficile à prédire (section 2.7.3). Les routeurs Cisco, par exemple, ne génèrent pas la réponse aux paquets ICMP echo sur la carte (fast path) mais dans leur processeur généraliste, bien plus lent. Avec de telles machines, le temps mesuré par ping est largement dominé par le temps de réponse du routeur et pas par le réseau proprement dit. Sur une machine Unix, ICMP est mis en œuvre dans le noyau, ce qui fournit certaines garanties, notamment que le swapping n'interviendra pas. Mais cela ne garantit pas, par exemple, qu'une surcharge du processeur de la machine ne va pas ajouter un délai inattendu. Si le Type-P est TCP avec le port 80, comme HTTP est typiquement mis en œuvre en mode utilisateur, les incertitudes sont bien plus grandes (swapping, temps de réponse de l'application - par exemple Apache, ...)

Une fois ces problèmes surmontés, il faut indiquer à l'utilisateur le résultat des mesures. C'est l'objet de la section 2.8 qui insiste sur la nécessité de transmettre au dit utilisateur toutes les informations permettant d'interpréter les données : le Type-P (pour echoping, il faut utiliser l'option -v et encore, l'affichage du Type-P n'est pas vraiment clair), la façon dont une réponse en retard est considérée comme perdue, les résultats de l'étalonnage et le chemin suivi par les paquets (à noter que cette information n'est en général pas accessible au programme de mesure, à part éventuellement l'interface réseau de sortie).

Une fois cette première métrique établie, le RFC, dans sa section 3, définit un échantillonage de cette mesure, selon une distribution de Poisson. Cette seconde métrique, définie de 3.1 à 3.4, a deux paramètres supplémentaires, le temps de fin de la mesure et le taux d'envoi des paquets (le lambda de la distribution de Poisson).

La section 3.5 discute du choix du paramètre lambda, en citant le RFC 2330. En gros, comme il s'agit d'une mesure active, plus lambda est élevé et plus la mesure est précise, mais plus on a perturbé le réseau avec tous ces paquets de test.

Munis de cette deuxième métrique, le RFC cite quelques statistiques intéressantes (section 4) qui peuvent être obtenues :

  • Le Xème centile (section 4.1), c'est-à-dire la valeur du RTT pour laquelle X % des mesures tombent en dessous. Ainsi, le 90ème centile est la valeur du RTT telle que 90 % des mesures donnaient une RTT plus faible. Le 50ème centile est presque équivalent à la médiane, décrite en section 4.2.
  • Le délai d'aller-retour minimum (section 4.3) qui reflète le cas idéal (réseau peu ou pas chargé, machine distante peu ou pas chargée et qui répond donc aux mieux de ses capacités).

Enfin, la section 5 est consacrée aux questions de sécurité. Comme toutes les mesures actives, celles du RTT doivent garder à l'esprit la nécessité de ne pas surcharger le réseau (ne pas utiliser l'option -f de ping). Mais ce point concerne la sécurité du réseau vis-à-vis des mesures. Il y a aussi un problème de sécurité des mesures vis-à-vis du réseau. En effet, les équipements sur le trajet peuvent fausser la mesure en retardant ou en donnant la priorité à certaines paquets. En cas de mesure d'un réseau franchement hostile, il peut être nécessaire de recourir à des techniques cryptographiques pour préserver l'intégrité des mesures.

Un protocole utilisant cette métrique a été normalisé, TWAMP (RFC 5357).


Téléchargez le RFC 2681


L'article seul

Remplacement automatisé de caractères en Emacs

Première rédaction de cet article le 18 septembre 2008
Dernière mise à jour le 19 septembre 2008


Un petit exercice de programmation en Emacs Lisp. Comment remplacer facilement un ensemble de caractères par un autre ?

Beaucoup de pages Web aujourd'hui utilisent tout le jeu de caractères Unicode et elles ont bien raison, le Web étant certainement un des services d'Internet le mieux « unicodisé ». Ainsi, on trouvera sur une page Web comme http://morris.blogs.nytimes.com/2008/08/11/photography-as-a-weapon/, pourtant en anglais, des caractères Unicode comme les jolis guillemets (“this information that you heard? It's wrong.”, utilisant les caractères U+0201c et U+0201d. Mais ces caractères ne sont pas présents dans ASCII ni même dans Latin-1. Comme je ne suis pas encore pas encore passé à UTF-8, ces caractères me gênent lorsque je veux copier-coller une partie d'une page Web dans, par exemple, un courrier. Emacs accepte le texte mais, à l'enregistrement, proteste que :

These default coding systems were tried to encode text
in the buffer `toto':
  (iso-latin-1 (15 . 342396) (51 . 342393) (60 . 342397) (185
  . 342393))
However, each of them encountered characters it couldn't encode:
  iso-latin-1 cannot encode these: “ ”

Comment les convertir sans procéder à un rechercher/remplacer par caractère (car il n'y a pas que les guillemets) ? Une des forces d'Emacs est d'être programmable, dans son langage dédié, un dialecte de Lisp. On peut donc écrire :

(defun to-latin1 ()
  (interactive "*")
  (goto-char (point-min))
  (replace-string "something" "other thing")
  (goto-char (point-min))
  (replace-string "some other thing" "yet another thing")
...
)

On peut alors appeler cette fonction (avec M-x to-latin1 ou bien en l'attachant à une touche) et la conversion est faite.

Bon, il reste à mettre les caractères à changer. Le moyen le plus simple est de convertir le code en chaîne. La syntaxe Emacs Lisp pour cela est :

"\x53979"

Comment ai-je trouvé le chiffre (hexadécimal) 53979 ? Emacs n'utilise pas les points de code de la norme Unicode, malheureusement. Ce code 53979 est donc spécifique à Emacs. Pour le trouver, le plus simple est donc de mettre le curseur sur le caractère problématique et de faire C-x =. Le code est alors affiché en bas dans la mini-fenêtre.

Voici donc le résultat final :

(defun to-latin1 ()
  (interactive "*")
  (goto-char (point-min))
  (replace-string "\x53979" "'")
  (goto-char (point-min))
  (replace-string "\x5397c" "\"")
  (goto-char (point-min))
  (replace-string "\x5397d" "\"")
)

Merci à Christopher J. Madsen (cjm) pour son aide sur la syntaxe.


L'article seul

RFC 5325: Licklider Transmission Protocol - Motivations

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : S. Burleigh (NASA/Jet Propulsion Laboratory), M. Ramadas (Ohio University), S. Farrell (Trinity College - Dublin)
Pour information
Première rédaction de cet article le 17 septembre 2008


Le groupe de travail de l'IRTF DTN (Delay-Tolerant Networking) continue son travail de création de protocoles de communication standards capables de fonctionner dans l'espace lointain, ou dans des milieux similaires. Après le protocole Bundle du RFC 5050, qui décrit un protocole de niveau Application pour le transfert de données, voici le protocole Licklider, de niveau Transport.

LTP (Licklider Transmission Protocol), ainsi nommé en l'honneur du pionnier de l'Internet, est donc sur le même créneau que des protocoles comme TCP, chargé de fournir un service de transport aux applications (ce que le RFC 5050 nomme un convergence layer). Il est normalisé dans le RFC 5326 et des extensions sont prévues par le RFC 5327. Notre RFC 5325, lui, expose les motivations derrière ce protocole.

Les milieux où LTP sera utilisé sont caractérisés (sections 1 et 2 du RFC) par des délais de transmission très longs (une heure pour joindre Jupiter depuis la Terre), une fiabilité faible des transmissions et le fait que celles-ci ne soient possibles que par intervalles, lorsque les deux astres ne sont pas masqués par un troisième. Le principal « client » de LTP sera donc la NASA. (Le problème général des communications spatiales avait été décrit dans le RFC 4838.)

La section 2.1 fait également remarquer que les limites de ces communications spatiales ne sont pas uniquement physiques (vitesse de la lumière) mais également économiques. Les antennes capables de communiquer avec les vaisseaux spatiaux, comme celles du DSN, sont rares et leur location coûte cher.

La même section 2.1 explique pourquoi ces caractéristiques condamnent les protocoles réseaux traditionnels : on ne peut pas attendre un accusé de réception avant de continuer à transmettre, vue la longueur du RTT ; on ne peut pas négocier des paramètres de transmission avec l'autre partie, la fenêtre de transmission est souvent trop courte pour cela ; l'évaluation du RTT par des mesures est en général impossible. LTP sera donc un protocole unidirectionnel, l'interactivité n'étant en général pas possible dans l'espace.

La section 2.2 détaille les limites de TCP ou SCTP pour ce problème. Avec une équation d'état comme celle du RFC 5348, une transmission de la Terre à Mars à seulement dix kilobits par seconde nécessiterait un taux de perte des données inférieur à 10^(-5), ce qui est irréaliste dans l'espace.

La section 3 explique les grandes lignes du protocole (il faut lire le RFC 5326 pour avoir la vraie norme). LTP transmet des blocs de données qui sont composés de deux parties, la « rouge » (ces données doivent faire l'objet d'un accusé de réception, sinon elles sont retransmises) et la « verte » (jamais retransmises). Chacune des deux parties peut être vide. Ainsi, une application de transfert de fichiers mettra typiquement toutes les données dans la partie rouge et rien dans la verte. LTP permet donc à l'application de choisir la sémantique de TCP ou bien d'UDP et ceci pour chaque bloc de données.

Vue la nature unidirectionnelle de LTP, il n'y a pas de négociation avec l'autre partie : la transmission des données se fait « en aveugle », LTP stockant les parties rouges pour pouvoir les retransmettre s'il n'y a pas d'accusé de réception. Seule la couche Liaison peut donner des indications à LTP (la section 3.1.1 détaille ces indications).

Justement, quand retransmettre ? Comme LTP ne peut pas mesurer le RTT, il doit dépendre de calculs réalisés avant la transmission (la section 3.1.3 détaille ces calculs), en se basant sur la vitesse de la lumière et les délais connus, par exemple dûs à la disponibilité des antennes. Cela permet d'évaluer à partir de quand une non-réponse est le signe de données perdues. Il faudra alors retransmettre (section 3.2).


Téléchargez le RFC 5325


L'article seul

La fête du Cheval 2008 au Trait

Première rédaction de cet article le 16 septembre 2008


Le 14 septembre 2008, Le Trait a accueilli la seizième édition de la Fête du Cheval. Voici plusieurs photos.


L'article complet

Adaptation des types Python à PostgreSQL pour psycopg

Première rédaction de cet article le 16 septembre 2008


psycopg est l'interface avec PostgreSQL la plus répandue chez les programmeurs Python. Parmi toutes ses qualités, psycopg adapte automatiquement les types Python aux types PostgreSQL. Mais cette adaptation ne fonctionne pas toujours toute seule et a parfois besoin d'un coup de main.

Avec psycopg, si j'ai créé une table en SQL avec :

 
CREATE TABLE Foobar (t TEXT, i INTEGER);

je peux écrire dans mon programme Python :

cursor.execute("INSERT INTO Foobar (t, i) VALUES (%s, %s)", 
               ["I like Python", 42])

et psycopg trouve tout seul que "I like Python" est une chaîne de caractères alors que 42 est un entier. Il quote (met entre apostrophes) donc le premier et pas le second. PostgreSQL recevra (instruction SQL affichée grâce à log_statement = 'all') :

2008-09-16 13:40:19 CEST STATEMENT:  INSERT INTO Foobar (t, i) VALUES ('I like Python', 42)

Cela marche bien dans ce cas car Python connait les types utilisés et peut donc le dire à psycopg2 :


>>> type(42)
<type 'int'>
>>> type("I like Python")
<type 'str'>

Mais si on a affaire à des types qui existent dans PostgreSQL et pas dans Python ? Le cas est fréquent car PostgreSQL dispose de nombreux types comme par exemple les points, les adresses IP ou encore les UUID (RFC 4122). Essayons avec les adresses IP. Créons la table  :

CREATE TABLE Foobar (addr INET);

puis remplissons-la :

cursor.execute("INSERT INTO Foobar (addr) VALUES (%s)", 
                            ["2001:DB8::CAFE:1"])

Ça marche, l'adresse IP 2001:db8::cafe:1 a bien été enregistrée. Python ne connait pas ce type, donc l'a traité comme une chaîne de caractères, que PostgreSQL a su analyser.

Mais si on veut mettre un tableau de telles adresses (petit détour par le DNS : il est tout à fait légal, et même fréquent, qu'à un nom de machine donnée correspondent plusieurs adresses IP) ? Là, Python, psycopg et PostgreSQL ne sont pas assez intelligents. On crée la table :

CREATE TABLE Foobar (addr INET[]);

et on tente de la peupler :


>>> cursor.execute("INSERT INTO Foobar (addr) VALUES (%s)", [["2001:DB8::CAFE:1", "192.168.25.34"]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
psycopg2.ProgrammingError: column "addr" is of type inet[] but expression is of type text[]
LINE 1: INSERT INTO Foobar (addr) VALUES (ARRAY['2001:DB8::CAFE:1', ...
                            ^
HINT:  You will need to rewrite or cast the expression.

En effet, PostgreSQL aura reçu :

2008-09-16 13:53:01 CEST LOG:  statement: INSERT INTO Foobar (addr) VALUES (ARRAY['2001:DB8::CAFE:1', '192.168.25.34'])

alors qu'il aurait fallu envoyer INSERT INTO Foobar (addr) VALUES ('{2001:DB8::CAFE:1, 192.168.25.34}'). (Le problème serait le même pour le type UUID.)

Quelle est la bonne solution ? psycopg pourrait être plus malin et mieux connaître les types de PostgreSQL mais c'est plus compliqué que ça en a l'air. Heureusement, il existe une solution assez simple. Depuis sa version 2, psycopg permet de définir des adaptateurs soi-même, c'est-à-dire le code qui va faire la conversion d'un objet Python, au moment de l'appel à PostgreSQL. Cette technique est documentée (sommairement) dans le fichier doc/extensions.rst qui est distribué avec psycopg. (On le trouve aussi sur le Web en http://www.initd.org/svn/psycopg/psycopg2/trunk/doc/extensions.rst mais, servi avec une mauvaise indication de son type, il est difficile à lire.) Voici l'exemple que donne la documentation. Il utilise le type POINT de PostgreSQL, qui représente un point dans un espace cartésien à deux dimensions. On crée la table avec :

CREATE TABLE Atable (apoint POINT);

et on peut la peupler en SQL ainsi :

INSERT INTO Atable (apoint) VALUES ('(1, 3.14159)');

Pour que cela soit fait automatiquement depuis le programme Python utilisant psycopg2, le code est :

    from psycopg2.extensions import adapt, register_adapter, AsIs
    
    class Point(object):
        def __init__(self, x=0.0, y=0.0):
            self.x = x
            self.y = y
    
    def adapt_point(point):
        return AsIs("'(%s,%s)'" % (adapt(point.x), adapt(point.y)))
        
    register_adapter(Point, adapt_point)
    
    curs.execute("INSERT INTO atable (apoint) VALUES (%s)", 
                 (Point(1.23, 4.56),))

Et voici enfin le (tout petit) adaptateur que j'ai écrit pour le type PostgreSQL INET, qui permet de représenter des adresses IP :

from psycopg2.extensions import adapt, register_adapter, AsIs

class Inet(object):
    """ Classe pour stocker les adresses IP. Pour que psycopg puisse
    faire correctement la traduction en SQL, il faut que les objets
    soient typés. Les chaînes de caractères ne conviennent donc pas. """
  
    def __init__(self, addr):
        """ Never call it with unchecked data, there is no protection
	against injection """
        self.addr = addr

def adapt_inet(address):
    """ Adaptateur du type Python Inet vers le type PostgreSQL du même
    nom. On utilise un "cast" PostgreSQL, représenté par '::inet' """
    return AsIs("'%s'::inet" % address.addr)

register_adapter(Inet, adapt_inet)

Et on l'utilise ainsi (notez qu'il faut appeler le constructeur Inet() pour « typer » les valeurs) :

cursor.execute("INSERT INTO Foobar (addr) VALUES (%s)", 
                 [[Inet("2001:DB8::CAFE:1"), Inet("192.168.25.34")]])

Désormais, cela fonctionne. PostgreSQL reçoit :

2008-09-16 17:43:48 CEST LOG:  statement: INSERT INTO Foobar (addr) VALUES (ARRAY['2001:DB8::CAFE:1'::inet, '192.168.25.34'::inet])

et exécute bien la requête.

Merci à Chris Cogdon et Federico Di Gregorio (l'auteur de psycopg) pour leur aide sur ce sujet.


L'article seul

Install Ubuntu / Linux on a Dell Inspiron 7500

First publication of this article on 15 September 2008
Last update on of 18 September 2010


I installed the operating system Ubuntu on a Dell Inspiron 7500 laptop machine. This article is to share the information that I obtained during the process.

While the basic functions are OK, there are problems. As often with laptops, even quite old machines, a lot of things do not work, or do not work out of the box.


L'article complet

RFC 5261: An Extensible Markup Language (XML) Patch Operations Framework Utilizing XML Path Language (XPath) Selectors

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : J. Urpalainen (Nokia)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF simple
Première rédaction de cet article le 11 septembre 2008


De nombreux protocoles IETF s'appuient sur XML, par exemple pour stocker de l'information de configuration. Dans ce cadre, le besoin de modifier de l'information XML sans devoir transporter le fichier entier, en communiquant juste les différences, est fréquent.

Pour le texte brut, ce besoin est couvert depuis longtemps par le format diff / patch. Jusqu'à présent, il n'existait aucune norme équivalente pour XML. Plusieurs propositions de « langages de patch » pour XML ont été faites mais ce RFC est le premier où on atteint le stade de la normalisation.

Il a été développé au sein du groupe de travail Simple, qui normalise des extensions au protocole SIP (RFC 3261) et qui en avait besoin, entre autres, pour la mise à jour de configurations stockées en XCAP (RFC 4825). Mais il est très général et applicable à tous les domaines.

Le principe de cette technique est simple. La partie du document XML à modifier est identifiée par une expression XPath. Une fois cette partie localisée, du contenu est ajouté, modifié ou retiré, selon que le fichier de modifications contienne des éléments <add>, <replace> ou <remove> (la section 4 détaille chacun de ces éléments).

L'annexe A du RFC contient de nombreux exemples, en voici quelques uns pour illustrer :


   <diff>
     <add sel="/section"><para>Nouveau paragraphe, lorem, ipsum, dolor, etc</add>
   </diff>

Ce code ci-dessus ajoute un nouvel élément <para>. L'expression XPath pour localiser le point où l'ajouter est donnée par l'attribut sel. Ici, on ajoute le nouvel élément dans l'élément <section> de premier niveau.


 <diff>
     <replace sel="section[title='Bibliographie']">
         <bibliography>...</bibliography>
     </replace>
   </diff>

Ici, la section de titre « Bibliographie » est remplacée par un élément <bibliography>.

   
   <diff>
     <remove sel="article/section/para/text()"/>
   </diff>

Ici, le texte de l'élément <para> est supprimé.

La syntaxe complète de ce nouveau format est décrite dans la section 8, elle est exprimée en W3C Schema.

À noter qu'il existe déjà une mise en œuvre de ce format, xmlpatch. Voici un exemple d'utilisation avec un premier document toto.xml :


<article>
<abstract>Brouillon</abstract>
<section>
<title>Premier essai</title>
<para>À l'heure actuelle, on ne sait pas encore grand'chose.</para>
</section>
</article>

et sa deuxième version, totoplus.xml :


<article>
<section>
<title>Premier essai</title>
<para>Aujourd'hui, nous en savons bien plus.</para>
</section>
<section>
<title>Révélations</title>
<para>Nous avons même une seconde section.</para>
</section>
</article>

Appliquons xml_diff pour obtenir un fichier de différences, au format du RFC :

% xml_diff -f toto.xml -t totoplus.xml -o toto.xmlpatch

Ce fichier des différences contient :


<?xml version="1.0"?>
<x:changes xmlns:x="urn:xml-changes">
  <x:remove sel="*/*[1]" ws="after"/>
  <x:replace sel="*/*/*[2]/text()">Aujourd'hui, nous en savons bien plus.</x:replace>
  <x:add sel="*"><section>
<title>R&#xE9;v&#xE9;lations</title>
<para>Nous avons m&#xEA;me une seconde section.</para>
</section>
</x:add></x:changes>

Personnellement, je ne trouve pas les expressions XPath extraordinaires, elles manquent notamment de robustesse en cas de légers changements du document source. Mais elles sont correctes et on peut appliquer ce patch :

% xml_patch -f toto.xml -p toto.xmlpatch -o toto-patched.xml

et cela nous redonne un document qui a le même contenu que totoplus.xml. Attention, cela ne signifie pas qu'il soit identique au bit près (par exemple, les caractères UTF-8 de l'original ont été remplacés par des entités numériques XML) mais que son contenu informationnel (l'infoset XML) est le même.

Au passage, vous remarquerez que l'élement XML qui englobe les éléments patch n'est pas défini par le RFC. <diff> (dans les exemples du RFC) ou bien <changes> (dans l'exemple avec xml_patch) sont des choix arbitraires. Cela été fait ultérieurement dans le RFC 7351.


Téléchargez le RFC 5261


L'article seul

La sécurité de BGP et l'importance des réactions rapides

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


Des problèmes récents comme l'attaque involontaire de Pakistan Telecom contre Youtube ou comme la polémique autour des annonces de l'ancienne adresse d'un serveur racine du DNS ont ravivé l'intérêt pour les problèmes de sécurité de BGP. L'annonce en août 2008 d'un nouveau moyen pour limiter le risque d'être détecté lorsqu'on fait des fausses annonces BGP a encore renforcé l'inquiétude. Certains se posent donc la question : pourquoi ne « sécurise » t-on pas BGP ? Pourquoi n'importe quel incompétent à Pakistan Telecom peut-il détourner l'accès à un service vital et stratégique comme Youtube ?

La réponse à cette question est parfois « parce que l'Internet a été conçu par des étudiants hippies et irresponsables qui ne pensaient pas à la sécurité ; aujourd'hui que l'Internet est une ressource critique, il faudrait prendre la sécurité de BGP plus au sérieux ». Cette position laisse entendre qu'on pourrait sécuriser BGP pour peu qu'on le veuille vraiment. Mais c'est trop simpliste. Voyons pourquoi.

BGP, normalisé dans le RFC 4271, fonctionne entre pairs, des routeurs qui ont été configurés pour échanger de l'information sur les routes disponibles. Chaque routeur peut accepter et refuser les routes annoncées par son pair, selon des critères choisis unilatéralement, et ils ne s'en privent pas (le RFC 5291 fournit un mécanisme - facultatif - pour informer son pair). Les deux pairs étant en général proches physiquement, souvent sur un câble dédié, la sécurité du canal BGP n'est guère en cause (on peut l'améliorer avec IPsec mais la plupart des opérateurs préfèrent la solution du RFC 2385, qui sera peut-être remplacée dans le futur par celle du RFC 5925). Le problème n'est pas d'authentifier le pair voisin, le problème est d'authentifier ce qu'il raconte ! Sachant que les annonces BGP sont transmises de routeur en routeur, comment garantir une chaîne de confiance depuis le premier ? En d'autres termes, si mon voisin m'annonce qu'il a entendu qu'il y avait une route vers 192.0.2.0/24, et qu'il le sait parce que lui-même l'a entendu d'un de ses voisins, comment savoir si cette route est authentique, d'autant que ce terme même n'est pas clairement défini (cf. RFC 5123) ?

Alors, comment authentifier des annonces BGP ? Les propositions actuelles, comme Secure BGP ou soBGP, actuellement discutées au sein du groupe de travail SIDR de l'IETF ne sont pas nouvelles. Elles visent à mettre au point un mécanisme de signature cryptographique des annnonces BGP. Le RIR qui attribue un préfixe IP signera cette attribution, permettant à l'opérateur qui a reçu le préfixe de signer ses annonces. Les RFC normalisant cette technique ont été publiés début 2012.

La principale difficulté commune à tous ces mécanismes est que la hiérarchie d'attribution des adresses IP (de l'IANA vers les RIR puis vers les LIR) ne correspond pas très bien au maillage BGP, qui, lui, n'est pas hiérarchique. Le client final annonce sa route (s'il fait du BGP lui-même) ou bien la fait annoncer par qui il veut, sans que le LIR par qui il a obtenu l'adresse n'approuve ou même soit au courant. Et c'est sans même parler des adresses PI, qui ne sont pas liées à un LIR. Changer ce mécanisme est certainement possible, mais cela change le modèle de fonctionnement de l'Internet. Et cela donnerait un plus grand pouvoir aux opérateurs puisque seules les annonces approuvées par eux pourront être faites.

Bien sûr, les annonces qui sont faites sont normalement annoncées dans les IRR. Mais les IRR publics sont souvent de piètre qualité. Certains sont assez à jour, par exemple celui du RIPE-NCC mais ce n'est pas le cas de tous (parfois tout simplement parce que les procédures de mise à jour sont trop strictes). Certaines entreprises ont leur propre IRR, tâche assez lourde. Il n'est donc pas étonnant que le filtrage des annonces BGP sur la base des IRR (n'accepter que les routes qui sont publiées dans un IRR) aie eu assez peu de succès : comme l'ont montré beaucoup d'études et d'expériences douloureuses, ce filtrage rencontre beaucoup de faux positifs (des routes légitimes refusées) et également des faux négatifs (routes illégitimes acceptées quand même). Il faut aussi se rappeler que, dans le cas du « détournement » du serveur racine L, l'annonce « anormale » était bien faite par le titulaire du préfixe...

Alors, n'y a t-il pas d'espoir pour la sécurité et la stabilité de l'Internet ? Notons d'abord que, bien que triviales en pratique et très connues, les vulnérabilités de BGP n'ont pas eu pour conséquence des attaques nombreuses. Une des raisons est que tout le monde voit l'attaque et peut réagir et tomber sur le dos du responsable. Jusqu'à l'annonce de Kapela & Pilosov, ces « attaques » (souvent en fait, des erreurs) étaient détectées et corrigées très vite. C'est un point important de la sécurité de l'Internet : celui-ci n'a pas la sécurité d'un bloc de béton, passif et n'étant protégé que par sa résistance aveugle. L'Internet est plutôt un organisme vivant : très vulnérable, mais aussi très réactif, doté d'un système immunitaire particulièrement efficace, puisque ses leucocytes sont intelligents...

L'Internet peut ainsi réagir à une large gamme d'attaques, y compris des attaques pas encore inventées. Lors de l'attaque contre Youtube, la détection, l'identification du responsable et la correction avaient été faites en quelques heures.

C'est pour cela que, jusqu'à présent, les armes les plus efficaces contre les détournements BGP ont été des systèmes d'alerte comme MyASN ou bien IAR. Ces systèmes fonctionnent aussi lors d'attaques du style Kapela & Pilosov. En effet, le détournement de Youtube avait été noté car plus personne ne pouvait travailler, sans ce service indispensable. Si l'attaquant avait utilisé les techniques mises au point par Kapela et Pilosov, il aurait pu échapper à la détection, mais pas si Youtube avait utilisé MyASN (ils utilisent probablement un tel service).

Un peu plus lointain, d'autres systèmes sont actuellement mis au point pour donner du temps aux administrateurs réseaux en cas de détournement, évitant ainsi d'avoir une perturbation, même de durée limitée. C'est ainsi que Pretty Good BGP ralentit délibérement la propagation de nouvelles routes (considérées suspectes par défaut) pendant 24 heures. Ainsi, une équipe réactive pourra arrêter le détournement avant qu'il ne soit accepté par les routeurs. (Une mise en œuvre de Pretty Good BGP est disponible pour Quagga.)


L'article seul

Les normes du courrier électronique enfin entièrement internationalisées

Première rédaction de cet article le 7 septembre 2008
Dernière mise à jour le 12 mars 2013


Parmi les protocoles utilisés sur Internet, presque tous sont internationalisés depuis longtemps. Le dernier gros manque concernait les adresses de courrier électronique, obligées de s'en tenir à stephane@internet-en-cooperation.fr alors qu'on voudrait pouvoir écrire à stéphane@internet-en-coopération.fr. Désormais, nous avons une solution normalisée, Internationalized Email, dont les spécifications viennent d'accéder au statut de norme IETF.

Bien sûr, pour l'exemple ci-dessus, n'utilisant que l'alphabet latin, le gain n'est pas évident. Mais il l'est beaucoup plus si vous voulez écrire votre adresse avec l'écriture arabe ou chinoise.

Le contenu des courriers était internationalisé depuis longtemps, au moins depuis MIME (RFC 1341 à l'origine, en juin 1992). Mais les adresses ne l'étaient pas encore. Une solution était en développement depuis longtemps à l'IETF, sous le nom d'EAI (Email Addresses Internationalization) et avait été publiée à l'origine en 2008, avec un statut « expérimental ». Elle est désormais, après une histoire complexe, entièrement normalisée.

Il y a deux parties à l'adresse (décrites dans le RFC 5322) : la partie locale, à gauche du @ et le nom de domaine à droite. Si ce nom de domaine, depuis la sortie du RFC 3490, en mars 2003, peut s'écrire en Unicode (norme IDN), le courrier exigeait toujours un nom de domaine en ASCII donc un message de non-délivrance, par exemple, allait affichait la forme Punycode du nom. Ce n'était pas une vraie internationalisation.

La nouvelle norme, qui réalise enfin cette internationalisation, est spécifiée dans les RFC suivants :

  • RFC 6530, Overview and Framework for Internationalized Email décrit le cadre général. Si on ne lit qu'un seul RFC de la série, c'est celui-là.
  • RFC 6531, SMTP extension for internationalized email address, qui indique les modifications de SMTP pour utiliser le courrier aux adresses Unicode.
  • RFC 6532, Internationalized Email Headers, qui décrit l'utilisation d'UTF-8 dans les en-têtes du courrier électronique où, jusqu'à présent, seul ASCII était autorisé.
  • RFC 6533, Internationalized Delivery Status and Disposition Notifications, qui précise le format des accusés de réception et des avis de remise et de non-remise.
  • Le cas des listes de diffusion est traité dans le RFC 6783.
  • Et des RFC pour les protocoles permettant la récupération locale du courrier, c'est-à-dire POP (RFC 6856) et IMAP (RFC 6855), ainsi que deux RFC (RFC 6857 et RFC 6858) décrivant un algorithme pour se « replier » au cas où, à la lecture d'un message reçu, il faille transmettre un message internationaisé à un vieux logiciel ne comprenant pas la nouvelle norme.

Il existe plusieurs mises en œuvre d'EAI, dont l'interopérabilité a été testée en juillet 2008 lors d'une session commune aux NIC chinois, coréens, japonais et taïwanais.

Je ne les ai pas encore déployées sur mes serveurs donc inutile d'écrire à stéphane@bortzmeyer.org, cela ne marchera pas. (Si vous voulez tester, des auto-répondeurs utilisant ces adresses sont disponibles.) Pire, en général, le message sera massacré par les divers intervenants (encodé en Quoted-Printable ou transformé en stphane@bortzmeyer.org ou Dieu sait quoi) avant même d'arriver à mon serveur. Merci à André Sintzoff pour ses tests.

L'expérience avec la syntaxe actuelle des adresses, ignorée par bien des programmeurs amateurs, donne à penser qu'il ne sera hélas pas possible de si tôt d'utiliser une telle adresse dans les formulaires.

Le principal protocole de la famille TCP/IP qui ne soit pas complètement internationalisé est donc désormais FTP qui dispose de deux types de transfert de données, « texte » et « binaire » où « texte » ne concerne que l'ASCII (ou, à la rigueur, les jeux ISO 8859). Un travail est en cours pour étendre FTP afin de pouvoir utiliser le texte Unicode du RFC 5198.


L'article seul

RFC 5335: Internationalized Email Headers

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : Y. Abel (TWNIC)
Expérimental
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 7 septembre 2008


Dans l'ensemble des RFC qui décrivent les adresses de courrier électronique internationalisées (c'est-à-dire pouvant utiliser tout le répertoire Unicode), celui-ci se consacre au nouveau format des en-têtes, mettant donc à jour le fameux RFC 2822 (en toute rigueur, il n'est mis à jour que par ceux qui participent à l'expérience, cf. section 1.2 du RFC). Il a été remplacé par la suite par le RFC 6532.

Désormais, on peut, si on participe à l'« expérience » (tel est son statut officiel) EAI (Email Address Internationalization), avoir dans un message un en-tête comme :

From: Stéphane Bortzmeyer <stéphane@sources.org>

Oui, avec du vrai UTF-8, y compris dans l'adresse proprement dite, pas seulement dans les commentaires, et encore, à condition de les surencoder selon le RFC 2047 comme c'était le cas avant.

L'éditeur du RFC travaille à TWNIC, le registre chinois de .tw. Les chinois ont, fort logiquement, été particulièrement actifs dans tout le processus EAI. Celui-ci visait à terminer l'internationalisation du courrier électronique, qui avait passé une étape décisive en novembre 1996, avec la sortie du RFC 2045 sur MIME. Mais cette norme MIME n'internationalisait que le corps des messages. EAI permet désormais d'internationaliser également les en-têtes comme From: ou Received: (mais pas, par exemple, Date: ou Message-ID:, qui resteront en ASCII pur, cf. section 4.3 ; Date:, par exemple, est censé être analysé par le MUA et présenté ensuite à l'utilisateur dans sa langue).

EAI comprend plusieurs RFC, par exemple à l'époque le RFC 4952 définit le cadre général, le RFC 5336, l'utilisation des adresses Unicode dans SMTP (avec l'extension UTF8SMTP), des futurs RFC qui traiteront le cas de POP ou IMAP et notre RFC 5335, qui se concentre sur le format des messages. Tous ont été remplacés en 2012 par la nouvelle série, autour du RFC 6530.

Concrètement, que change donc ce RFC ? La section 4 détaille ce qui est modifié :

  • La grammaire ABNF qui décrit les en-têtes est changée (sections 4.1 et 4.3) pour accepter des caractères UTF-8, de préférence normalisés en NFC (cf. RFC 5198). Déjà très complexe, cette grammaire devient ainsi réellement difficile.
  • La syntaxe des adresses (telles qu'on les trouve dans des en-têtes comme From: ou To:) est modifiée pour accepter UTF-8. Pour les sites qui utilisent une adresse électronique comme identificateur, comme le fait Amazon.com, ce sera un intéressant défi !
  • Un nouveau type MIME est créé, message/global, pour permettre d'identifier un message EAI (section 4.6).

Parmi les conséquences pratiques de ce changement, il faut noter que les programmeurs qui écrivent des logiciels traitant le courrier doivent désormais gérer Unicode, même s'ils se contentent d'analyser les en-têtes... L'époque du courrier traité avec des scripts shell est bien passée.

La section 5 liste également quelques conséquences pour la sécurité comme le fait qu'un mécanisme d'authentification devra être prêt à gérer plusieurs adresses pour la même personne (car, pendant un certain temps, plusieurs utilisateurs auront à la fois une adresse en Unicode et une en ASCII pur).


Téléchargez le RFC 5335


L'article seul

RFC 5336: SMTP extension for internationalized email address

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : J. Yao (CNNIC), W. Mao (CNNIC)
Expérimental
Première rédaction de cet article le 7 septembre 2008


Dans la grande série des RFC décrivant les adresses de courrier internationalisées, ce document traite des modifications au protocole SMTP. Il a été remplacé quatre ans après par le RFC 6531 et n'est donc plus une lecture indispensable.

Plusieurs RFC composent la nouvelle norme EAI ou « Email Addresses Internationalized » (cf. RFC 4952, remplacé depuis par le RFC 6530). Les deux principaux concernent le format des messages (RFC 5335) et le dialogue entre deux serveurs de messagerie, suivant le protocole SMTP. Ce dernier cas est couvert dans notre RFC 5336.

Les adresses de courrier en Unicode ne sont pas en effet compatibles avec le SMTP « brut ». Ainsi, la commande RCPT TO qui permet d'indiquer le destinataire, ne prend en paramètre que de l'ASCII. Il faut donc étendre SMTP (actuellement normalisé en RFC 5321) pour permettre de l'UTF-8 en paramètre de commandes comme MAIL FROM et RCPT TO. Cette extension se signale avec l'option UTF8SMTP, dont l'usage permet de vérifier que le MTA situé en face comprend bien la nouvelle norme (sections 1 et 2 du RFC). Si ce n'est pas le cas, une adresse en ASCII facultative peut être utilisée.

La section 3 forme le gros du RFC en spécifiant rigoureusement le nouveau protocole. Voyons d'abord un exemple de dialogue SMTP avec la nouvelle extension (C est le client - l'appelant - et S le serveur - l'appelé) :


S: 220 mail.example.org ESMTP Foobar (Debian/GNU)
C: EHLO mail.iloveunicode.example 
S: 250-mail.example.org
 250-ENHANCEDSTATUSCODES
 250-8BITMIME
 250-UTF8SMTP
 250 DSN
C: MAIL FROM:<stéphane@internet-en-coopération.fr> ALT-ADDRESS=bortzmeyer@afnic.fr
S: 250 2.1.0 Ok
C: RCPT TO: <françoise@comptabilité.example.org>
S: 250 2.1.5 Ok

Notez les deux adresses, chacune comprenant des caractères non-ASCII, à gauche et à droite du @.

Les serveurs qui mettent en œuvre l'extension UTF8SMTP doivent également accepter la très ancienne extension 8BITMIME (RFC 1652) qui permet, depuis belle lurette, de ne pas se limiter à l'ASCII dans le contenu des messages, sans pour autant nécessiter des encodages comme Quoted-Printable (en dépit d'une légende tenace).

La section 3.1 présente la nouvelle extension, UTF8SMTP. Les extensions SMTP sont définies par le RFC 5321, section 2.2. Un MTA peut annoncer qu'il accepte UTF8SMTP, permettant à son pair, s'il l'accepte également, d'utiliser des adresses UTF-8. C'est également cette section qui définit ce que doit faire un MTA lorsqu'il tente de transmettre un message internationalisé à un ancien MTA qui ne gère pas cette extension. Quatre solutions sont possibles, la plus fréquente sera sans doute d'utiliser le mécanisme de repli (downgrade).

La section 3.3 décrit la nouvelle syntaxe pour les adresses. L'ancienne était limitée à ASCII mais très permissive (bien qu'on trouve, notamment derrière les formulaires Web, énormément de logiciels de « vérification » bogués). En gros, la syntaxe est qu'une adresse est formée de deux parties, la partie locale et le nom de domaine, tous les deux séparés par l'arobase. La nouveauté est que les deux parties peuvent désormais être en Unicode, avec peu de restrictions sur la partie locale (le nom de domaine étant soumis aux restrictions du RFC 3490).

Une adresse alternative tout en ASCII peut être fournie par le paramètre ALT-ADDRESS. C'est l'objet des sections 3.4 et 3.5. Elle doit s'utiliser conjointement à une modification du message (qui peut contenir des en-têtes en UTF-8) et l'ensemble du processus s'appelle le repli (downgrade). Sa spécification est publiée dans le RFC 5504. (Dans l'exemple de dialogue SMTP plus haut, seul l'expéditeur avait une adresse alternative.)

Il y a plein d'autres détails dans cette section, comme celui (section 3.7.1) que le paramètre de la commande EHLO (un nom de machine) doit être encodé en Punycode puisque, à ce stade, on ne sait pas encore si UTF8SMTP est accepté ou pas.

Je n'ai pas encore testé avec mes Postfix, ni vérifié quels étaient les plans des auteurs de ce logiciel vis-à-vis de cette extension de SMTP.


Téléchargez le RFC 5336


L'article seul

RFC 5337: Internationalized Delivery Status and Disposition Notifications

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : C. Newman (Sun), A. Melnikov (Isode)
Expérimental
Réalisé dans le cadre du groupe de travail IETF eai
Première rédaction de cet article le 7 septembre 2008


Dans l'ensemble des RFC sur l'internationalisation des adresses de courrier électronique, ce document traite le cas des accusés de réception et avis de non-remise (DSN pour Delivery Status Notification). Il est le prédécesseur du RFC 6533, la norme actuelle.

Puisque les RFC 5336 et RFC 5335 permettent désormais d'utiliser des adresses de courrier électroniques internationalisées, c'est-à-dire utilisant tout le jeu de caractères Unicode, il faut prévoir le cas où les courriers provoquent l'envoi d'avis de remise ou de non-remise (DSN pour Delivery Status Notification, RFC 3461 et RFC 3464) et d'accusés de réception (MDN, pour Message Disposition Notification, RFC 8098). C'est l'objet de ce RFC, qui met à jour les anciens documents qui limitaient ces accusés et avis au jeu ASCII.

Le format des DSN dans le RFC 3464 parle de « types d'adresse ». Les adresses en UTF-8 du RFC 5335 sont un nouveau type d'adresses. Si le serveur SMTP accepte l'extension UTF8SMTP du RFC 5336 et l'extension DSN du RFC 3461, il doit permettre d'utiliser ce type dans le paramètre ORCPT (Original Recipient, section 4.2 du RFC 3461). Si le serveur n'accepte pas UTF8SMTP, l'adresse à utiliser dans les DSN doit être encodée en 7bits, selon les règles exposées dans cette section 3 (et non pas selon les règles du RFC 5137, paru trop tard). Par exemple, stéphane@bortzmeyer.org peut s'écrire st\x{E9}phane@bortzmeyer.org. (La section 3 détaille plus complètement le traitement des adresses UTF-8.)

Une fois réglé le problème de la représentation des adresses, la section 4 traite les DSN en UTF-8. Les DSN traditionnels étaient composés d'un objet MIME de type multipart/report comportant trois objets décrivant le problème (un objet conçu pour être lu par un humain, un message/delivery-status et le message originel, message/rfc822). Pour le courrier internationalisé, de nouveaux types ont été créés :

  • message/global-delivery-status qui, contrairement à son prédécesseur message/delivery-status, accepte l'UTF-8 et permet donc de placer directement les adresses UTF-8, sans encodage en ASCII. En outre, il dispose d'un nouveau champ, Localized-Diagnostic, qui permet de stocker des messages lisibles par un humain. La langue de ces messages est indiquée par une étiquette de langue (RFC 4646).
  • message/global qui remplace message/rfc822 (dont le nom, hommage au vieux RFC 822, était de toute façon dépassé). À noter que le terme global (mondial) utilisé pour noter ce type avait fait l'objet de vives discussions et même d'un vote. Cet objet permet de transporter le message original (si on ne transporte que les en-têtes, on utilise message/global-headers.

On peut noter que la norme MIME (RFC 2046) interdisait l'usage de l'option Content-Transfer-Encoding pour les objets de type message/* mais cette règle a été assouplie par le RFC 5335.

La section 5 traite des MDN (Message Disposition NOtificatin, RFC 3798). Ils ne sont pas très différents des DSN et ont un format très proche, avec un type MIME message/global-disposition-notification.

La section 6 traite des registres IANA. Le type « UTF-8 » est ajouté au registre des types d'adresses (section 6.1), et les nouveaux types MIME comme message/global sont ajoutés au registre des types MIME (sections 6.3 à 6.5).

Enfin, la section 7 est dédiée aux questions de sécurité. Outre les problèmes de sécurité classiques des DSN et des MDN (non authentifiés, ils permettent de faire croire qu'un message a échoué, alors qu'il a bien été délivré, ou le contraire), le RFC nous prévient que des DSN ou des MDN délibérement incorrects peuvent être envoyés par un attaquant dans l'espoir de profiter d'erreur dans la programmation des analyseurs, par exemple pour déclencher un débordement de tampon. Le risque est plus important s'il y a beaucoup d'encodage, le décodage pouvant faire varier la taille des données.


Téléchargez le RFC 5337


L'article seul

Combien de fils d'exécution ?

Première rédaction de cet article le 4 septembre 2008


Je viens de commencer un programme comportant plusieurs fils d'éxcution (threads). Lorsqu'on découpe un programme en fils, il y a une décision à prendre concernant le nombre de fils ; beaucoup de fils permet un parallélisme maximal mais implique aussi un surtravail dû à la communication avec ces fils. Peu de fils fait que du travail peut rester bloqué car le fil en est toujours au travail précédent. La valeur optimale dépend évidemment du problème précis.

Ici, il s'agissait d'un projet AFNIC d'interrogation des zones DNS sous .fr pour en déduire des informations, par exemple sur le niveau de déploiement de IPv6 ou bien de DNSSEC (projet DNSwitness). Les requêtes DNS aux serveurs de noms peuvent être très lentes, surtout si un ou plusieurs serveurs de la zone sont en panne, et qu'on doit attendre l'expiration du délai de garde. Avec un programme séquentiel, quelques pourcents de zones vraiment cassées peuvent retarder considérablement tout le programme. D'où l'idée de parallèliser.

.fr compte actuellement environ 1 200 000 zones déléguées. Faut-il 1 200 000 fils d'exécution ? Ou bien seulement 10 ? Ou entre les deux ? On peut toujours spéculer a priori sur le chiffre idéal. Il dépend de beaucoup de facteurs (matériel utilisé, efficacité de l'ordonnanceur utilisé, ici celui de Python, nombre de communications nécessaires avec les fils, etc). Notons que, le programme étant écrit en Python, où l'interpréteur lui-même n'est pas parallèle, une machine multiprocesseur n'est pas forcément utile.

Le mieux est de mesurer plutôt que d'essayer d'imaginer. Je fais un programme qui lit le fichier de zone de .fr, je crée N tâches Python et je confie à chacune 1 200 000 / N zones à interroger (chaque tâche doit évidemment aussi signaler à la tâche maîtresse le résultat de ses interrogations). L'interrogation se fait avec l'excellent module DNS Python, en ne parlant pas directement aux serveurs de noms mais en étant derrière un résolveur/cache Unbound (donc, attention, le cache peut influencer les mesures, c'est pour cela qu'elles ont été faites deux fois).

Avec seulement cent tâches (N = 100), le programme ne peut faire qu'environ cent zones par seconde. Je l'ai interrompu avant la fin. Avec 1000 tâches, on arrive à 480 zones par seconde. Et avec 10 000 tâches, on atteint 550 zones par seconde.

Cela illustre l'efficacité de l'ordonnanceur Python : il vaut mieux utiliser « beaucoup » de tâches.

Ne prenez pas le résultat au pied de la lettre pour vos programmes. Ce qui compte ici est la méthode (mesurer au lieu de supposer ; l'informatique est une science expérimentale). Le résultat, lui, dépend de beaucoup de facteurs.

Les tests ont été faits avec Python 2.5.2 sur une machine Debian lenny avec le noyau Linux 2.6.22. L'ordinateur était un Dell Poweredge avec huit gigaoctets de RAM et quatre processeurs AMD Opteron.


L'article seul

RFC 5334: Ogg Media Types

Date de publication du RFC : Septembre 2008
Auteur(s) du RFC : I. Goncalves (Xiph), S. Pfeiffer (Xiph), C. Montgomery (Xiph)
Chemin des normes
Première rédaction de cet article le 4 septembre 2008


Ce court RFC documente les types « MIME » (RFC 2045) à utiliser pour le format de fichiers multimédia Ogg, changeant sérieusement les anciens types du RFC 3534.

Dans un monde du multimédia dominé par des formats fermés comme WMF ou partiellement ouverts comme Flash (sans compter les innombrables et futiles brevets sur ces formats), Ogg, format maintenu par la fondation Xiph et décrit dans le RFC 3533, reste le principal format ouvert. Comme beaucoup de formats multimédia (par exemple AVI), Ogg ne permet que de créer des containers, des ensembles de flux de données, dont chacun a son propre format. Ainsi, un film stocké dans un container Ogg contiendra en général deux flux, un vidéo (typiquement au format Theora) pour l'image et un audio (typiquement au format Vorbis) pour le son. D'autres containers Ogg peuvent contenir plus de deux flux de données temporelles.

Cette façon de stocker les données complique un peu la définition d'un type de données pour étiqueter les containers Ogg, lorsqu'ils sont distribués par courrier électronique ou bien envoyés via le protocole HTTP. Le RFC originel, le RFC 3534, définissait un type unique, application/ogg. Le problème était qu'un container Ogg ne contenant que du son au format Vorbis se trouvait étiqueté avec le type très général application/ alors que le type audio/ aurait certainement mieux convenu. Notre RFC introduit donc deux nouveaux sous-types de video/ et audio/, soit video/ogg et audio/ogg, et redéfinit le type application/ogg.

La section 2 du RFC rappelle les changements depuis le RFC 3534, la principale étant ces deux nouveaux types.

La section 4 décrit les problèmes de compatibilité qui pourraient surgir avec les anciennes applications. Elle pose le principe que du contenu purement audio devrait être marqué avec le nouveau type audio/ogg (même chose pour la vidéo), réservant l'usage de application/ogg aux contenus plus complexes (par exemple dans le secteur scientifique, où ils sont plus fréquents que dans le monde du multimédia). Pour ces contenus, notre RFC impose l'extension Ogg Skeleton pour identifier les différents flux contenus. Elle décrit aussi l'utilisation du paramètre codecs qui permet de préciser le format des flux inclus, et donc le codec à utiliser. Ainsi, un flux Speex dans un fichier Ogg pourra être identifié par audio/ogg; codecs=speex. La section 5 du RFC précise d'avantage les relations entre les trois types désormais normalisés, du plus général, application/ogg au plus spécifique, audio/ogg.

La section 10 contient la « paperasse » nécessaire à l'enregistrement des trois types dans le registre IANA des types. La section 10.1 enregistre application/ogg, recommandant l'extension de fichier .ogx (.ogg étant souvent utilisé uniquement pour l'audio).

10.2 définit video/ogg (extension .ogv) et 10.3 audio/ogg, qui garde l'extension « historique » .ogg.

Ogg dispose d'une mise en œuvre de référence, sous une licence libre, la libogg (section 8 du RFC, sur l'interopérabilité).

Notons enfin une section 7 du RFC consacrée à la sécurité et qui donne quelques avertissements utiles : si Ogg en lui-même n'est qu'un format et ne pose pas de problème de sécurité en soi, certains contenus d'un fichier Ogg peuvent être exécutables et poser alors de redoutables problèmes de sécurité comme l'ont montré les nombreuses alertes de sécurité qui concernaient Flash. Ces contenus ne devraient pas être exécutés sans une validation (par exemple une signature électronique, service non fourni actuellement par Ogg lui-même mais qui peut être utilisé sur les flux transportés dans un container).

D'autre part, les contenus multimédia sont souvent de grande taille et des attaques par déni de service indirect sont toujours possibles, par exemple en envoyant une image qui, après décompression, sera ridiculement grande, ou un flux audio avec un rythme d'échantillonage impossible à suivre. Les programmes qui lisent les fichiers multimédia doivent donc être prudents.


Téléchargez le RFC 5334


L'article seul

Premiers jours d'utilisation du Neo Freerunner avec Openmoko

Première rédaction de cet article le 3 septembre 2008


J'ai reçu en rentrant de vacances mon Neo Freerunner, un téléphone portable équipé de la plate-forme logicielle Openmoko. Ce téléphone entièrement libre, matériel et logiciel, tiendra t-il ses promesses ?

Le monde de la téléphonie mobile est aujourd'hui dominé par des engins totalement fermés dont le plus extrême est sans doute l'iPhone d'Apple. Ces appareils font tourner un système d'exploitation complètement privateur mais, surtout, ils ne permettent pas toujours de faire tourner dessus les applications qu'on veut. C'est ainsi que la machine favorite des ignorants, l'iPhone, refuse les applications non approuvées par Apple et ne permet d'utiliser qu'un seul opérateur de téléphone mobile. (Cf. Problems of typical "closed" phones. Autres articles sur l'iPhone : Apple interdit aux développeurs d'applications refusées de publier ce refus et Apple censure à sa guise les contenus qui lui déplaisent.)

Ces appareils sont donc bien plus fermés qu'un PC avec MS-Windows. Au moins, Steve Ballmer ne m'empêche pas de faire tourner n'importe quel logiciel, par exemple Firefox et Open Office sur son système « fermé » ! Il est curieux de voir des gens critiquer vertement le géant états-unien du logiciel et se précipiter ensuite chez le petit Satan pour acheter très cher un engin dont le degré de fermeture ferait envie à Microsoft.

Il n'est donc pas étonnant qu'un gros effort marketing soit en cours pour nous convaincre que l'avenir de l'accès à Internet est dans la téléphonie mobile : l'Internet est un symbole d'ouverture et le refermer est une priorité pour beaucoup.

Pourtant, la téléphonie mobile n'est pas forcément synonyme de fermeture. Il existe plusieurs plate-formes qui sont relativement ouvertes (comme le fameux Android de Google) et surtout un système totalement ouvert, Openmoko. Avec Openmoko, non seulement le téléphone ne fait tourner que du logiciel libre mais, en outre, la partie matérielle repose également sur des composants dont les schémas sont publiés et réutilisables pour d'autres fabricants (pour des raisons légales, la partie GSM n'est pas dans ce cas). C'est donc un projet très (trop ?) ambitieux ; il offrirait plus de liberté que mon PC/Debian de la maison, où seul le logiciel est libre.

Il existe aujourd'hui un téléphone construit pour Openmoko, le Neo Freerunner. Il est distribué en France par Bearstech.

Son noyau est un Linux mais ce n'est pas cela qui compte : la Freebox a un Linux aussi et elle est extrêmement fermée. Par contre, la séquence de boot avec les messages du noyau de 0,4 mm de hauteur vaut le coup d'œil.

Qu'en est-il après quelques jours d'essais ? Si le matériel est très soigné (vous pouvez lire un excellent récit illustré du déballage et de la mise en route), le logiciel n'est pas à la hauteur. D'abord, il faut bien comprendre que l'état actuel d'Openmoko est franchement beta, voire alpha. Il n'est pas utilisable par des simples utilisateurs, et n'a pas vraiment d'intérêt même pour des geeks, si ces derniers ne sont pas des développeurs pour cette plate-forme. Quelques exemples : la partie GPS est très difficile à faire marcher, la dernière version officielle, Om 2008.8, ne permet pas de téléphoner sans un insupportable écho, l'application de gestion des contacts (stockés sur la carte SIM) n'a pas de fonction de recherche, le clavier virtuel a une touche d'effacement très complexe (les problèmes d'ergonomie sont fréquents sur Openmoko), etc.

Surtout, le logiciel est très peu stable : les Freerunner sont livrés avec une image, Om 2007.2, qui n'est plus maintenue et que personne n'utilise. Le nouvel utilisateur doit donc commencer par en flasher une nouvelle. Il existe plusieurs images possibles, radicalement différentes (Qtopia, FSO, Debian, Om) et il est donc difficile de partager des expériences. La seule documentation d'usage concerne Om 2007.2 (Om 2008.8 est complètement différent). Le seul fait de signaler une bogue est un travail difficile.

Bref, le projet est intéressant mais encore peu avancé. Si j'apprécie de pouvoir me connecter avec ssh sur mon téléphone pour y taper ls, cela ne suffit pas encore pour remplacer mon téléphone ordinaire. Enfin, cela permet de frimer :

root@om-gta02:~# uname -a
Linux om-gta02 2.6.24 #1 PREEMPT Thu Apr 24 08:23:36 CST 2008 armv4tl unknown

root@om-gta02:~# traceroute www.google.com
traceroute: warning: www.google.com has multiple addresses; using 74.125.39.104
traceroute to www.l.google.com (74.125.39.104), 30 hops max, 38 byte packets
 1  192.168.0.200 (192.168.0.200)  0.871 ms  3.278 ms  1.697 ms
 2  192.168.2.254 (192.168.2.254)  5.235 ms  4.121 ms  4.520 ms
 3  88.189.152.254 (88.189.152.254)  37.890 ms  35.868 ms  49.363 ms
 4  78.254.1.62 (78.254.1.62)  36.765 ms  37.107 ms  39.220 ms
 5  seg75-1.v902.intf.nra.proxad.net (78.254.255.37)  37.450 ms  36.687 ms  37.085 ms
 6  inv75-1-v900.intf.nra.proxad.net (78.254.255.33)  35.948 ms  37.212 ms  37.182 ms
...

Bien sûr, il faut voir où sont les responsabilités : le monde de la téléphonie est corporatiste et ultra-fermé. Les licences pour des puces 3G coûtent des millions de dollars (sans compter le coût de fabrication de la puce elle-même) et ne sont données qu'en échange de NDA léonins. Même chose pour le monde du multimédia, où des entreprises prédatrices ont acquis de nombreux brevets logiciels et harcèlent ceux qui utilisent les formats (peut-être) couverts par ces brevets.

J'espère que l'argent que j'ai dépensé sera utile pour les futurs développements mais je n'ai pas actuellement davantage de temps à y consacrer.


L'article seul

Install Ubuntu / Linux on a Packard Bell EasyNote MX37

First publication of this article on 30 August 2008
Last update on of 16 September 2010


I installed the operating system Ubuntu on a Packard-Bell EasyNote MX37 laptop machine. This article is to share the information that I obtained during the process.

While the basic functions are OK, there are problems. As often with laptops, especially very recent machines, a lot of things do not work, or do not work out of the box.


L'article complet

Produire des données uniquement en tapant sur le clavier

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


Question idiote du jour : quelle quantité de données peut produire un être humain tapant sur un clavier ?

Un être humain normal tape environ 1 à 2 caractères par seconde (à noter que les professionnels mesurent plutôt en mots/minute ; vous pouvez tester votre propre vitesse avec l'excellent http://www.lecturel.com/clavier/mots-par-minute.php ; mais il s'agit alors de la vitesse de frappe brute alors qu'on considère ici qu'on écrit des textes originaux, pour lesquels il faut réfléchir). Si on prend deux caractères par seconde et s'il tape de 20 ans à la mort, 40 heures par semaine (sans RTT, ni vacances, le rêve du MEDEF), cet humain (ou plutôt ce surhomme pour avoir une telle productivité) produira dans sa vie (en moyenne 81 ans en France) presque un milliard de caractères. Supposant que ces textes soient encodés en Latin-1, où chaque caractère occupe un octet, cela fera un giga-octet seulement. Soit même pas la taille d'une clé USB moderne. Une vie entière de frappe sur un petit machin qui tient au creux de la main...

Si on multiplie par le nombre d'humains qui aient jamais vécu sur Terre (environ cent milliards selon Arthur Clarke dans un passage célèbre de 2001), on n'arrive encore qu'à cent exa-octets, ce qui dépasse la taille d'un seul très gros disque dur d'aujourd'hui, mais reste probablement un faible nombre par rapport à la capacité totale de tous les disques durs de la planète (tiens, qui la connait ?).

Même si ces données étaient stockés en UTF-32, un encodage d'Unicode parfois critiqué (bien à tort) pour la place qu'il utilise (quatre octets pour tout caractère), on n'aurait que quatre cents exa-octets.

Conclusion : s'il n'y avait pas de machines comme les caméscopes numériques ou le LHC pour produire rapidement d'énormes quantités de données, les fabricants de disques durs seraient au chômage...


L'article seul

La faille de sécurité BGP de 2008

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


Des failles de sécurité sur Internet, il y en a. Des failles concernant le protocole de routage BGP, il y en a. Que dire de particulier sur celle annoncé à Defcon en août 2008 ?

Notons d'abord la mise en scène. Comme le disait un participant de Nanog : « I think they saw the DNS people getting their 10 minutes of fame and wanted their own :) ». La sécurité informatique est un métier, comme le show-business : il faut faire parler de soi. Ce n'est pas par hasard que les exposés à Defcon commencent toujours par « cette faille est particulièrement sérieuse ». On n'a jamais vu un chercheur en sécurité débuter avec « C'est une petite vulnérabilité sans intérêt. ». Prendre conscience de cela aide à mettre cette annonce dans son contexte.

Ensuite, la faille de sécurité en question est-elle réellement nouvelle ? Non et oui. Non, car elle ne contient que des éléments déjà bien connus comme les limites du modèle de sécurité de BGP (BGP est normalisé dans le RFC 4271 et le RFC 4274 fournit une bonne analyse du protocole), qui avait par exemple été bien illustrées par l'attaque de Pakistan Telecom contre YouTube. Oui parce qu'une combinaison intelligente de techniques connues est en soi une nouveauté. Ce qu'ont présenté Anton Kapela & Alex Pilosov à Defcon est une réelle percée.

En quoi consiste t-elle ? Le socle sur lequel elle s'appuie est le fait que n'importe quel routeur BGP de la planète (donc, en pratique, n'importe quel opérateur, ou craqueur ayant piraté un opérateur), peut annoncer la route qu'il veut et elle se propagera, dans certaines conditions, à tous les autres routeurs BGP du monde, faisant ainsi converger le trafic vers les routeurs choisis par l'attaquant. Par exemple, si je veux récupérer le trafic de Paypal, j'observe que leur annonce BGP est pour le préfixe 66.211.160.0/19, j'annonce 66.211.168.0/24 (un préfixe plus spécifique, pour être sûr qu'il se propage et qu'il soit utilisé, tout en couvrant quand même les adresses IP de www.paypal.fr) et hop, je récupère les paquets destinés à Paypal.

Mais, évidemment, ça se voit : la grande ouverture de l'Internet, qui fait sa vulnérabilité, est aussi sa principale ligne de défense, la base de son système immunitaire. N'importe qui peut utiliser un looking glass et voir qui est l'attaquant. Il y a même des services d'alerte automatique bâtis sur ce principe (commme MyASN ou bien Renesys Route Intelligence). Et, surtout, tout le trafic étant dévié, le service normal s'arrête et tout le monde peut faire un traceroute pour voir à cause de qui. Grâce à cela, l'attaque de Pakistan Telecom avait tourné court.

La première innovation de Kapela & Pilosov était donc de bloquer les méthodes de détection les plus simples en acheminant le trafic détourné vers son destinataire légitime. Si l'attaquant ne veut pas réaliser une DoS mais simplement espionner le trafic, cela lui permet d'être plus discret (cela porte le doux nom, emprunté à l'électricité, de BGP shunt). Cela ne stoppe pas les alarmes des systèmes comme MyASN mais cela empêche la détection immédiate. Il est probable que la majorité des sites qui sont ainsi attaqués ne se rendent compte de rien (tout le monde n'est pas abonné à MyASN).

La redirection est délicate à réussir : il faut que tout l'Internet achemine le trafic de la victime vers l'attaquant sauf les réseaux qui sont sur le chemin de retour choisi, de façon à ce que le trafic puisse revenir à son destinataire légitime. Kapela & Pilosov utilise pour cela l'AS prepending en mettant dans le chemin d'AS de l'annonce BGP des valeurs qui assureront le rejet de la route de retour pour tous... sauf pour les routeurs du chemin de retour que les attaquants ont choisi.

La deuxième innovation de nos deux chercheurs est de modifier le TTL dans les paquets IP qu'ils voient passer, pour rendre encore plus difficile la détection par la victime.

Faut-il s'inquiéter ? Oui. Même s'il n'y a rien de révolutionnaire dans cette attaque, on peut dire qu'elle démocratise le détournement BGP, comme l'attaque Kaminsky démocratisait les empoisonnements de caches DNS.

Que peut-on faire ? D'abord, le site normal, qui n'est pas opérateur. Il ne peut pas faire grand'chose pour empêcher le shunt mais il peut se protéger en utilisant systématiquement des mécanismes de sécurisation de bout en bout, notamment la cryptographie (par exemple SSH et jamais telnet). Ainsi, même détourné, le trafic révèlera nettement moins de chose. Mais c'est essentiellement aux opérateurs d'agir. Si on a son propre numéro d'AS, il est recommandé de s'inscrire aux mécanismes d'alarme cités plus haut. Si on est opérateur ou auteur de logiciel BGP, on peut vérifier ses règles de filtrage, se demander s'il ne serait pas une bonné idée d'utiliser un IRR (sans se faire d'illusions : la qualité des données qu'on y trouve est loin d'être parfaite) ou espérer le déploiement de technologies de sécurisation de BGP comme RPKI+ROA, Secure BGP et soBGP (celles-ci ont du mal à décoller, non pas qu'elles soient trop compliquées mais parce qu'elles ont en commun de nécessiter la création d'une nouvelle infrastructure de confiance, avec ce que cela suppose de problèmes organisationnels et politiques. Le RFC 5123 en explique certains.)

L'article qui a fait le plus de bruit est Revealed: The Internet's Biggest Security Hole. C'est un article très sensationnaliste, une de ses plus grosses erreurs est de reprendre le discours standard : Those protocols were largely developed in the 1970s with the assumption that every node on the then-nascent network would be trustworthy. En fait, les concepteurs de l'Internet à l'époque (au fait, BGP est bien plus récent que « les années 70 ») étaient bien conscients de ces problèmes mais, même si on repartait de zéro, on ne pourrait pas les résoudre facilement (il n'existe pas d'État policier mondial qui pourrait attribuer des « licences d'opérateur » et des certificats X.509 afférents pour pouvoir signer les annonces BGP). Le second article de Wired, More on BGP Attacks -- Updated est bien meilleur, surtout pour les détails techniques. Mais le mieux est de lire les transparents originaux des deux découvreurs de la faille (également sur le site de Defcon).

Sur BGP, on peut aussi lire mon cours pratique.


L'article seul

RFC 4941: Privacy Extensions for Stateless Address Autoconfiguration in IPv6

Date de publication du RFC : Septembre 2007
Auteur(s) du RFC : T. Narten (IBM), R. Draves (Microsoft), S. Krishnan (Ericsson)
Chemin des normes
Première rédaction de cet article le 26 août 2008
Dernière mise à jour le 18 décembre 2008


Une des particularités d'IPv6 est de disposer d'un mécanisme, l'autoconfiguration sans état qui permet à une machine de se fabriquer une adresse IP globale sans serveur DHCP. Ce mécanisme crée typiquement l'adresse IP à partir de l'adresse MAC de la machine et une même machine a donc toujours le même identifiant (les 64 bits les plus à droite de l'adresse IPv6), même si elle change de réseau et donc de préfixe. Il est donc possible de « suivre à la trace » une machine, ce qui peut poser des problèmes de protection de la vie privée. Notre RFC fournit une solution, sous forme d'un mécanisme de création d'adresses temporaires, partiellement aléatoires.

L'autoconfiguration sans état, normalisée dans le RFC 4862 est souvent présentée comme un des gros avantages d'IPv6. Sans nécessiter de serveur central (contrairement à DHCP), ce mécanisme permet à chaque machine d'obtenir une adresse globale (IPv4, via le protocole du RFC 3927, ne permet que des adresses purement locales) et unique. Cela se fait en concaténant un préfixe (par exemple 2001:db8:32:aa12::), annoncé par le routeur, à un identifiant d'interface (par exemple 213:e8ff:fe69:590d, l'identifiant de mon PC portable - les machines individuelles, non partagées, comme les PDA sont particulièrement sensibles puisque la connaissance de la machine implique celle de son maître), typiquement dérivé de l'adresse MAC.

Partir de l'adresse MAC présente des avantages (quasiment toute machine en a une, et, comme elle est unique, l'unicité de l'adresse IPv6 est obtenue facilement) mais aussi un inconvénient : comme l'identifiant d'interface est toujours le même, cela permet de reconnaître une machine, même lorsqu'elle change de réseau. Dès qu'on voit une machine XXXX:213:e8ff:fe69:590d (où XXXX est le préfixe), on sait que c'est mon PC.

La solution initiale de ce problème avait été introduite par le RFC 3041, que notre RFC 4941 met à jour.

Les sections 1.2 et 2 du RFC décrivent le problème plus en détail. Elles notent entre autre que le problème n'est pas aussi crucial que l'avaient prétendu certains (une véritable campagne anti-IPv6 avait été montée à une époque par des gens mal informés). En effet, il existe bien d'autres façons, parfois plus faciles, de suivre une machine à la trace, par exemple par les fameux petits gâteaux de HTTP mais aussi par des moyens de plus haute technologie comme les caractéristiques matérielles de l'ordinateur, que l'on peut observer sur le réseau. Parmi les autres méthodes, notons aussi que si on utilise les adresses temporaires de notre RFC 4941 mais qu'on configure sa machine pour mettre dynamiquement à jour un serveur DNS avec cette adresse, le nom de domaine suffirait alors à suivre l'utilisateur à la trace !

La section 2.2, consacrée à la situation actuelle avec IPv4, fait d'ailleurs remarquer que la situation n'est pas parfaite avec IPv4 non plus, et que certains articles qui sonnaient l'alarme contre les dangers de IPv6 étaient donc vraiment peu informés. Aujourd'hui, en pratique, beaucoup de machines ont une adresse IPv4 qui change peu ou pas et elles sont donc plus vulnérables au « pistage » (sauf si elles changent de réseau souvent) que les machines IPv6 utilisant ce RFC 4941.

La section 2.4 commence à discuter des solutions possibles. DHCPv6 (RFC 3315, notamment la section 12) serait évidemment une solution, mais qui nécessite l'administration d'un serveur. L'idéal serait une solution qui permette, puisque IPv6 facilite l'existence de plusieurs adresses IP par machine, d'avoir une adresse stable pour les connexions entrantes et une adresse temporaire, non liée à l'adresse MAC, pour les connexions sortantes, celles qui « trahissent » la machine. C'est ce que propose notre RFC, en générant les adresses temporaires selon un mécanisme pseudo-aléatoire.

Enfin, la section 3 décrit le mécanisme de protection lui-même. Il y a deux cas, celui où on dispose d'un mécanisme de stockage des données, par exemple une mémoire Flash et celui où l'appareil, trop simple, n'a pas un tel mécanisme.

Le premier cas est détaillé dans la section 3.2.1 : on stocke une « valeur historique » à chaque génération d'une adresse. On utilise la valeur précédente, on la concatène à l'identifiant d'interface et on passe le tout à travers MD5. Les 64 premiers bits du résumé MD5 formeront le suffixe de l'adresse IPv6. La faiblesse cryptographique de MD5 n'est pas un problème, on ne cherche pas ici à résister à une attaque, juste à condenser un nombre aléatoire. Il n'est pas nécessaire que toutes les machines utilisent la même fonction de hachage et l'usage d'autres algorithmes que MD5 est donc autorisé.

La section 3.2.2 traite des cas où un dispositif de stockage n'existe pas et recommande alors l'usage d'une source réellement aléatoire, selon le RFC 4086.

Une fois l'adresse temporaire générée (les détails sont dans la section 3.3), il faut la renouveler de temps en temps (sections 3.4 et 3.5, cette dernière expliquant pourquoi renouveler une fois par jour est plus que suffisant). L'ancienne adresse peut rester active pour les connexions en cours mais plus pour de nouvelles connexions.

Maintenant que l'algorithme est spécifié, la section 4 du RFC reprend de la hauteur et examine les conséquences de l'utilisation des adresses temporaires. C'est l'occasion de rappeler un principe de base de la sécurité : il n'y a pas de solution idéale, seulement des compromis. Si les adresses temporaires protègent d'avantage contre le « flicage », elles ont aussi des inconvénients comme de rendre le déboguage des réseaux plus difficile. Par exemple, si on note un comportement bizarre associé à certaines adresses IP, il sera plus difficile de savoir s'il s'agit d'une seule machine ou de plusieurs.

L'utilisation des adresses temporaires peut également poser des problèmes avec certaines pratiques prétendument de sécurité comme le fait, pour un serveur, de refuser les connexions depuis une machine sans enregistrement DNS inverse (un nom correspondant à l'adresse, via un enregistrement PTR). Cette technique est assez ridicule mais néanmoins largement utilisée.

Un autre conflit se produira, note la section 7, si des mécanismes de validation des adresses IP source sont en place dans le réseau. Il peut en effet être difficile de distinguer une machine qui génère des adresses IP temporaires pour se protéger contre les indiscrets d'une machine qui se fabrique de fausses adresses IP source pour mener une attaque.

Quelles sont les différences entre le RFC originel, le RFC 3041 et celui-ci ? Peu importantes, elles sont résumées dans la section 8. Les principales sont des demandes plus fortes sur la configurabilité de l'usage des adresses temporaires, l'acceptation explicite d'autres fonctions de hachage que MD5 et surtout le fait que le réglage standard par défaut doit désormais être de couper l'usage des adresses IP temporaires.

Sur MS-Windows, ce mécanisme semble avoir été implémenté depuis Vista.

Sur Linux, notre RFC est mis en œuvre depuis longtemps (c'est l'option CONFIG_IPV6_PRIVACY de compilation du noyau), mais désactivé par défaut, comme demandé par le RFC (section 3.6). Le paramètre sysctl qui contrôle ce protocole est net.ipv6.conf.XXX.use_tempaddr où XXX est le nom de l'interface réseau, par exemple eth0. En mettant dans le fichier /etc/sysctl.conf :

# Adresses temporaires du RFC 4941
net.ipv6.conf.default.use_tempaddr = 2

On met en service les adresses temporaires, non « pistables » pour toutes les interfaces (c'est le sens de la valeur default). Il y a plusieurs pièges, très bien expliqués par Pascal Hambourg : au moment où le sysctl.conf est lu, le module noyau ipv6 n'est pas forcément chargé. Et certaines interfaces ont pu être configurées avant, alors que default ne s'applique qu'aux futures interfaces. Pour s'assurer que les réglages soient bien pris en compte, il vaut mieux faire en sorte que le module ipv6 soit chargé tout de suite (sur Debian, le mettre dans /etc/modules) et que les interfaces fixes aient leur propre réglage. Par exemple, sur Debian, on peut mettre dans /etc/network/interfaces :

iface eth2 inet dhcp
   pre-up sysctl -w net.ipv6.conf.eth2.use_tempaddr=2

Ou alors il faut nommer explicitement ses interfaces :

net.ipv6.conf.eth0.use_tempaddr = 2

Le comportement du noyau Linux face à ces options est souvent surprenant. Voir par exemple la bogue #11655. Notez aussi qu'ifconfig n'affiche pas quelles adresses sont les temporaires (mais ip addr show le fait).

Notons que l'adresse « pistable » est toujours présente mais vient s'y ajouter une adresse temporaire choisie au hasard. Selon les règles du RFC 6724, rappelées dans la section 3.1 de notre RFC, c'est cette adresse temporaire qui sera choisie, en théorie, pour les connexions sortantes. Avec Linux, il faut pour cela que use_tempaddr vale plus que un (sinon, l'adresse temporaire est bien configurée mais pas utilisée par défaut). ifconfig affichera donc :

wlan0     Link encap:Ethernet  HWaddr 00:13:e8:69:59:0d  
...
          inet6 addr: 2001:db8:32:aa12:615a:c7ba:73fb:e2b7/64 Scope:Global
          inet6 addr: 2001:db8:32:aa12:213:e8ff:fe69:590d/64 Scope:Global

puis, au démarrage suivant, l'adresse temporaire (la première ci-dessus) changera :

wlan0     Link encap:Ethernet  HWaddr 00:13:e8:69:59:0d
...
          inet6 addr: 2001:db8:32:aa12:48a9:bf44:5167:463e/64 Scope:Global
          inet6 addr: 2001:db8:32:aa12:213:e8ff:fe69:590d/64 Scope:Global

Sur NetBSD, il n'y a qu'une seule variable syscvtl pour toutes les interfaces. Il suffit donc de mettre dans /etc/sysctl.conf :

net.inet6.ip6.use_tempaddr=1

Par contre, je n'ai pas trouvé comment faire que l'adresse temporaire soit utilisée par défaut. Sur FreeBSD, je n'ai pas essayé, mais je suppose que les variables sysctl au nom bien parlant net.inet6.ip6.use_tempaddr et net.inet6.ip6.prefer_tempaddr sont là pour cela.

Ceux qui veulent configurer ce service sur une machine Linux peuvent aussi lire Stateless Network Auto Configuration With IPv6 ou IPv6 privacy extensions on Linux. Sur les autres systèms, je suggère Enabling Privacy Enhanced Addresses for IPv6.


Téléchargez le RFC 4941


L'article seul

Représentation sous forme texte de ce qui passe sur le réseau

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


Dans beaucoup de protocoles réseau, ce qui passe « sur le câble » est dans un format binaire incompréhensible pour un humain. Il est souvent utile de pouvoir le représenter sous forme texte, par exemple lorsque des programmes comme tcpdump le décodent. C'est encore mieux si ce format texte est normalisé, cela permet la communication facile entre humains. Regardons quelques exemples surtout empruntés à la famille TCP/IP. Ce sera l'occasion de voir que la syntaxe des adresses IPv4 n'a jamais été normalisée...


L'article complet

RFC 5291: Outbound Route Filtering Capability for BGP-4

Date de publication du RFC : Août 2008
Auteur(s) du RFC : E. Chen (Cisco Systems), Y. Rekhter (Juniper Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF idr
Première rédaction de cet article le 24 août 2008


Quand deux routeurs BGP échangent des routes, il est fréquent que certaines soient refusées par le routeur récepteur, par exemple parce qu'ils les estime invalides ou parce qu'elles ne correspondent pas à ses politiques de routage (section 2 du RFC). C'est donc un gaspillage que de les envoyer et ce nouveau RFC permet au routeur récepteur de signaler à l'avance à son pair BGP quelles routes il n'acceptera pas.

BGP, normalisé dans le RFC 4271 est le protocole d'échange de routes dans l'Internet. Pratiqué surtout entre organisations distinctes, il permet de faire du routage politique, cest-à-dire de rejeter certaines routes en fonction de la politique de chaque organisation. Pour cela, les routeurs BGP mettent typiquement en œuvre des filtres sur les routes reçues. Avec notre RFC, ces filtres peuvent être transmis au routeur pair sous le nom d'ORF (Outbound Route Filters) que le pair appliquera sur le jeu de routes qu'il allait annoncer, supprimant de ce jeu les routes qui ne conviennent pas à son pair.

La section 3 détaille ce qu'est un ORF. C'est un tuple composé de :

  • l'AFI/SAFI (qui permet notamment d'indiquer si la route concerne IPv4 ou bien IPv6), termes définis dans le RFC 4760.
  • le type d'ORF, qui sera enregistré dans un registre IANA (pas encore peuplé, cf. section 7).
  • l'action à effectuer sur cet ORF, typiquement ADD (l'ajouter à la liste) ou REMOVE (le supprimer).
  • la politique à appliquer aux routes qui corrspondent à ce critère (PERMIT ou DENY).
  • Et la valeur, dont le contenu dépend de l'AFI/SAFI, c'est typiquement un préfixe réseau.

La section 4 explique ensuite comment encoder les ORF et les transmettre dans une session BGP. Les sections 5 et 6 précisent que le routeur qui gère les ORF doit l'annoncer (cf. RFC 5492) par la capacité BGP n° 3 Outbound Route Filtering Capability.


Téléchargez le RFC 5291


L'article seul

RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2

Date de publication du RFC : Août 2008
Auteur(s) du RFC : Tim Dierks (Independant), Eric Rescorla (Network Resonance)
Chemin des normes
Première rédaction de cet article le 24 août 2008


Le protocole de cryptographie TLS, autrefois nommé SSL, est un des protocoles de l'IETF les plus utilisés. À chaque seconde, des milliers de connexions TCP, en général HTTP, sont protégées contre l'écoute, et même parfois authentifiées par TLS. Ce RFC met à jour l'ancienne norme, le RFC 4346.

Aujourd'hui, plus personne n'aurait l'idée de faire circuler un mot de passe en clair sur le réseau, car il serait très facile à capturer (par exemple avec un programme comme dSniff). TLS fournit la confidentialité à une connexion TCP. (TLS peut aussi fonctionner avec d'autres protocoles de transport comme SCTP - RFC 3436 ou bien UDP - RFC 6347.)

L'authentification par mot de passe a par ailleurs des défauts, notamment que le mot de passe soit réutilisable. Si l'utilisateur a été victime d'un faux serveur, par exemple par suite d'un hameçonnage, il donne son mot de passe et le méchant qui contrôle le faux serveur peut l'utiliser sur le vrai site. Pour traiter ce problème, TLS fournit une solution d'authentification reposant sur les certificats X.509 ou bien sur les clés OpenPGP (RFC 5081). TLS permet aussi bien au client d'authentifier le serveur qu'au serveur d'authentifier le client (cette deuxième possibilité est à l'heure actuelle peu utilisée).

Les certificats X.509 sont composés de la partie publique d'une clé asymétrique et de métadonnées, comme la date d'expiration. Ils sont signés par une CA, qui a elle-même un certificat signé par une CA et ainsi de suite jusqu'à arriver aux CA racines installés dans le logiciel. La plupart du temps, l'utilisateur n'a jamais examiné ces certificats des CA racine et n'a aucune idée de leur fiabilité. C'est l'un des gros points faibles de l'authentification par TLS / X.509.

TLS n'est pas une solution miracle, il n'en existe pas en sécurité informatique. Par exemple, TLS ne protège pas dans les cas suivants :

  • Si un programme espion tourne sur la machine de l'utilisateur (ce qui est le cas de beaucoup, peut-être la plupart des machines MS-Windows),
  • Si le serveur est méchant ou mal protégé. Par exemple, un numéro de Carte Bleue transmis par TLS n'est protégé que pendant le voyage ! Si le serveur à l'autre bout stocke ces numéros et se fait pirater, TLS n'y pourra rien.

Passons maintenant au RFC proprement dit. Il fait plus de cent pages et pourtant de nombreux points n'y sont pas, comme la définition des algorithmes cryptographiques utilisés. La sécurité est un domaine compliqué, d'autant plus qu'une petite erreur peut annuler toute la sécurité de même que l'oubli de fermer à clé peut rendre inutile une lourde porte blindée.

TLS est composé de deux parties (section 1 du RFC), le Record Protocol, protocole de bas niveau qui transmet des messages en les chiffrant pour la confidentialité et l'intégrité et le Handshake protocol, bâti sur le premier, et qui se charge entre autres de négocier les paramètres de la session.

En effet, TLS fonctionne en négociant au début un algorithme de chiffrement ainsi qu'une clé cryptographique de cet algorithme pour la session. Le Record protocol va ensuite chiffrer les messages avec cette clé.

La section 4 du RFC détaille le langage de présentation. L'IETF n'a pas de langage unique de spécification, chaque RFC utilise des outils différents pour décrire ses protocoles ou algorithmes. TLS crée donc le sien, proche du C. Par exemple la section 4.4 décrit les nombres, tous créés à partir d'un type unit8, qui stocke un octet. La section 4.5 décrit les types énumérés comme enum { null, rc4, 3des, aes } BulkCipherAlgorithm; (le type qui sert à définir les valeurs de l'algorithme de cryptographie symétrique).

La section 6 décrit en détail le Record protocol. C'est un protocole qui va effectuer le chiffrement, mais aussi la compression, la fragmentation, etc.

La section 7 couvre le protocole de négociation (Handshake protocol). C'est le protocole qui permet l'authentification du serveur par le client (ou, plus rarement, le contraire) et la sélection des options, par exemple l'algorithme de chiffrement utilisé. L'authentification se fait en général en présentant un certificat X.509, certificat signé par un tiers de confiance (RFC 5280, en pratique, le tiers « de confiance » est une des CA installées par défaut avec le logiciel, dont personne ne sait pourquoi elles ont été choisies). Voici par exemple le résultat de ce protocole, tel qu'affiché par la commande gnutls-cli (qui est livrée avec GnuTLS) :

% gnutls-cli -d 9 www.example.org
Connecting to '192.0.2.20:443'...
...
|<3>| HSK[80708e8]: Selected cipher suite: DHE_RSA_AES_256_CBC_SHA

Le chiffrement AES en mode CBC a été choisi. gnutls-cli permet de voir le passage de tous les messages TLS de ce protocole, tels qu'ils sont décrits dans la section 7.4 :

      enum {
          hello_request(0), client_hello(1), server_hello(2),
          certificate(11), server_key_exchange (12),
          certificate_request(13), server_hello_done(14),
          certificate_verify(15), client_key_exchange(16),
          finished(20), (255)
      } HandshakeType;

Comme précisé dans la section 7.3, ce protocole de négociation a aussi ses propres vulnérabilités. Au démarrage, il n'y a évidemment pas d'algorithme de chiffrement ou de clé de session sélectionnés. Comme le précise la section 7.4.1, TLS démarre donc sans chiffrement. Un attaquant actif, capable de modifier les paquets IP, peut changer la liste des algorithmes acceptés, avant que le chiffrement ne soit actif, de façon à sélectionner un algorithme faible. (Le remède est de refaire la négociation une fois le chiffrement activé.)

Comme souvent avec TLS, le protocole est extensible. La section 7.4.1.4 décrit par exemple les extensions à l'annonce que font les machines TLS, possibilité qui est utilisée dans le RFC 5081 pour ajouter les clés OpenPGP aux certificats X.509. (Les extensions existantes étaient initialement décrites dans le RFC 4366 et sont désormais dans le RFC 6066. Le registre complet des extensions est maintenu à l'IANA.)

La section 9 indique l'algorithme de chiffrement obligatoire, RSA avec AES. Il est nécessaire de définir un algorithme obligatoire, autrement, deux mises en œuvre légales de TLS pourraient être incompatibles si les deux ensembles d'algorithmes n'avaient aucun élément en commun.

Par rapport à son prédécesseur, le RFC 4346, qui normalisait TLS 1.1, les changements sont de peu d'importance (la liste figure en section 1.2). Un client TLS 1.2 peut interagir avec un serveur 1.1 et réciproquement (voir l'annexe E pour les détails.) Il s'agit en général de clarifications ou bien du changement de statut de certains algorithmes cryptographiques. En effet, la cryptographie bouge et certains algorithmes, qui paraissaient solides à une époque, sont vulnérables aux attaques modernes (c'est par exemple ce qui est arrivé à MD5 et SHA1). C'est pour cela que l'algorithme « RSA avec AES » fait désormais partie des algorithmes obligatoires et que par contre IDEA et DES sont partis.

Contrairement à IPsec (RFC 4301), TLS fonctionne entre la couche de transport et les applications. Il n'est donc pas invisible aux applications, qui doivent être explicitement programmées pour l'utiliser. Pour cela, il n'existe malheureusement pas d'API standard. OpenSSL, l'implémentation la plus populaire de TLS, a la sienne, son concurrent GnuTLS en a une autre, etc. (GnuTLS dispose d'une couche d'émulation de OpenSSL mais elle est incomplète.)

Un programme comme echoping qui peut utiliser aussi bien OpenSSL que GnuTLS, doit donc recourir aux services du préprocesseur C, par exemple :

#ifdef OPENSSL
        ...
        SSL_set_fd(sslh, sockfd);
        if (SSL_connect(sslh) == -1)
#endif
#ifdef GNUTLS
...
        gnutls_transport_set_ptr(session, 
                                 (gnutls_transport_ptr) (long) sockfd);
        tls_result = gnutls_handshake(session);
...
#ifdef OPENSSL
        if ((rc = SSL_write(sslh, sendline, n)) != n) {
...
#ifdef GNUTLS
        if ((rc = gnutls_record_send(session, 
                                     sendline, strlen (sendline))) != n) {
...

Une autre solution pour une application qui veut faire du TLS sans se fatiguer est de compter sur le fait que TLS est indépendant du protocole utilisé par l'application et qu'on peut donc simplement créer un tunnel TLS, par exemple avec stunnel. Ainsi, on n'a même pas besoin de modifier le source de l'application.

Le déploiement de protocoles est toujours lent dans l'Internet. TLS 1.2, décrit dans ce RFC, ne s'est retrouvé dans le navigateur Firefox que cinq ans après.


Téléchargez le RFC 5246


L'article seul

Y aura t-il un groupe de travail ALTO à l'IETF ?

Première rédaction de cet article le 31 juillet 2008
Dernière mise à jour le 14 novembre 2008


À la réunion IETF 72 de Dublin, la création du groupe de travail nommé ALTO pour Application Layer Traffic Optimisation n'est pas allée de soi et ne semble pas garantie.

À quoi sert ALTO ? La majorité du trafic sur Internet est aujourd'hui consacrée aux services pair-à-pair. Ces services remettent en cause bien des suppositions sur lesquelles avait été architecturé le réseau. Ils consomment autant de trafic montant que de descendant (contrairement à des systèmes asymétriques comme le Minitel ou l'ADSL), ils sont bavards, et imprévisibles. Il n'est donc pas étonnant que ces services se retrouvent souvent dans les médias comme à l'occasion du piratage des sessions BitTorrent par Comcast.

Tous ces points sont résumés dans l'expression du problème, l'Internet-Draft, draft-marocco-alto-problem-statement. À l'atelier P2P infrastructure workshop de l'IETF le 29 mai 2008 à Boston (dont le compte-rendu figure dans le RFC 5594), plusieurs mesures ont été étudiées, par exemple de meilleurs systèmes de contrôle de la congestion, mais aussi des mesures visant à améliorer la localité, mesures qui mènent à ALTO.

En effet, contrairement au client/serveur, pour lequel on cherche à accéder à une machine (et on ne peut optimiser que le chemin qui y mène), le pair-à-pair concerne l'accès à une ressource. On peut alors chercher un exemplaire de cette ressource qui soit plus proche. ALTO peut donc se résumer à « Quand on est à Dublin, télécharger le fichier à partir d'un pair à Londres plutôt qu'à Tokyo ».

Les machines terminales, celles des utilisateurs, ne sont pas forcément les mieux placées pour sélectionner les « meilleurs » pairs (notons que la définition de « meilleur » est un des sujets les plus chauds dans les discussions sur ALTO). Par exemple, elles n'ont aucune idée des coûts, de quels liens sont du transit cher et desquels sont du peering gratuit. ALTO repose donc sur un système d'« oracle » où le pair demande au serveur ALTO (l'oracle) de lui indiquer les meilleures solutions. Le futur protocole conçu par le futur groupe ALTO ne gérera que l'interface entre le client ALTO (le pair) et le serveur ALTO (l'oracle). Comment l'oracle prend sa décision est hors-sujet pour ALTO. L'oracle a pu utiliser les ICS, Meridian, un flux BGP ou un ensemble de préférences configurées manuellement, par exemple par le FAI.

Ça, c'était le principe. Maintenant, il y a les difficultés pratiques. Par exemple :

  • Est-ce que l'oracle doit donner des informations sur la topologie du réseau ou bien juste indiquer quel(s) pair(s) choisir ? Les opérateurs ne sont pas très chauds pour la première solution, car ils ne souhaitent pas distribuer d'informations sur leur réseau.
  • Comment le client ALTO trouve t-il l'oracle ?
  • Et la question qui ravira les fans de Matrix : le client peut-il faire confiance à l'oracle ? La question n'est pas purement théorique vu le nombre de FAI qui mentent délibérement à leurs clients (par exemple en réécrivant les réponses DNS).

Une fois le problème posé, quelles sont les solutions actuelles ? (Elles sont décrites dans un Internet-Draft, draft-hilt-alto-survey.) Il y a en gros deux catégories :

  • Les cas où c'est l'application qui cherche le meilleur pair, par exemple par des ping brutaux vers un ensemble de pairs potentiels (ce qui consomme beaucoup de ressources et ne supporte pas le passage à l'échelle) ou bien par des techniques plus intelligentes comme les ICS.
  • Les cas où c'est le réseau qui décide, ce qui est l'idée de base du projet P4P (une expérience P4P a été décrite dans le RFC 5632). ALTO fonctionnera ainsi, l'oracle pouvant utiliser des techniques comme ICS pour récupérer l'information qu'il servira à ses clients.

Naturellement, une des principales motivations pour ALTO est financière, d'où l'amusant exposé de Henning Schulzrinne (par ailleurs auteur de SIP) à Dublin à propos de l'économie de l'Internet. Compte-tenu du caractère fongible qu'à aujourd'hui la capacité des accès Internet, on peut calculer, par exemple, que l'envoi du contenu d'un DVD coûte aujourd'hui 1,05 $ US, uniquement en bande passante. Schulzrinne suggérait de signaler ces coûts à l'utilisateur par exemple « Do you want to watch the movie now (4$) or wait until night (2.5$)? ».

Enfin, le dernier document important dans l'état actuel du développement d'ALTO est le cahier des charges (Internet-Draft draft-kiesel-alto-reqs) que Sebastian Kiesel a présenté à Dublin. ALTO doit, selon ce document :

  • Se concentrer sur le protocole entre le client ALTO et le serveur ALTO (les mécanismes, par exemple, de synchronisation des informations entre serveurs ALTO étant ainsi exclus),
  • Ne pas mettre tous ses œufs dans le même panier. ALTO ne va pas résoudre tous les problèmes seuls et il est également nécessaire de réagir proprement à la congestion... et de se débrouiller correctement si, pour une raison ou une autre, ALTO n'est pas disponible.

La question délicate des informations que le client ALTO envoie au serveur ALTO n'est pas réglée. Il serait intéressant pour le serveur, afin de prendre une meilleure décision, que le client donne le plus de détails possibles (« Je compte télécharger le dernier album de Carla Bruni, au format zip, soit 631 méga-octets ») mais cela soulève évidemment bien des questions liées à la protection de la vie privée. La plupart des clients ne voudraient pas avouer le nom des ressources qu'ils téléchargent. Même la simple indication de la taille de la ressource pourrait donner trop d'indications à un oracle indiscret.

Il n'existe pas encore de documents sur le protocole lui-même.

C'est dans ce contexte que s'est tenu la réunion de l'IETF à Dublin le 29 juillet. Cette réunion avait le titre de BoF (Birds of a Feather, réunion informelle) puisque le groupe de travail n'est pas encore constitué. Ce fut un grand succès, avec plus de 150 personnes et un agenda chargé. Après les exposés résumés ci-dessus, une importante discussion porta sur la future charte du futur groupe de travail. Plusieurs questions ne posaient pas réellement de problème comme le fait que les questions de légalité du contenu seraient jugées hors-sujet. Les serveurs ALTO ne serviront donc pas à mettre en œuvre les desiderata de Sony ou d'Universal.

Une discussion très technique sur les caches suscita plus d'intérêt mais, gloalement, aucune objection à la charte ou au groupe de travail n'a été soulevée pendant la réunion.

C'est pourquoi ce fut une surprise pour beaucoup de voir une opposition apparaître au moment du « hum ». Le hum est une institution IETF, permettant d'indiquer une préférence, de manière non publique. Il consiste simplement à faire du bruit sans ouvrir la bouche. Le « hum » montra une salle partagée moitié-moitié. Il n'y a donc pas de consensus.

Quel était le problème ? Lisa Dusseault, Area Director (directrice de l'activité Applications à l'IETF), demanda si le problème était jugé inintéressant ? Insoluble ? Ou bien que la solution proposée risquait d'être dangereuse ?

Contrastant avec le silence pendant la réunion (timidité ?), la liste de diffusion ALTO a vu une longue discussion s'ensuivre. Une des objections les plus fréquentes était que les intérêts des utilisateurs et des FAI étaient différents, voire opposés, et qu'il n'y avait aucune chance qu'un oracle géré par le FAI puisse donner des réponses utiles aux utilisateurs.

Une objection plus technique était que le projet de charte ne restreignait pas assez l'ensemble des questions qui pouvaient être posées à l'oracle.

Enfin, encore plus politique, certains craignaient que, une fois déployés, les oracles deviennent plus ou moins obligatoires et qu'il ne soit plus possible à un pair d'un réseau pair-à-pair de ne pas obéir aux « suggestions » de l'oracle...

Finalement, l'IESG a approuvé la création du groupe le 12 novembre, avec une charte modifiée, qui cadre mieux ce que ALTO pourra faire ou ne pas faire, et un calendrier qui prévoit que l'essentiel du travail devra être terminé fin 2009. Le premier RFC a déjà été publié, le RFC 5693.


L'article seul

Comment fonctionne la faille DNS « Kaminsky » ?

Première rédaction de cet article le 31 juillet 2008


La faille de sécurité DNS découverte par Dan Kaminsky à l'hiver 2007-2008 et annoncée le 8 juillet 2008 n'a pas encore été officiellement publiée en détail. Cela doit être fait le 8 août à la conférence BlackHat à Las Vegas. Mais, l'Internet étant ce qu'il est, il n'est pas étonnant que cette date n'aie pas été tenue et que les informations aient été publiées avant l'annonce officielle. Trois exploitations de la faille ont déjà été publiées. Plusieurs articles publics ont déjà repris en détail ces informations (voir par exemple, en français, l'article de Sid. On peut donc désormais expliquer en quoi cette faille consiste.

Je tiens d'abord à rappeler que des tas de bêtises ont été écrites sur l'Internet (et plus encore dans la presse papier ou à la télévision) sur cette faille. Ne vous fiez pas à des messages arrogants d'ignorants complets qui écrivent dans les commentaires d'un blog « La faille est une faiblesse du générateur aléatoire de BIND » ou bien « C'est une faille classique et il n'y a rien de nouveau ».

Plaçons un peu de contexte : le DNS fonctionne typiquement sur UDP (il peut aussi utiliser TCP et l'utilisation de ce protocole règlerait complètement la faille Kaminsky mais beaucoup de serveurs de noms sont incorrectement configurés et refusent les accès TCP). UDP n'a pas la notion de connexion et l'adresse IP de la machine avec laquelle on parle n'est donc pas du tout authentifée (avec TCP, elle est vérifiée par le processus de connexion, le 3-way handshake - section 3.4 du RFC 793 -, ainsi que par les numéros de séquence, qui doivent démarrer d'un nombre imprévisible). Lorsqu'un résolveur (le serveur de noms qui pose une question) interroge le serveur faisant autorité (le serveur de noms qui connait la réponse), il ne peut pas savoir si la réponse vient bien du serveur faisant autorité, elle peut venir d'un méchant qui a usurpé l'adresse IP de celui-ci, et répondu avant lui. Si le méchant peut donc deviner quant une requête va être émise (il existe des techniques pour cela, la plus simple étant de la générer soi-même, si le résolveur est un récursif ouvert, ou bien si on dispose d'un zombie autorisé à y accéder), cet attaquant peut envoyer une fausse réponse (en bombardant le vrai serveur en même temps, le méchant peut le ralentir pour augmenter les chances de gagner la course).

S'il n'y avait que cela, le DNS serait trivial à abuser. Mais quelques protections existent : la plus importante est que la requête DNS contient un nombre, le Query ID (QID, parfois appelé Transaction ID, TXID). Il est décrit dans la section 4.1.1 du RFC 1035. Le résolveur n'accepte une réponse que si elle contient un Query ID identique à celui qu'il a lui-même envoyé. La réponse doit également correspondre à une question actuellement en suspens et être reçue sur le port UDP d'où venait la question. (Il y a très longtemps, les implémentations du DNS étaient naïves et acceptaient à peu près n'importe quoi, ce qui est fini depuis belle lurette.) Malheureusement, le Query ID ne fait que 16 bits de long, ce qui est suffisant pour démêler des questions distinctes mais pas assez pour sécuriser la transaction. Envoyer 2^16 soit 65 536 réponses fausses pour qu'au moins une soit acceptée ne prend pas assez de temps, avec l'Internet rapide d'aujourd'hui. (Une vraie solution à la faille Kaminsky et à toutes les failles de la même famille serait de passer le Query ID à 128 bits. Mais cela serait un changement du DNS incompatible.)

Cette faiblesse du DNS est connu depuis très longtemps. Par exemple, en 1995, Paul Vixie écrivait « With only 16 bits worth of query ID and 16 bits worth of UDP port number, it's hard not to be predictable. A determined attacker can try all the numbers in a very short time and can use patterns derived from examination of the freely available BIND code. Even if we had a white noise generator to help randomize our numbers, it's just too easy to try them all. ». Ce risque (et d'autres) a été documenté par exemple dans le RFC 3833 en 2004. Il n'y a en effet rien de nouveau ici, mais la faille Kaminsky permet d'exploiter cette vulnérabilité avec bien plus d'efficacité qu'une attaque par force brute.

Jusqu'à présent, en effet, cette protection avait quand même suffit, à condition que le Query ID soit réellement aléatoire (suivant les recommandations du RFC 4086). Des problèmes étaient survenus avec le serveur DNS de Microsoft (qui n'utilisait que 14 des 16 bits du Query ID) ou avec BIND (générateur aléatoire bogué, faille CVE-2007-2926). Mais ils étaient facilement solubles en mettant à jour le logiciel bogué.

Fin 2007, la situation était donc d'une faiblesse connue (16 bits ne sont pas suffisants) mais peu exploitée car l'attaque n'était pas pratique. Typiquement, si on voulait empoisonner le cache d'un résolveur pour le nom www.example.com, il fallait d'abord attendre l'expiration de l'enregistrement stocké (si on a accès au résolveur, c'est facile, puisque le TTL est publié), faire en sorte qu'une question sur www.example.com soit générée (là encore, c'est beaucoup plus facile si on a accès au résolveur) et, pendant les quelques dizaines de millisecondes avant que les serveurs faisant autorité répondent, envoyer une bouffée de fausses réponses, en comptant qu'une corresponde. Même aidé par le paradoxe de l'anniversaire, cela ratait plus souvent que cela ne réussissait.

La menace se rapprochait toutefois suffisamment pour avoir poussé l'IETF à s'intéresser au travail de Bert Hubert sur la résistance aux faux. Ce travail est actuellement documenté dans l'Internet-Draft Measures for making DNS more resilient against forged answers. Ce document, pas encore approuvé, contient de très intéressants calculs quantitatifs sur l'attaque exposée ci-dessus, évaluant ses chances de succès (trop élevées, hélas) et proposant des mesures pour rendre l'attaque plus difficile, mesures dont la principale est la SPR (Source Port Randomisation, le fait de rendre le port UDP source imprévisible, le faisant ainsi venir au secours du Query ID). Ce travail avançait cahin-caha lorsque la nouvelle de la faille Kaminsky a commencé à circuler en février 2008.

Cette faille est très simple dans son principe. Elle repose sur la faiblesse expliquée ci-dessus (les 16 bits du Query ID ne représentent pas suffisamment d'entropie). Mais elle la rend facilement exploitable. Avant Kaminsky, toutes les attaques reposaient sur une question portant sur le nom qu'on voulait détourner. Si on voulait empoisonner le cache avec une fausse valeur pour www.example.com, on faisait poser au résolveur la question « Quelle est l'adresse IP de www.example.com ? » et on glissait une fausse réponse. Le problème de cette méthode est qu'on n'a droit qu'un un essai : même s'il reçoit plusieurs questions identiques de ses clients, le résolveur n'en envoie qu'une seule et il faut donc deviner le Query ID de cette unique question. Pire, si on rate son coup, la bonne réponse, celle qui vient du serveur faisant autorité, va être mise dans le cache du résolveur et, si le TTL a une valeur raisonnable, l'attaquant ne pourra pas réessayer avant plusieurs heures ou même jours.

Dan Kaminsky a innové essentiellement sur un point : si on veut fausser www.example.com, on va demander au résolveur des informations sur quelquechoseNNN.example.com où NNN est un nombre qui varie à chaque requête. Ainsi, le résolveur devra envoyer autant de requêtes que de noms de domaine différents, augmentant énormément les chances de l'attaquant, surtout s'il est aidé par le paradoxe de l'anniversaire. Notez que, le nom de la zone (ici example.com) doit être le même, pour que les requêtes aillent toutes au même serveur faisant autorité mais aussi pour passer les contrôles du paragraphe suivant.

Bon, maintenant, l'attaquant, au lieu de n'avoir qu'une seule chance, en a des milliers et l'attaque devient bien plus facile. Mais quel intérêt pour lui d'arriver à mettre une fausse réponse pour quelquechose5447.example.com dans le cache du résolveur ? C'était www.example.com qui l'intéressait ! C'est la deuxième innovation de Kaminsky. Dans la fausse réponse, l'attaquant glisse non seulement un enregistrement pour quelquechoseNNN.example.com (qui n'est pas obligatoire, on peut aussi répondre sans section Answer) mais également des enregistrements pour www.example.com dans les autres sections comme Additional. Les tests qu'effectuent les résolveurs ne suffiront pas à le rejeter puisque ce nom est dans le bailliage (les résolveurs rejettent les noms dits « hors-bailliage », les noms qui sont dans une autre zone que la zone du nom cherché, justement pour limiter les risques d'empoisonnement).

Si jamais le résolveur devenait d'avantage paranoïaque, il suffirait d'ailleurs de glisser de faux enregistrements NS (Name Server) et une fausse colle dans la section Authority, que le résolveur ne peut pas ignorer. C'est ce que fait une des exploitations, et voici la réponse DNS fausse, telle que vue par Wireshark. Ici, on a tenté de tricher sur l'adresse IP de www.example.com, un domaine dont les serveurs faisant autorité sont à l'IANA (ici, 193.0.0.236). On tente d'empoisonner le cache avec l'adresse 192.0.2.1 :

...
    Source: 193.0.0.236 (193.0.0.236)
    Destination: 192.0.2.253 (192.0.2.253)
User Datagram Protocol, Src Port: 53 (53), Dst Port: 49186 (49186)
    Source port: 53 (53)
    Destination port: 49186 (49186)
    Length: 175
    Checksum: 0x98a1 [correct]
        [Good Checksum: True]
        [Bad Checksum: False]
Domain Name System (response)
    Transaction ID: 0x0001
    Flags: 0x8400 (Standard query response, No error)
        1... .... .... .... = Response: Message is a response
        .000 0... .... .... = Opcode: Standard query (0)
        .... .1.. .... .... = Authoritative: Server is an authority for domain
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...0 .... .... = Recursion desired: Don't do query recursively
        .... .... 0... .... = Recursion available: Server can't do recursive queries
        .... .... .0.. .... = Z: reserved (0)
        .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
        .... .... .... 0000 = Reply code: No error (0)
    Questions: 1
    Answer RRs: 1
    Authority RRs: 1
    Additional RRs: 1
    Queries
        deb623f600000009.example.com: type A, class IN
            Name: deb623f600000009.example.com
            Type: A (Host address)
            Class: IN (0x0001)
    Answers
        deb623f600000009.example.com: type A, class IN, addr 1.1.1.1
            Name: deb623f600000009.example.com
            Type: A (Host address)
            Class: IN (0x0001)
            Time to live: 1 day
            Data length: 4
            Addr: 1.1.1.1
    Authoritative nameservers
        example.com: type NS, class IN, ns www.example.com
            Name: example.com
            Type: NS (Authoritative name server)
            Class: IN (0x0001)
            Time to live: 1 day
            Data length: 20
            Name server: www.example.com
    Additional records
        www.example.com: type A, class IN, addr 192.0.2.1
            Name: www.example.com
            Type: A (Host address)
            Class: IN (0x0001)
            Time to live: 1 day
            Data length: 4
            Addr: 192.0.2.1

L'attaque Kaminsky est donc bien nouvelle. Elle passe d'une méthode laborieuse et ayant de faibles chances de succès à une méthode qui marche à presque tous les coups et en très peu de temps (moins de dix minutes avec les exploitations publiées, beaucoup moins avec certaines non publiées).

Voici pourquoi il est donc urgent de mettre à jour, si ce n'est pas encore fait, les résolveurs DNS dont vous avez la responsabilité. À part PowerDNS et Unbound, qui le mettaient déjà en œuvre, cette mise à jour installe la SPR (rendre le port source aléatoire) sur les résolveurs. On passe ainsi de seulement 16 bits d'entropie (le Query ID) à 32 (le Query ID plus le port source, qui est également sur 16 bits). Cela retarde le moment où l'attaque sera efficace, en attendant des mesures plus radicales.


L'article seul

RFC 5283: LDP Extension for Inter-Area Label Switched Paths (LSPs)

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : B. Decraene (France Telecom), JL. Le Roux (France Telecom), I. Meinei (Juniper)
Chemin des normes
Première rédaction de cet article le 27 juillet 2008


Le protocole MPLS de commutation de paquets selon une étiquette (label) utilise souvent LDP comme mécanisme d'attribution des étiquettes. LDP ne fonctionnait bien qu'à l'intérieur d'une même zone du système autonome et ce nouveau RFC étend LDP pour le cas où on dispose de plusieurs zones.

La section 1 du RFC explique la motivation pour cette modification : un certain nombre d'opérateurs ont tiré profit du caractère hiérarchique de protocoles de routage internes comme OSPF ou IS-IS pour créer plusieurs zones (areas) dans leur système autonome. Ce découpage en zones (section 3 du RFC 2328) permet de gérer des très grands systèmes autonomes, en évitant que chaque routeur connaisse tout le réseau.

Mais, sur les réseaux MPLS utilisant LDP, pour qu'un routeur qui reçoit une correspondance entre une étiquette MPLS et une FEC (Forwarding Equivalent Class, section 2.1 du RFC 3031) la prenne en compte, la norme LDP (section 3.5.7.1 du RFC 5036) impose que la table de routage du routeur possède une entrée qui corresponde exactement cette FEC. Par exemple pour monter un tunnel MPLS, le routeur MPLS doit avoir dans sa table une route avec une correspondance exacte avec le point de sortie du tunnel, c'est-à-dire en IPv4 le préfixe en /32 ; avoir une route en /24 qui couvrirait ce /32 ne suffit pas.

En pratique, sur les réseaux MPLS utilisant LDP et qui ont un IGP multi-zones, monter des tunnels vers ou depuis des routeurs appartenant à d'autres zones nécessitait donc des bricolages comme l'annonce des adresses (préfixes en /32 ou bien /128 en IPv6) dans tous les sens entre tout plein de zones en passant aussi par la zone qui sert d'épine dorsale, ce qui est très lourd à gérer et rend l'intérêt des zones douteux. Elles avaient justement été conçues pour éviter de transporter des détails internes à une zone, en agrégeant les annonces de préfixes...

La section 4 du RFC détaille le problème, notamment dans le cas de tunnels (RFC 4364, RFC 4761 et RFC 4762). La section 6 fournit des exemples, avec de jolis dessins.

La section 5 présente la solution. Notre RFC 5283 permet donc désormais de faire accepter à LDP des associations étiquette/FEC pour lesquelles le LSR (le routeur MPLS) aurait des routes moins spécifiques, par exemple parce qu'elles ont été agrégées. C'est donc simplement l'application de la traditionnelle règle IP de la « meilleure correspondance » (longest match) à la sélection d'une étiquette MPLS.

L'ancienne règle continue à s'appliquer par défaut (le RFC impose que la nouvelle extension ne soit pas activée automatiquement). En effet, si on arrête de publier les préfixes les plus spécifiques, il faut que tous les routeurs MPLS de la zone acceptent l'extension. Elle est donc déployable de manière progressive (section 7.1) mais à condition de faire attention.

Merci à Sarah Tharan pour ses explications détaillées sur cette extension.


Téléchargez le RFC 5283


L'article seul

RFC 5279: A Uniform Resource Name (URN) Namespace for the 3rd Generation Partnership Project (3GPP)

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : A. Monrad, S. Loreto (Ericsson)
Pour information
Première rédaction de cet article le 26 juillet 2008


3GPP dispose désormais d'une famille d'URN, identifiée par le NID (Namespace IDentifier) 3gpp.

3GPP est un groupe de normalisation privé, composé de fournisseurs de systèmes de téléphonie mobile (section 1). Ses activités nécessitent des identificateurs stables et 3GPP a choisi les URN (RFC 8141).

La description complète de leurs URN apparait dans la section 2 du RFC et est également documentée en ligne en http://www.3gpp.org/tb/Other/URN/URN.htm.

La section 3 donne quelques exemples de ces nouveaux URN comme urn:3gpp:featurephones ou bien urn:3gpp:acme.foo-serv (cette seconde URN utilisant un système hiérarchique, non documenté dans le RFC, où « acme » est un opérateur et « foo-serv » un de ses services).


Téléchargez le RFC 5279


L'article seul

RFC 5290: Comments on the Usefulness of Simple Best-Effort Traffic

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : S. Floyd, M. Allman (ICIR/ICSI)
Pour information
Réalisé dans le cadre du groupe de travail IETF tsvwg
Première rédaction de cet article le 25 juillet 2008


L'Internet a toujours fonctionné sur le principe du « fais au mieux » (best effort), c'est-à-dire que les applications qui l'utilisent n'ont aucune garantie sur les caractéristiques quantitatives du réseau qui sera à leur disposition. Le débit, par exemple, ne peut pas être connu à l'avance ; lorsqu'on commence un transfert de fichiers, on ne sait pas quand il se terminera. Ce principe a assuré le succès de l'Internet, par rapport à des réseaux concurrents qui se vantaient de leurs « garanties de qualité de service » et qui, en conséquence, offraient un service moyen nettement inférieur. Mais il est contesté par certains qui voudraient la possibilité de garantir une « qualité de service » (QoS pour « Quality of Service ») dans le réseau. Ce nouveau RFC ne tranche pas sur la question de savoir si la QoS est une bonne idée ou pas, il rappelle uniquement l'intérêt qu'il y a à disposer d'un mécanisme équivalent au « fais au mieux », une offre très efficace et qui correspond à beaucoup d'usages.

À l'époque où l'Internet avait du mal à s'imposer face aux réseaux prônés par les gens des télécommunications, appuyés par les gouvernements, un des reproches qui lui étaient le plus souvent fait était de ne pas garantir de « qualité de service » (QoS). Avant un appel téléphonique avec SIP, en effet, on ne peut pas savoir quel sera la capacité disponible, quel sera le RTT ou quelle sera la gigue. On peut les mesurer mais rien ne garantit que ces grandeurs resteront constantes pendant l'appel. Cela peut gêner certaines applications. C'est pour cela que des mécanismes visant à gérer la QoS ont été développés sur Internet comme intserv (RFC 1633) ou bien diffserv (RFC 2475). En pratique, ces mécanismes ont été très peu déployés, ce qui relativise la soi-disant demande de QoS. En général, il est moins coûteux d'augmenter le débit des tuyaux que de déployer ces mécanismes complexes. Mais certains vont plus loin et réclament le déploiement généralisé de QoS dans Internet, au point de ne plus garder de service « fais au mieux ». C'est là qu'intervient notre RFC 5290.

Sa thèse de base est que le socle de l'Internet doit rester un service « fais au mieux » (quitte à ajouter quelques mécanismes de QoS par dessus). Ce service est défini comme « tout ce qui ne bénéficie pas d'un service différencié » (section 1). Un moyen simple d'assurer ce service est l'« équité entre les flux » (flow-rate fairness).

La section 2 expose les propriétés de ce service simple best effort. En 2.1, les auteurs listent les forces de ce service :

  • Il ne demande pas trop d'efforts de la part de l'infrastructure réseau : les routeurs, par exemple, ont ainsi le minimum de travail. Ce service libère ainsi des ressources pour, par exemple, augmenter la capacité (les réseaux télécoms traditionnels passaient tellement de temps à gérer la QoS que leur débit total était sérieusement réduit).
  • Il ne demande pas trop de mécanismes économiques entre les opérateurs. Une des principales raisons du très faible déploiement de diffserv est qu'il nécessite des mécanismes de compensation entre opérateurs. Autrement, tout le monde enverrait ses paquets avec la classe la plus favorisée ! Ces compensations sont complexes et nécessitent des accords entre opérateurs qui vont plus loin que les mécanismes actuels entre opérateurs, ou entre un opérateur et son client.
  • Et, surtout, ce service « fais au mieux » est utile dans le monde réel. Il marche, pour une grande variété d'applications, et il propulse l'Internet depuis trente ans, malgré les affirmations (qu'on trouve par exemple dans la quasi-totalité des ouvrages universitaires sur les réseaux informatiques publiés en France) comme quoi un réseau sans QoS ne servait à rien.

Évidemment, tout n'est jamais uniformément rose. Le service « fais au mieux » a aussi des limites, que détaille la section 2.2. D'abord, certains utilisateurs veulent de la QoS et sont prêts à payer pour cela (section 2.2.1). Il ne faut pas les en priver mais cette demande soulève des questions très diverses. Par exemple, l'ensemble des ressources réservées pour les services « à garantie » ne doit pas mener à l'épuisement des ressources pour le service de base, autrement les riches utilisateurs pourraient s'approprier tout le réseau pour eux. Il existe une abondante littérature (le RFC donne quelques références) sur l'économie de l'Internet, la légitimité et l'efficacité de faire payer de manière différenciée, etc. Ensuite, les services avec QoS peuvent interférer avec la « transparence du réseau ». En effet, il n'est pas difficile d'imaginer des cas où, pour certaines applications, celui qui ne paierait pas le surcoût de la QoS serait, en pratique, exclu du réseau. Mais le débat est loin d'être clos sur la question de savoir quel niveau de QoS reste compatible avec cette transparence du réseau. (Le RFC 2990 donne des éléments de départ sur l'architecture de QoS.)

Une autre faiblesse du « fais au mieux » est sa sensibilité aux incivilités (section 2.2.2). Si un certain nombre d'utilisateurs ne jouent pas le jeu, le réseau peut s'effondrer puisqu'il n'y a pas de limites à l'allocation de ressources. Dans cette optique, les services différenciés ne seraient pas tant un moyen de « donner plus à ceux qui paient plus » qu'un mécanisme de contrôle de la congestion, même en présence d'implémentations « agressives » de TCP/IP, qui ne respecteraient pas les règles énoncées dans le RFC 2914.

Enfin, la dernière faiblesse (section 2.2.3) est le cas de « pics » de trafic brutaux (suite à une DoS ou tout simplement en cas de grand succès d'un site Web), pour lesquels le mécanisme « fais au mieux » mène en général à ce que personne ne soit servi...

Après ce tour des forces et faiblesses du mécanisme « fais au mieux », le RFC aborde, dans la section 3, le concept d'« équité entre les flux ». L'idée est que cette équité ne serait certes pas parfaite, mais assurerait un service « fais au mieux » qui soit convenable pour tout le monde. Notre RFC paraphrase Winston Churchill en disant que l'équité entre les flux est le plus mauvais des services, à l'exception de tous les autres.

En effet (section 3.1), cette équité serait relativement facile à mettre en œuvre (pour TCP, qui forme la grande majorité du trafic actuel, elle est déjà implémentée dans ses algorithmes), elle ne nécessite pas de calculs de facturation complexes, elle marche aujourd'hui et elle satisfait une notion sommaire, mais raisonnable, de la « justice » puisque chaque flot aura une part de la capacité du réseau.

Elle a par contre des limitations (section 3.2). Elle est difficile à faire respecter (section 3.2.1). En effet, dans l'Internet actuel, son respect dépend des machines aux extrémités du réseau, machines qui sont sous le contrôle d'un utilisateur qui peut être un méchant égoïste. Changer ce système pour que les routeurs fassent le contrôle serait un changement considérable d'architecture. Et, après tout, l'Internet s'en est passé jusqu'à présent.

Une deuxième question est qu'il n'existe pas de définition claire et consensuelle de ce qu'est l'équité entre les flux. Tout le monde est pour l'équité, c'est lorsqu'on essaie de la définir que les ennuis commencent (section 3.2.2). D'abord, « flux » (flow) n'est pas bien défini (cf. RFC 2309, RFC 2914, RFC 3124 et bien d'autres). Est-ce par connexion ? (Un concept qui n'existe pas pour tous les protocoles, par exemple UDP.) Ou bien pour tout trafic entre deux machines ? Ou bien, à une granularité intermédiaire, faut-il mettre toutes les connexions TCP démarrées par le même navigateur Web ou bien le même client BitTorrent dans le même flux ? Et l'équité doit-elle se mesurer en nombre de paquets ou en octets/seconde ? (Les protocoles interactifs comme SSH préféreraient certainement la première solution.) Et que faire avec les protocoles où le trafic tend à être très irrégulier ? Faut-il une équité « en moyenne » ? Si oui, sur quelle période ? Bref, si l'objectif politique est clair, le traduire en chiffres précis semble très difficile.

La section 4 du RFC 5290 s'attaque à un problème sur lesquels bien des protocoles se sont brisés : le déploiement. Pour reprendre l'exemple traditionnel du fax, celui qui a acheté le premier fax a fait preuve d'une confiance aveugle dans le succès de la technologie. Son fax ne lui servait à rien. Ce n'est qu'une fois qu'un nombre suffisant d'acheteurs s'en sont procuré un que son achat avait un sens. De même, une bonne partie des difficultés d'IPv6 s'explique par cet effet « œuf et poule ». Les premiers à déployer IPv6 n'ont aucun intérêt à le faire (ils ne pourront communiquer avec personne). Résultat, le déploiement ne se fait pas.

Et pour la QoS ? C'est le même problème : déployer un réel système de QoS sur l'Internet nécessiterait des actions par un certain nombre d'acteurs différents et ceux-ci ne voient pas de motivation à le faire. Voici pourquoi presque tous les déploiements actuels de QoS sont restés limités à une seule organisation.

Enfin, la section 5 décrit le travail qui a été fait, à l'IETF et ailleurs, sur ce problème. L'histoire de la qualité de service sur l'Internet est vieille, on trouve déjà une discussion dans le RFC 896, mais aussi, plus tard, dans le RFC 2212 et RFC 2475. Le RFC 2309 traite du cas où certains flux ne jouent pas le jeu et tentent d'occuper toute la capacité disponible et le RFC 3714 de la notion d'équité. La référence reste le RFC 2914 sur les principes de contrôle de congestion sur l'Internet.

La section 5.2 contient plusieurs autres références sur le travail fait à l'extérieur de l'IETF comme les articles Flow Rate Fairness: Dismantling a Religion ou Pricing the Internet.


Téléchargez le RFC 5290


L'article seul

RFC 5218: What Makes For a Successful Protocol?

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : D. Thaler (IAB), B. Aboba (IAB)
Pour information
Première rédaction de cet article le 25 juillet 2008


Qu'est-ce qui fait qu'un protocole a du succès ou pas ? Pourquoi certains restent-ils dans une petite niche alors que d'autres accèdent à la domination mondiale ? Et y a t-il des leçons à tirer de ces succès et de ces échecs, pour améliorer les prochains protocoles ? C'est à ces questions que s'attaque le dernier RFC de l'IAB, « qu'est-ce qui fait un succès ? ».

Il n'y a évidemment pas de réponse simple et univoque. Le RFC 5218 ne tente bien sûr pas de trouver une recette simple qui garantirait le succès. Il liste plutôt des facteurs qui jouent un rôle, essayant d'évaluer l'importance de ce rôle. La moitié du RFC est constituée d'études de cas où plusieurs protocoles sont étudiés du point de vue de ces facteurs.

Ce qui est sûr, c'est que la qualité technique du protocole n'est qu'un des facteurs, et pas le plus important.

Au sein des protocoles IETF, pourquoi Diameter (RFC 3588, puis RFC 6733) n'a t-il jamais remplacé Radius (RFC 2865) ? Pourquoi SNMP v1 (RFC 1157) continue t-il à être tant utilisé ? Et, bien sûr, même s'il est très peu cité dans le RFC, pourquoi IPv6 (RFC 2460) n'a t-il pas remplacé IPv4 (RFC 791) ? Pourtant, à chaque fois, le protocole présenté comme « le successeur » avait bénéficié d'un marketing vigoureux.

Entre protocoles IETF et protocoles d'autres origines, pourquoi IP a t-il écrasé IPX, qui était probablement techniquement supérieur, ou bien OSI, qui bénéficiait d'un soutien politicien et bureaucratique marqué ?

La section 1.1 du RFC commence par tenter de définir ce qui fait le succès. BGP (RFC 4271) est un succès, bien qu'il ne soit installé que sur un petit nombre de machines et qu'il ne soit utilisé directement que par une petite minorité de personnes. DHCP (RFC 2131) est un autre exemple d'un succès qui ne se voit pas forcément, puisqu'il n'est utilisé qu'à l'interieur d'un site (DHCP est un « protocole TCP/IP » mais pas vraiment un « protocole Internet »). Même chose pour OSPF (RFC 2328). En revanche, les protocoles célèbres, utilisés à travers l'Internet, sont des succès incontestables comme HTTP (RFC 2616), SIP (RFC 3261) ou le DNS (RFC 1034).

La section 1.2 essaie de quantifier cette question en parlant des deux dimensions du succès : les usages et l'échelle. Un protocole est conçu pour certains usages. Le succès signifie souvent qu'il est utilisé pour d'autres usages. Un protocole est prévu pour une certaine échelle d'utilisation et le succès va souvent le conduire à la dépasser largement (par exemple, il y a bien plus de machines connectées à l'Internet que n'en prévoyaient ses concepteurs, même dans leurs rêves les plus fous). Le RFC invente même le concept de « succès fou » (wild success) pour désigner les protocoles qui, comme IPv4, ont dépassé toutes les espérances.

HTTP (section 1.2.1) est un exemple encore meilleur d'un succès fou. Il a dépassé les usages prévus (puisqu'on se sert de HTTP en dehors du Web, par exemple pour REST et XML-RPC, voire pour traverser les coupe-feux et « tunneler » le trafic). L'ampleur de son déploiement a aussi largement dépassé les ambitions initiales de Tim Berners-Lee !

Plus complexe, toujours en section 1.2.1, est le cas d'ARP (RFC 826). En ampleur du déploiement, c'est un grand succès. Mais ses usages ont été réduits : conçu pour fonctionner sur n'importe quel type de réseau local, il n'a jamais été déployé que sur Ethernet.

Alors, est-ce souhaitable pour un concepteur de protocole de voir son bébé devenir un « succès fou » ? Ce n'est pas évident, comme le note la section 1.3. Avoir un succès fou a des conséquences, certaines bonnes et d'autres mauvaises. Par exemple, le succès peut entraîner le protocole aux limites de ses capacités quantitatives, « problème » que connait actuellement IPv4, dont les quatre milliards d'adresses possibles ne sont plus suffisantes. (À l'époque de sa conception, le modèle dominant était « un ordinateur par organisation ». Il est passé ensuite à « un ordinateur par département » puis « un ordinateur par personne » et le modèle actuel de plusieurs ordinateurs par personne est une des causes de l'épuisement des adresses IPv4.)

De même, le succès peut aggraver ou révéler des problèmes de sécurité : le protocole qui réussit va attirer l'attention des craqueurs.

Et l'échec ? Symétrique du succès, c'est le sort de certains protocoles. La section 1.3 essaie de l'analyser. D'abord, il ne faut pas forcément être pressé. Au début, un protocole n'a aucun déploiement et aucune implémentation. Ce n'est qu'avec le temps qu'on peut dire que le protocole a réussi ou échoué. HTTP a mis plusieurs années à décoller, par exemple. IPv4 est resté le protocole d'un petit réseau inconnu des décideurs et des journalistes pendant de nombreuses années.

Les protocoles réseaux ont un problème particulier à surmonter, celui de l'œuf et la poule (un terme que critique notre RFC, d'ailleurs). En effet, le réseau ne sert à rien si on est tout seul. Si j'invente un protocole de courrier électronique supérieur à SMTP (avec l'expérience qu'on a aujourd'hui, ce n'est pas très difficile), ce protocole, si réussi soit-il, ne servira à rien puisque j'en serai le seul utilisateur et que je ne pourrai donc envoyer du courrier à personne. Le cercle vicieux s'enclenche facilement : personne n'a déployé le nouveau protocole donc les auteurs de logiciels ne se pressent pas pour l'intégrer dans leurs programmes donc les utilisateurs ne s'en servent pas, donc il n'y a pas de déploiement, etc. Tout le monde aurait intérêt à ce que le nouveau protocole réussisse mais les premiers convertis supporteraient tous les coûts. En l'absence d'une autorité centrale qui pourrait ordonner le déploiement du nouveau protocole, bien des propositions de réforme ont ainsi été victimes de ce que les économistes appellent un échec du marché.

Quelles sont les méthodes pour faire face au problème de l'œuf et de la poule ? La section 1.3 en cite plusieurs :

  • Résoudre un problème immédiat et brûlant, ce qu'a fait, par exemple, le NAT (RFC 3022).
  • Fournir un « service qui tue » (killer app), comme l'ont fait les services de distribution de fichiers en pair-à-pair, service tellement utile que les utilisateurs sont prêts à faire des efforts, par exemple à reconfigurer leur routeur.
  • Être invisible, c'est-à-dire ne nécessiter aucun changement.
  • Réduire les ambitions, en diminuant les usages prévus, ce qui rend le succès plus facile. C'est ainsi que la diffusion restreinte (multicast) sur tout l'Internet, telle qu'envisagée à l'origine, a été un échec mais cette même diffusion restreinte est largement pratiquée sur les réseaux locaux.
  • Obtenir une aide ou une directive gouvernementale. La question est chaudement disputée, les adorateurs du marché aimant prétendre que l'Internet s'est créé tout seul, par le seul jeu non régulé des forces du marché. Rien n'est plus faux, l'Internet et son prédécesseur Arpanet ont vécu pendant quinze ans aux crochets de l'état états-unien. Mais l'intervention de l'État (à part sous une dictature extrême du genre Ivan le Terrible) ne marche pas toujours, les acteurs gardant leur liberté. Le RFC cite l'intervention du gouvernement japonais en faveur d'IPv6 mais, si cette aide a permis à Kame de faire un travail très intéressant sur IPv6, ce protocole reste minoritaire au Japon comme ailleurs. De même, les protocoles OSI ont nettement perdu face à TCP/IP malgré un soutien gouvernemental très obtus (par exemple en France). Et, dans un domaine différent de celui des réseaux, le langage de programmation Ada ne s'est pas imposé, en dépit d'une consigne officielle de n'utiliser que lui pour tous les programmes de l'armée états-unienne (le plus gros consommateur de logiciels du monde).

La section 2 explore les différentes causes de succès, en précisant bien qu'aucun succès n'a réuni toutes ces causes. 2.1 se spécialise dans les raisons du succès « de base », 2.2 dans celles du succès fou.

D'abord, le protocole doit évidemment avoir un intérêt et cet intérêt doit compenser les coûts (section 2.1.1). Si les coûts liés au matériel sont les plus visibles, ils ne sont pas forcément les plus importants. Ainsi, tout protocole qui nécessite de re-former les utilisateurs a un travail plus difficile pour s'imposer car le coût de cette formation est non-trivial. Les coûts liés à l'invalidation des anciens calculs économiques sont également à prendre en compte : si un FAI fonde son modèle économique sur des connexions Internet intermittentes, un protocole qui permet d'être connecté tout le temps comme l'ADSL, va remettre en cause ce modèle (de façon significative, mais étonnante pour un RFC, le paragraphe sur l'économie est le plus long de la section).

Et quels sont les bénéfices possibles ? Résoudre un problème lancinant (DHCP a ainsi mis fin au cauchemar des administrateurs réseaux courant de machine en machine pour faire un changement), permettre des choses qu'on ne faisait pas avant, ou rendre simplement plus efficace les choses qu'on faisait déjà (de tels protocoles sont souvent plus simple à déployer car ils ne remettent pas en cause les usages). Si le coût initial est élevé, le protocole peut avoir du mal à s'imposer, même si les bénéfices futurs sont prometteurs.

En outre, coûts et bénéfices ne sont pas équitablement répartis. Les techniques de NAT sont très coûteuses pour les développeurs d'applications, qui doivent coder des contournements compliqués mais apportent des bénéfices aux FAI, qui font des économies d'adresses IP. Tout dépend donc de qui décide. Le RFC note donc que le succès d'un protocole vient souvent de « l'alignement des coûts et des bénéfices », c'est-à-dire du fait que les bénéfices viennent à ceux qui supportent les coûts initiaux (même si, comme dans le cas du NAT, les coûts finaux sont payés par d'autres).

Ensuite, pour être un succès, le protocole a tout intérêt à être déployable petit à petit (section 2.1.2). En effet, le dernier flag day (tout l'Internet change de protocole le jour J à l'heure H) a eu lieu en janvier 1983 lors du déploiement d'IPv4 (et du passage à TCP/IP). Aujourd'hui, il est complètement impossible de changer tout l'Internet d'un coup et le nouveau protocole doit donc pouvoir s'intégrer à l'Internet existant (le grand drame d'IPv6 vient de là).

D'autres causes de succès non technique sont la disponibilité du code en logiciel libre ou quasi-libre (sections 2.1.3 et 2.1.4), le fait que le protocole soit ouvert (section 2.1.5) et maintenu par une SDO selon un processus ouvert (section 2.1.6, qui est un peu un plaidoyer pro domo pour l'IETF). Le succès d'IPv4 contre IPX ou OSI (ce dernier cas n'est pas cité par le RFC mais est encore plus net) tient largement à ces points. TCP/IP a gagné en bonne partie par sa disponibilité dans les Unix de Berkeley.

Le fait que la norme soit « ouverte » joue un rôle important, ce qui explique aussi la vigueur des débats dans le groupe de travail IPR de l'IETF. Les RFC ne sont pas les normes les plus ouvertes du monde, par exemple leur licence (RFC 5378) limite les usages qui peuvent en être faits...

Et la technique, alors, elle ne joue aucun rôle ? Un peu quand même, argumente la section 2.1.7, qui explique qu'un protocole bien conçu a d'avantage de chances.

Mais le succès est une chose et le succès fou en est une autre. Qu'est-ce qui cause un succès fou ? L'extensibilité et l'absence de limites aident (sections 2.2.1 et 2.2.2). DECnet était limité par construction à 65 536 machines, ce qui garantissait son échec à terme, même s'il avait connu de bons débuts.

L'un des points où il y a la plus grosse différence entre le succès et le succès fou concerne la sécurité (section 2.2.3). Au début, il n'est pas nécessaire qu'un protocole soit sûr (ce point est développé également en section 3). Compte-tenu des divers coûts associés à la sécurité, notamment les difficultés d'usage, faire l'impasse sur la sécurité est en général un bon moyen de réussir au début. Mais, lorsque le protocole devient très répandu, les craqueurs se précipitent dessus et cherchent à le subvertir. C'est alors que les impasses qui avaient été faites sur la sécurité peuvent se payer cher. Néanmoins, foncer d'abord et réfléchir ensuite à la sécurité semble être une bonne stratégie (les protocoles qui intègrent la sécurité dès le début ne sont souvent jamais déployés et donc jamais attaqués).

Notons que l'annexe A, qui représente la moitié du RFC, décline ces analyses pour une série d'étude de cas. C'est ainsi que sont examinés :

  • Protocoles Web (HTTP et HTML) contre Gopher (section A.1). La qualité technique n'a guère joué (HTML à cette époque était très pauvre et, contrairement à ce que dit le RFC, n'avait même pas les formulaires). Mais le déploiement était simple et apportait des bénéfices immédiats.
  • IPv4 contre IPX (section A.2). Il existait d'innombrables protocoles réseaux à l'époque. Tout administrateur réseau devait en gérer plusieurs. Aucun des protocoles concurrents n'était déployable progressivement mais la base installée était faible. Certains de ces protocoles avaient des limites fondamentales (comme AppleTalk) qui leur interdisaient d'être le protocole d'un réseau mondial. IPX n'avait pas ces défauts et avait bien des avantages techniques sur IPv4 (comme l'auto-configuration, alors que DHCP n'existait pas encore). Mais la grande force d'IPv4 était la disponibilité d'une mise en œuvre libre, dans BSD (financée par des fonds publics). Même chose pour la disponibilité d'une norme.
  • SSH (section A.3). Ce protocole (RFC 4251) a remplacé telnet et rlogin en très peu de temps. Très simple à installer et à utiliser (beaucoup l'ont adopté uniquement pour la redirection des sessions X11, un énorme progrès à l'époque), ne nécessitant pas d'infrastructure centrale (contrairement aux solutions à base de Kerberos), SSH, malgré un statut légal peu clair au début, s'est vite imposé. Les puristes de la sécurité avaient pourtant critiqué cette simplicité (bien que beaucoup de solutions de sécurité aient échoué en raison de la grande complexité qu'elles imposaient aux utilisateurs). Le modèle TOFU (Trust On First Use) de SSH leur semblait une hérésie. Mais l'alternative était du telnet avec zéro sécurité. (Aujourd'hui, des techniques comme Perspectives tentent d'améliorer le système TOFU.)
  • Diffusion restreinte (multicast) entre domaines distincts (section A.4). C'est cette fois un échec qui est analysé. Le multicast (RFC 5110) a souvent été présenté comme indispensable aux services multimédia sur Internet mais la réalité est qu'il n'a jamais connu d'utilisation significative. Pourquoi ? Il manquait de la plupart des facteurs de succès. Il n'est pas évident qu'il répondait à un problème réel (la diffusion est utile si tout le monde regarde la même chaîne de télévision en même temps, comme dans les années 60, mais elle ne sert à rien pour la VoD). Il nécessite des grands changements dans tous les routeurs du chemin. Bref, les coûts étaient importants et les bénéfices peu clairs.
  • WAP (section A.5) est un autre échec, qui avait pourtant bénéficié d'un marketing très lourd et peu subtil, composé essentiellement d'affirmations tonitruantes comme quoi « 90 % des accès au Web se feraient en WAP dans cinq ans » et autre fumage de moquette de consultant. Coincé entre le classique HTTP et le plus perfectionné I-Mode, WAP n'apportait rien de précis. Très fermé (licences à acheter, normes non accessibles, évolution pilotée par une organisation où le coût d'adhésion était de 27 000 $), WAP n'est pas allé loin. Il est amusant a posteriori de compter le nombre d'articles sur WAP qui étaient parus dans la presse pour décideurs, alors qu'il n'avait connu aucun déploiement, par rapport au nombre d'articles qu'avait eu IP alors que l'Internet était déjà massivement utilisé.
  • La lutte du protocole IETF Radius (RFC 2865) contre le protocole de Cisco Tacacs (section A.7) est un autre cas où la disponibilité d'une norme ouverte et sans entraves a été le facteur dominant. Tacacs a évolué par la suite, une implémentation libre est apparue, ainsi qu'une norme (RFC 1492) mais c'était trop tard.
  • Plus douloureux est le succès du NAT (section A.8). Apportant un bénéfice immédiat à celui qui le déploie (le IP masquerading de Linux, première mise en œuvre répandue du NAT, avait été un succès foudroyant et avait beaucoup contribué au décollage de Linux), le NAT, propulsé par la pénurie d'adresses IPv4, s'est répandu partout, en dépit de l'opposition vigoureuse de l'IETF. Le fait qu'il apportait un bénéfice à court terme et qu'il était déployable sur un site sans aucune coordination avec les autres lui ont permis de progresser très vite.

La section 3 sert de conclusion au RFC. Elle estime que les facteurs de succès les plus importants sont le fait que le protocole apporte un avantage réel et le fait qu'il puisse être déployé progressivement, sans flag day.

Les qualités techniques du protocole sont secondaires et le RFC note, à juste titre, que beaucoup de protocoles ayant connu un succès fou ne passeraient pas l'examen de l'IESG aujourd'hui...

La conclusion finale est donc que l'examen par l'IETF des nouveaux protocoles devrait donc inclure l'étude des facteurs de succès.

Enfin, je note que l'IAB n'a guère mentionné des cas où l'échec est plus gênant pour l'IETF comme le peu de déploiement d'IPv6...


Téléchargez le RFC 5218


L'article seul

Fiche de lecture : Honni soit qui mal y pense

Auteur(s) du livre : Henriette Walter
Éditeur : Laffont
978-2-253-15444-0
Publié en 2001
Première rédaction de cet article le 25 juillet 2008


Aujourd'hui, on tend souvent à opposer l'anglais et le français, par exemple dans les réunions francophones où on discute de l'inquiétante montée de l'anglais dans le monde. Mais les deux langues ont en fait une importante histoire en commun, se sont mutuellement influencées, et la connaissance de leurs relations tumultueuses, par exemple par la lecture du livre d'Henriette Walter, peut aider à mieux les comprendre toutes les deux.

Henriette Walter nous entraîne à travers quatorze ou quinze siècles d'histoire commune. Le lecteur devra réviser pour suivre les bouleversements historiques qui font que, par exemple, la cour d'Angleterre parlait français au XIème siècle (et le roi d'Angleterre était donc incapable de comprendre ses sujets) mais l'avait abandonné au XVème. Deux langues proches géographiquement, dont les locuteurs ont beaucoup commercé, beaucoup échangé d'idées et se sont beaucoup fait la guerre. Cela crée des liens et les échanges ont été innombrables entre les deux langues, dans le vocabulaire et dans la grammaire. Et bien d'autres langues ont participé à l'évolution du français et de l'anglais comme l'italien ou les langues scandinaves.

Le livre est rempli d'informations éclairantes à ce sujet. Je ne savais pas que challenge, un mot symbole du franglais était à l'origine un mot français (qui s'écrivait « chalenge »), apporté par les Normands, disparu en France entre-temps et revenu ensuite via les États-Unis. Ni que l'on peut dire computer pour ordinateur, le mot était français, voulait dire « calculer » et venait en droite ligne du latin (ceci dit, un ordinateur ne sert pas qu'à calculer, mais aussi à écrire et à diffuser ce texte...).

Outre son côté ludique, ses nombreuses anecdotes historiques et ses tests (« Quels sont les noms d'animaux qui sont identiques en anglais et en français, comme condor, alligator, lion ou python ? »), ce livre est également très pratique pour chercher un mot particulier, grâce à un excellent index.

Un chapitre très intéressant concerne les langues de la science. Mais c'est là où j'ai trouvé les deux plus grosses erreurs du livre : Henriette Walter affirme que « client-serveur » est un calque, c'est-à-dire un mot formé selon les règles de grammaire d'une autre langue, ici l'anglais, puisque, dit-elle, le déterminant précède le déterminé. Mais l'explication est fausse, « client-serveur » ne veut pas dire « le serveur du client » mais exprime une relation entre deux parties.

De même, Henriette Walter affirme que « attracteur étrange » est « mystérieux » et prétend que le mot strange de l'anglais strange attractor aurait du être traduit par « étranger » alors que n'importe quel livre de physique lui aurait montré que les attracteurs étranges sont bien... étranges.

Passons sur ces deux erreurs, le livre en contient sûrement d'autres mais c'est inévitable vue l'ampleur du sujet et la difficulté à retrouver les racines de tous ces mots.


L'article seul

RFC 5340: OSPF for IPv6

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : R. Coltun (Acoustra Productions), D. Ferguson (Juniper Networks), J. Moy (Sycamore Networks), A. Lindem (Redback Networks)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ospf
Première rédaction de cet article le 24 juillet 2008


Le protocole de routage OSPF, normalisé dans le RFC 2328 est, à l'origine, très lié à IPv4. Le déploiement d'IPv6 nécessitait une adaptation d'OSPF et c'est ainsi que la version 3 d'OSPF (le RFC 2328 décrivait la version 2) est sortie, baptisée « OSPF pour IPv6 ».

Le premier RFC sur cette nouvelle version d'OSPF était le RFC 2740 que notre RFC 5340 met à jour. Comme son prédécesseur, ce RFC est écrit sous forme d'une liste de différences avec OSPF v2 (la version pour IPv4) et il faut donc lire également le RFC 2328 si on veut tout comprendre. Dur travail car la seule liste des différences fait 111 pages, mais il est vrai qu'OSPF n'est pas un protocole simple. En tout cas, je présente ce RFC comme il est écrit, sans reprendre ce que disait déjà le RFC 2328.

OSPF v3, la version pour IPv6, reprend les concepts habituels d'OSPF, comme l'inondation des LSA, l'élection des routeurs sur l'Ethernet, etc. Mais il n'est pas compatible avec OSPF v2, en raison du changement de format des paquets (section 2.7). Un site « double-pile » (IPv4 et IPv6) doit donc faire tourner les deux protocoles en parallèle (certains sites ont préféré adopter IS-IS pour n'avoir qu'un seul protocole).

Reprenant les concepts et le vocabulaire d'OSPF v2, le RFC a parfois eu des problèmes avec certains concepts qui avaient des noms différents entre IPv4 et IPv6. La section 1.2, de terminologie, détaille ces pièges.

La section 2 résume le RFC, puisqu'elle explique les différences entre OSPF v2 et OSPF v3. La plus grosse différence est le fait que tout ce qui est spécifique des adresses IP a été retiré des paquets généraux et mis dans des LSA spécifiques du protocole considéré (section 2.2). OSPF v3 est ainsi plutôt « multi-protocole » que purement IPv6 et il aurait pu être utilisé pour IPv4. Mais, en pratique, cela n'a jamais été fait et OSPF v3 ne sert qu'à IPv6. Peut-être les extensions à OSPFv3 qu'a finalement apporté le RFC 5838, en avril 2010, décoinceront enfin les choses.

Ainsi, les paquets Hello d'OSPF v2 indiquaient le masque de sous-réseau utilisé, ce qui n'est plus le cas en OSPF v3. De même, les identificateurs comme le Router ID ne sont plus des adresses, ce sont simplement des nombres de 32 bits, qu'on écrit avec la syntaxe habituelle des adresses IPv4.

Parmi les autres différences, on peut noter qu'OSPF v3 travaille par lien réseau et plus par sous-réseau IP (section 2.1), qu'on peut faire tourner plusieurs incarnations d'OSPF sur le même lien, différenciées par leur Instance ID (section 2.4) et que les voisins sont identifiés par une adresses « locale au lien » (section 2.5) comme fe80::207:cbff:fec3:8323 ce qui, à mon avis, ne facilite pas le déboguage (peu d'administrateurs réseaux connaissent par cœur les adresses locales au lien de leurs routeurs).

L'authentification des routeurs voisins a disparu du RFC (section 2.6), puisqu'on est censé désormais utiliser IPsec (via le RFC 4302). L'idée était que tout le monde utiliserait IPsec, de toute façon, d'autant plus qu'il était censé être obligatoirement intégré dans IPv6 ce qui, en pratique, n'a pas été le cas. L'idée de se reposer entièrement sur IPsec a été abandonnée avec la sortie du RFC 6506, qui prévoit un mécanisme d'authentification pour OPSFv3.

La section 3 décrit les différences entre l'ancien RFC, le RFC 2740 et celui-ci. Normalement, anciennes et nouvelles implémentations d'OSPF v3 interopèrent. Parmi les changements, l'abandon de MOSPF (section 3.2), le service de multicast (RFC 1584), jamais réellement utilisé. Ou bien l'abandon des adresses IPv6 « locales au site » (section 3.7), suivant le RFC 3879.

La section 4 est ensuite consacrée aux « conseils aux implémenteurs », c'est-à-dire tout ce qu'il faut savoir pour créer une belle mise en œuvre d'OSPF v3. Elle détaille les changements dans les structures de données que doit maintenir le routeur (section 4.1), le traitement des paquets (section 4.2), les nouveaux LSA (comme le Link LSA de la section 4.4.3.8) et les changements des anciens (section 4.4), etc.

La section 5 est consacrée à la sécurité. Elle revient sur l'authentification des routeurs, qui doit désormais se faire avec IPsec, comme détaillé dans le RFC 4552 (idée abandonnée avec le RFC 6506). Elle note aussi que l'authentification des routeurs ne suffit certainement pas à éliminer tous les problèmes de sécurité du routage, comme le détaille le RFC 4593.

L'annexe A détaille le format des paquets, les B et C les paramètres qui gouvernent le comportement d'OSPF.

Des exemples de configuration concrète d'un routeur OSPF v3 se trouvent dans mon cours OSPF. Par exemple, on peut voir les adjacences IPv6 sur un des routeurs :

# show ipv6 ospf6 neighbor
 RouterID         State/Duration    DR              BDR             I/F[State]
 192.134.7.241     Full/00:01:42    192.134.7.245   192.134.7.241   eth0[DR]
 10.4.200.2        Full/00:00:01    0.0.0.0         0.0.0.0         eth1[DR]

où on note que les routeurs sont identifiés par un Router ID, qui a la forme d'une adresse IPv4.


Téléchargez le RFC 5340


L'article seul

Pourquoi le domaine de tête ".local" n'est pas une bonne idée

Première rédaction de cet article le 19 juillet 2008


Sur beaucoup de sites, les ressources réseaux internes ont des noms situées sous le pseudo-TLD .local. Ce TLD (domaine de tête) n'avait pas été enregistré à cet usage et son utilisation peut apporter des mauvaises surprises.

Il vaut mieux en effet utiliser un vrai nom de domaine par exemple grandeentreprise.fr ou petiteassociation.org. Si on veut séparer les ressources locales, purement internes, local.grandeentreprise.fr ou monsite.petiteassociation.org (qui tirent profit du caractère hiérarchique du DNS) conviennent également. À une époque lointaine, un nom de domaine en .com était gratuit (oui, la réservation de renault.com m'avait coûté 0 €).

Puis obtenir un nom de domaine était devenu très cher ou bien soumis à de pénible restrictions bureaucratiques. Mais le prix a été nettement abaissé par des acteurs comme Gandi et les règles d'enregistrement se sont souvent assouplies. Aujourd'hui il est raisonnable de supposer que tout le monde a un nom de domaine, et peut l'utiliser pour ses ressources internes comme pour les externes.

Mais, au fait, pourquoi .local est-il une mauvaise idée ? D'abord, parce qu'il n'était nullement garanti. Ce n'est qu'en février 2013 qu'il a été inclus dans le nouveau registre des TLD spéciaux. Le RFC 2606 réserve quelques TLD à des fins de test ou de documentation et .local n'en fait pas partie.

Mais le problème de fond est que .local n'est pas unique puisque des tas d'entreprises l'utilisent. Que se passera t-il en cas de fusion ou d'acquisition ? Si un utilisateur de .local absorbe un autre utilisateur, les conflits de noms seront fréquents (Et le cas s'est souvent produit.)

Ce n'est pas parce que ces ressources ne sont pas accessibles de l'Internet qu'il faut leur donner un nom qui n'est pas unique.

Certes, des géants états-uniens du logiciel comme Microsoft (avec son système Active Directory) ou bien Apple (avec Bonjour), utilisent ce pseudo-TLD. Mais ils ne sont pas des exemples à suivre. Cette utilisation montre simplement leur peu d'intérêt de la normalisation et leur tendance au « Je fais ce que je veux et tant pis pour l'opinion des autres ». Lors de la discussion du RFC 4795 sur LLMNR, Apple avait même tenté d'obtenir la réservation de .local avec comme seul argument « Nous nous en sommes servis unilatéralement, désormais l'IETF doit approuver ce choix. » Cela a finalement été fait dans les RFC 6761 et RFC 6762.


L'article seul

Les registres IANA désormais en XML

Première rédaction de cet article le 18 juillet 2008


Le 14 juillet, l'IANA a annoncé que les registres qu'elle maintenait seraient désormais en XML et a produit les premiers registres convertis au nouveau format. L'annonce met fin à une étonnante tradition de l'Internet, le fait que les registres des numéros affectés aux différents protocoles étaient simplement maintenus sous forme de fichiers texte.

On connait surtout le rôle politicien que joue l'IANA, un service de l'ICANN, dans la maintenance du fichier de zone de la racine DNS. Mais ce rôle ne doit pas faire oublier que l'IANA est également chargée, pour le compte de l'IETF, de la maintenance d'un grand nombre de registres plus techniques, pour stocker les informations sur les nombres qui doivent être unique pour que l'Internet fonctionne. Par exemple, les numéros de ports TCP ou UDP (80 pour HTTP, 25 pour SMTP, etc) sont stockés dans un tel registre à l'IANA. Ce rôle est formalisé dans le RFC 2860 et la partie IETF du travail dans le RFC 5226.

Pendant presque toute son existence, l'IANA a géré ses registres d'une manière très simple. Chaque registre était un fichier texte édité à la main par Jon Postel. Cela marchait mais, aujourd'hui, un tel système semble bien dépassé. Il ne permet notamment pas d'analyser facilement les registres (qui sont, à quelques exceptions près, non structurés) et il ne permet pas de présenter ces registres sous d'autres formats, par exemple HTML. L'IANA était consciente du problème depuis longtemps mais n'a bougé qu'avec beaucoup de précautions. En effet, son rôle est d'être conservatrice. Les registres doivent rester accessibles pendant des dizaines d'années et les convertir dans le dernier format à la mode, uniquement pour devoir en changer six mois plus tard, ne serait pas une bonne façon de les gérer. En outre, il fallait évidemment que ces registres soient décrits dans un format ouvert. Le processus a donc été long (et, contrairement à ce qu'on lit parfois sur le fonctionnement ouvert de l'Internet, très secret et conduit uniquement par un petit groupe non public). XML était le candidat évident pour le format des données.

Désormais, le train du changement est sur les rails et les premiers registres ont été convertis et officiellement annoncés.

Prenons un exemple, le registre des paramètres d'AAA, utilisé par exemple par le RFC 3588. Le registre texte traditionnel est https://www.iana.org/assignments/aaa-parameters (qui existe toujours, jusqu'au basculement prévu cette année vers une version texte produite automatiquement à partir de la version XML). La nouvelle version faisant autorité est https://www.iana.org/assignments/aaa-parameters/aaa-parameters.xml. À partir de cette version, on peut produire automatiquement, par exemple, une version HTML.

Outre les données, on trouve à l'IANA les outils de conversion, par exemple le script XSLT de conversion en XHTML, https://www.iana.org/assignments/aaa-parameters/aaa-parameters.xsl.

Le maintien de données cohérentes dans les registres nécessitait évidemment la définition d'un schéma de données XML. Il est écrit en RelaxNG (je recommande le livre d'Eric ven der Vlist sur ce langage). Le schéma du registre AAA est en https://www.iana.org/assignments/aaa-parameters/aaa-parameters.rng. Convertie en syntaxe « compacte », voici ce schéma. On note qu'il inclus un schéma plus général, applicable à tous les registres, https://www.iana.org/assignments/_support/iana-registry.rng (dont voici la version en syntaxe compacte).

Armé de ces schémas, on peut vérifier que le registre est bien correct :

% rnv aaa-parameters.rnc aaa-parameters.xml
aaa-parameters.xml

ou bien, avec xmllint :

% xmllint --noout --relaxng aaa-parameters.rng aaa-parameters.xml 
aaa-parameters.xml validates

L'IANA va désormais travailler à convertir tous les registres et à développer de nouveaux services que permet ce format, par exemple des mécanismes permettant de suivre les changements dans un registre, sans doute grâce à un système de syndication, où les flux de syndication pourront être produits automatiquement.

On notera que certains registres, ayant déjà un format structuré, ne seront pas convertis en XML. C'est le cas par exemple du registre des langues du RFC 4646.


L'article seul

RFC 5220: Problem Statement for Default Address Selection in Multi-Prefix Environments: Operational Issues of RFC 3484 Default Rules

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : A. Matsumoto, T. Fujisaki (NTT), R. Hiromi (Intec Netcore), K. Kanayama (INTEC Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 18 juillet 2008


Lorsqu'un système connecté à Internet a plusieurs adresses IP, la question de savoir laquelle utiliser comme source se pose. Si ce système dispose d'adresses IP de familles différentes, par exemple IPv4 et IPv6, la question de la sélection de l'adresse de destination peut également survenir. Le RFC 3484 décrivait un mécanisme pour cette sélection, mais qui a posé des problèmes en pratique, problèmes que décrit notre RFC.

Le RFC 3484 est par exemple mis en œuvre dans le système GAI (à noter que ce système est très peu documenté) de la GNU libc (utilisée dans des systèmes comme Gentoo ou Debian). Ce système se configure via le fichier /etc/gai.conf et permet d'avoir des politiques comme « Privilégier systématiquement les adresses IPv6 » ou bien « Préferer IPv4 sauf pour tels préfixes ». C'est l'expérience avec des systèmes analogues (sur FreeBSD, c'est /etc/ip6addrctl.conf, cf. la documentation ; Solaris a un mécanisme proche) qui a donné naissance au travail actuel sur le successeur du RFC 3484, travail dont notre RFC 5220 décrit les motivations et dont le RFC 5221 donne le cahier des charges pour le prochain mécanisme. Le successeur a finalement été le RFC 6724, en septembre 2012.

La section 2 forme l'essentiel de notre RFC, en listant successivement plusieurs cas concrets et les solutions - ou l'absence de solution - que leur apporte le RFC 3484. La section 2.1.1, par exemple, analyse le cas où il y a deux routeurs sur le même lien. La sélection du premier routeur à utiliser ne dépendant typiquement pas de l'adresse IP source, un site connecté à deux FAI va avoir des problèmes puisque les paquets pourront être envoyés au « mauvais » routeur, celui connecté à un autre FAI que celui qui a attribué l'adresse source choisie (le cas de la section 2.1.2 est similaire et montre un FAI qui met en œuvre le RFC 2317, éliminant ainsi les paquets IP malchanceux).

La section 2.1.3 décrit par contre un cas qui peut être résolu par le RFC 3484, contrairement aux deux précédents. La machine y est connectée à l'Internet via un FAI et à un réseau privé, utilisant par exemple des adresses IP locales (RFC 4193). Dans ce cas, il suffit de donner la priorité aux adresses globales. Si le préfixe global est 2001:db8:1000::/48 et que le préfixe du réseau privé est 2001:db8:8000::/48, les règles suivantes dans gai.conf donneront le résultat attendu :

# Tout l'Internet
precedence  ::/0          40
# Le réseau privé, à n'utiliser que si le destinataire est dans ce réseau privé,
# grâce à la règle "longest matching rule" du RFC 3484, section 5,
# règle 8. On lui met une précédence plus faible.
precedence 2001:db8:8000::/48    20

La section 2.1.4 décrit un cas similaire.

La section 2.1.5 décrit le cas où le site change son préfixe (cf. RFC 4192) et où les machines doivent, pendant la transition, utiliser la bonne adresse source. Ce problème se résoud également dans le cadre du RFC 3484. Mais il faut noter que, le RFC en question ne spécifiant pas de mécanisme d'auto-configuration, cela nécessitera d'aller éditer le gai.conf (ou équivalent) sur toutes les machines du site, ce qui rendra le renumérotage très pénible !

La section 2.1.7 étudie le cas des adresses « vie privée » du RFC 4941. Ces adresses ayant des propriétés spécifiques, il serait préférable de choisir ou non leur utilisation par service et pas globalement et le RFC 3484 ne permet pas cela (le RFC 5014 fournit une solution possible).

La section 2.2 couvre le cas de la sélection de l'adresse destination. Par exemple, 2.2.1 étudie le cas très courant où un site est connecté nativement en IPv4 mais, compte tenu du manque de FAI IPv6, utilise un tunnel lent et peu fiable pour se connecter en IPv6. La table par défaut du RFC 3484, section 2.1, prioritise IPv6, ce qui n'est pas une bonne idée dans ce cas. Il est donc préférable de pouvoir choisir IPv4, ce qui se fait par exemple avec la ligne suivante dans /etc/gai.conf :

# Always prefer IPv4
precedence ::ffff:0:0/96  100

::ffff:0:0 désigne les adresses IPv4 mappées (section 2.5.5.2 du RFC 4291). Ce cas ne nécessite donc pas de modification du RFC 3484. 2.2.2 est un cas similaire où il n'y a pas de connectivité Internet IPv6 du tout mais où le réseau local offre IPv6.


Téléchargez le RFC 5220


L'article seul

RFC 5221: Requirements for address selection mechanisms

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : A. Matsumoto, T. Fujisaki (NTT), R. Hiromi (Intec NetCore), K. Kanayama (INTEC Systems)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 16 juillet 2008


L'ancien modèle d'IP prévoyait seulement une adresse IP par interface réseau donc, pour la plupart des machines, une seule adresse IP tout court. Le choix de l'adresse IP à utiliser lorsque cette machine initiait une communication avec une autre machine était donc trivial. Mais ce modèle a changé, notamment avec l'arrivée d'IPv6, où la multiplicité des adresses devient la règle. Quelles adresses source et destination utiliser, dans ces conditions ? Le RFC 3484 exposait un mécanisme, qui a prouvé quelques limitations, menant à la conception d'un système amélioré dont notre RFC 5221 est le cahier des charges et le RFC 6724 la réalisation.

Le système du RFC 3484 a été mis en œuvre dans plusieurs systèmes d'exploitations. Par exemple, ceux utilisant la GNU libc disposent de la méthode de ce RFC et, en prime, ont /etc/gai.conf à leur disposition pour configurer manuellement le choix des adresses. Mais ce mécanisme n'est pas parfait et le RFC 5220 décrit les problèmes qu'il pose.

Le nouveau mécanisme va tenter de traiter ces problèmes, tout en gardant la possibilité d'un mécanisme totalement automatique (section 1).

La section 2 liste les onze exigences du nouveau système (je ne les cite pas toutes ci-dessous). Par exemple, 2.2 pose comme principe qu'il ne doit pas rendre la machine plus pénible à utiliser : le processus de sélection ne doit pas être long et il ne doit pas imposer une action manuelle. 2.5 exige que le mécanisme puisse être spécifique à chaque application, permettant à Firefox d'utiliser des règles différentes de celles de Thunderbird (via par exemple une API qui reste à définir). 2.7 insiste sur la nécessité pour l'administrateur système de pouvoir contrôler ce mécanisme, depuis un point central (comme /etc/gai.conf sur Debian ou Gentoo).

La sélection d'adresses IP source et destination a évidemment un impact sur la sélection du premier routeur à utiliser et ce point faisait l'objet du RFC 4191, et désormais de la section 2.8 de notre RFC.

Comme il n'est pas question de réécrire toutes les applications, le mécanisme envisagé doit évidemment être compatible avec l'API socket du RFC 3493 (section 2.9). Et, toujours sur la question de compatibilité, ce mécanisme doit marcher avec celui du RFC 3484.


Téléchargez le RFC 5221


L'article seul

RFC 2181: Clarifications to the DNS Specification

Date de publication du RFC : Juillet 1997
Auteur(s) du RFC : Robert Elz (Computer Science), Randy Bush (RGnet, Inc.)
Chemin des normes
Première rédaction de cet article le 14 juillet 2008


Le DNS est à la fois un des protocoles de base de l'Internet, dont presque toutes les transactions dépendent, et un des protocoles les plus mal spécifiés. Les RFC de référence, les RFC 1034 et RFC 1035, sont toujours en service mais, écrits il y a plus de vingt ans, ils accusent leur âge. Ils sont souvent ambigus et ont été mis à jour par de nombreux RFC ultérieurs. Ainsi, celui qui développe une nouvelle mise en œuvre du DNS doit lire plusieurs RFC successifs. L'un des plus importants est notre RFC 2181 qui avait clarifié plusieurs points particulièrement importants de la norme originelle.

On ne peut rien faire avec le DNS si on ne lit pas ce RFC 2181. Il est une sorte de FAQ des erreurs les plus souvent commises en lisant trop vite les RFC 1034 et RFC 1035. Mais il corrige aussi ces RFC, qui comportaient parfois de réelles erreurs (sections 1, 2 et 3).

Les consignes de notre RFC 2181 sont très variées.

Ainsi, la section 4 rappelle que le serveur DNS doit répondre depuis l'adresse IP à laquelle la question a été posée (pour un serveur qui a plusieurs adresses). La section 4.2 pose le même principe pour le numéro de port.

La section 5 introduit un concept nouveau, celui de RRSet (Resource Record Set ou « ensemble d'enregistrements de données »). Ce concept n'existait pas dans les RFC 1034 et RFC 1035. Un RRSet est un ensemble d'enregistrements DNS pour le même nom de domaine, et le même type. Ainsi, ce groupe forme un RRSet :

foobar.example.com.    IN    AAAA      2001:DB8:123:456::1
foobar.example.com.    IN    AAAA      2001:DB8:CAFE:645::1:2

mais pas celui-ci :

foobar.example.com.    IN    AAAA      2001:DB8:123:456::1
baz.example.com.       IN    AAAA      2001:DB8:CAFE:645::1:2

(car le nom est différent) ni celui-ci :

foobar.example.com.    IN    AAAA      2001:DB8:123:456::1
foobar.example.com.    IN    A         192.0.2.34

(car le type est différent).

Le RFC impose ensuite (section 5.1) que les enregistrements d'un RRSet soient tous envoyés dans une réponse (ou bien que le bit TC - indiquant la troncation - soit positionné, ce que détaille la section 9). Pas question de n'envoyer qu'une partie d'un RRSet. Il impose également que les différents enregistrements d'un RRSet aient le même TTL (section 5.2). Il existe également des règles pour DNSSEC (section 5.3) mais elles concernent l'ancienne version de DNSSEC, qui a depuis été remplacée par DNSSEC-bis (RFC 4033 et suivants).

De même qu'un serveur ne peut pas n'envoyer qu'une partie des enregistrements d'un RRSet, il ne doit pas fusionner un RRSet reçu en réponse avec des données du même RRSet qui seraient dans son cache (section 5.4). Le reste de la section 5.4 est d'ailleurs consacré à la nécessaire paranoïa d'un serveur de noms récursif. En effet, le RFC 2181 lui impose de ne pas accepter aveuglément n'importe quelle donnée mais de juger de la confiance qu'on peut lui accorder (section 5.4.1). Ainsi, les données présentes dans la section additional d'une réponse DNS sont moins fiables que celles de la section answer. Le déploiement de notre RFC a ainsi résolu un gros problème de sécurité du DNS : les serveurs de noms récursifs avalaient tout le contenu de la réponse, sans juger de sa valeur, et étaient donc faciles à empoisonner avec de fausses données. Ainsi, avant le RFC 2181, un serveur qui demandait les enregistrements de type A pour www.example.org et qui recevait une réponse :

;; QUESTION SECTION:
;www.example.org.                            IN      A

;; ANSWER SECTION:
www.example.org.                       IN   A    192.0.2.1

;; ADDITIONAL SECTION:
www.google.example.                       IN   A   192.0.2.178

acceptait l'enregistrement A dans la section additionnelle, bien que cet enregistrement n'aie aucun rapport avec la question posée et ne fasse pas autorité.

La section 6 du RFC traite des frontières de zones DNS (zone cuts). L'arbre des noms de domaine est découpé en zones (RFC 1034, section 2.4 et 4.2), chaque zone étant traditionnellement décrite dans un fichier de zone spécifique. Pour connecter une zone parente à la fille, la parente ajoute des enregistrements de type NS. Il faut se rappeller que les frontières de zone ne se voient pas dans le nom de domaine. Est-ce que org.uk est géré par la même organisation que co.uk ? Vous ne pouvez pas le savoir juste en regardant ces noms. D'autre part, les zones ne correspondent pas forcément à des frontières organisationnelles. Pendant longtemps, nom.fr était dans une zone différente de fr alors que les deux domaines étaient gérés par le même organisme, l'AFNIC. En sens inverse, le futur domaine .tel n'aura qu'une seule zone, tout en permettant aux utilisateurs de mettre leurs propres données.

Bref, la zone est une notion complexe. Notre RFC rappelle juste que les données de délégation (les enregistrements NS) ne font pas autorité dans la zone parente (section 6.1). En dehors des enregistrements indispensables à la délégation (NS et peut-être A et AAAA de colle), les serveurs ne doivent pas envoyer de données qui sont au delà d'une frontière de zone.

La section 8 corrige légèrement la définition du TTL qui se trouve section 3.6 du RFC 1034 en imposant que ce soit un entier non signé.

La section 10 s'attaque à des question plus délicates car plus visibles par l'utilisateur humain, les questions de nommage. Au contraire des règles des sections précédentes, qui ne seront guère vues que par les programmeurs qui écrivent des serveurs de noms, les règles des sections 10 et 11 concernent tous les gérants de zones DNS.

D'abord, un rappel en début de section 10 : dire que telle machine « a pour nom de domaine gandalf.example.net » est un net abus de langage. Une machine n'a pas un nom qui serait le « vrai » ou l'« authentique ». Il faut plutôt dire que des tas de noms dans le DNS peuvent pointer sur une machine donnée. Ainsi, il n'y a aucune obligation d'avoir un seul enregistrement de type PTR (section 10.2) pour une adresse IP donnée.

La section 10.1 clarifie les enregistrements de type CNAME. Leur noms peut être trompeur car il veut dire Canonical Name (« nom canonique ») alors que le CNAME sert plutôt à enregistrer des alias (section 10.1.1). Si le DNS contient :

www.example.org.    IN    CNAME    www.example.net.

il ne faut pas dire que www.example.org est le CNAME de www.example.net mais plutôt qu'il est l'alias de www.example.net ou, plus rigoureusement, qu'il existe un enregistrement de type CNAME dont le nom est www.example.org.

La section 10.2 rappelle qu'on peut avoir plusieurs enregistrements de type PTR et surtout qu'un PTR peut mener à un alias, et pas directement au nom de domaine désiré. Cette propriété est d'ailleurs à la base de la délégation sans classe de in-addr.arpa décrite dans le RFC 2317.

Par contre, les enregistrements NS et MX ne peuvent pas mener à un alias (section 10.3). Un logiciel comme Zonecheck teste d'ailleurs cela.

Enfin, la section 11 est peut-être la plus ignorée de tout le RFC. Consacrée à la syntaxe des noms de domaines, elle rappelle (c'est juste un rappel, les RFC 1034 et RFC 1035 étaient déjà clairs à ce sujet) qu'un nom de domaine peut prendre n'importe quelle valeur binaire. Si vous entendez quelqu'un dire que « le DNS est limité aux caractères ASCII » ou bien « le DNS est limité aux lettres, chiffres et tiret », vous pouvez être sûr que la personne en question est profondément ignorante du DNS. Le DNS a toujours permis de stocker n'importe quels caractères, même non-ASCII et, s'il a fallu inventer les IDN du RFC 3490, c'est pour de tout autres raisons.

La section 11 souligne juste que les applications qui utilisent le DNS peuvent avoir des restrictions. Ainsi, avant les IRI du RFC 3987, les adresses du Web étaient en effet limitées à ASCII.


Téléchargez le RFC 2181


L'article seul

RFC 5211: An Internet Transition Plan

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : J. Curran
Pour information
Première rédaction de cet article le 13 juillet 2008


Il y a déjà eu des tas de plans pour réaliser la transition depuis l'actuel IPv4 vers le futur protocole IPv6. Ce très court RFC, qui est une contribution individuelle, expose sommairement un tel plan, dont rien ne garantit qu'il sera d'avantage suivi que les autres.

Comment passer d'un Internet très majoritairement IPv4 à un Internet où IPv6 représenterait l'essentiel des adresses et du trafic, ne laissant que des îlots attardés avec l'ancien protocole ? Le problème est d'autant plus difficile que les premiers à migrer n'ont aucun intérêt à le faire puisqu'ils ne peuvent joindre personne en IPv6 ; aujourd'hui, il n'y a pratiquement aucun « gros » site Web accessible en IPv6, et ce n'est pas différent pour les autres services. Il y a peu de chances que les seules lois du marché suffisent à effectuer ce changement (voir aussi le RFC 1669).

Notre RFC décrit un plan possible, en notant bien qu'il n'est pas obligatoire. J'ajoute qu'il ne semble pas plus réaliste que les autres, qu'on trouve par exemple dans les RFC 3750 ou RFC 4057. Il part d'une prémisse optimiste, que les acteurs voudront la connectivité IPv6 pour elle-même.

L'idée est de décrire la transition en plusieurs étapes (section 2). Trois étapes sont prévues, chacune permettant de tirer d'avantage de bénéfices de la transition. Dans l'étape de Préparation (section 2.1, prévue pour durer jusqu'en décembre 2009, c'est-à-dire quasiment demain), on dote certains serveurs accessibles de l'extérieur de capacités IPv6 (sans forcément mettre IPv6 sur tous les réseaux locaux). Pour limiter les risques, ces serveurs sont accessibles avec un nom spécial, comme expliqué en section 2.1.1 (c'est ce que fait Google en ce moment où son service phare, le moteur de recherche, est accessible sous le nom http://ipv6.google.com). Notons que la grande majorité des organisations connectées à Internet n'a toujours pas commencé cette étape, prévue pour se terminer dans un an et demi. Notons aussi que cette étape ne permet pas encore d'abandonner IPv4, toute machine devant rester « double-pile » (v4 et v6).

Dans la seconde étape (section 2.2), prévue de janvier 2010 à décembre 2011, tous les serveurs ont IPv6, et on déploie IPv6 sur les réseaux internes. Idéalement, à la fin de cette étape, un accès Internet en IPv6 seul serait possible. Notons que, même si ce calendrier était respecté, il suffirait à peine à éviter l'épuisement des adresses IPv4, qui devrait survenir en 2011.

Enfin, la troisième étape (section 2.3), prévue à partir de janvier 2012, sera consacrée au démantèlement progressif des services IPv4 et à la stabilisation des services IPv6.

Évidemment, ce calendrier devrait être suivi, vu l'approche de la date où la dernière adresse IPv4 sera allouée. Mais le sera t-il ? Compte-tenu de l'actuelle situation de déni de la réalité, c'est peu probable.

Un mot en passant : ce blog n'est pas accessible en IPv6, le fournisseur d'hébergement actuel ne le proposant pas. Un tunnel existe mais il est bien trop lent et surtout trop peu fiable pour que j'annonce une adresse IPv6 dans le DNS.


Téléchargez le RFC 5211


L'article seul

L'accessibilité des sites Web, ce n'est pas uniquement pour les handicapés !

Première rédaction de cet article le 12 juillet 2008


L'accessibilité des sites Web est un sujet à la mode. De nombreux articles sont publiés, de nombreuses réunions ou colloques se tiennent, de nombreux débats ont lieu. Mais la plupart des sites Web restent très peu accessibles. Est-ce parce qu'on restreint trop souvent les utilisateurs de l'accessibilité aux handicapés ?

Le discours sur l'accessibilité est en général du type « Il faut qu'un aveugle puisse voir le site Web, il en a le droit comme les autres ». Ce discours est largement repris et jamais contesté ouvertement (personne n'osera dire, même s'il le pense, « Les aveugles nous embêtent, tant pis pour eux, je ne vais pas laisser cette minorité de perdants affadir le design de mon beau site Web tout en Flash qui bouge »). Mais ce discours a peu d'effet : la très grande majorité des sites Web ne sont pas accessibles à tous. Mise en page et contenu mélangés (par exemple par l'utilisation de tableaux (<table> HTML), contenus entièrement en Flash, profusion d'images sans texte alternatif (ou avec un attribut alt alors que l'image ne sert qu'à la décoration, ce qui est tout aussi absurde), fonctionnement impossible sans Javascript, pas de structuration des données (qui permettrait de les reprendre facilement)...

Les sites Web commerciaux, réalisés par des professionnels, ne sont pas les meilleurs, loin de là. Comme il existe bien plus de sites Web que d'auteurs Web compétents, les sites sont réalisés par des gens dont la compétence n'est pas en écriture Web mais en graphisme ou en programmation, des disciplines utiles mais différentes, et qui ne rendent pas forcément sensibles à la structuration des sites Web.

Pourquoi les sites Web ne sont-ils pas plus accessibles aujourd'hui qu'avant ? Est-ce par manque de documentation ? Non, des documents comme la référence, le Web Content Accessibility Guidelines du W3C sont souvent cités. En français, l'excellent site d'Alsacréations contient également plein d'informations utiles si le webmestre a décidé de rendre le site Web accessible.

Peut-être est-ce parce que le discours dominant réduit l'accessibilité à une préoccupation pour une minorité. On demande aux auteurs de sites Web d'être généreux, de penser aux plus faibles (une pensée très démodée dans la France de Sarkozy), alors que ces auteurs ont déjà beaucoup de travail pour boucler le projet Web à temps et que prendre en compte les besoins de 2 ou 3 % des utilisateurs ne se justifie pas financièrement.

Mais c'est un raisonnement discutable. Quittons un peu l'accessibilité numérique et voyons comment se pose le problème pour l'accessibilité physique, par exemple des bâtiments. Si on rend un bâtiment accessible à tous, par exemple en installant des rampes d'accès, des ascenseurs larges, on ne rend pas service qu'à la minorité qui est en fauteuil roulant. On aide aussi les gens chargés de paquets, les femmes avec des bébés et les jeunes cadres dynamiques qui se sont claqués un muscle au squash.

En d'autres termes, les dépenses entraînées par l'accessibilité profitent à tous et pas seulement aux handicapés qu'on essaie de culpabiliser en leur annonçant les dépenses qu'on a fait « pour eux ».

C'est la même chose avec l'accessibilité numérique. Si on rend un site Web accessible à tous, cela ne servira pas qu'aux aveugles. On aidera également les économiquement faibles qui ont un vieux navigateur sans possibilités sophistiquées, les frimeurs riches qui ont un téléphone portable avec accès EDGE (le plus cher des téléphones portables a un écran et un processeur dont les capacités sont inférieures à celles du moindre PC), les moteurs de recherche qui n'ont en général pas de capacité Javascript ou Flash, etc.

Terminons en citant le site Web de Renaissance Numérique qui dit fort justement : « Les standards d'accessibilité séparent le contenu et le contenant. Il est ainsi plus facile de maintenir un site et de le mettre à jour. Une meilleure organisation du contenu permet également de fournir un service de meilleur qualité et mieux ciblé. » et « La conformité aux standards permet de concevoir facilement des interfaces utilisateurs en fonction des supports et de leurs usages. Nous ne pouvons pas proposer la même interface sur un écran de téléphone mobile que sur un PC portable à écran 11' ou un PC de bureau avec un grand écran. »


L'article seul

Vulnérabilité du DNS rendant l'empoisonnement plus facile

Première rédaction de cet article le 9 juillet 2008
Dernière mise à jour le 22 juillet 2008


Le 8 juillet, l'avis VU#800113 du CERT a révélé publiquement une faille du protocole DNS. Cette faille permet un empoisonnement relativement facile des caches DNS.

On peut trouver un bon résumé dans l'article Fixes Released for Massive Internet Security Issue. L'attaque a été découverte par Dan Kaminsky et repose sur une vulnérabilité classique du DNS. Le résolveur DNS (serveur récursif) accepte en effet une réponse si la question posée, le Query ID (RFC 1035, section 4.1.1) et le port UDP où arrive la réponse coïncident avec une question en attente. Mais Kaminsky a découvert un mécanisme pour envoyer une fausse réponse ayant de très bonnes chances d'être acceptée. (Le mécanisme détaillé est expliqué dans un autre article.) Indépendamment de cette attaque spécifique, il faut noter que la vulnérabilité est connue depuis longtemps (voir par exemple l'article DNS and BIND Security Issues de Paul Vixie qui dit With only 16 bits worth of query ID and 16 bits worth of UDP port number, it's hard not to be predictable. A determined attacker can try all the numbers in a very short time and can use patterns derived from examination of the freely available BIND code. Even if we had a white noise generator to help randomize our numbers, it's just too easy to try them all.) C'est pour cela que certains résolveurs ne sont pas vulnérables (ils mettaient en œuvre des mécanismes de défense depuis longtemps).

Depuis le site Web de l'auteur de la découverte, on peut tester la vulnérabilité de son résolveur. Mais ledit site Web est très chargé et le code Javascript bogué. Si on veut tester via le Web, il faut mieux utiliser https://www.dns-oarc.net/oarc/services/dnsentropy. Si on préfère tester en local, une bonne solution est le script de Michael C. Toren :

%  perl noclicky-1.00.pl 192.0.2.225
Looking up zqq0wi2odh5x.toorrr.com against 192.0.2.225
Fetching http://209.200.168.66/fprint/zqq0wi2odh5x
Requests seen for zqq0wi2odh5x.toorrr.com:
  192.0.2.225:32769 TXID=2234
  192.0.2.225:32769 TXID=22512
  192.0.2.225:32769 TXID=17521
  192.0.2.225:32769 TXID=32880
  192.0.2.225:32769 TXID=40914
Your nameserver appears vulnerable; all requests came from the same port.

Aïe, cette machine est vulnérable.

Et une autre solution pour tester la vulnérabilité de son serveur récursif, ne nécessitant que le traditionnel dig, est de demander à porttest.dns-oarc.net :

%  dig +short porttest.dns-oarc.net TXT
z.y.x.w.v.u.t.s.r.q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.pt.dns-oarc.net.
"192.0.2.248 is POOR: 26 queries in 4.5 seconds from 1 ports with std dev 0.00                 "

On voit que cette machine est vulnérable : toutes les requêtes DNS sont émises depuis le même port.

Enfin, deux autres outils plus graphiques, entièrement via le Web, et que je recommande, DNS ENtropy, de l'OARC et le test de GRC.

Les logiciels peuvent diminuer leur vulnérabilité en utilisant un port source UDP aléatoire. C'est ce que font toutes les mises à jour qui viennent d'être publiées (voir par exemple communiqué de l'ISC). Le seul fait de choisir le Query ID au hasard est nécessaire mais pas suffisant (il ne fait que 16 bits de large). Certains résolveurs comme PowerDNS ou bien Unbound avaient déjà ce mécanisme et n'étaient donc pas vulnérables (pour Unbound, voir leur analyse complète et aussi celle de PowerDNS).

Attention : il ne suffit pas de faire la mise à jour du logiciel, encore faut-il tester que la configuration du serveur de noms ne force pas l'usage d'un port unique. C'est par exemple un problème possible avec BIND si le fichier named.conf contient une ligne du genre query-source port 53;. Cette ligne, qui force l'usage d'un port unique annule tout l'effet du patch correctif ! (Et c'est détecté par les tests ci-dessus.)

Les systèmes comme Debian ou Gentoo ont très vite intégré les patches et la mise à jour normale suffit donc.

On peut noter que ce patch peut perturber certains coupe-feux, qui s'étonneraient des réponses arrivant à un grand nombre de ports. Par exemple, il semble que Zone Alarm sur Windows XP proteste et qu'il faille passer son niveau de sécurité à Medium si la machine fait tourner un BIND sécurisé (voir http://www.pcinpact.com/actu/news/44747-zonealarm-windows-dns-internet-probleme.htm et http://www.zdnet.fr/actualites/informatique/0,39040745,39382271,00.htm.

Comme le rappelle le communiqué de l'ISC cité plus haut, la solution idéale est de passer à DNSSEC (RFC 4033, RFC 4034 et RFC 4035). Mais c'est une opération très lourde, nécessitant des mise à jour des logiciels, l'action des registres, celle des gérants de résolveurs, etc. Et DNSSEC apporte ses propres vulnérabilités et la complication de gestion qui est associé aux systèmes utilisant la cryptographie. Réclamer son déploiement est donc assez yakafokon.


L'article seul

RFC 5227: IPv4 Address Conflict Detection

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : Stuart Cheshire (Apple)
Chemin des normes
Première rédaction de cet article le 4 juillet 2008


Ce RFC est entièrement consacré à un problème qui a causé des cheveux blancs à beaucoup d'administrateurs de réseaux informatiques : la détection d'une duplication d'adresses IP.

Que la duplication soit un phénomène normal (cas des réseaux non gérés, ceux dont personne ne s'occupe, où il n'y a pas de liste des adresses allouées), le résultat d'une erreur humaine, ou une incivilité (« Je prends une adresse IP au hasard, on verra bien »), elle est quasiment impossible à empêcher. Une machine peut toujours émettre avec l'adresse qu'elle veut, le protocole ARP (RFC 826) ne peut fournir aucune sécurité (section 6 du RFC). Peut-on au moins la détecter ? C'est ce que propose notre RFC, après avoir expliqué (section 1) pourquoi le mécanisme proposé par le RFC 2131 n'est pas suffisant (cette section 1, comme souvent avec Stuart Cheshire, tourne d'ailleurs souvent au réglement de comptes, comme lorsque l'auteur souligne que Mac OS avait déjà résolu le problème en 1998).

Le nouveau protocole, ACD, repose sur ARP. La section 1.2 commence en listant les nouveautés. Le principe d'ACD est d'utiliser ARP, non pas pour poser sincèrement la question « Qui utilise telle adresse IP ? » mais pour détecter ceux qui répondraient à une requête pour l'adresse IP de la machine émettrice. Comme le note la section 1.2, de telles questions « orientées » sont courantes dans la vie. Si on demande au café « Est-ce que cette table est libre ? » c'est en général avec l'intention de s'y asseoir si elle l'est. De même, avec ACD, la machine qui veut vérifier l'unicité de son adresse IP, mettons 192.0.2.48 va demander à tout le monde « Qui utilise 192.0.2.48 ? » et confirmer cette adresse si personne ne réagit. ACD est utilisable sur tout réseau où ARP fonctionne.

La section 2 est la description détaillée du protocole. Lors du démarrage ou redémarrage d'une interface réseau, la machine ACD envoie une requête ARP pour sa propre adresse, avec sa propre adresse MAC comme adresse MAC source et 0.0.0.0 comme adresse IP source (section 2.1.1 : cette surprenante précaution est nécessaire pour éviter de polluer les caches ARP si quelqu'un utilise déjà cette adresse).

Après une attente suffisante (les détails se trouvent dans le RFC), si personne n'a répondu, la machine considère qu'il n'y a pas de duplication d'adresse et envoie une deuxième requête ARP, cette fois-ci avec son adresse IP en source, pour prévenir qu'elle va désormais utiliser cette adresse.

La réponse ARP est normalement acheminée en unicast mais la section 2.6 explique qu'ACD peut aussi utiliser la diffusion générale.

Et si ça va mal ? Si quelqu'un utilise cette adresse ? La section 2.4 couvre ce cas, en notant également que la détection de conflit doit être continue, puisqu'une autre machine peut arriver à tout moment en voulant utiliser la même adresse. La section détaille donc le concept de « défendre son adresse », comment et dans quelles conditions.

La section 3 contient l'explication d'un choix de conception qui fut très discuté, l'utilisation, pour tester la duplication, de requêtes ARP au lieu de réponses ARP, a priori plus adaptées. La principale raison est la crainte que certaines implémentations ne gèrent pas correctement des réponses qui n'ont été précédées d'aucune requête. Notons aussi qu'il est malheureusement rare dans les RFC de voir une discussion des choix alternatifs : la spécification est en général annoncée telle quelle, sans justification des choix, contrairement à ce que fait ce RFC.

La section 4, historique, rappelle l'ancienne technique des « ARP gratuits » (au sens de « meurtres gratuits »), qui avait été proposée par Stevens dans son TCP/IP illustrated et explique en quoi ACD est préférable (l'ARP gratuit est l'équivalent de crier « Je vais prendre cette table » sans vérifier si elle est déjà occupée).


Téléchargez le RFC 5227


L'article seul

RFC 5250: The OSPF Opaque LSA Option

Date de publication du RFC : Juillet 2008
Auteur(s) du RFC : Lou Berger (LabN), Igor Bryskin (Adva), Alex Zinin (Alcatel)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ospf
Première rédaction de cet article le 4 juillet 2008


Le protocole de routage OSPF fonctionne en distribuant de l'information sur les interfaces du routeur, informations qui sont transmises par inondation à tous les routeurs de la zone. Cette information est structurée en LSA (Link State Advertisement) et ces LSA appartiennent à différents types, les premiers ayant été décrits dans le RFC 2328. Comme tous les routeurs de la même zone (area) doivent comprendre tous ces types, ajouter un nouveau type de LSA n'est pas facile. D'où l'idée, qui avait fait l'objet du RFC 2370, de créer un type « opaque » qui pourrait stocker de l'information spécifique à une application, sans que les routeurs aient besoin de connaitre autre chose que le fait qu'il soit opaque. C'est l'objet de notre RFC, qui remplace le 2370.

Ainsi, il sera plus facile d'étendre OSPF, comme l'avaient fait les RFC 3623 ou RFC 3630. Il suffit désormais d'enregistrer un « type de LSA opaque » auprès de l'IANA. Les routeurs qui ne connaissent pas ce type passeront les LSA sans les comprendre et sans être affectés. Le RFC 5250 ne spécifie d'ailleurs pas comment utiliser les LSA opaques, cela dépend complètement de l'application envisagée (section 2).

La section 3 décrit en détail ces nouveaux LSA. Il en existe de trois types :

  • Le type OSPF 9 est réservé aux LSA opaques locaux à un segment de réseau et ne sont pas transmis aux routeurs qui sont sur d'autres segments,
  • Le type OSPF 10 sert aux LSA opaques locaux à une zone OSPF,
  • Et le type 11 est pour les LSA opaques diffusés dans tout un AS (à l'exception des zones « terminales » par exemple les NSSA du RFC 3101).

Le LSA opaque est composé d'un en-tête LSA normal (section 12.1 du RFC 2328) suivi de 32 bits d'information qui sont divisés en un sous-type de 8 bits (le registre IANA les nomme opaque LSA option types) et 24 bits pour les informations spécifiques à l'application. Ainsi, le sous-type 1 désigne l'application traffic engineering du RFC 3630, alors que le 4 est la router information du RFC 4970. Le reste du LSA contient les données (de longueur variable, voir l'annexe A.2).

La section 3.1 gouverne la diffusion de ces LSA opaques, par inondation (section 13 du RFC 2328). Un routeur sait que son voisin OSPF est capable de gérer des LSA opaques en regardant le bit O (comme Opaque, valeur 0x40) lu dans les paquets Database Description que les deux routeurs s'échangent.

Justement, la section 4 décrit les changements dans les structures de données du protocole. En raison de l'option O citée plus haut, la description d'un voisin OSPF doit avoir un champ de plus pour stocker cette information sur les capacités du voisin.

La section 5 est la grosse nouveauté par rapport au RFC 2370, qui avait normalisé le protocole à l'origine. Elle décrit la diffusion des LSA opaques entre différentes zones OSPF. Enfin, la section 7 décrit les questions de compatibilité avec les vieux routeurs qui ne mettent pas en œuvre les LSA opaques (ils les ignorent, et ne peuvent donc pas les transmettre à leurs voisins).

La plupart des mises en œuvre d'OSPF supportent ces LSA opaques. Avec Quagga, il faut s'assurer que le logiciel a été configuré avant la compilation avec --enable-opaque-lsa. Il suffit ensuite de mettre ospf opaque-lsa dans le fichier de configuration OSPF. IOS et JunOS disposent également de ces LSA opaques.


Téléchargez le RFC 5250


L'article seul

RFC 2460: Internet Protocol, Version 6 (IPv6) Specification

Date de publication du RFC : Décembre 1998
Auteur(s) du RFC : Stephen E. Deering (Cisco Systems, Inc.), Robert M. Hinden (Nokia)
Chemin des normes
Première rédaction de cet article le 1 juillet 2008


Si IPv4 est normalisé dans un seul document, le RFC 791, le candidat à sa succession IPv6 est décrit de manière plus modulaire, dans plusieurs RFC dont notre RFC 2460, essentiellement consacré au format des paquets. Il a depuis été remplacé par le RFC 8200.

Remplaçant le premier RFC sur le format des paquets IPv6, le RFC 1883, notre RFC 2460 est resté stable pendant dix-huit ans, alors que la plupart des RFC sur IPv6 ont connu des révisions ; les autres RFC importants pour IPv6 sont le RFC 4291 sur l'adressage - certainement le moins stable -, le RFC 4861 sur le protocole de découverte des voisins, le RFC 4862 sur l'autoconfiguration des adresses et le RFC 4443 sur ICMP.

À l'heure actuelle, le déploiement de ce RFC est très limité : peu de paquets IPv6 circulent sur Internet et il est loin d'avoir succédé à IPv4. Le fait d'avoir un numéro de version plus élevé ne suffit pas ! Notre RFC 2460 présente sans hésiter IPv6 comme le successeur d'IPv4, ce qui reste pour l'instant un vœu pieux.

IPv6 reprend largement le modèle qui a fait le succès d'IPv4 : un protocole de datagrammes, un routage jusqu'au prochain saut (peu ou pas de routage de bout en bout), des datagrammes acheminés « au mieux possible », un en-tête de paquet simple et où les champs sont de taille fixe. La section 1 du RFC résume les différences entre les formats de paquets IPv4 et IPv6.

La plus spectaculaire des différences est bien sûr l'augmentation de la taille des adresses. Toujours fixe (contrairement à des concurrents où les adresses étaient de tailles variables), cette taille passe de 32 à 128 bits. Le maximum théorique d'adresses (en supposant une allocation parfaite) passe donc de quatre milliards (ce qui ne permet même pas d'allouer une adresse à chaque personne sur Terre) à plus de 10^40, un nombre qui défie l'imagination.

Compte-tenu de l'épuisement rapide des adresses IPv4, cette augmentation est à elle seule une bonne raison de migrer vers IPv6. Elle reflète les changements de paradigme successifs en informatique, de « un ordinateur par entreprise » au début des années 70, lorsque IPv4 a été conçu, à « un ordinateur par département » au cours des années 80 puis à « un ordinateur par personne » avec l'explosion de la micro-informatique et à « plusieurs ordinateurs par personne » de nos jours lorsque le cadre dynamique et branché se promène avec d'avantage d'appareils électroniques sur lui que n'en portait James Bond dans ses premiers films. Les quatre milliards d'adresses d'IPv4 sont donc aujourd'hui bien insuffisantes.

Mais ce changement de format des adresses est également la faiblesse d'IPv6 : il ne permet en effet pas à des machines v4 et v6 de communiquer directement et les premiers adopteurs du nouveau protocole ne peuvent donc pas parler aux anciens, ce qui a puissamment freiné le déploiement d'IPv6.

Les autres changements apportés par IPv6 sont moins connus mais semblaient à l'époque justifier le nouveau protocole :

  • Le format de l'en-tête est simplifié, facilitant la tâche des routeurs (en pratique, IPv4 garde son avantage, la complexité de son format étant compensée par l'expérience des développeurs et la quantité de main d'œuvre qui a travaillé à optimiser les routeurs IPv4).
  • Les options sont à la fois plus libres, notamment en taille, et moins contraignantes à gérer pour les routeurs,
  • Les services d'authentification et de confidentialité ont été inclus (cet argument est souvent cité en faveur d'IPv6 mais il est largement bidon, IPv4 ayant désormais les mêmes capacités, et elles n'ont pas souvent été intégrées dans les implémentations IPv6).

La section 3 détaille le format du nouvel en-tête de paquet.

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version| Traffic Class |           Flow Label                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Payload Length        |  Next Header  |   Hop Limit   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                                                               +
   |                                                               |
   +                         Source Address                        +
   |                                                               |
   +                                                               +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                                                               +
   |                                                               |
   +                      Destination Address                      +
   |                                                               |
   +                                                               +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Contrairement aux paquets IPv4, il n'y a pas de champ « Options » de taille variable. Le champ « Version » contient évidemment le numéro 6 (il y a eu des protocoles ayant reçu le numéro 5 ou 7 mais ils n'ont jamais été déployés). Le champ DSCP, ex-TOS, d'IPv4 est remplacé par les champs Traffic class et Flow label qui semblent très peu utilisés en pratique (sections 6 et 7 du RFC, ainsi que l'annexe A ; le flow label a été ensuite mieux normalisé dans le RFC 6437).

Le champ Next header indique le type de l'en-tête suivant. La plupart du temps, c'est l'en-tête d'un protocole de transport comme TCP (numéro 6) ou DCCP (numéro 33), dont les numéros sont stockés dans un registre IANA. Mais cela peut être aussi un en-tête d'extension de la couche réseau par exemple 44 pour les fragments (ces numéros sont stockés dans le même registre IANA). Notez que, depuis, le RFC 6564 a modifié les règles pour les futurs en-têtes, imposant un format commun. (Pour analyser les paquets IPv6, voir mon article « Analyser les en-têtes IPv6 avec pcap ».)

Vu avec tshark, la version texte de l'analyseur Wireshark, et son option -V, voici un paquet IPv6 contenant lui-même du TCP :

Internet Protocol Version 6
    0110 .... = Version: 6
        [0110 .... = This field makes the filter "ip.version == 6" possible: 6]
    .... 0000 0000 .... .... .... .... .... = Traffic class: 0x00000000
    .... .... .... 0000 0000 0000 0000 0000 = Flowlabel: 0x00000000
    Payload length: 40
    Next header: TCP (0x06)
    Hop limit: 64
    Source: 2a01:e35:8bd9:8bb0:21e:8cff:fe76:29b6 (2a01:e35:8bd9:8bb0:21e:8cff:fe76:29b6)
    Destination: 2a01:e35:8bd9:8bb0:21c:23ff:fe00:6b7f (2a01:e35:8bd9:8bb0:21c:23ff:fe00:6b7f)

La section 4 présente les en-têtes d'extension. Grande nouveauté d'IPv6, ils sont situés entre l'en-tête IP normal et l'en-tête de la couche transport. La plupart d'entre eux sont ignorés par les routeurs situés sur le trajet et traités seulement à l'arrivée (alors qu'un routeur IPv4 devait, en théorie, toujours examiner les options). Notre RFC normalise certaines de ces extensions, mais d'autres peuvent être ajoutées par des RFC ultérieurs comme par exemple le RFC 3775 qui normalise le Mobility Header (numéro 135, section 6.1 du RFC).

C'est ainsi que la section 4.3 décrit l'en-tête d'extension « Hop-by-hop », une de celles qui doivent être examinées par tous les routeurs sur le trajet. Elle contient des options (décrites en section 4.2), qui sont stockées sous forme de tuples TLV. Le type de chaque option indique, dans ses deux premiers bits, si l'option peut être ignorée ou non.

Le symétrique de cet en-tête est le « Destination », section 4.6, qui stocke, de la même façon, les options qui ne doivent être traitées que par le destinataire. (Pour mettre un tel en-tête dans vos paquets, voir mon article.)

La section 4.4 décrit l'en-tête « Routing » qui permet d'indiquer la route qu'on souhaite voir le paquet prendre, ou bien d'enregistrer la route effectivement suivie. Notons qu'un champ, le « Routing Type », indique le type de routage souhaité et que sa valeur 0 ne doit plus être utilisée : en raison de problèmes de sécurité serieux, le Type 0 Routing Header a été abandonné dans le RFC 5095.

La section 4.5 décrit l'en-tête « Fragment » qui permet de représenter des paquets IP qui, trop longs, ont été fragmentés par l'émetteur (contrairement à IPv4, les routeurs IPv6 n'ont pas le droit de fragmenter).

La section 5 décrit les questions liées à la taille des paquets. IPv6 impose une MTU minimale de 1280 octets et, en théorie, une machine qu n'enverrait que des paquets de cette taille (ou plus petits) n'aurait jamais de problème. Au delà, on doit utiliser la découverte de la MTU du chemin, spécifiée dans le RFC 1981 mais dont le moins qu'on puisse dire est qu'elle n'est pas très fiable (cf. RFC 4821).

Les différences avec le RFC 1883 sont décrites après la bibliographie. Elles sont en général de peu d'importance. Par exemple, la MTU minimale passe à 1280 octets (après des débats enfiévrés, à une époque où LocalTalk était une technologie assez courante, le RFC 1883 utilisait 576 octets). Outre changement, la possibilité d'envoyer des très grands paquets, les jumbograms, a disparu du RFC de base et figure désormais dans un RFC dédié, le RFC 2675. Le RFC 8200, qui a remplacé notre RFC, n'a pas apporté de changements cruciaux.


Téléchargez le RFC 2460


L'article seul

RFC 5248: A Registry for SMTP Enhanced Mail System Status Codes

Date de publication du RFC : Juin 2008
Auteur(s) du RFC : T. Hansen (AT&T Laboratories), J. Klensin
Première rédaction de cet article le 1 juillet 2008


Le protocole SMTP de transport du courrier électronique, normalisé dans le RFC 5321, prévoit depuis le RFC 3463 des codes d'erreur à trois nombres très détaillés. Mais il n'existait pas de registre de ces codes et des doublons commençaient à apparaître. Ce RFC spécifie donc un registre des codes de retour SMTP, où tout le monde pourra vérifier que 4.3.1 signifie « Mail system full ».

Parmi les scénarios que résolvent ces codes de retour figure celui de l'internationalisation. SMTP est asynchrone et indirect. L'expéditeur du message n'a pas de contact direct avec les serveurs SMTP sur le trajet. Cela rend donc difficile des problèmes comme celui de la génération de messages d'erreur dans la langue de l'expéditeur. Actuellement, le serveur SMTP typique génère des messages d'erreur dans sa langue à lui (en général de l'anglais), pas dans celle de l'expéditeur qui va le recevoir. Plusieurs approches complémentaires ont été tentées pour résoudre ce problème, celle permise par notre RFC 5248 étant d'envoyer un code de statut numérique, que le MUA de l'expéditeur aura la charge de traduire. Ainsi, recevant « 5.2.2 - User's mailbox is too large - over ten gigabytes », le MUA pourra afficher « Pas assez de place dans la boîte aux lettres du destinataire » (et ignorer les détails en anglais).

Les codes SMTP (RFC 5321, section 4.2.1) originaux, dits « de base » sont composés de trois chiffres écrits sans séparateur (par exemple 554 pour Transaction failed). Les codes « améliorés » du RFC 3463 comportent, eux, trois nombres, la classe (2 : tout va bien, 4 : erreur temporaire, 5 : erreur définitive, etc), le second le sujet (6 : problème avec le contenu du message, 7 : problème avec la politique de sécurité, etc) et le troisième le détail. Ils s'écrivent avec un point comme séparateur. Ainsi, 5.5.2 signifie « Commande non reconnue » (erreur de classe 5, permanente, puisque le serveur SMTP ne va pas spontanément accepter de nouvelles commandes, erreur de sujet 5, problème de protocole). Dans cette session SMTP, on voit le code de base, 502 et le code amélioré 5.5.2 :

% telnet MYSERVER smtp
220 myserver.example.com ESMTP Postfix (Ubuntu)
XMPA <me@foobarfr>
502 5.5.2 Error: command not recognized

Dans ce cas précis, le gain apporté par les codes améliorés est faible, le code de base était déjà suffisamment spécifique. Mais, dans le futur, des codes améliorés supplémentaires pourront être enregistrés (comme ce fut le cas pour ceux du RFC 7372). Ainsi, il n'y a pas actuellement de code pour le greylisting (RFC 6647, notamment la section 5)) et les serveurs SMTP renvoient donc un code générique :

RCPT TO:<foobar@langtag.net>
450 4.7.1 <foobar@langtag.net>: Recipient address rejected: Greylisted by greyfix 0.3.2,\
    try again in 3480 seconds.\
    See http://projects.puremagic.com/greylisting/ for more information.

Un futur RFC pourra donc créer un code pour cette utile technique anti-spam.

Notre RFC demande donc à l'IANA (section 2) de créer un registre, le SMTP Enhanced Status Codes, précisant les codes et leur signification.

Ce registre, dit la section 2.3, sera rempli, en suivant les règles du RFC 5226, selon la règle « Specification required » qui impose l'existence d'un texte écrit (pas forcément un RFC). La section 2.4 décrit les valeurs initiales contenues dans ce registre.


Téléchargez le RFC 5248


L'article seul

Le support de Free, une source de distractions sémantiques

Première rédaction de cet article le 29 juin 2008


Le FAI Free est réputé pour la qualité très approximative de son service : pannes fréquentes, support totalement incompétent et payant (y compris le temps d'attente, si on appelle depuis un autre réseau téléphonique, ce qui est évidemment toujours le cas lorsqu'il y a une panne), etc. Cette réputation est-elle justifiée ? Le support, en tout cas, est à la hauteur de son image.

La dernière question que j'ai posée au support par courrier électronique était : « Y a t-il un moyen de dire à la Freebox (configurée en routeur + serveur DHCP) de distribuer comme serveur DNS non pas sa propre adresse mais des adresses IP de serveur que je choisis ? » Et la réponse, qui a mis pas moins de trois jours pleins à arriver, est « Si vous désirez configurer un réseau wifi, il vous faut vous rendre dans la rubrique "Fonctionnalités Optionnelles" de l'interface personnalisée de votre compte utilisateur à l'adresse suivante (http://subscribe.free.fr/login/). Ensuite veuillez cliquez sue le lien: "internet" puis : "Configurer mon routeur Freebox" Ensuite veuillez activer le mode routeur et le mode DHCP ensuite veuillez sortir et cliquer de nouveau sur "internet" puis sur la partie guache de la page vous trouverez le lien :"Personnaliser mon reverse DNS" ou vous pouvez distribuer les adresses que vous choisissez. » D'où sort le Wifi ? Et, d'une manière générale, quel rapport avec ma question ?

On voit que la rumeur fréquente selon laquelle le support de Free serait assuré entièrement par des logiciels, type Eliza, est une pure calomnie. Un robot ne mettrait pas trois jours à répondre et lirait probablement mon message, sans inventer n'importe quoi comme ce Wifi mystérieusement apparu. La réalité est plutôt que le support est assuré par des gens incompétents, sous-payés et méprisés, et que la qualité est à l'avenant. Compte-tenu du marché de l'emploi, on se doute bien que quelqu'un qui aurait, ne serait-ce qu'un Bac+2 en informatique ne ferait pas le support de premier niveau...


L'article seul

Pourquoi avoir développé IDNA au lieu d'utiliser directement l'Unicode dans le DNS ?

Première rédaction de cet article le 29 juin 2008


On voit souvent des questions du genre « Pourquoi la norme actuelle sur les noms de domaine internationalisés, IDNA (RFC 5890), utilise t-elle un encodage en ASCII (le Punycode du RFC 3492), plutôt que d'utiliser directement Unicode dans le DNS ? ». Cet article tente de répondre à cette question.

Actuellement, la norme pour les noms de domaine internationaux, IDNA (pour Internationalized Domain Names in Applications), prévoit que le nom de domaine en Unicode, par exemple Ὅμηρος.gr, va être traduit dans un sous-ensemble d'ASCII, ici en xn--sxajkhl1633b.gr (le TLD grec n'est pas encore traduit). C'est ce nom en ASCII qui sera mis dans les fichiers de zone et qui circulera entre serveurs DNS. Pourquoi avoir introduit ce système ? Pourquoi ne pas avoir permis directement l'Unicode dans le DNS ?

On lit parfois que c'est parce que le DNS ne permettrait qu'ASCII. C'est totalement faux. Celui qui écrit ça montre qu'il ne connait pas le sujet. Le DNS a en effet toujours permis n'importe quel contenu, bien au delà d'ASCII. Le RFC 2181, dans sa section 11, a bien enfoncé le clou en rappelant que tout caractère est légal dans le DNS.

Le premier problème à l'utilisation d'Unicode ne vient pas du DNS mais des applications qui gèrent des noms de machines et pour lesquelles la règle (RFC 1123, section 2.1) est en effet bien plus restrictive. Cette règle est connue sous le nom de LDH (pour Letters-Digits-Hyphen, cette règle limite en effet les noms de machine aux lettres, chiffres et au tiret).

Comme on enregistre en général un nom de domaine pour y mettre des noms de machine, la plupart des registres ont intégré cette règle et ne permettent que des noms de domaines LDH. Par exemple, les règles d'enregistrement dans ".fr" disent « Sont admis à titre de noms de domaine les termes alphanumériques constitués de lettres de l'alphabet français [sic] A à Z et de chiffres de 0 à 9 et du tiret - ». Mais c'est une politique des registres, pas une limitation du DNS.

Changer cette règle nécessiterait de modifier beaucoup de logiciels, tous ceux qui manipulent des noms de machine.

Mais il existe un second problème, plus subtil. Le DNS ne permet pas de recherches floues. Soit le nom correspond parfaitement à un nom dans la base, soit le serveur renvoie le code NXDOMAIN (No Such Domain). Comme c'est un peu dur pour les utilisateurs, une canonicalisation (ou normalisation) est prévue, actuellement uniquement l'insensibilité à la casse. Cette canonicalisation rend le DNS un peu plus agréable à l'utilisateur, qui serait certainement dérouté s'il fallait taper exactement le bon caractère, et que CHOCOLAT.fr soit différent de chocolat.fr.

Elle suffit pour ASCII. Pour Unicode, elle ne serait pas réaliste car Unicode offre d'autres possibilités. Ainsi, « thé » peut s'écrire en Unicode avec trois caractères, U+0074, U+0068, et U+00E9 (le dernier identifiant le « e avec accent aigu ») ou bien avec quatre, U+0074, U+0068, U+0065, et U+0301, le dernier étant l'accent aigu combinant. Pour la plupart des lecteurs, ces deux chaînes de caractères sont « identiques ». Pour un logiciel, elles ne le sont pas. Seule une canonicalisation permet une comparaison « raisonnable » de ces deux chaînes. Ainsi, NFC, un des algorithmes standard de canonicalisation d'Unicode, ne laisserait que la première forme, celle à trois caractères.

Il faudrait donc, si on déploie un jour un hypothétique « DNSv2 » (100 % Unicode), mettre NFC (ou un de ses équivalents) dans tous les serveurs de noms... Cet algorithme est compliqué, nécessite des tables (alors que, en ASCII, on peut passer des majuscules ou minuscules sans tables, uniquement en ajoutant ou retirant 32), a des points obscurs (notamment si le caractère Unicode n'est pas affecté)... Peu d'auteurs de serveurs de noms envisagent de l'inclure dans leur code.

Cette seconde raison est la principale. Même si on choisissait une approche « table rase » et qu'on fasse DNSv2 en partant de zéro, en ignorant l'existant, il faudrait résoudre ce problème de canonicalisation (voir le RFC 5198 pour une façon de le traiter).


L'article seul

Utiliser son câblage téléphonique existant avec une Freebox en dégroupage total

Première rédaction de cet article le 27 juin 2008


Les abonnés au FAI Free en dégroupage total bénéficient d'un service téléphonique permettant de connecter des téléphones ordinaires à une prise de la Freebox. Mais ce service est très limité, notamment parce que, par défaut, il ne permet pas de réutiliser le câblage téléphonique existant dans la maison, et impose de poser le téléphone juste à côté de la Freebox (qui n'est pas forcément située dans un endroit pratique, elle est en général là où arrive la ligne). Quelles sont les solutions ?

Dans mon appartement, j'ai déjà câblage téléphonique pré-installé et prises, qui datent du temps de France Télécom, et qui marchent. Dommage de devoir les abandonner. C'est pourtant la solution la plus souvent proposée :

  • Utilisation d'un téléphone SIP connecté en IP via le Wifi ou le CPL.
  • Pose d'une base DECT près de la Freebox et du téléphone à la distance qu'on veut (si la Freebox est dans une chambre, ce qui est mon cas, il faut penser à couper la sonnerie sur la base).

Mais pourquoi la Freebox ne peut-elle activer le câblage existant ? Garfield le Chat explique :

« Une ligne téléphonique fonctionne avec deux fils (un joli schéma et une documentation complète sont disponibles en Utilisation du filtre gigogne (livré par les Fai) en filtre de tête ainsi qu'en http://goctruc.free.fr/Telephonie/Telephonie.html).

La plupart des pré-câblages réalisés en appartement sont prévus sur 4 fils (deux lignes possibles).

Le truc est d'utiliser la paire 2 pour l'arrivée FT (initialement cablée sur la paire 1 bien sûr), brancher la Freebox sur cette paire 2 (un dédoubleur de ligne - que j'ai à la maison - suffit), et de réinjecter sur la paire 1 (qui est disponible et libre) le signal sorti de la prise RJ-11 téléphone de la Freebox.

Du coup, toutes les prises de la maison deviennent potentiellement des points d'accès à des téléphones fixes (sans besoin de filtre ADSL bien sur) ou des bases DECT auto-alimentées (c'est mieux).

Mais je privilégie quand même une bonne base DECT (Siemens) avec autant de combinés que nécessaire et tant pis pour le pré-câblage.

Il faut savoir que l'énergie qui peut être transmise par la Freebox au(x) téléphones est limitée et qu'en outre la Freebox se calibre (au redémarrage) sur le (seul) téléhpone qui est censé être branché dessus.

Attention : une erreur de câblage et pssschittt la Freebox. Le 48 volts ca ne pardonne pas. »

Bref, c'est faisable mais pas juste en claquant des doigts.

Une autre façon de décrire la même approche est donnée par un contributeur anonyme :

« Tu mets un doubleur de prise téléphonique sur chacune de tes prises T murales (c'est un gros machin un peu moche qui sépare une prise T en deux prises T).

Sur la prise 1 (principale) tu connectes l'arrivée ADSL de la Freebox, comme en direct sur la prise 2, tu réinjectes la sortie téléphonique de la Freebox, et sur chacune des prises 2 dans ta maison tu as récupéré une ligne téléphonique... »

Coyote Errant nuance : « Ce principe n'est vrai que si l'installation intérieure est câblée standard, c'est-à-dire avec au moins deux paires : à vérifier avant d'acheter les doubleurs. »

Le doubleur semble disponible aux alentours de dix euros.

Voilà, pour l'instant, je ne me suis pas encore lancé mais déjà, c'est documenté :-)

Merci à Garfield le Chat, à Christian Thomas, à Era, à Coyote Errant, à Hcx, à JKB et aux autres.


L'article seul

PowerDNS permet de modifier facilement les réponses DNS

Première rédaction de cet article le 27 juin 2008


Le serveur DNS récursif PowerDNS permet, depuis la version 3.1.7, de modifier facilement les réponses DNS, par exemple pour filtrer du contenu indésirable ou bien pour transformer les réponses « Domaine inexistant » en une réponse pointant vers un site Web d'aide. C'est, je crois, le premier récurseur à permettre cela, via une interface claire et bien documentée.

Il existe une forte demande de « réécriture » des réponses DNS. Par exemple, la justice peut imposer à un FAI de filtrer tel ou tel site illégal. Ou bien un FAI peut vouloir mentir à ses clients en les dirigeant vers une page Web avec des publicités dès que ces clients font une faute de frappe et que le nom de domaine n'existe pas. Ces demandes étaient jusqu'à présent satisfaites en modifiant le source du résolveur (par exemple BIND), ou bien en programmant de zéro avec des bibliothèques comme Net::DNS en Perl.

Désormais, avec l'annonce de la version 3.1.7 de PowerDNS, cette réécriture est démocratisée. Le serveur récursif PowerDNS appelle une fonction écrite en Lua avant de renvoyer la réponse et cette fonction peut modifier ladite réponse. Changer une valeur est désormais aussi simple que d'écrire un script Lua comme :

function nxdomain  ( ip, domain, qtype )
       if qtype ~= pdns.A then return -1, {} end  --  only A records
       if not string.find(domain, "^www%.") then return -1, {} end  -- only things that start with www.
       ret={}
       ret[1]={qtype=pdns.CNAME, content="www.example.com", ttl=3602}
       ret[2]={qname="www.example.com", qtype=pdns.A, content="192.0.2.4", ttl=3602}
       return 0, ret
end

Les notes de cette version parlent de l'utilité de ce service pour des « réécritures responsables ». Mais c'est là que le bât blesse. Certes, PowerDNS n'est qu'un outil, il n'est pas responsable des mauvaises utilisations qui ne manqueront pas d'être faites. Certes, il existe des utilisations légitimes d'un tel système (comme le filtrage des publicités grâce au script en http://www.fredan.org/nomoreads_pdns-recursor.tar). Certes, si un serveur récursif est utilisé par une seule personne, elle a tout à fait le droit de modifier les réponses comme elle veut.

Mais la demande de réécriture des réponses DNS vient surtout de ceux qui veulent tromper leurs utilisateurs. Le cas le plus fréquent est celui de FAI peu scrupuleux qui renvoient, à la place du NXDOMAIN (No Such Domain, nom non trouvé) l'adresse IP d'un de leurs serveurs Web, avec la publicité qui va avec.

Ces pratiques ont été critiquées dans le RFC 4924, section 2.5.2. Mais il faudra plus qu'un RFC pour les faire cesser ! En attendant, il est dangereux de donner de tels outils à ceux qui n'hésitent pas à envoyer de fausses réponses à leurs propres clients.


L'article seul

RFC 5210: A Source Address Validation Architecture (SAVA) Testbed and Deployment Experience

Date de publication du RFC : Juin 2008
Auteur(s) du RFC : J. Wu (Université de Tsinghua), J. Bi (Université de Tsinghua), X. Li (Université de Tsinghua), G. Ren (Université de Tsinghua), K. Xu (Université de Tsinghua), M. Williams (Juniper)
Expérimental
Première rédaction de cet article le 26 juin 2008


On le sait, l'Internet ne dispose pas de moyen de garantir l'authenticité de l'adresse IP de l'expéditeur d'un paquet. Le projet SAVA (Source Address VAlidation, il ne semble pas avoir de page Web mais il existe une liste de diffusion) vise à explorer les moyens de valider les adresses IP source. Il est actuellement à un stade très préliminaire mais une première expérience en vraie grandeur a été tentée en Chine et ce RFC la documente.

Si l'Internet n'authentifie pas les adresses IP, ce n'est pas, comme on le lit souvent, parce que ses concepteurs étaient naïfs, trop confiants dans la nature humaine, ou bien parce qu'ils étaient distraits et avaient oublié cette fonction. C'est parce que le problème est très difficile dans un réseau ouvert comme l'Internet. Si les réseaux X.25 vérifiaient les numéros des appelants, c'est simplement parce qu'il n'existait qu'un petit groupe d'opérateurs (seulement deux aux États-Unis et un seul en France) et que leurs clients devaient passer par un opérateur (pas de connexion directe). C'est aussi parce que ce petit groupe fermé d'opérateurs était uniquement situés dans les pays de l'OCDE. Dans l'Internet d'aujourd'hui, si une université thaïlandaise vérifie les adresses IP des machines de ses étudiants, par quelque moyen que ce soit, pourquoi un site gouvernemental brésilien, situé à plusieurs AS de là en tiendrait-il compte ?

(Il faut également mentionner les cas où il n'est même pas évident de savoir qui est le titulaire légitime d'une adresse, comme ce fut le cas lors du récent problème avec le serveur racine L.)

Plusieurs tentatives d'authentifier les adresses IP ont déjà eu lieu. Les documents les plus souvent cités sur ce travail sont les RFC 2827 et RFC 3704. Si tous les opérateurs appliquaient ces RFC et qu'on pouvait avoir confiance en tout le monde, le problème de l'usurpation d'adresses IP disparaitrait. Comme ce n'est pas le cas, le projet SAVA aborde le problème différemment.

SAVA est à la fois plus ambitieux (puisqu'il vise à permettre l'authentification de toute adresse IP partout dans le monde) et plus modeste, puisqu'il est bâti sur le prémisse que tout le monde n'adoptera pas SAVA (en tout cas, pas imémdiatement), et que peu d'opérateurs en déploieront immédiatement toutes les composantes et qu'il faut donc qu'il y aie des bénéfices même pour les premiers adoptants (ce qui manque au RFC 2827).

Le principe de SAVA est que chacun vérifie ce qu'il peut (il n'y a pas obligation de vérifier chaque adresse IP, une vérification du préfixe est déjà appréciable) et qu'il le communique à ceux qui le veulent. Selon les relations de confiance entre opérateurs, ces informations se propageront plus ou moins loin.

Le réseau chinois de la recherche et de l'enseignement CRNET a décidé de monter un test en grandeur nature de SAVA, dans son état actuel (SAVA n'est pas du tout normalisé, pour des raisons à la fois techniques et politiques.) Ce RFC est le compte-rendu de cette expérience. Douze sites ont participé à l'expérience, qui n'était donc pas une simple petite manipulation de laboratoire.

La section 2 du RFC résume les principes de SAVA, notamment le caractère « multi-barrières » (les vérifications peuvent se faire à divers endroits, puisqu'il n'est pas réaliste de les imposer, on aura donc toujours des cas où l'autre n'aura pas validé les adresses). Autre règle de SAVA : le fait que plusieurs mécanismes de vérification peuvent coexister. Non seulement il ne serait pas réaliste techniquement d'utiliser le même mécanisme pour un réseau Wifi et pour un réseau national, mais cette souplesse dans le choix des techniques de validation permet de maximiser le nombre de participants. SAVA se veut donc plus réaliste que les incantations habituelles « Il faudrait que tout le monde mette en œuvre le RFC 2827 ». Actuellement, dans SAVA, les vérifications peuvent se faire dans le réseau local, à l'intérieur de l'AS (c'est la seule possibilité dans le RFC 2827) ou bien entre AS. Autant que possible, SAVA réutilise des techniques existantes.

Les sections suivantes du RFC détaillent ces trois possibilités. La 2.2 explore les moyens de vérifier les adresses IP sur le réseau local, par exemple en ayant un commutateur qui interagisse avec le protocole d'allocation d'adresses IP. Aujourd'hui, le commutateur Ethernet est typiquement ignorant des allocations faites, par exemple avec DHCP et ne peut donc pas vérifier les adresses. Si ce commutateur jouait un rôle dans DHCP, il connaitrait les adresses IP qui peuvent apparaitre sur chaque port physique et pourrait les valider (cette technique se répand depuis : RFC 7513).

La section 2.3 traite la validation à l'intérieur de l'AS en recommandant simplement l'usage des techniques du RFC 2827 et RFC 3704.

Et les sections 2.4 et 2.5 traitent de la validation des adresses IP entre deux AS. 2.4 s'occupe du cas où les deux AS sont directement connectés. Dans ce cas, le problème est bien connu, chaque AS doit n'accepter de son voisin qu'un jeu limité de préfixes, enregistré dans un registre comme les IRR. Notons que l'expérience du détournement de YouTube par Pakistan Telecom a bien montré que cette pratique restait minoritaire, en partie parce que les IRR sont de qualité médiocre et en partie parce qu'elle impose un travail supplémentaire à tous. Certes, cette affaire portait sur le non-filtrage des annonces BGP et pas sur le non-filtrage des adresses IP mais rien ne permet de penser que le second filtrage sera fait plus sérieusement que le premier.

Plus délicat techniquement est le cas où les deux AS ne sont pas connectés directement. La solution préconisée par SAVA (sections 2.5 et 5.3) est alors l'utilisation d'un en-tête IPv6 spécial (l'expérience a été faite dans un environnement purement v6, ces en-têtes sont décrits da