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.
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.
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).
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.
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 :
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.
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 ».
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).
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ébogage 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.
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:
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).
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.
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.
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) :
STARTTLS
(RFC 2817) qui permet de
transmettre le nom du serveur avant 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.
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 :
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 8981. 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) :
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.
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>
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 8721 et RFC 5378) mais de manière incomplète.
Première rédaction de cet article le 30 novembre 2008
Dernière mise à jour le 2 octobre 2023
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@nic.fr
(Accessible en IPv6 et accepte TLS.)ping@stamper.itconsult.co.uk
(analyse
SPF et
DKIM, 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.)check-auth@verifier.port25.com
ping@zici.fr
(mais seulement IPv4, et sans
TLS), il y a une
documentation et le code.test@doesnotwork.eu
(IPv6
seulement, à n'utiliser que si vous pouvez
envoyer et recevoir du courrier en IPv6, il teste réception et envoi, et vous envoie donc
deux confirmations.)ping@tools.mxtoolbox.com
(la réponse est en
deux parties, texte et HTML et la partie texte
est du n'importe quoi, il faut regarder
la partie HTML, ou passer par
le site Web ;
sinon, tests SPF, DKIM et DMARC).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).https://www.mailgenius.com/
, https://aboutmy.email/
ou avec https://scanmy.email/
.Certains 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
.
Une liste alternative de tels services (entre autres) :
.https://www.sweego.io/fr/canal/email/liste-doutils-gratuits-en-ligne-pour-tester-ses-emails
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
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.
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).
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ébogage 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, technique
désormais abandonnée). Ainsi, à l'heure
actuelle, la plupart des zones signées sont délégués depuis le registre DLV de l'ISC, ce qui n'est
plus le cas depuis. (Cf. RFC 8749.)
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ébogage 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ébogage du texte et à Mark Andrews pour ses exemples de déboguage sur la liste bind-users.
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.
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 9063).
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...
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.
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.
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
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.
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...
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, davantage 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.
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 :
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ésout 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 :
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.
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.
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.
Voyons maintenant les détails pratiques, très bien expliqués en http://therowes.net/~greg/2008/01/08/creating-a-certificate-with-multiple-hostnames/
ou en http://www.hsc.fr/ressources/breves/ssl_virtualhosts.html.fr
.
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ésout 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.
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à davantage 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.
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 8721.
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 davantage 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 davantage 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).
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 ? (Il a depuis été remplacé par le RFC 8721.)
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 :
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.
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 ? »
Lire l'article promotionnel.
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>
où <& 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>
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.)
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 :
Ce qui nécessite des adaptations :
Ce que je n'ai même pas essayé :
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).
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.
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.
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).
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 :
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...
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 :
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.)
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 :
J'ai rassemblé quelques ressources Web sur ce thème en http://del.icio.us/bortzmeyer/dataportability
.
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. (Ce RCF a depuis été remplacé par le RFC 8489, qui est désormais la norme STUN.)
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ésout 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 ».
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 »). Notez enfin que le RFC actuel sur STUN est, depuis février 2020, le RFC 8489.
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.)
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ésout 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
.
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.
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 :
Depuis la sortie de ce RFC, le RFC 7857 a apporté quelques compléments.
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.
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 :
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).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.
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 ».
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).
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) :
*.DOMAINE.example
,DOMAINE.example
,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'])
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.
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.
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 :
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.
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 :
From:
,
Sender:
et Reply-To:
,
section 3.6.2.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ébogage 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.
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ébogage, 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ébogage, 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.
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 :
ASAP_REGISTRATION
, section
2.2.1),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.
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 :
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 :
À 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.
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/
.
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 (♀)...
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.
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.
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 :
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 :
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).
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é.
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.
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 dus à 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).
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.
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.
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.
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évélations</title> <para>Nous avons mê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.
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.)
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 :
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.
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.
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.
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é :
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 !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).
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.
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 davantage 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.
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.
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.
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...
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.
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. (Elle a depuis été assez sérieusement révisée et améliorée dans le RFC 8981.)
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 davantage contre le « flicage », elles ont aussi des inconvénients comme de rendre le débogage 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. En revanche, les changements ont été davantage prononcés avec la mise à jour suivante de cette technique, dans le RFC 8981.
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.
Première rédaction de cet article le 25 août 2008
Dernière mise à jour le 18 mai 2020
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...
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. (Depuis, la version 1.3, très différente, a été normalisée dans le RFC 8446.)
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 :
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.
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 :
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.
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 davantage 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.
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 :
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 :
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 :
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.
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.
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 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).
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 :
É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.
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 :
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 davantage 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 :
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...
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.
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ébogage (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.
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.
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.
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ésout é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
où
::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.
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.
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.
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 davantage 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
). 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).http://ipv6.google.com
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.
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. »
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.)
Ces méthodes sont décrites dans un Internet-Draft nommé Measures for making DNS more resilient against forged answers.
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.
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 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.
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).
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 davantage 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 :
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.
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.
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).
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...
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.
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 :
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.
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 dans le RFC 2460, section 4.3), le authentication tag. Signé cryptographiquement, cet en-tête permet de s'assurer que les routeurs des AS intermédiaires n'ont pas « bricolé » les adresses.
Après ces principes, la section 3 décrit l'expérience effective. La Chine a changé depuis « Tintin et le lotus bleu ». Le réseau CNG1-CERNET2, utilisé pour le test, connecte vingt-cinq sites, répartis dans tout le pays, à des débits allant jusqu'à 10 Gb/s. Il comprend plusieurs AS et est purement IPv6. L'expérience n'a utilisé qu'une moitié de ces sites, mais a mis en œuvre les trois scénarios de validation décrits en section 2. Les douze sites participants n'ont pas tous déployé ces trois scénarios, ce qui permet de tester SAVA dans le cas (réaliste) où tout le monde n'est pas au même niveau de déploiement.
La section 4 présente les résultats de l'expérience et proclame qu'elle fut un succès. Les paquets usurpateurs injectés dans le réseau, ont été tous jetés tôt ou tard. Les performances n'ont pas toujours été au rendez-vous, par exemple le routeur IPv6 routait toutes les extensions hop-by-hop en logiciel, donc à des performances catastrophiques pour des liaisons si rapides.
Cela ne veut pas dire que SAVA, tel que déployé dans le banc de test, soit parfait. La section 5 détaille ses limites et devrait être lue par tous ceux qui s'indignent bruyamment que l'Internet ne leur offre pas encore le niveau de traçabilité qu'ils réclament. D'abord, il faut noter qu'il y a belle lurette que la majorité des attaques sur Internet ne sont plus effectuées en trichant sur l'adresse IP. Les zombies ne se soucient en effet pas de déguiser leur adresse. D'autre part, même si SAVA peut commencer localement, une validation de bout en bout nécessitera en général la coordination de plusieurs AS, chose très difficile à obtenir. Enfin, la section 5 note que des techniques comme le multihoming ou la mobilité compliquent encore les choses.
Reste à savoir ce que deviendra SAVA. La section 6 propose une synthèse en affirmant que l'expérience a été un succès mais que le protocole doit être considérablement amélioré. Le cadre général et les protocoles ne sont pas encore normalisés et l'IETF n'a pas encore accepté un groupe de travail pour le faire (un groupe de travail avec une charte plus restreinte, SAVI, a été proposé mais pas encore accepté), SAVA soulevant bien des problèmes, notamment politiques. Ce n'est pas par hasard que la première expérimentation de SAVA sur le terrain aie eu lieu dans un pays gouverné par une dictature. Dans les couloirs de l'IETF, on entend souvent des protestations contre une technique qui rendrait la tâche des policiers chinois plus facile.
Date de publication du RFC : Février 2005
Auteur(s) du RFC : K. Zeilenga (OpenLDAP Foundation)
Chemin des normes
Première rédaction de cet article le 20 juin 2008
Beaucoup de protocoles Internet ont besoin de comparer des noms, par exemple pour tester leur égalité avant une authentification de ce nom. Si les noms sont en Unicode, il est préférable de les normaliser avant la comparaison, pour que le résultat de celle-ci ne soit pas trop déroutant pour l'utilisateur. C'est le but de SASLprep, normalisé dans ce RFC.
Le RFC sur SASLprep est très court car SASLprep est juste un profil de stringprep (normalisé dans le RFC 3454). Stringprep était l'algorithme général de normalisation des noms à l'IETF. Il ne spécifiait pas tous les détails de la normalisation effectuée, laissant ceux-ci à des profils comme nameprep (RFC 3491, utilisé dans les IDN) ou bien notre SASLprep. Stringprep ayant depuis été abandonné (cf. RFC 7564), ce RFC 4013 a été remplacé par le nouveau mécanisme du RFC 7613.
SASLprep est conçu pour l'utilisation dans le contexte de l'authentification, notamment pour SASL (RFC 4422). L'idée est de passer les noms et les mots de passe à travers SASLprep avant toute comparaison, pour que le résultat de celle-ci corresponde aux attentes de l'utilisateur (section 1).
Le profil lui-même est décrit dans la section 2. Par exemple,
SASLprep utilise la normalisation Unicode NFKC
(section 2.2 de notre RFC et section 4 du RFC 3454). Ainsi, comme l'illustre les exemples de la section 3,
la chaîne U+2168
(Ⅸ, chiffre romain 9)
sera transformée en la chaîne « IX », qui a la même
signification. Sans SASLprep, un utilisateur dont le nom comporterait
ce caractère Unicode aurait du mal à se loguer ! La section 2 spécifie aussi (section 2.3) les caractères interdits
par SASLprep, comme les caractères de contrôle.
On peut tester cet algorithme sur Unix avec
la commande idn
de la GNU
libidn et son option --profile
:
% echo Café | idn --quiet --stringprep --profile SASLprep Café % echo pi² | idn --quiet --stringprep --profile SASLprep pi2
Dans le premier exemple, on note que SASLprep est sensible à la casse (qui n'a pas été modifiée). Dans le second exemple, l'exposant 2 dans « pi au carré » a été remplacé par un 2 ordinaire, conséquence de la normalisation NFKC. Un hypothétique mot de passe « pi² » serait donc équivalent à « pi2 ».
Une mise en œuvre de SASLprep, sous forme d'une bibliothèque utilisable depuis vos programmes, figure dans la GNU SASL Library.
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : E. Boschi (Hitachi Europe), L. Mark (Fraunhofer FOKUS), J. Quittek, M. Stiemerling (NEC), P. Aitken (Cisco)
Pour information
Première rédaction de cet article le 18 juin 2008
Le protocole IPFIX, décrit désormais dans les RFC 7011 et RFC 7012, permet à une machine d'observation (en général un routeur) d'envoyer des résumés sur le trafic observé à une machine de récolte, qui produira ensuite de jolis camemberts. Ce RFC donne des conseils aux programmeurs qui développent des systèmes IPFIX, jusqu'à citer en section 10 une liste des erreurs de mise en œuvre les plus courantes.
C'est donc un document non-normatif (section 2 pour les détails), qui ne remplace pas les RFC qui spécifient le protocole mais qui les complète, si on développe un observateur ou un récolteur IPFIX.
Comme le rappelle la section 1.2, IPFIX fonctionne en envoyant des tuples TLV. Des gabarits (Template) décrivent les données possibles (des gabarits standards sont décrits dans le RFC 7012) et des enregistrements IPFIX (Data Record) contiennent les données elles-mêmes. Les tuples peuvent être envoyés avec plusieurs protocoles de transport, SCTP étant recommandé.
Après ces préliminaires, commencent les conseils aux implémenteurs. La section 3 discute l'implémentation des gabarits. Par exemple, l'exporteur devrait envoyer le gabarit avant les données. Mais, selon le protocole de transport utilisé, le gabarit peut arriver après et le récolteur devrait donc être patient, ne pas jeter immédiatement les données où le Template ID est inconnu (section 3.1).
Les données envoyées en IPFIX sont typiquement de grande taille et le programmeur doit donc faire attention à la taille des messages envoyés. Il ne faut pas dépasser la MTU en UDP (section 3.5).
La section 4 couvre les responsabilités de l'exporteur. Ainsi, 4.3 lui rappelle de maintenir les compteurs (par exemple le nombre de paquets d'un flot), y compris sur une longue période. S'il risque de ne pas en être capable, il doit plutôt utiliser des compteurs différentiels (Delta Counter, section 3.2.3 du RFC 7012). 4.5 se consacre aux enregistrements qui portent l'indication de l'heure et rappelle donc qu'il faut synchroniser ses horloges, par exemple avec NTP.
Ceux qui développent le logiciel du récolteur liront plutôt la section 5 qui leur rappellera, par exemple, que les identificateurs des gabarits (Template ID) ne sont uniques que par exporteur (plus rigoureusement, par observation domain) et qu'il faut donc maintenir une liste par exporteur.
La section 6 est consacrée aux problèmes de transport. Contrairement à beaucoup d'autrs protocoles IETF, où un seul protocole de transport est spécifié, afin de maximiser l'interopérabilité, IPFIX offre un grand choix : UDP, TCP et SCTP, ce dernier étant le seul obligatoire (avec son extension PR du RFC 3758). La section 6.1 justifie ce choix et rappelle quelques conséquences de l'utilisation de SCTP. Par exemple, l'extension PR (Partial Reliability) permet d'envoyer les enregistrements avec différents niveaux de fiabilité (ceux liés à la facturation nécessitant typiquement davantage de soins que ceux de simple statistique).
En revanche, la section 6.2, consacrée à UDP, explique pourquoi ce protocole est dangereux et comment limiter les risques (notamment en ne l'utilisant qu'au sein de réseaux fermés et contrôlés). Cela peut être le cas si on met à jour un système Netflow en IPFIX, puisque Netflow n'utilisait que UDP.
La section 7 est consacrée aux middleboxes, les machines intermédiaires comme les coupe-feux ou les routeurs NAT. Perturbant les flots mesurés, elles entrainent de délicats problèmes pour la mesure, par exemple la nécessité de bien choisir le point exact d'observation (section 7.2). Comme ces intermédiaires peuvent modifier certaines caractéristiques du flot comme le port, l'information transmise par IPFIX peut devenir très variable (section 7.3.3).
La section 8 est dédiée à la sécurité. IPFIX sert souvent à transporter des données sensibles et la section 8.1 rappelle qu'il peut être prudent d'utiliser DTLS ou TLS, afin d'éviter qu'un indiscret ne prenne connaissance des informations.
Première rédaction de cet article le 11 juin 2008
Vous connaissez le TOFU ? Pas celui qui se mange. TOFU est un sigle qui veut dire Trust On First Use et qui désigne les applications réseau qui vérifient, via la cryptographie, que la machine à laquelle elles parlent est bien la même que la dernière fois, alors même qu'il n'y a en général pas de vérification sérieuse la première fois. SSH est l'exemple le plus connu.
À la première connexion SSH avec une machine, on reçoit un avertissement :
% slogin rebecca The authenticity of host 'rebecca.generic-nic.net (192.134.7.252)' can't be established. DSA key fingerprint is b8:28:72:4d:66:40:9e:40:47:55:a1:40:ad:4a:d8:30. Are you sure you want to continue connecting (yes/no)?
Si on répond OUI, sans vérifier l'empreinte (ce que fait quasiment tout le monde), on est connectés. Mais si le méchant s'était glissé sur le chemin à ce moment là, on est fichus.
SSH est plus efficace si le méchant arrive par la suite :
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that the DSA host key has just been changed. The fingerprint for the DSA key sent by the remote host is b8:28:72:4d:66:40:9e:40:46:55:a1:40:ad:4a:d8:30. Please contact your system administrator. Add correct host key in /home/bortzmeyer/.ssh/known_hosts to get rid of this message. Offending key in /home/bortzmeyer/.ssh/known_hosts:11 DSA host key for rebecca.generic-nic.net has changed and you have requested strict checking. Host key verification failed.
Par défaut, SSH bloque l'accès dans ce cas. Il reste donc la faiblesse
de la première connexion. Une solution possible est d'utiliser des
options « fascistes » comme StrictHostKeyChecking yes
et de vérifier à la main les empreintes des clés. Très peu le font,
c'est bien trop contraignant. Une autre approche a été choisie par le
RFC 4255, qui consiste à publier la clé SSH dans
le DNS. Évidemment,
cela implique que la zone soit signée par
DNSSEC et que l'administrateur de la zone fasse
bien son nouveau travail d'Autorité de certification.
Perspectives, présenté dans l'article Improving SSH-style Host Authentication with Multi-path Network Probing adopte une autre approche. Un réseau de machines situées un peu partout dans l'Internet se connectent aux machines qu'on leur a indiqué et, sur demande, indiquent la clé observée. Ce réseau fournit donc une redondance spatiale (les différentes machines observent depuis différents points du réseau, ce qui protège contre certaines attaques, par exemple celles utilisant BGP) et une redondance temporelle (les machines du réseau de vérification, les notaires, ont une mémoire des clés précédentes et peuvent détecter un changement).
Voyez l'article pour les détails, qui sont nombreux (il faut authentifier les notaires et qu'ils signent leurs messages, il faut pouvoir accepter plusieurs réseaux de notaires concurrents, il faut gérer le cas où, comme dans Minority Report, ils ne sont pas d'accord entre eux, etc).
Ce système ne s'applique pas qu'à SSH, il peut concerner toutes les applications de type TOFU, ce qui est souvent le cas de HTTPS.
L'équipe de Perspectives a continué le travail et le tout est désormais présenté sur leur site officiel. Des idées similaires ont été avancées pour le DNS, par exemple ConfiDNS.
Date de publication du RFC : Juillet 2007
Auteur(s) du RFC : X. Li (Cernet), S. Dawkins (Huawei), D. Ward (Cisco), A. Durand (Comcast)
Pour information
Réalisé dans le cadre du groupe de travail IETF softwire
Première rédaction de cet article le 11 juin 2008
Les réseaux informatiques typiques d'il y a vingt ans étaient multi-protocoles et ces protocoles coexistaient plus ou moins harmonieusement. Pour connecter deux réseaux via un troisième, parlant un protocole différent, on utilisait souvent des tunnels. C'est ainsi que, par exemple, IP a servi à connecter beaucoup de réseaux AppleTalk. Puis IP a tout remplacé et les réseaux sont devenus mono-protocole. Maintenant, avec l'épuisement des adresses IPv4 qui se rapproche, avec le déploiement d'îlots IPv6 qu'il faut relier entre eux, les tunnels reviennent, et avec eux beaucoup de complexité. Un groupe de travail de l'IETF, softwire (« câbles virtuels ») travaille donc à une meilleure spécification de ces tunnels. Ce RFC est la première étape publiée de leur travail.
Les idées derrière le système des « câbles virtuels » (soft wires) sont très anciennes. Par exemple, le système de « courtier en tunnels » (tunnel broker) du RFC 3053, en janvier 2001, était déjà un câble virtuel, même si le mot n'existait pas encore. Mais pourquoi avoir remplacé les tunnels par des « câbles virtuels » ? La raison principale est cosmétique : les tunnels souffrent d'une mauvais réputation, lents, compliqués, peu fiables, posant des problèmes de MTU. Comme les balayeurs sont devenus techniciens de surface, comme le surveillant général est devenu conseiller d'éducation, les tunnels sont devenus des soft wires (la section 1.1 détaille le vocabulaire et définit le câble virtuel comme un tunnel, créé sous le contrôle d'un protocole, ce qui exclut donc les tunnels manuels).
Ce premier RFC ne fait que définir le problème. D'autres documents, en cours d'élaboration à l'IETF, s'occuperont des protocoles effectifs. La section 1 introduit le problème, spécifier des câbles virtuels qui pourront être établis rapidement, mais durer longtemps, afin de connecter des réseaux IP entre eux (typiquement, des réseaux IPv6 via un réseau IPv4). Cette section introduit également la grande distinction entre les topologies « Centraliser et redistribuer » (Hubs and Spokes) et « Maillage » (Mesh). Dans le premier cas, le réseau est organisé autour de points proéminents (les hubs) qui concentrent le trafic et le redistribuent. Dans le second, tout le monde est au même niveau.
La section 2 est consacrée au « Centraliser et redistribuer ». Les tunnels du RFC 4213 sont un exemple typique de cette approche. Voici, extrait de cette section, un cas où une machine double pile (v4 et v6) se trouve sur un réseau local où le CPE est purement v4 (la section 2.2 décrit plus finement ce cas), et qui est connecté à un FAI purement v4. Elle va donc établir un câble virtuel avec un concentrateur de câbles virtuel (le « hub ») qui va ensuite la connecter aux réseaux v6. Seul IPv6 circulera sur ce câble virtuel. Comme précisé dans la section 2.4, le protocole du câble virtuel doit permettre la délégation d'un préfixe IPv6 fixe, même si l'adresse IPv4 du CPE change. On peut utiliser pour cela le RFC 3633. Cette exigence fait que 6to4 ne permet pas de créer de véritables câbles virtuels, puisque l'adresse IPv6 change en même temps que la v4.
Dans le mode « Centraliser et redistribuer », c'est toujours la machine double pile qui crée le câble virtuel, en se connectant au concentrateur. Elle est nommée l'initiateur (section 2.5). Le concentrateur est typiquement un routeur double pile (section 2.6). Le RFC impose que le protocole permette « des millions » d'initiateurs. Le protocole de découverte du concentrateur n'est pas spécifié. Enfin, la section 2.11 détaille les exigences de sécurité, comme la possibilité d'authentifier les initiateurs.
La section 3, elle, parle de l'architecture maillée. Dans cette architecture, un réseau uniquement IPv4 connecte des clients IPv6 entre eux en fournissant des AFBR (Address Family Border Routers) qui parlent les deux protocoles et peuvent créer des câbles virtuels entre eux. Cela ressemble donc beaucoup aux VPN, par exemple dans le RFC 4364, mais sans l'exigence de gérer plusieurs espaces d'adressage distincts.
Les câbles virtuels, en pratique, vont nécessiter d'encapsuler les paquets d'un protocole (en général IPv6) dans un autre (en général IPv4). Les sections 2.13 et 3.5 discutent de l'encapsulation en notant que toutes les techniques existantes doivent pouvoir être utilisées. Cela implique GRE (RFC 2784), MPLS (RFC 3031) ou L2TP (RFC 3931).
Première rédaction de cet article le 10 juin 2008
Ce blog est entièrement publié en XHTML, une
instance de XML. Pourtant, si vous regardez les
en-têtes HTTP émis par le serveur, vous verrez
text/html
et pas
application/xhtml+xml
, qui est la valeur
officielle (cf. RFC 3236 ou bien XHTML
Media Types).
Pas mal d'électrons ont déjà
été maltraités pour écrire des pages Web expliquant que ceux qui
utilisent text/html
sont des crétins ignorants et
que seul application/xhtml+xml
est
acceptable. C'est le cas par exemple du texte Sending XHTML as text/html
Considered Harmful (une traduction en français existe). Ce texte est très
pinailleur, mettant en avant des problèmes ponctuels, liés à des
cas vraiment rares. Son quasi-unique argument c'est que avec XHTML, les auteurs
feront du XML invalide sans s'en rendre compte. Ça ne s'applique pas à
mon blog, où les fichiers sont tous validés. (Le cas de tels sites est traité
dans l'annexe B du document, mais celle-ci ne va pas jusqu'à
reconnaître que le conseil est mauvais.)
Un autre argument, celui des risques que les lecteurs copient-collent le XML dans un document HTML et aient des problèmes est vraiment ridicule. C'est comme dire « C'est mal de programmer en D car cela ressemble trop au C et les utilisateur vont le copier-coller, produisant ainsi du C incorrect ».
Mais pourquoi ne pas utiliser
application/xhtml+xml
quand même ? Après tout,
c'est la norme. Je n'ai pas de position bien tranchée sur ce point (contrairement à Karl Dubost qui dit « N'en déplaise à de nombreuses personnes, servir des pages en application/xhtml+xml n'est plus un choix difficile »). À
une époque, certains logiciels comme lynx
avaient des problèmes avec application/xhtml+xml
(cela semble réglé). Mais MSIE n'accepte toujours pas ce type (il propose
juste d'enregistrer le fichier), ce qui élimine pas mal d'utilisateurs.
Et je regrette surtout qu'on utilise le type
MIME application
alors que
text
conviendrait bien mieux
(text/*
est pour tous les types qu'on peut lire
avec un éditeur ordinaire, ou bien avec cat ou
more, ce qui est bien le cas de XML).
Je changerais donc
peut-être la configuration de mon blog un jour, mais je n'accepte pas
le discours comme quoi text/html
pose des
problèmes, cela ne correspond pas à ce que j'observe, même avec
IE. Même http://www.w3c.org/
ne le fait pas.
À noter que la question est uniquement du type MIME à annoncer. Mes pages sont toujours en XHTML et c'est très bien comme cela (l'article Laisser tomber le XHTML ? donne un autre point de vue).
Enfin, pour parler de choses pratiques, si votre site est servi par Apache, la configuration pour envoyer le type MIME officiel est :
AddType application/xhtml+xml .html
Date de publication du RFC : Juin 2008
Auteur(s) du RFC : M. Crispin (Panda Programming), K. Murchison (Carnegie Mellon University)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF imapext
Première rédaction de cet article le 10 juin 2008
Le protocole IMAP d'accès aux boîtes aux lettres distantes s'étoffe dans toutes les directions. Ce RFC normalise les extensions permettant au serveur IMAP de faire le tri des messages lui-même, avant de les envoyer chez le client.
Un serveur IMAP peut être simpliste,
laissant le client faire l'essentiel du travail, par exemple de tri
des messages pour les afficher dans l'ordre souhaité par
l'utilisateur. Mais certains serveurs IMAP, par exemple ceux qui
stockent les messages dans une base de données
SQL peuvent aussi faire ce travail facilement et les
extensions SORT
et THREAD
permettent à un client de demander ce tri. C'est utile pour certains
clients (cf. RFC 1733) et cela garantit aux utilisateurs un
tri standard.
La section 2 du RFC présente d'abord quelques termes de
base. Ainsi, 2.1 explique le concept de « sujet de base ». Le sujet
des messages (dans le champ Subject:
) étant
parfois modifié en cours de discussion (notamment par l'ajout des
caractères indiquant une réponse, typiquement
Re:
), le tri par sujet doit se faire sur le
sujet de base, pas sur le contenu littéral du sujet. Ce sujet de base
s'obtient notamment en décodant les séquences du RFC 2047 et en supprimant les Re:
ou
Fwd:
initiaux. (La section 2.1 précise bien que,
vue la fantaisie avec laquelle certains logiciels modifient le sujet,
on n'atteindra pas 100 % de succès.)
La section 3 contient la définition formelle des deux nouvelles
extensions. La nouvelle commande SORT
pourra
indiquer le critère de tri, parmi un ensemble pré-défini (date,
expéditeur, taille, sujet, etc). Si on trie selon l'expéditeur,
seulement la partie locale de l'adresse
(addr-mailbox
) est utilisée donc par exemple
l'expéditeur de mes messages, pour ce tri, sera
stephane+blog
et pas
stephane+blog@bortzmeyer.org
et encore moins
Stéphane Bortzmeyer
<stephane+blog@bortzmeyer.org>
. Trier sur le nom
affiché, par exemple, ouvrirait des possibilités très intéressantes pour
les amateurs d'internationalisation. Ainsi, la liste suivante (tel
qu'elle serait triée par un tri alphabétique stupide) :
peut être triée de nombreuses façons. Un tri qui croirait être malin en utilisant le nom de famille donnerait :
alors que le tri correct, tenant compte de la position du nom de famille dans les différentes cultures, serait :
Les auteurs ont jugé que demander à implémenter un tel tri, internationalement correct, serait trop exiger. Le tri se fait donc seulement sur le nom de la boîte aux lettres.
Plusieurs critères peuvent être spécifiés, chacun servant de clé successive pour départager les ex-aequo. Par exemple, à la commande IMAP :
TAG145 SORT (SUBJECT FROM DATE) UTF-8 ALL
le serveur triera selon le sujet, puis selon l'expéditeur (à sujet identique), puis selon la date si les deux premiers critères donnent le même résultat.
La nouvelle commande THREAD
, quant à elle,
permet d'organiser les messages en fils (threads)
de discussion, selon les références (la méthode normale, avec les
champs References:
et
In-Reply-To:
) ou selon le sujet (« rangement du
pauvre », pour le cas où les références manquent). Notons qu'une telle
méthode nécessite que les utilisateurs se servent du courrier
correctement et, par exemple, ne
volent pas les fils.
La section 4 décrit les réponses possibles à ces deux commandes et la section 5 donne la grammaire formelle en ABNF.
Désolé, je n'ai pas encore cherché quels serveurs IMAP mettaient en
œuvre les nouvelles extensions mais elles sont apparemment
largement déployées sur le terrain depuis de nombreuses années (l'extension
SORT
est annoncée dans la réponse
CAPABILITY
de beaucoup de serveurs IMAP, cf. section
7.2.1 du RFC 3501 pour cette réponse).
Date de publication du RFC : Juin 2008
Auteur(s) du RFC : Chris Newman (Sun), Arnt Gulbrandsen
(Oryx), Alexey Melnikov (Isode)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF imapext
Première rédaction de cet article le 10 juin 2008
Le protocole IMAP (RFC 3501) d'accès à des boîtes aux lettres distantes a déjà quelques capacités d'internationalisation mais ce RFC en ajoute deux : la possibilité de demander des messages en diverses langues et la possibilité de demander d'autres fonctions de comparaison du texte.
La section 3 présente la première extension,
LANGUAGE
. Elle permet à un client
IMAP de demander, en utilisant les étiquettes
de langue du RFC 4646 une autre langue que celle par défaut,
pour les messages du serveur, messages qui sont souvent transmis tels
quels à l'utilisateur humain. Par exemple, un dialogue entre le client
C:
et le serveur S:
(ici, le
serveur parle anglais, allemand et italien) pourra
être :
C: A003 LANGUAGE S: * LANGUAGE (EN DE IT i-default) S: A003 OK Supported languages have been enumerated ... C: C001 LANGUAGE DE S: * LANGUAGE (DE) S: C001 OK Sprachwechsel durch LANGUAGE-Befehl ausgefuehrt
La section 4 présente la deuxième extension, qui comprend deux
niveaux, I18NLEVEL=1
et
I18NLEVEL=2
. Cette extension permet aux fonctions de
tri du RFC 5256 d'utiliser divers
comparateurs (RFC 4790). Au premier
niveau (section 4.3), le comparateur i;unicode-casemap
(RFC 5051) est utilisé, au deuxième niveau (section 4.4), le client
peut choisir un comparateur de son choix, avec la commande
COMPARATOR
(section 4.7).
La section 4.5 décrit un problème de compatibilité avec les mises en œuvre actuelles d'IMAP, qui n'utilisent pas toutes le même comparateur par défaut.
Enfin, le RFC note (section 5) que l'internationalisation complète du courrier nécessite également des actions en dehors d'IMAP comme les adresses de courrier internationalisées (RFC 6530).
Première rédaction de cet article le 9 juin 2008
Depuis des années que je fais des documents XML, je regrette l'absence d'un mécanisme de macros, permettant de mettre plusieurs éléments d'un coup.
Quelques exemples concrets pour expliquer ce qui me manque :
<systemitem role="domainnname">fr</systemitem>
, j'écrirai bien
<domain>fr</domain>
.<listitem><para>
à chaque fois, je
préférai juste mettre <item>
.Les transformations XML ne résolvent pas le problème. Ce n'est pas la présentation finale que je veux changer, c'est le code XML tapé. Ainsi, si j'utilise un programme XSLT pour convertir mes « macros », comme l'éditeur XML ne les connait pas, il ne va pas pouvoir m'afficher les éléments valides (une fonction de mon éditeur XML dont je me passerais difficilement).
Les entités XML ne résolvent pas le problème parce que j'ai en général des paramètres (cf. l'exemple des noms de domaine ci-dessus). Et, de toute façon, elles ne survivent pas aux transformations XSLT.
Changer le schéma (ce qui est relativement facile avec des schémas comme Docbook) pour y introduire mes nouveaux éléments m'oblige ensuite à gérer une version locale de Docbook, et à adapter les feuilles de style alors que je veux juste définir un élément en terme d'autres éléments existants.
Les macros traditionnelles comme celles de M4 ou de cpp ne me plaisent guère car elles ne connaissent pas XML. Leur usage perturberait les éditeurs XML et, en utilisant ces macros, on risque de produire des documents invalides, voire mal formés (problème courant en C où l'usage des macros peut produire du code syntaxiquement invalide).
Je préférerai ce que les programmeurs Scheme appellent « macros hygiéniques » (« macros de transformation source à source » dans l'article de Wikipédia) mais elles ne semblent pas exister en XML ? C'est une des grosses limites de ce format. Les formats qui sont presque toujours produits par un programme comme JSON n'ont pas ce problème car ils ne cherchent pas à faciliter la vie d'un auteur humain. Mais XML est utilisé pour des textes (comme ce blog) et ce manque est donc sérieux.
Première rédaction de cet article le 9 juin 2008
Idéalement, il n'existerait qu'un seul jeu de caractères universel et un seul encodage de ce jeu et tout le monde l'adopterait et il n'y aurait pas de problème. Mais dans le monde où nous vivons, beaucoup de jeux coexistent sur Internet et encore plus d'encodages différents. Pour que les visiteurs de votre site Web voient les caractères corrects et non pas des signes cabalistiques (comme dans le fameux pastiche de Martine, « Martine écrit en UTF-8 »), il faut un peu de méthode.
Il n'y a en effet pas de truc magique, juste de la méthode. Celle que je suggère, et qui doit être suivie dans cet ordre est exposée ici.
1) Décider d'un jeu de caractères et d'un encodage pour les pages Web publiées. On prend ce qu'on veut, l'important est de s'y tenir. Pour le jeu de caractères, Unicode est le choix évident, puisqu'il permet de représenter tous les caractères. Pour des pages en français, son encodage UTF-8 est un bon choix. Mais on peut aussi utiliser ISO-8859-15 ou ISO-8859-1, l'important est de ne pas changer tout le temps.
2) Trouver comment produire les pages à cet encodage. Cela dépend du processus de publication. Si l'encodage choisi est UTF-8, si on édite les pages avec Emacs en UTF-8, il n'y a rien à faire. Si on édite les pages avec Emacs en ISO-8859-1, il fait convertir avec recode. Avec un CMS, il faut lire la documentation du CMS. Etc.
3) S'assurer que les pages contiennent l'indication correcte de
l'encodage. En XML / XHTML, cela se fait dans la
déclaration. Exemple: <?xml version="1.0" encoding="UTF-8" ?>
. En
HTML traditionnel, cela se fait via les
éléments <meta>
. Exemple: <meta
http-equiv="content-type" content="text/html; charset=iso-8859-15"
/>
. Il parait que MSIE ignore l'encodage XML et il peut donc être
prudent de mettre le <meta>
de toute façon, c'est ce que je fais sur
mon blog.
4) S'assurer que le serveur HTTP envoie la
bonne indication d'encodage. (Cette étape peut être facultative, ça
dépend de beaucoup de choses. Dans le doute, je la fais toujours.)
Cela se règle, avec Apache, grâce à AddCharset
. Exemple:
AddCharset UTF-8 .html
. Ensuite, le validateur du W3C doit permettre
de vérifier cela. On peut aussi utiliser l'excellente extension
Firefox WebDeveloper
(menu Information, option View Response
Headers). Sinon, sur Unix, avec
wget :
% wget --server-response --output-document /dev/null http://www.example.org/ HTTP/1.1 200 OK Date: Tue, 13 May 2008 19:22:43 GMT Server: Apache/1.3.34 Ben-SSL/1.55 X-Powered-By: PHP/4.4.8 Connection: close Content-Type: text/html
Ici, aucun charset n'est indiqué dans la ligne
Content-Type
, ce qui est clairement
mauvais. Questions :
Première rédaction de cet article le 9 juin 2008
Beaucoup d'utilisateurs du shell Unix ne se servent jamais d'alias ni de fonctions. Ils tapent et retapent de longues commandes compliquées, sans jamais consacrer une demi-journée à apprendre les possibilités avancées du shell. « Je n'ai pas le temps » est un excuse souvent entendue. Mais, s'ils calculaient le Temps Total (comme on définit désormais un Coût Total), peut-être trouveraient-ils que cette demi-journée d'apprentissage leur ferait gagner pas mal de temps pour leurs tâches futures. Lorsque je montre une commande compliquée à des utilisateurs Unix, leur réponse est souvent « Mais je ne vais pas taper un truc aussi long à chaque fois ! ». Bien sûr, c'est pour cela que les alias existent.
Les alias sont une fonction du shell qui permet de définir un équivalent court pour une commande. Si on veut simplement mettre quelques options, toujours les mêmes, certaines commandes Unix permettent de les fixer dans un fichier de configuration. Mais toutes les commandes n'ont pas cette possibilité. Et elle ne résout pas tous les problèmes. Si je veux enchaîner plusieurs commandes ? Si je veux utiliser parfois certaines options et parfois d'autres ? Je peux écrire un script, bien sûr, mais les alias sont une solution plus légère.
La définition d'un alias dépend légèrement du shell utilisé (en gros, la famille sh et la famille csh divergent). Tous les exemples qui suivent ont été testés avec zsh, un shell de la famille sh.
On définit un alias avec la commande du même nom :
% alias dir="ls -lt" % dir total 4 -rw-r--r-- 1 stephane stephane 30 Jun 9 16:55 truc.c ...
Si on veut que cette définition soit permanente, on peut mettre la
commande alias
dans le fichier de démarrage (pour
zsh, en ~/.zshrc
).
Voici quelques alias que j'utilise souvent. Taper alias
NOM
va afficher la définition de l'alias de ce nom.
Pour voir facilement les en-têtes renvoyés par un serveur HTTP, ce qui aide souvent au débogage, faire un telnet à la main est une solution mais elle est souvent pénible. wget fournit ce service, s'il est appelé avec les bonnes options :
% alias hh hh='wget --server-response --output-document /dev/null' % hh http://www.example.org/ ... HTTP/1.1 200 OK Date: Mon, 09 Jun 2008 15:02:40 GMT Server: Apache/2.2.8 (Ubuntu) mod_python/3.3.1 Python/2.5.2 PHP/5.2.4-2ubuntu5.1 with Suhosin-Patch mod_perl/2.0.3 Perl/v5.8.8 Last-Modified: Wed, 19 Sep 2007 06:43:55 GMT ETag: "17c0cf-203-43a775c8b60c0" Content-Length: 515 Content-Type: text/html ...
J'utilise, dans la définition de l'alias, les noms longs des options
(--server-response
au lieu de juste
-S
car l'alias est ainsi mieux documenté. Les
noms courts des options sont très pratiques en interactif mais
déconseillés dans un alias ou un script.
Un alias peut être composé de plusieurs commandes, reliées par un point-virgule (exécution séquentielle) ou un tube (execution séquentielle et la sortie de la première commande est l'entrée de la seconde). Ainsi, pour voir les 20 derniers fichiers chargés via mlDonkey :
% alias lastdonkey lastdonkey='ls -lt /var/lib/mldonkey/ | head -n 20'
Il n'y a pas de limite au nombre de commandes utilisables. Ici, l'alias
svnpurge
supprime dans une copie de travail
Subversion, tous
les fichiers qui ne sont pas gérés par ce
logiciel (attention, c'est une commande dangereuse). Elle est définie
ainsi dans mon ~/.zshrc
:
alias svnpurge="svn status | awk '/^\?/ {print $2}' | xargs rm -f"
Comment marche t-elle ? svn status
affiche les
fichiers non gérés par Subversion avec un point d'interrogation. awk les extrait et
xargs appelle rm pour les détruire.
Après, si on veut des paramètres, des structures de contrôle un peu compliquées, il faut mieux passer aux fonctions.
Première rédaction de cet article le 7 juin 2008
Il devient de plus en plus difficile de déployer de nouvelles techniques sur l'Internet, en raison de coupe-feux excessivement zélés qui bloquent tout ce qu'ils ne connaissent pas. L'Internet s'ossifie, peut-être jusqu'au point où il faudra un nouveau réseau pour retrouver cette possibilité de déploiement de nouvelles techniques. Une étude de chercheurs de Berkeley montre ainsi que les options IP sont bloquées dans environ la moitié des cas.
Le protocole IPv4, normalisé dans le RFC 791, prévoit dans la section 3.1 du RFC l'ajout éventuel d'options dans l'en-tête du paquet IP. Ces options étaient prévues pour permettre certaines fonctions supplémentaires (le RFC 791 en normalisait quatre). En théorie, toute implémentation d'IP doit les reconnaitre.
Et en pratique ? Bien des fonctions parfaitement standards, normalisées depuis des années, comme ECN (RFC 3168) sont, en pratique, inutilisables car filtrées par beaucoup de routeurs. Un groupe de chercheurs a donc cherché ce qu'il en était des options IP et leur conclusion, publiée dans l'article IP Options are not an option est inquiétante : environ la moitié des chemins entre deux machines jettent les paquets IP ayant une option.
Comment ont-ils mesuré ? Ils sont partis du réseau PlanetLab, qui comprend de nombreuses machines un peu partout dans le monde. Entre chaque couple de machines, ils ont tenté d'envoyer des paquets IP avec et sans option (et avec diverses options) et ont compté les cas où le paquet sans option arrivait, mais pas le paquet avec option.
Leur étude approfondit ce résultat en montrant également que le paquet est en général jeté près du point de départ ou bien d'arrivée, c'est-à-dire aux franges de l'Internet, pas dans les réseaux des grands opérateurs.
À noter que, bien que IPv6 soit mentionné dans leur étude, les tests ont été effectués uniquement en IPv4. Il serait intéressant de voir ce que cela donne en v6 puisque le mécanisme d'options est complètement différent. En IPv4, tout paquet avait un champ Options, et de longueur variable, ce qui est très pénible à analyser rapidement pour les routeurs. En IPv6, les options (RFC 2460, section 4.2) sont en dehors de l'en-tête, dans une « extension d'en-tête ».
Une analyse équivalente pour TCP, pas plus optimiste, se trouve dans l'excellente étude de Google Probing the viability of TCP extensions.
Date de publication du RFC : Mai 2008
Auteur(s) du RFC : S. Mirtorabi (Nuova), P. Psenak (Cisco), A. Lindem, A. Oswal (Redback networks)
Chemin des normes
Première rédaction de cet article le 7 juin 2008
Le protocole de routage OSPF, normalisé dans le RFC 2328 pour IPv4 et RFC 5340 pour IPv6 est toujours autant utilisé et connait régulièrement de nouveaux perfectionnements. C'est ainsi que, grâce à ce nouveau RFC, on peut désormais mettre un lien physique dans deux zones OSPF.
Dans l'OSPF classique multi-zones (les zones - areas - sont un mécanisme de découpage des grands réseaux OSPF, cf. section 3 du RFC 2328), un lien physique, par exemple un réseau Ethernet, ne peut appartenir qu'à une seule zone. C'est parfois contraignant, comme le montre l'exemple cité dans la section 1.1 de notre RFC. En effet, OSPF préférera toujours une route interne à la zone à une route inter-zones et cette règle l'empêchera parfois de choisir la meilleure route. Dans cet exemple : les routeurs R1 et R2 vont communiquer via les trois liens qui se trouvent dans la zone 1 et pas par l'épine dorsale, pourtant plus rapide mais située dans une autre zone.
La section 1.2 du RFC examine donc les contournements possibles et leurs inconvénients, avant que la 1.3 ne résume la solution choisie : permettre la création d'une adjacence entre deux routeurs OSPF au dessus d'un lien appartenant à une autre zone. Cette adjacence se fera comme si les deux routeurs étaient connectés par une liaison point-à-point (section 2.7 pour les détails).
La section 2, assez courte, détaille les changements que cela nécessite dans le protocole, changements qui sont compatibles avec les implémentations existantes (la section 3 discute cette compatibilité). Ce changement est le même pour OSPF IPv4 et OSPF IPv6 (OSPFv3), comme décrit dans la section 4.
Je ne connais pas encore d'implémentations de ce RFC.
Date de publication du RFC : Mars 2005
Auteur(s) du RFC : R. Arends (Telematica
Institute), R. Austein (ISC), M. Larson
(Verisign), D. Massey (Colorado State
University), S. Rose (NIST)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 5 juin 2008
L'ensemble connu sous le nom de DNSSEC vise à authentifier les réponses des serveurs DNS en signant cryptographiquement lesdites réponses. Cet ensemble est normalisé dans plusieurs RFC dont notre RFC 4035, qui spécifie les changements dans le protocole. Ces modifications du protocole sont modérées mais indispensables pour l'authentification des données.
Ce RFC complète donc le RFC 4033 qui exposait les principes généraux de DNSSEC, ainsi que son cahier des charges, et du RFC 4034 qui décrivait les nouveaux types d'enregistrements DNS nécessaires, DS, DNSKEY, RRSIG et NSEC. Il met à jour l'ancien RFC qui couvrait tous les aspects de DNSSEC (RFC 2535). Il explique ce que doivent faire des serveurs et résolveurs DNSSEC pour permettre l'authentification. En effet, la simple utilisation des nouveaux enregistrements ne suffit pas à valider les réponses.
D'abord, la section 2 explique ce que doivent faire les programme
de génération des zones (dnssec-keygen
chez
BIND) et de
signature des zones (dnssec-signzone
chez
BIND). Elle parle donc du comportement « hors-ligne » du serveur,
indépendamment des requêtes qu'il reçoit. La section 2.1 couvre la gestion des clés : leur partie
publique doit être incluse dans la zone, dans des enregistrements
DNSKEY, par exemple, ici dans .bg
:
bg. IN DNSKEY 257 3 5 AwEAAcNsUEdXDwV5Sgr55kFzm0kCFNOL9iP8asHh1FKvDcxdJCe4mQJm l4kQ0C1CZyMwPIL3QWNP8yWcBLs2rfFeTX/lPXWDRvujLVxDCXCDvYkH Av4q3OkwDn+5pSH3DApKjVaW9K5XFFzNVTf3DRXWGzPNiWWXB35JHSo+ Iz2nYEHX4ZQumcT7z1BmQgQ91cS+wFT4FiCKrKdpPfxBFDSRgVZKPrL5 l6BFd/EK4jrbpzGM+83UxEBsqhR+K/GDk/yZC9jSm9DMOZJ7woYBhIwz q3lPpaoBBMbFLKw1FVQR4oFL1yznFkkcOOvZ5bu1G2s6lohoYz9Qlwld jwSqVg2TMXMclZzlUzGLFiMJsqwNnwfnD6mFaqjWbZXqRXLMupNYlKiu NKKs9zvnjpH5P/QjWX3Ym6owMebVTvlqbGc3lwIhk+d8gOYQzaUBf7Vk NRS3lb92zQe8DDhdyGosH7Po/rIP/QewKrcmgcExB4YpEZQ8M2EI5ddy 4bcnHCAqgjZ05b2mQyaxN3y4m3Ws85QsNQ7t9MnBXMkRkL6Zh9Zvs4k3 MQK4h0S6Jn22/kjqoBBsJYB2VYhToE/ljEt+uHjHVMWUtZ3jyfo1nY23 7cWXaYRW/2XNWXYluaOPdzJOuaDm6bBz5w+JbaY3GjEs78T7nmkn7MsK gDjDNwYf+8hrbDO3
La section 2.2 passe ensuite aux signatures. Elles doivent être mises
dans des enregistrements RRSIG et il doit y en
avoir un par RRset (ensemble des enregistrements de
différents types pour
un même nom de domaine). Cette section rappelle aussi qu'on ne signe
que les enregistrements pour lesquels on fait
autorité. Ainsi, les NS
qui
indiquent les serveurs de noms d'une zone, sont signés dans la zone
fille, pas dans la zone parente qui s'en sert pour la délégation. Même
chose pour la colle (adresses IP indispensables à
la délégation), qui n'est pas signée.
Un des problèmes les plus difficiles de DNSSEC est la « preuve de
non-existence ». Afin que les requêtes et réponses DNS puissent passer
par des serveurs traditionnels (pour que le DNS continue à marcher,
même sans validation), DNSSEC utilise des enregistrements DNS
classiques. Prouver qu'un nom de domaine existe consiste simplement à
produire une signature d'un enregistrement portant sur ce nom. Mais
comment prouver qu'un nom de domaine n'existe pas, alors qu'il
n'existe rien à signer ? DNSSEC résout ce problème par deux sortes
d'enregistrement prouvant la non-existence, les
NSEC, introduits dans le RFC 4034 et dont l'inclusion dans le fichier de zone est
spécifiée en section 2.3 de notre RFC, et les
NSEC3
qui ont été introduits plus tard par le
RFC 5155. Les NSEC qui, à
l'époque de la publication de notre RFC 4035, étaient le seul
mécanisme de preuve de non-existence, ont en effet un gros défaut :
ils permettent à un client DNS de récupérer indirectement toute la
zone DNS.
La section 2.3 dit donc que tout nom de domaine pour lequel un
enregistrement est signé doit avoir un NSEC, par
exemple, ici le MX de laperouse.sources.org
est signé et un NSEC annonce que le nom suivant est ludwigVII.sources.org
:
laperouse.sources.org. 86400 IN MX 10 aetius.bortzmeyer.org. 86400 RRSIG MX 3 3 86400 20080802035206 ( 20080601035206 55957 sources.org. CH+eYPc36AXc9W9sEIaUFnOLdlodKXa+9yLQ SuXYgDbmEQMufy052L0= ) 43200 NSEC ludwigVII.sources.org. MX RRSIG NSEC
La section 2.4 explique le placement des DS,
les enregistrements qui complètent les NS
dans la
zone parente, afin de permettre une délégation signée depuis une zone
vers sa fille. Un DS référence les clés publiques
de la zone fille. Les DS ne se trouvent donc pas dans la zone
déléguée. Ils sont générés par le gérant de cette zone déléguée et
transmis au gérant de la zone parente, qui les inclut dans son fichier
de zone et les signe. (On pourrait aussi envoyer les
DNSKEY au parent pour qu'il génère les DS
lui-même mais le RFC 6781, section 4.3.2, recommande plutôt
d'envoyer les DS.) Ainsi, si le gérant de
bortzmeyer.example
signe sa zone avec
BIND, dnssec-signzone
va
lui générer un fichier dsset-NOMDELAZONE.
qui contiendra les DS
qu'il transmettra au gérant de .example
(par
exemple en EPP selon le RFC 4310 ou bien selon une procédure
qui dépend du registre). Voici le contenu de ce fichier des DS :
sources.org. IN DS 55957 3 1 A12F149F84B34E09501C32CC9F984FB9E1ED196A sources.org. IN DS 55957 3 2 DFE4A96D7FCC9B3F99990861AE3B915E832B699FC9628CE0DF7BE45D DE37DFB3
La section 2.5 parle des CNAME
, ces
enregistrements « alias » qui permettent à un nom de domaine de
pointer vers un autre. Les CNAME
doivent
évidemment être signés, ce qui implique de leur adjoindre un
RRSIG et notre RFC 4035 adoucit donc la
vieille règle (RFC 1034) selon laquelle on ne pouvait pas mettre des données avec
un CNAME
:
openid.sources.org. 86400 IN CNAME munzer.bortzmeyer.org. 86400 RRSIG CNAME 3 3 86400 20080802035206 ( 20080601035206 55957 sources.org. CFhUR1j+1b684LERarhf6bmIbWHvnox6/cZT txCiMpOS5rRHBcQQHYQ= ) 43200 NSEC sub.sources.org. CNAME RRSIG NSEC
De même, la section 2.6 modère l'ancienne règle qui disait
que, dans la zone parente, seuls des NS
pouvaient
être présents pour une zone fille (désormais, les
DS et les NSEC sont
également possibles).
La section 3 s'attaque aux serveurs de noms qui veulent distribuer
des données authentifiées. Ces serveurs se voient d'abors imposer de
gérer l'extension EDNS0 (RFC 2671), notamment en raison de la plus grande taille de
réponse qu'elle permet (les enregistrements DNSSEC sont typiquement
assez grands). Mais c'est aussi parce que EDNS0 permet aux
résolveurs DNS d'indiquer qu'ils acceptent DNSSEC, selon le mécanisme du DO
bit, décrit dans le RFC 3225. Pour BIND, utilisé en
résolveur, on met ce bit avec l'option dnssec-validation
yes;
dans le fichier de configuration. Pour dig, si je donne
l'option +dnssec
, dig va
mettre ce DO bit (bit DNSSEC OK)
dans la requête, comme on le
voit ici avec wireshark et son option Export (tcpdump ne permet apparemment pas de l'afficher) :
Additional records <Root>: type OPT Name: <Root> Type: OPT (EDNS0 option) UDP payload size: 4096 Higher bits in extended RCODE: 0x0 EDNS0 version: 0 Z: 0x8000 Bit 0 (DO bit): 1 (Accepts DNSSEC security RRs) Bits 1-15: 0x0 (reserved) Data length: 0
Outre ce bit dans les requêtes, DNSSEC prévoit deux bits dans les réponses, les CD (Checking Disabled) et AD (Authentic Data).
La section 3.1 traite d'un serveur faisant autorité pour une
zone. Pour que BIND gère le DNSSEC dans ce cas, il faut mettre
l'option dnssec-enable yes;
dans son fichier de
configuration. Un tel serveur qui reçoit une requête avec le bit DO
doit inclure les enregistrements DNSSEC comme les RRSIG, et fournir
les NSEC si le nom n'existe pas (ou s'il existe mais sans
enregistrement du type demandé). Voici un
exemple avec dig et BIND :
% dig +dnssec MX sources.org ... ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 # La réponse a été validée, "ad" est présent ... ;; ANSWER SECTION: sources.org. 86379 IN MX 10 uucp.bortzmeyer.org. sources.org. 86379 IN RRSIG MX 3 2 86400 20080802035206 20080601035206 55957 sources.org. CEYv0Tds6c7OSD7ZxEPmY0hQgs4ZMM5QE/8Ecmgm8Re7srtPhPEGVyg= # Et, si le nom n'existe pas : % dig +dnssec MX nexistepas.sources.org ... ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 14178 # Le nom n'existe pas, NXDOMAIN ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1 # Réponse validée grâce aux NSEC ... ;; AUTHORITY SECTION: ... ludwigvii.sources.org. 10800 IN NSEC openid.sources.org. AAAA RRSIG NSEC # Le NSEC dit qu'il n'existe rien entre ludwigvii.sources.org et openid.sources.org
L'inclusion des RRSIG (section 3.1.1) peut poser des problèmes de taille, car ils sont nettement plus gros que les enregistrements habituels. Le RFC détaille donc dans quels cas les envoyer. L'envoi des NSEC obét à des règles encore plus complexes, détaillées dans la section 3.1.3. Par exemple, s'il y a une réponse, mais qu'elle a été générée par un joker (le caractère * dans le fichier de zone), il faut envoyer les NSEC.
Après les serveurs faisant autorité de la section précédente, la
section 3.2 parle des serveurs récursifs. Lorsque
leur client indique son désir de faire du DNSSEC, via le bit DO, le
serveur récursif doit leur envoyer les enregistrements DNSSEC et
procéder à la validation, puis en indiquer le résultat via le bit AD
(« ces données sont authentiques, je les ai vérifiées »). Pour BIND, c'est l'option dnssec-validation yes;
qui met en route DNSSEC pour un serveur récursif.
Il y a tout un débat sur le meilleur endroit où effectuer la validation DNSSEC. Dans les applications pour qu'elles aient le plus d'informations possibles et puissent ajuster ainsi leurs messages à l'utilisateur ? Dans un résolveur situé sur la machine de l'utilisateur, la seule à laquelle il puisse vraiment faire confiance, puisque les autres machines et le réseau peuvent être sous le contrôle des méchants ? (Mais l'utilisateur de base ne va certainement pas installer et gérer BIND et il n'existe pas de serveur récursif et validateur « clés en main ».) Dans les résolveurs du FAI, qui sont déjà utilisés et configurés et qui sont gérés par des professionnels ? (Mais le FAI est parfois le premier à mentir, par exemple en dissimulant les réponses NXDOMAIN - ce domaine n'existe pas - derrière des fausses réponses menant à un serveur publicitaire qu'il contrôle.)
Ce débat n'aura pas de réponse consensuelle de si tôt (voir par exemple la section 4.9.3 du RFC). En attendant, notre RFC permet tous les modes de fonctionnement. Par exemple, si le résolveur ne veut pas que les serveurs auxquels il parle fassent de la validation, il peut leur demander avec le bit CD (section 3.2.2). S'il veut signaler à son client qu'il a validé (libre au client de le croire ou pas), il a le bit AD (section 3.2.3) pour cela.
La liste des tâches à accomplir par un résolveur continue en section 4, qui couvre tous les résolveurs, pas seulement les serveurs de noms récursifs de la section précédente. Eux aussi doivent gérer EDNS0 (section 4.1).
Si un résolveur valide les réponses avec DNSSEC, la section 4.3 donne les résultats auquel il peut parvenir :
SERVFAIL
(Server failure).Mais, justement, comment vérifier une signature ? Faut-il mettre dans le résolveur la clé de toutes les zones DNS du monde ? Évidemment pas. La section 4.4 parle des trust anchors (« points de départ de la confiance »), ces clés (au moins une) qui sont mises en dur dans la configuration du résolveur. À partir d'une telle clé, on peut vérifier une zone, et toutes ces sous-zones signées, en suivant les enregistrements DS, où on trouvera les clés des sous-zones. Idéalement, si la racine du DNS était signée, un seul trust anchor suffirait, la clé de la racine.
En pratique, la racine n'est pas actuellement signée. Il faut donc
gérer à la main un ensemble de trust anchors (voici
par exemple le fichier que j'utilise
avec BIND, qui est à jour le 2008-06-04). On retrouve ces clés
sur des sites tels que https://www.ripe.net/projects/disi/keys/
ou http://www.iis.se/domains/sednssec/publickey
. La meilleure façon de
gérer ces trust anchors est décrite dans la
section 5, qui décrit par exemple les vérifications de cohérence que
devrait faire un résolveur (tester que la trust
anchor se retrouve bien dans la zone sous la forme d'un
enregistrement DNSKEY). La section 5.1 parle
notamment des « îlots de confiance » (islands of
security), qui sont les zones signées sans que leur zone
parente le soit (la très grande majorité, à l'heure actuelle). Par
exemple, aujourd'hui, la zone .org
n'est pas
signée donc sources.org
, qui l'est, est un « îlot
de sécurité » dont les clés sont :
sources.org. IN DNSKEY 256 3 3 CKoOFAptkq5oqs8hlDf1gYDDpRPrjySc+wjBxLBbQtkXOrAUoBOrUa6I Yx83fYsA/i3BbhOXjS3K5/JlIupCszv2xTtrgIb0uivatvtO1WSySjOw R4dhfgPXdYbTAcYLYZRSiOFXxzXjnczRgqJu6tu50U7m7RK5wiIBTE6Q StNEanhez3srKtJK07iYutga/INvPxE82zVdGeBmIJpLqQ7gnCR3VaMh FtX+jO0/QHY/07vtZxNJhMucQt/oCG8rGQYVl1g8diZUtfd4iIgf2ill fBppxqc5EW3lLH1yVmu4JcHLaC4E7WiipupGd9N4APi5PzR3tuER8iua JYDHaZIwBmOm9weedHM9fUhOWYjmbEejvC8DvX6epDHVpAxgzysTapLa VBAci4a2/A/VVnrO2snUTdRzx8B8p5gnAgwl0ojXrgQRcPb0eDaFUdQx b9qLM75oM6miFeg1qsoqWNW/P1YvX/Kd2IDRcpskFE/ReYMpna40Ywj9 941/dRoDm6AMRpejsXYTlcpQRuRW54qpJuaY sources.org. IN DNSKEY 256 3 5 AwEAAduXW4l/heiryuKxgipsGR2mIDnZxotS1Cf6+hzYROeGqPUnO2SI aQVh8s89u2hUT6I8T0C0UGVAJ2lmgTV6jEXwNyAm9wYzkZg6WnP5Nt3W eitsSBPQljAQvWsxNpp99QQrtycE4RDCtOiQS1igFPaEFPSawuvDEW8X oM2adQFa7RBXue8Xk5uxgbHorLLb3UTi7Ai1E7/J786XhlNGGJmpQJaB +qbyWG6Y81Uvnvj+CkU/hl7gRq2PE4TD2cJOZ85kia3fVUqOY6rOWK0X gylkQCV8Pjsd0LwVUfQ73/yDEpmw3ZBZDZUahWYnya2jFaidFJqfACoK ZXKMFcqkFt0=
La section 5.4 est consacrée aux NSEC, qui nécessitent des règles particulières pour leur validation.
Le reste du RFC est consacré à des exemples détaillés de zones signées, et de requêtes et réponses DNSSEC, avec leurs explications.
Si on veut tester un résolveur DNSSEC, il existe une zone prévue
pour cela, test.dnssec-tools.org
.
Elle contient à peu près toutes les erreurs possibles. Par exemple,
futuredate-A.newzsk-ns.test.dnssec-tools.org
a
une date de signature située dans le futur :
% dig A futuredate-A.newzsk-ns.test.dnssec-tools.org ; <<>> DiG 9.4.2 <<>> A futuredate-A.newzsk-ns.test.dnssec-tools.org ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 10278
Et, sur le serveur résolveur, le journal contiendra :
28-May-2008 14:07:59.910 dnssec: info: validating @0xa9c450: futuredate-A.newzsk-ns.test.dnssec-tools.org A: no valid signature found
Voici quelques extraits des fichiers de configuration de BIND, pour faire du DNSSEC (on peut trouver des instructions plus détaillées dans le DNSSEC HOWTO, a tutorial in disguise ou dans DNSSEC Resolver Test) :
options { dnssec-enable yes; // Accepte les requêtes avec le bit DO et // renvoie les enregistrements DNSSEC dnssec-validation yes; // Valide les // enregistrements DNSSEC reçus (le bit DO est mis // systématiquement par les BIND récents) };
Pour le débogage, il peut être prudent de mettre le résultats des traitements DNSSEC dans un fichier séparé :
logging { channel dnssec_log { // a DNSSEC log channel file "/var/tmp/bindlog/dnssec.log" size 20m; print-time yes; // timestamp the entries print-category yes; // add category name to entries print-severity yes; // add severity level to entries severity debug 7; // print debug message <=7 // Cela va noter *beaucoup* de messages // On peut aussi mettre "severity info;" qui // est nettement moins bavard. }; category dnssec { dnssec_log; }; };
Une fois que c'est fait, on peut tester le résultat avec des noms
correctement signés comme
sigok.verteiltesysteme.net
ou délibérement mal
signés comme sigfail.verteiltesysteme.net
.
Pour un serveur faisant autorité, il faut générer des clés par exemple :
% dnssec-keygen -a RSASHA1 -b 2048 -n ZONE sources.org
On peut aussi générer plusieurs clés de types différents et les
inclure dans la zone, par exemple, pour une clé
DSA, avec dnssec-keygen -a DSA -b
1024 -n ZONE sources.org
. Notons que cette commande dépend du générateur
aléatoire de la machine et elle consomme beaucoup
d'entropie, se bloquant dès qu'il n'y en a pas assez de
disponible. Paradoxalement, il vaut donc mieux l'exécuter sur une
machine chargée.
Il faut ensuite signer la zone et penser à la resigner
après chaque modification (ou bien avant son expiration, selon
l'évenement qui a lieu en premier). Pour simplifer le processus, on
peut utiliser make avec un
Makefile
de ce genre :
reload: sources.org.signed foobar.example.signed rndc reload # Ou nsdc rebuild && nsdc reload pour NSD %.signed: % @echo Signing requires a lot of entropy in /dev/random, do not hesitate to load the machine... # 5356800 seconds = two months of validity dnssec-signzone -e +5356800 $^
Le serveur devra alors avoir dans son fichier de configuration
(named.conf
pour BIND,
nsd.zones
pour NSD), le
fichier sources.org.signed
(et non pas le fichier
sources.org
qu'on édite et qui ne contient pas
les signatures).
Auteur(s) du livre : Les Éconoclastes
Éditeur : La Découverte
2-7071-4450-9
Publié en 2004
Première rédaction de cet article le 5 juin 2008
Un excellent petit livre d'économie pour tous ceux qui entendent tous les jours que « à cause de la démographie, il va falloir passer aux retraites par capitalisation » ou que « les entreprises privées sont plus efficaces que les services publics » ou encore que « il y a trop de charges sociales » et qui se demandent si c'est bien vrai, ou si c'est simplement répété suffisamment souvent pour que tout le monde y croie.
« Les Éconoclastes », pseudonyme collectif des auteurs, sont un groupe d'étudiants et de chercheurs en économie qui trouvent l'enseignement de cette discipline trop mathématique et trop éloigné des réalités. Ils abordent l'économie avec un prisme simple : « quels sont les faits connus ? ». Loin des théories purement idéologiques, ils montrent que ce ne sont pas forcément les pays ayant le plus d'impôts qui ont le plus de chômage, que le système de santé aux États-Unis est bien moins efficace qu'en France (mais beaucoup plus coûteux), que la différence entre retraite par capitalisation et retraite par répartition est bien moindre qu'on ne le dit (lors d'une retraite par capitalisation, on ne stocke pas d'or sous son matelas, on achète des produits financiers dont le rendement, comme pour les retraites par répartition, dépendra de l'état de l'économie)...
Un livre simple (quoique tous les termes ne sont pas forcément définis, il faut parfois aller faire un tour sur Wikipédia) et qui rectifie pas mal de préjugés.
Première rédaction de cet article le 4 juin 2008
Dernière mise à jour le 25 février 2009
La norme ISO portant le numéro 639-5 vient d'être approuvée. Elle ajoute aux autres normes 639, qui portent sur la normalisation des listes de langues humaines, une liste des classifications de ces langues.
La nouvelle norme a le nom officiel de « Codes for the representation of names of languages - Part 5: Alpha-3 code for language families and groups », en français, « Codes pour la représentation des noms de langue - Partie 5: Code alpha-3 pour les familles de langues et groupes de langues ». Elle normalise des codes de trois lettres pour les familles et autres groupes de langues. Son agence de maintenance est la Bibliothèque du Congrés états-unien, comme pour ISO 639-1 et 639-2 (mais pas ISO 639-3) qui gère le site officiel.
À noter qu'ISO 639-5 est une liste de codes, pas une
classification. On y trouve l'information qu'il existe une famille
sdv
(« Langues soudaniques orientales ») mais pas
d'information sur ses membres comme le nubien.
Les classifications des langues (un
sujet parfois chaudement débattu entre linguistes) restent extérieures
à la norme. En revanche, la hiérarchie des familles est, elle,
présente. Le fait que le manxois (code ISO 639-3
glv
) est membre de la famille celtique (code ISO 639-5
cel
n'est pas cité mais le fait que la famille
celtique est elle même membre de l'ensemble indo-européen (code ISO
639-5 ine
) est indiqué dans la
liste. De même, on voit que les langues soudaniques orientales
comprennent plusieurs familles, dont celle des langues nubiennes (dont
fait partie le nubien cité plus haut).
La liste des codes est disponible gratuitement sur le site de l'agence de maintenance.
Première rédaction de cet article le 4 juin 2008
À l'occasion des JTR (Journées Techniques Réseaux) sur le thème d'IPv6, j'ai fait un exposé sur les politiques d'allocations de ressources virtuelles, notamment des adresses IP. Voici les transparents de cet exposé.
Date de publication du RFC : Juin 2008
Auteur(s) du RFC : A. van Wijk, G. Gybels
Pour information
Réalisé dans le cadre du groupe de travail IETF sipping
Première rédaction de cet article le 4 juin 2008
De même que le sigle VoIP désigne le transport de la voix sur IP, ToIP veut dire « Texte sur IP » et désigne le transport de texte au dessus d'IP, une technique proche de la messagerie instantanée mais néanmoins distincte. Ce RFC définit un cadre pour la mise en œuvre de ToIP sur le protocole SIP.
SIP, normalisé dans le RFC 3261, est un des grands succès de l'Internet. C'est le seul protocole ouvert permettant des services tel que la téléphonie sur IP. D'où l'idée de l'utiliser pour le ToIP. Mais qu'est-ce que le ToIP ?
La section 1 du RFC répond à cette question : au contraire de la messagerie instantanée, qui est semi-interactive (le texte n'est envoyé qu'après une action explicite de l'utilisateur), le texte-sur-IP est commplètement « temps réel », il est transmis au fur et à mesure qu'il est tapé. Il est largement utilisé par les sourds ou les personnes atteintes d'un handicap de la parole (le RFC 3351 détaille les demandes spécifiques de ces utilisateurs). Mais des utilisateurs non-handicapés apprécient également la réactivité de ce medium. Il est également utile dans certains environnements, par exemple une usine bruyante.
Étant proche de la téléphonie, il est donc logique de vouloir le réaliser avec les protocoles de signalisation SIP (RFC 3261) et de transport de données RTP (RFC 3550). RTP a déjà une norme pour le transport du texte, le RFC 4103.
Le cahier des charges proprement dit débute à la section 5 du RFC. Le ToIP doit être l'équivalent du téléphone et doit donc fournir un transport et une présentation « en temps réel », une transmission bidirectionnelle, et doit pouvoir être utilisé en même temps que d'autres médias tels que la vidéo (la norme ITU F.703 pose également ces exigences). Parmi les nombreux détails qui émaillent la section 5, on peut noter :
La section 6 détaille comment le service pourrait être implémenté, avec les équipements et logiciels SIP et RTP existants. L'interconnexion avec la téléphonie classique n'est pas oubliée, puisque la section 6.2.5.1 détaille comment faire passer du texte « temps réel » sur cette téléphonie traditionnelle, selon la norme (ou plutôt la description de diverses normes) ITU V.18.
Enfin, la section 7 couvre les cas divers, comme l'accès aux services d'urgence. J'ignore s'il est actuellement réaliste d'appeler les pompiers en texte seul...
Première rédaction de cet article le 28 mai 2008
« Le développement de l'Internet se fera sur des téléphones mobiles » est une tarte à la crème du marketing actuel. C'est donc une très bonne chose que Joi Ito s'attache à chercher les arrières-pensées derrière ce slogan.
Que dit Joi Ito dans son article Is Mobile Internet Really Such a Good Thing? ? Tout simplement que les intentions des promoteurs de cet Internet mobile ne sont pas toujours très avouables. L'Internet se caractérise par des engins ouverts (les ordinateurs) dans un réseau ouvert. Cela permet le déploiement rapide d'innovations (comme l'avait été le Web à ses débuts) et cela permet aux utilisateurs le choix et surtout le contrôle sur ce qui tourne sur leurs machines. Au contraire, l'Internet mobile, aujourd'hui, consiste surtout à déployer des engins fermés et contrôlés (comme l'iPhone), où on ne peut pas choisir les applications qui tournent dessus, et à les déployer dans un réseau fermé (comme l'offre soi-disant Internet d'Orange/3GPP où seuls les ports 80 et 443, ceux d'HTTP, sont autorisés).
Sur le même sujet (le danger de ces boîtes fermées, pratiques à utiliser, mais sur lesquelles l'utilisateur n'a aucun contrôle), le livre de Jonathan Zittrain, The Future of the Internet and How to Stop It est la référence. En français, je recommande l'excellent article de Benjamin Sonntag « Pourquoi l'Internet mobile n'est PAS Internet ? ».
Première rédaction de cet article le 28 mai 2008
Les téléchargements de fichiers avec le protocole
BitTorrent peuvent prendre des jours, voires
des semaines. Laisser un logiciel ouvert pendant ce temps n'est pas
possible pour une machine de maison ordinaire, qui est souvent
éteinte. Même sur un serveur allumé en permanence, cela bloque un
terminal par téléchargement, si on utilise le client traditionnel,
btdownloadcurses
. Il existe plusieurs solutions à
ce problème, la mienne combine un des logiciels du client
traditionnel, btlaunchmanycurses
et le programme
screen.
Une des solutions est évidemment d'utiliser un autre programme,
puisqu'il existe beaucoup de clients BitTorrent, tous plus ou moins
compatibles (en dépit de l'absence d'une norme écrite du protocole). Je n'ai jamais eu de
succès avec Azureus (core dumped
) qui, contrairement à ce que
prétend le discours marketing, comme presque tous les
programmes Java, ne
fonctionne pas avec n'importe quel environnement Java mais uniquement
avec celui de Sun (qui était non-libre jusqu'à une époque très récente). De même,
bien que mlDonkey aie, en théorie, un support
BitTorrent, les téléchargements ne démarrent jamais, dans mon cas (et
ce logiciel semble en voie d'abandon, avec une communauté qui est
devenue inactive). Quant à TorrentFlux, il nécessite un serveur Web, PHP, etc.
Retour au client BitTorrent original, écrit en Python. Il comprend de nombreux
programmes différents dont un qui fait presque tout ce dont j'ai
besoin : btlaunchmanycurses
prend en argument un
répertoire, ouvre tous les fichiers « torrent » de ce répertoire et
lance simultanément les opérations. Ajouter un nouveau « torrent » à
la liste est aussi simple qu'un wget dans ce
répertoire (par exemple wget ftp://ftp.netbsd.org/pub/NetBSD/iso/4.0/i386cd-4.0.iso.torrent
pour récupérer le CD de NetBSD).
Pour libérer le terminal et pour que
btlaunchmanycurses
s'exécute tranquillement en
arrière plan, la meilleure solution est d'utiliser le programme screen qui permet de lancer le programme en
arrière-plan, le reprendre à volonté (y compris depuis une autre
machine), le détacher à nouveau, etc. Le script
shell attaché fait exactement cela :
#!/bin/sh NAME=BitTorrent DIR=${HOME}/Downloads BT=btlaunchmanycurses BT_OPTIONS="--ipv6_enabled 1 --max_uploads 3 --max_upload_rate 8 --max_download_rate 85" cd ${DIR} # Starts "screen" detached, with a command to run screen -S ${NAME} -d -m ${BT} ${BT_OPTIONS} . # The limit of this approach is that screen disappears when ${BT} is # over. If ${BT} scrashes, you lose the error messages :-) # The alternative would be to launch screen without a command (just -d # -m) and then to issue a "screen -X -r ${NAME} exec ${BT} ...". But # this is ignored, probably because a bug in screen (see # <https://savannah.gnu.org/bugs/index.php?18882> # Another solution (thanks to Thomas Montfort to bring it to me) is to # use the 'zombie kr' command in ~/.screenrc.
Il ne reste plus qu'à faire en sorte que ce script,
start-bittorrent
, soit lancé automatiquement au
démarrage de la machine. Le client BitTorrent sait reprendre les transferts interrompus. Encore faut-il le mettre en route. Pour éviter d'utiliser le compte
root, on peut exploiter un service des
crons modernes comme Vixie Cron qui
permet de lancer une commande au moment de certains événements comme
le démarrage. Ainsi, j'ai dans ma crontab :
@reboot bin/start-bittorrent
Je dois des remerciements à Erwan Arzur pour m'avoir indiqué btlaunchmanycurses
et à Erwan David pour son aide sur cron.
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : K. Murchison (Carnegie Mellon University)
Chemin des normes
Première rédaction de cet article le 27 mai 2008
Beaucoup d'utilisateurs du courrier électronique utilisent des
sous-adresses pour présenter plusieurs
identités à l'extérieur. La sous-adresse est
typiquement séparée du nom de la boîte aux lettres par un
+ (mais chacun a sa convention, il n'y a rien
de standard, cf. section 1 du RFC). Ainsi, l'adresse que je publie sur ce
blog,
stephane+blog@bortzmeyer.org
contient une
sous-adresse, blog
. Cette nouvelle extension du
langage de filtrage de courrier Sieve permet de
prendre des décisions en fonction de la sous-adresse.
Le principal intérêt pratique des sous-adresses est en effet de
pouvoir filtrer automatiquement le courrier en fonction de
l'identité (à noter que, par méchanceté ou par simple incompétence, un
certain nombre de sites Web refusent les sous-adresses). Si j'écris sur toutes les listes du
W3C avec une adresse
stephane+w3c@bortzmeyer.org
, je peux filtrer les
réponses facilement, en procmail avec une règle
comme :
:0: * !^TO_(stephane\+w3c)@ Mail/sdo/w3c
Et avec Sieve ? Ce langage, normalisé dans le
RFC 5228, permet d'exprimer des règles de
filtrage de manière standard. Notre RFC 5233 l'étend avec
l'extension subaddress
qui permettra, dès qu'elle
sera mise en œuvre par les logiciels, d'utiliser :
require ["envelope", "subaddress", "fileinto"]; if envelope :detail "to" "w3c" { fileinto "inbox.sdo.w3c"; }
Le :detail
a été introduit par l'extension
subaddress
. Il renvoie la sous-adresse
(:localpart
renvoie la partie à gauche du @ et
:user
renvoie le nom de la boîte, sans la sous-adresse).
Cette extension subaddress
avait
originellement été spécifiée dans le RFC 3598, que ce nouveau
RFC modifie sur des points de détail (l'annexe B détaille ce qui a changé).
Première rédaction de cet article le 26 mai 2008
Le groupe de travail LTRU (Language Tag
Registry Update) de l'IETF est très
en retard dans son projet de normalisation des futures étiquettes de langue, ces courtes
chaînes de caractères qui permettent d'indiquer la
langue d'un document ou de préciser la langue
qu'on souhaite utiliser sur Internet. Une des
raisons de ce retard est le débat sans fin sur les « extlangs »,
ces mécanismes permettant de représenter le concept de « macrolangue »
introduit par la norme ISO 639-3. En
gros, l'égyptien doit-il
se noter ar-arz
ou bien arz
? Et
le cantonais doit-il être
zh-yue
ou simplement yue
?
Dans la norme actuelle, le RFC 4646, les étiquettes de langue sont formées de plusieurs sous-étiquettes, chacune identifiant la langue, l'écriture ou le pays. Les sous-étiquettes qui identifient la langue sont tirées de ISO 639-1 ou ISO 639-2, normes qui placent toutes les langues sur un pied d'égalité.
Mais le monde des langues humaines est complexe. La définition
traditionnelle d'une langue est le critère de compréhension
mutuelle. Si différents que puissent être les accents, le vocabulaire
et l'orthographe, l'anglais
d'Australie peut être compris par un irlandais (parfois avec effort). C'est donc
la même langue, dont la sous-étiquette est en
. De
même, si proches que soient le français et le
catalan, par leur origine commune, deux
locuteurs de ces deux langues ne peuvent pas se comprendre. Il s'agit
donc bien de deux langues distinctes, dont les sous-étiquettes sont
fr
et ca
.
Naturellement, il existe une zone grise : le danois est-il si différent du norvégien ? L'arabe marocain du tunisien ? Le cas est d'autant plus difficile que certaines langues sont différentes à l'oral mais moins à l'écrit (c'est justement le cas de l'arabe). D'une certaine façon, il n'existe qu'une langue arabe. D'une autre, il en existe plusieurs (qui ne recoupent pas forcément exactement les frontières nationales). Parfois, l'histoire ou la politique contribuent à brouiller la perception linguistique correcte, comme dans le cas du mandarin, souvent appelé chinois par abus de langage, parce que c'est la langue de l'État chinois.
Pour tenter de modéliser ce monde très complexe et qui n'a pas été
conçu rationnellement, SIL, l'organisation qui
a été la principale responsable de la norme ISO
639-3 a créé un nouveau concept, celui de
macrolangue. Une macrolangue est une langue
unique, selon certains critères, et un groupe de langues selon
d'autres. Les deux plus célèbres sont le chinois (avec la
sous-étiquette zh
) et l'arabe
(ar
). Le registre d'ISO 639-3 indique donc pour
chaque langue si elle est couverte par une macrolangue. Le cantonais
est ainsi « couvert » par le chinois. Notons tout de suite que les
langues couvertes (parfois appelées par dérision « microlangues ») ne
sont pas des dialectes, ce
sont bien des langues séparées, typiquement sans mutuelle compréhensibilité.
Comment représenter les macrolangues dans le successeur du RFC 4646 ? La première idée, dont les prémisses
figurent dans le RFC 4646, était d'utiliser un concept nouveau,
l'Extended Language Subtag,
l'extlang. Dans ce système, tel que prévu à
l'origine, la première sous-étiquette identifiait la macrolangue (ou
la langue tout court pour les cas - les plus fréquents - où il n'y
avait pas de macrolangue) et un ou plusieurs
extlangs la suivaient. Ainsi, l'arabe tunisien était
ar-aeb
et le zapotèque de
la Sierra de Juárez était zap-zaa
(zap
étant la sous-étiquette de la macrolangue
zapotèque).
Pour comprendre l'intérêt de ce système, il faut voir que les
logiciels qui manipulent les étiquettes de langue, lorsqu'ils ne
trouvent pas une langue satisfaisante, cherchent en général en
supprimant les sous-étiquettes en partant de la droite, où se trouvent
les sous-étiquettes les moins significatives (ce mécanisme
est décrit dans le RFC 4647). Ainsi, si on
demande à un
système de recherche un document en az-Arab-IR
(l'azéri écrit dans l'écriture arabe tel qu'il est utilisé en
Iran), et qu'aucun document ne correspond à
cette étiquette, le logiciel peut chercher s'il a
az-Arab
(en abandonnant les spécificités
iraniennes) ou même az
(de l'azéri, quelles que
soient ses autres caractéristiques). Les extlangs
collaient bien à ce modèle. Une demande de sq-als
(le tosque) serait ainsi tronquée en
sq
(la macrolangue pour
l'albanais), ce qui ne serait pas une mauvaise
solution de repli.
Mais, à l'examen plus attentif des extlangs, plusieurs problèmes sont survenus. D'abord, la constation que le repli en tronquant par la droite ne donnait pas toujours des résultats corrects. Rien ne garantit que les langues couvertes par une même macrolangue sont mutuellement compréhensibles, bien au contraire. Donc, le repli « aveugle » obtenu en supprimant les sous-étiquettes en partant de la droite ne va pas être satisfaisant. Ensuite, les extlangs compliquent le modèle puisqu'ils représentent un nouveau cas à spécifier, à implémenter et à expliquer. Enfin, les extlangs peuvent porter un message erroné, celui comme quoi une langue particulière du groupe serait la langue principale. Ce message peut être souhaité (la plupart des arabophones sont très attachés à la référence à une langue arabe unique), ou pas mais il est toujours délicat, puisqu'il place les langues dans une hiérarchie. De nombreuses discussions, parfois houleuses, avaient animé le groupe de travail autour de ces problèmes.
C'est ainsi que LTRU avait, en décembre 2007, renoncé à
utiliser les extlangs et changé les
Internet-Drafts pour mettre en œuvre cette décision. Dans cette nouvelle version, le registre des langues gardait l'information comme quoi une langue était couverte par une macrolangue mais les étiquettes de langue étaient uniquement formées avec la langue elle-même. Le tosque était donc noté als
, le zapotèque de
la Sierra de Juárez zaa
et le mandarin
cmn
.
Mais, à l'IETF, les choses ne se passent pas
toujours aussi simplement. Cinq mois après ce changement, les
problèmes de la nouvelle version apparaissent, souvent soulevés par
des gens qui n'avaient guère contribué au travail concret, et rien dit
à l'époque de l'abandon des extlangs. Dans les cas où le
groupe autour d'une macrolangue comporte une langue dominante (ce qui
est le cas du chinois avec le poids du mandarin, ou celui de l'arabe
avec la référence qu'est l'arabe standard, mais
pas du zapotèque), de
nombreux documents ont déjà été étiquetés avec l'étiquette qui est
devenue celle de la macrolangue. Par exemple, les ressources en
mandarin ne devraient plus être notées zh
comme
avant mais cmn
. Que faire avec les innombrables
documents en mandarin qui avaient été étiquetés
zh
en suivant le RFC 4646 ?
Idéalement, le seul registre des langues suffirait à trouver des bonnes solutions. Mais, en fait, les décisions à prendre par le logiciel dépendent souvent de critères non linguistiques. Par exemple, si un utilisateur a configuré comme langue préférée le breton, il n'est pas déraisonnable de lui servir du texte en français. Non pas que les deux langues soient proches (la première est une langue celte et le second une langue romane) mais parce que, en pratique, presque tous les gens qui comprennent le breton comprennent également le français. Mais on ne peut pas mettre cette information (de taille importante et qui change souvent) dans le registre ! Il faudrait donc se résigner, ce qui ne semble pas facile, à ne pas avoir dans le registre d'information permettant un repli « intelligent ».
Après, là encore, un débat très chaud, le groupe LTRU a finalement fait marche arrière le 26 mai 2008, revenant aux extlangs. Cela nécessite de revenir à la précédente version des Internet-Drafts, de revoir documents et implémentations. Et sans garantie que cela ne recommence pas dans quelques mois...
Ma vue personnelle est que le système est instable : on peut bâtir un bon argumentaire pour les deux solutions (contre les extlangs, voir le texte de Mark Davis), aucune n'est parfaite, car les langues humaines n'ont pas été conçues pour faciliter la tâche de l'IETF. Il aurait fallu adopter une solution et s'y tenir mais les mécanismes de décision à l'IETF ne rendent pas cela facile.
Date de publication du RFC : Mai 2008
Auteur(s) du RFC : D. Forsberg (Nokia), Y. Ohba
(Toshiba), B. Patil
(Nokia), H. Tschofenig
(Siemens), A. Yegin (Samsung)
Chemin des normes
Première rédaction de cet article le 26 mai 2008
PANA est un protocole conçu pour transporter un protocole d'authentification lors d'accès à un réseau, EAP. Le RFC 5193 donne une vision de haut niveau de PANA, notre RFC 5191, quant à lui, définit en détail le protocole. Comme l'indiquent les appartenances des auteurs, PANA et EAP sont surtout utilisés dans le monde de la téléphonie mobile.
PANA est assez simple : les messages EAP (RFC 3748) sont encapsulés dans les messages PANA, qui sont transportés sur UDP. PANA ne fait pas d'authentification lui-même, il transporte juste des paquets. Les méthodes d'authenfication sont donc complètement extérieures à PANA.
La section 2 décrit la terminologie de PANA, pour laquelle il vaut mieux se référer au RFC 5193. La machine qui veut accéder au réseau (par exemple un téléphone portable) est le client PANA, le PaC. La machine avec laquelle elle parle est le serveur PANA, le PAA. Pour prendre sa décision, ce serveur va souvent parler à un serveur AAA, par exemple avec la protocole Radius (RFC 2865). Une fois l'authentification terminée, le trafic réel passera par un routeur ou autre machine d'accès, l'EP. Souvent, EP et PAA seront dans la même boîte et communiqueront via une API
La section 3 résume le protocole : les dialogues PANA sont composés de requêtes et de réponses, chaque message portant ou ou plusieurs AVP. Le transport utilisé est UDP, choisi pour sa simplicité de mise en œuvre.
Puis la section 4 détaille le protocole. Le PaC ou le PAA
peuvent être à l'origine du dialogue. Lorsque le PaC veut
s'authentifier (section 4.1), il envoie une requête
PANA-Client-Initiation
au PAA. Notez que le
mécanisme de découverte du PANA n'est pas spécifié ici (une solution
possible est décrite dans le RFC 5192). Le PAA répond alors
avec une PANA-Auth-Request
, qui porte la charge
EAP. Un échange de messages PANA-Auth-Answer
et
PANA-Auth-Request
suivra alors, jusqu'à ce qu'EAP
aie terminé. (La liste complète des messages possibles figure dans la section 7.) Si l'authentification est un succès, le dernier message
peut également contenir des consignes pour le PaC comme de
reconfigurer son adresse IP. Les autres
sous-sections de la section traitent de la ré-authentification en
cours de session ou bien de la terminaison de la session.
La section 5 précise les règles de traitement des messages, notamment en cas de perte de paquets (UDP ne promettant pas de délivrer tous les paquets). Chaque participant au dialogue PANA doit maintenir une séquence numérotée des paquets, pour pouvoir détecter et corriger une perte. La même section explique aussi comment s'assurer de l'intégrité des messages, via un hachage cryptographique.
Le format exact des messages est normalisé dans les sections 6 et 8, qui présentent les AVP, qui sont très proches de ceux du RFC 3588.
Vu le but de PANA, transporter un protocole d'authentification, il n'est pas étonnant que la section sur la sécurité soit détaillée. Cette section 11 du RFC explique donc les mécanismes qui, de concert avec ceux d'EAP, vont permettre d'utiliser PANA même sur un réseau peu sûr.
Première rédaction de cet article le 23 mai 2008
Toute SDO publie des normes qui ont besoin
d'être référencées. Il faut pouvoir, de manière non ambiguë, dire « Ce
compilateur Lisp est conforme à
la norme ISO/IEC 13816:2007
ou bien « Ce
routeur IP implémente le RFC 4970 ». L'IETF voit en ce moment une
vive discussion sur l'achat d'un ISSN pour
identifier la série des RFC.
Cette discussion a été lancée par Ray Pelletier, de l'IETF Trust ; sa proposition est d'acheter un numéro ISSN, pour identifier la série des RFC. La série complète, pas juste un RFC particulier, puisque le rôle d'un ISSN n'est pas de désigner un seul document. La question de la citation d'un RFC particulier reste donc ouverte (l'IETF a une norme pour cela, le RFC 2648, mais personne ne l'utilise).
Cet ISSN permettrait par exemple des références correctes aux RFC,
notamment dans la littérature « académique ». L'ISSN peut s'exprimer tel
quel (ISSN
0395-2037
) ou bien via un
URN, selon le RFC 8254 : urn:ISSN:0395-2037
.
Le débat sur les identificateurs a toujours fait rage dans les communautés de bibliothécaires, de documentalistes et autres professionnels de la gestion de l'information. (Voir par exemple les articles d'Emmanuelle Bermès, de la BNF.) Le fil de discussion qui a suivi l'annonce de l'IETF Trust a donc, logiquement, cité les DOI (une très mauvaise idée), les ISBN et plusieurs autres familles d'identificateurs.
Comme l'a noté Steve Crocker, le but principal est sans doute simplement de calmer les trolls qui s'obstinent à prétendre que les normes IETF ne sont pas de vraies normes. En gros, l'ISSN pour les RFC serait l'équivalent du costard/cravate pour les humains...
Finalement, l'ISSN a été demandé et obtenu : 2070-1721.
Première rédaction de cet article le 23 mai 2008
Un récent petit incident, sans conséquence pratique, la
réutilisation de l'ancienne adresse IP d'un
serveur racine du DNS, le serveur
L.root-servers.net
, a mis en évidence la question
de la gestion des serveurs racine. Onze organisations gèrent un de
ces treize serveurs. Qui les a désignées ? Qui les contrôle et les
surveille ? Que se passe t-il s'il l'une d'elles ne rend plus un service
correct ? Que se passe t-il si une organisation se porte volontaire
pour remplacer l'une d'elles ?
Revenons d'abord sur ce minuscule incident. Le serveur racine
L.root-servers.net
, géré par
l'ICANN, a changé d'adresse IP le 1 novembre
2007, passant de 198.32.64.12
à
199.7.83.42
. Compte-tenu de la nature
particulière des serveurs racine (toutes les résolutions DNS
commencent par eux, jusqu'à ce que les caches soient peuplés), de tels changements sont difficiles
à propager. Il faut mettre à jour d'innombrables fichiers de
configuration un peu partout dans le monde (avec
BIND, c'est typiquement dans le fichier
root.hints
ou db.root
). Il
n'est donc pas étonnant que, des mois plus tard, l'ancienne adresse
reçoive encore des requêtes. (Plus bizarre est le fait qu'elle reçoive
des requêtes autre que la requête initiale, dite de
« priming », après laquelle le
résolveur DNS, aurait dû se rendre compte de
son erreur. Mais c'est une autre histoire.)
L'ancienne adresse de L venait de l'espace d'adresses allouées à
ep.net
. Et
c'est là que commence le problème. ep.net
a
commencé à annoncer en BGP les adresses
incluant l'ancienne adresse du serveur racine et, plus fort, un
serveur DNS répondait bien à cette ancienne adresse. Ses réponses
étaient apparemment correctes (identiques à celles des « vrais »
serveurs racine) donc l'incident n'a eu aucune conséquence
pratique. Mais pourquoi ep.net
avait-il fait
cela ? Avaient-ils le droit ?
Je passe sur les débats parfois assez puérils sur ce
point. Bill Manning, le responsable
d'ep.net
, étant une personnalité controversée, il
n'est pas étonnant que certaines accusations soient allées assez loin
(voir par exemple le règlement de comptes de David
Conrad et la réponse de CommunityDNS,
qui travaillait avec Manning).
Mais la discussion a soulevé un point d'habitude pudiquement laissé
dans l'ombre. Qui est responsable des serveurs racine ? Si un
opérateur de serveur racine ne fait pas son travail comme attendu
(Bill Manning opère un autre serveur racine, le
B.root-servers.net
), peut-on le virer ? À partir
de quel niveau de non-service ? Et, sans citer de cas aussi dramatiques
(après tout, les opérateurs actuels font plutôt bien leur travail), est-ce
qu'une nouvelle organisation peut candidater et proposer de remplacer
un des serveurs existants (certains, sans être clairement en panne, ne
sont pas très performants) ?
La réponse à toutes ces questions est la même et elle représente un
des secrets les mieux gardés de la gouvernance
Internet : personne ne sait. Aucune règle, aucun contrat,
n'encadre le travail des opérateurs de serveurs racine. (Une seule
petite exception à cette absence de contrat, le Mutual
Responsibilities Agreement entre l'ISC et l'ICANN.) Tout dépend
uniquement de leur bonne volonté. Certes, elle n'a pas manqué jusqu'à présent,
avec des félicitations particulières pour les opérateurs du
F.root-servers.net
, de loin les plus dynamiques et ceux qui se soucient le plus d'informer la communauté des utilisateurs. Mais cette bonne volonté se maintiendra t-elle dans le futur ? Est-ce acceptable qu'une ressource aussi critique pour l'Internet dépende juste de cela ?
Les onze organisations ont été désignées il y a très longtemps, parce que Jon Postel les connaissait et personne aujourd'hui n'ose remettre en cause cette désignation. Aucune organisation, et surtout pas l'ICANN, n'a de légitimité suffisante pour « virer » un serveur racine. La liste est donc, de facto, fermée et non modifiable.
Quelques autres articles sur ce sujet : plein de détails techniques sur le blog de Renesys (gâchés par un titre racoleur, voir aussi la suite et leur exposé à NANOG) et un bon résumé de Danny McPherson, qui plaide pour un contrôle accru par l'ICANN.
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : J. Laganier (DoCoMo Euro-Labs), T. Koponen (HIIT), L. Eggert (Nokia)
Expérimental
Première rédaction de cet article le 22 mai 2008
Le protocole HIP, décrit dans le RFC 5201 est très bien adapté au cas où l'adresse IP (le localisateur) change après l'établissement d'une association. Mais cela laisse ouvert le grand problème de la connexion initiale. Comment trouver une machine HIP ? Par le mécanisme de rendez-vous du RFC 5204 ? C'est certainement une bonne solution mais, alors, comment les machines HIP sont-elles connues du serveur de rendez-vous ? C'est là que notre RFC rentre en jeu pour normaliser un mécanisme d'enregistrement auprès d'un service. (Il a depuis été remmplacé par le RFC 8003.)
Le mécanisme est très simple et le RFC court. On réutilise
simplement les établissements d'associations de HIP, avec de nouveaux
types de paramètres, notamment REG_INFO
(pour
l'hôte qui accepte d'être registrar, c'est-à-dire
d'enregistrer) et REG_REQUEST
(pour celui qui
demande un enregistrement). Le mécanisme exact est détaillé dans la
section 3 et les nouveaux
paramètres dans la section 4.
HIP authentifiant les deux parties bien plus solidement que IP seul, le registrar peut alors décider s'il accepte l'enregistrement ou pas (sections 3.3 et 6).
Le rendez-vous, normalisé dans le RFC 5204 est donc une simple application de notre RFC mais d'autres pourront apparaître à l'avenir.
Date de publication du RFC : Septembre 2001
Auteur(s) du RFC : K. Ramakrishnan (TeraOptic
Networks), S. Floyd (ACIRI), D. Black (EMC)
Chemin des normes
Première rédaction de cet article le 21 mai 2008
De tout temps, un des plus gros problèmes de l'Internet a été de gérer la congestion, le fait qu'il y a plus de paquets IP qui veulent passer par les tuyaux que de capacité pour les faire passer. La réponse classique d'IP à la congestion est de laisser tomber certains paquets, les protocoles de plus haut niveau étant alors censés ralentir en réponse à ces pertes. Notre RFC normalise une autre méthode : lorsque le routeur sent que la congestion est proche, il marque les paquets IP pour indiquer aux machines terminales qu'il faudrait ralentir. Une excellente page, par une des auteures du RFC, ECN (Explicit Congestion Notification) in TCP/IP décrit ce système, qui n'a malheureusement pratiquement pas connu de déploiement.
C'est le RFC 2481 qui avait proposé pour la première fois ce mécanisme (et notre RFC le remplace et passe du statut « expérimental » au statut « chemin des normes »). La méthode classique, laisser tomber des paquets, rappelée dans la section 1 du RFC, a toujours bien marché. Le réseau est traité comme une boîte noire, on y envoie des paquets et la seule signalisation reçue est le fait que certains paquets ne ressortent pas. Les protocoles de plus haut niveau, comme TCP (RFC 793) ou DCCP (RFC 4340) ralentissent alors leur débit. Mais cela fait perdre des données, juste pour envoyer une indication. D'où l'idée de prévenir avant que la congestion ne soit réellement installée, en modifiant deux bits de l'en-tête IP, pour indiquer que le routeur a du mal à suivre. Les machines terminales, si elles gèrent ECN, vont alors ralentir leur débit de manière plus efficace que si elles avaient attendu en vain un paquet (Active Queue Management, décrit dans le RFC 7567 et dans la section 4 de notre RFC 3168).
Avec la section 5, commence la description des changements effectués dans IP. Deux bits de l'en-têtes sont réservés pour ECN. Ils peuvent prendre les valeurs 01, 10 (ces deux valeurs, dites ECT, indiquant que l'expéditeur du paquet comprend ECN, l'intéressante section 20 explique pourquoi il y en a deux), 00 (pas d'ECN accepté) et 11 (dite CE, cette valeur indiquant la congestion). Ces deux bits se placent juste après le DSCP (l'ancien TOS) du RFC 2474. Si le routeur détecte que la congestion est proche, par exemple parce que ses files d'attente de sortie se remplissent, et que le paquet IP indique que l'expéditeur comprend ECN, alors le routeur peut, au lieu d'attendre la congestion, mettre un bit à 1 pour indiquer le problème au destinataire.
La section 6 du RFC décrit ensuite ce que le protocole de transport au dessus d'IP devrait faire avec les bits ECN (seul TCP est couvert dans ce RFC). 6.1 couvre TCP et modifie donc la section 3.1 du RFC 793. Deux nouveaux bits sont réservés dans l'en-tête TCP, permettant aux deux machines qui se parlent en TCP de se prévenir qu'elles comprennent ECN et, si nécessaire, d'indiquer le début de congestion, détecté en regardant les paquets IP modifiés par le routeur. Une fois ECN ainsi « négocié », les paquets IP porteront le bit ECN adapté, comme on le voit avec tcpdump :
12:04:58.525094 IP (tos 0x2,ECT(0), ttl 64, id 2069, offset 0, flags [DF], proto TCP (6), length 142) 192.134.4.97.50418 > 192.134.4.69.80: P 1:91(90) ack 1 win 46 <nop,nop,timestamp 3266115 18052032> 12:04:58.525242 IP (tos 0x0, ttl 64, id 61994, offset 0, flags [DF], proto TCP (6), length 52) 192.134.4.69.80 > 192.134.4.97.50418: ., cksum 0x1463 (correct), 1:1(0) ack 91 win 46 <nop,nop,timestamp 18052032 3266115>
ECT(0) désignant le motif 10 (« je comprends ECN »). Les paquets de pur acquittement TCP (le deuxième paquet affiché ci-dessus) ne portent pas de bits ECN.
Les sections 8 à 11 du RFC discutent de détails pratiques et d'évaluation d'ECN. Les section 18 et 19 sont consacrées au cas où une middlebox dans le réseau modifie maladroitement les bits ECN. Les sections 21 et 22 ne normalisent rien mais expliquent les choix qui ont été fait dans les en-têtes de paquets, en revenant sur les anciennes définitions de ces en-têtes.
L'Internet étant infecté de machines non
gérées et non modifiables, comme certains routeurs bas de gamme (les
CPE, par exemple), il est très difficile de
déployer de nouveaux protocoles ou de nouveaux services. Ainsi, sept
ans après sa normalisation formelle, ECN ne passe toujours pas avec
certains sites, où les paquets marqués sont jetés. La section 6.1.1.1
du RFC discute ce problème (voir aussi http://www.icir.org/tbit/ecn-tbit.html
).
C'est pour cela que beaucoup de systèmes d'exploitation viennent avec ECN coupé par défaut. Par exemple, sur Linux, on peut voir si ECN est accepté avec :
% sysctl net.ipv4.tcp_ecn net.ipv4.tcp_ecn = 0
et les développeurs discutent régulièrement de son activation par défaut.
FreeBSD, lui, ne semble pas avoir de support
ECN du tout ? Un guide complet de configuration pour les
Cisco se trouve en http://www.cisco.com/en/US/docs/ios/12_2t/12_2t8/feature/guide/ftwrdecn.html
. Pour
MPLS, on peut consulter le RFC 5129. Autre lecture possible,
une
proposition d'activer ECN par défaut.
Depuis des années, des utilisateurs demandent un support de ECN dans echoping mais ça reste à développer. Il n'est pas évident que ECN doive être sous le contrôle des applications.
Première rédaction de cet article le 20 mai 2008
On voit souvent des administrateurs réseaux parler de « classe B » ou de « classe C » en se référant à un groupe d'adresses IP. Ces termes sont dépassés et reflètent une réalité qui a disparu depuis longtemps. Ils ne devraient plus être employés.
Pour expliquer pourquoi, je dois faire un détour sur la façon dont
fonctionne l'adressage IP, normalisé, pour IP
version 4, dans le RFC 791. Les adresses IPv4
faisant 32 bits, ce protocole permet 2^32 soit
plus de quatre milliards d'adresses. Pas question que les routeurs aient une route vers chacune de
ces adresses. Leur mémoire n'y suffirait pas et, surtout, le rythme de
changement serait trop élevé. On regroupe donc aujourd'hui les adresses
contiguës en préfixes de
longueur N où N est le nombre de bits qui servent à identifier le
préfixe, les autres bits identifiant la machine. En IPv4 et IPv6, ce
nombre de bits n'est pas fixé par le protocole, il est déterminé par
l'administrateur système. On note un réseau par son préfixe, suivi
d'une barre oblique et de la longueur du préfixe. Par exemple, le préfixe
192.0.2.128/25
a une longueur N de 25 bits, ces
25 bits valant 11000000 00000000 00000010 10000000
,
laissant 7 bits pour identifier une machine sur ce réseau. Si
plusieurs routes sont possibles pour une destination donnée, le
routeur prendra la plus spécifique (celle dont N
est le plus grand).
A t-on toujours fait comme cela ? Non. Il y a de nombreuses années,
les préfixes étaient de taille fixe, on avait uniquement le choix en
des préfixes de longueur 8, baptisés « classes A », de longueur 16, les
« classes B » et de longueur 24, les « classes C ». Ce système était
très rigide et gaspillait considérablement les adresses (si une classe C
ne suffisait pas, pas possible de prendre un /23
,
il fallait sauter directement à une classe B). Il a donc été abandonné
au profit de l'adressage actuel, qui avait été baptisé
CIDR pour Classless Inter-Domain
Routing. Classless donc, « sans
classe ». Ce nom dit bien ce qu'il veut dire, les classes ont disparu.
Le premier RFC sur les idées qui mèneront à CIDR a été le RFC 1338 en juin 1992. Le RFC 1467 en août 1993 faisait le point sur le déploiement de CIDR. Les RFC 1518 et RFC 1519 en septembre 1993 sont les premier à décrire CIDR sous sa forme actuelle, pendant que le RFC 1517 décrivait les motivations et les problèmes que CIDR visait à résoudre. C'est donc depuis quinze ans que les classes ont disparu ! Révisée, la norme actuelle est le RFC 4632. Comme on le voit, l'adressage actuel est très ancien. Il est très inquiétant que des enseignants ignorants donnent toujours des cours IP où les classes sont citées, sans préciser qu'elles n'ont qu'un intérêt historique.
Les classes se voient encore un peu dans certaines techniques comme
le DNS où les
délégations dans in-addr.arpa
se font sur des
frontières d'octets. Ce problème a
été largement réglé par le RFC 2317.
Pendant les quelques années où la communauté Internet testait la
nouvelle technique, certains termes avaient été utilisés, qui n'ont
plus de raison d'être. C'est ainsi qu'on parlait de
supernetting pour désigner
l'agrégation de plusieurs classes en un préfixe
plus général (cette technique étant la base de CIDR, elle n'a plus
besoin d'un nom spécifique, même s'il faut encore apparemment dire à
IOS ip classless
pour
qu'il l'accepte). De même, les VLSM (Variable Length Subnet
Mask) ont été oubliés : le masque du réseau est désormais
toujours de longueur variable.
Le successeur d'IPv4, IPv6, est, lui, parti proprement en tenant compte de l'expérience de son prédécesseur et a toujours été « sans classe ».
Date de publication du RFC : Mars 2008
Auteur(s) du RFC : T. Chown (University of Southampton)
Pour information
Première rédaction de cet article le 20 mai 2008
Une technique classique des méchants craqueurs qui cherchent à pénétrer un gentil réseau est de balayer (to scan) l'ensemble des adresses IP à l'intérieur du réseau, pour voir lesquelles répondent et ainsi trouver des cibles. Par exemple, Slammer l'utilisait. Mais en IPv6, où le nombre d'adresses possibles est infiniment plus grand, cette tactique est-elle encore efficace ? (Notez que ce RFC a, depuis, été remplacé par le RFC 7707.)
Imaginons que le craqueur aie déterminé que le préfixe IP du réseau
de sa victime est le 192.0.2.128/25
. Il reste 7
bits pour les machines soit 128 victimes potentielles à interroger, ce
qui ne prend que quelques secondes pour un programme comme
fping. Cette technique est donc très utilisée
pour avoir une liste des adresses IP utilisées... et donc des cibles
possibles. Mais en IPv6, si la victime a le
réseau de préfixe 2001:DB8:AF:42::/64
, comment
le balayer de manière efficace ? Cela fait 64 bits pour les machines
donc 18446744073709551616 adresses à examiner, ce qui ne peut pas se
faire en un temps raisonnable (sections 2.1 et 2.2 du RFC).
Certains en ont donc déduit que le balayage (scanning) était impossible en IPv6 et que donc, sur ce point, IPv6 offrait davantage de sécurité qu'IPv4.
Mais notre RFC montre que ce n'est pas si simple et qu'il existe d'autres méthodes que la force brute pour trouver les machines allumées (un excellent article de Steve Bellovin avait déjà déblayé ce terrain).
La section 2.3 parle par exemple de l'exploitation de conventions
d'adressage. Si l'administrateur du réseau
2001:DB8:AF:42::/64
cité plus haut numérote ses
machines 2001:DB8:AF:42::1
,
2001:DB8:AF:42::2
,
2001:DB8:AF:42::3
, etc, l'attaquant n'aura à
tester qu'une petite partie des adresses théoriques. Si au lieu
d'adresses calculées ainsi, on utilise la traditionnelle
autoconfiguration sans état d'IPv6 (RFC 4862), la
connaissance du fournisseur des cartes Ethernet
fournit déjà un bon moyen de sérieusement réduire l'espace de recherche.
Les sections 3 et 4 du RFC listent l'ensemble des techniques connues et que le méchant pourrait utiliser pour arriver néanmoins à balayer un réseau IPv6. La section 4 concerne les cas où l'attaquant est lui-même sur ce réseau et le problème est alors assez simple (il lui suffit d'espionner les paquets ND (Neighbor Discovery, cf. RFC 4861). La section 3 parle des cas où l'attaquant n'est pas sur le réseau. Sa tâche est alors plus difficile mais reste faisable : par exemple la section 3.3 détaille l'information qu'on peut tirer d'un transfert de zone DNS, et la 3.4 l'intérêt qu'on peut trouver à regarder les journaux d'un gros serveur, journaux où on trouvera les adresses de clients qui sont autant de cibles potentielles.
Plus moderne est l'observation des pairs dans un réseau P2P (section 3.5). La plupart des protocoles de P2P, par exemple BitTorrent, mettent en rapport direct les « offreurs » et les « preneurs » et, en offrant du contenu intéressant, on peut récolter beaucoup d'adresses IP de machines.
La section 5 passe aux recommandations et contre-mesures :
utilisation d'adresses « vie privée » (RFC 8981), dont la
durée de vie est limitée, utilisation d'adresses
EUI-64 (RFC 4291, cf. section 5.1) mais sans l'adresse
MAC (section 5.3), configuration du serveur
DHCP (RFC 8415) pour ne pas attribuer les adresses
séquentiellement à partir de ::1
(section 5.4),
etc.
Enfin, en guise de synthèse, la section 7, qui résume le problème et les moyens de le limiter, rappelle que dissimuler les adresses IP des machines est de la Sécurité par l'obscurité : cela peut ralentir l'attaquant, mais cela ne doit certainement pas être utilisé comme unique moyen de défense, car, tôt ou tard, l'attaquant trouvera ces adresses.
Un nouveau RFC, plus détaillé, a remplacé celui-ci, le RFC 7707.
Date de publication du RFC : Mai 2008
Auteur(s) du RFC : Thomas Narten (IBM), Harald
Alvestrand (Google)
Première rédaction de cet article le 20 mai 2008
Dernière mise à jour le 24 juin 2015
Un aspect peu connu du travail de normalisation est la nécessité de tenir des registres de certains paramètres, lorsque la liste de ces derniers n'est pas fixée dans un RFC. Par exemple, les algorithmes publiés dans le DNS pour IPsec ne sont pas définis de manière limitative dans le RFC 4025 mais sont enregistrés dans un registre public. Pour les RFC, ces registres sont tenus par l'IANA. Celle-ci ne décide pas quels registres elle doit tenir ni à quelle condition un nouveau paramètre peut y rentrer, elle applique les décisions contenus dans la section IANA Considerations d'un RFC. C'est cette section qui était décrite ici. Ce RFC a depuis été remplacé par le RFC 8126.
Prenons l'exemple du RFC 3315 (DHCP). Sa section 24 contient le
texte
This document defines several new name spaces associated with DHCPv6
and DHCPv6 options:
- Message types
- Status codes
- DUID
- Option codes
IANA has established a registry of values for each of these name
spaces, which are described in the remainder of this section. These
name spaces will be managed by the IANA and all will be managed
separately from the name spaces defined for DHCPv4.. En application de ce texte,
l'IANA a créé le registre
DHCPv6 and DHCPv6 options qu'on peut consulter en ligne à https://www.iana.org/assignments/dhcpv6-parameters
. Et comment ajoute-t-on des entrées dans ce registre ? En
suivant les règles données dans ce même RFC :
New DHCP option codes are tentatively assigned after the
specification for the associated option, published as an Internet
Draft, has received expert review by a designated expert [11]. The
final assignment of DHCP option codes is through Standards Action, as
defined in RFC 2434 [11].
.
Pour aider les auteurs de RFC à écrire correctement cette section IANA Considerations, notre RFC 5226, qui succède au RFC 2434, pose quelques règles.
Les sections 1 et 2 du RFC décrivent le problème général de la gestion d'un espace de nommage (namespace). Tous ces espaces n'ont pas les mêmes caractéristiques. Certains sont très petits (le champ protocole, qui n'a que huit bits soit 256 valeurs possibles, cf. RFC 5237) et doivent donc être gérés avec prudence, certains sont hiérarchiques comme le DNS ou comme les OID et peuvent donc être délégués, certains sont immenses, et peuvent être gérés avec moins de précautions (mais nécessitent quand même des règles, comme expliqué dans la section 2).
La section 3 décrit le rôle des experts sur
lesquels doit parfois s'appuyer l'IANA. Certains registres nécessitent
en effet un choix technique avec l'enregistrement d'un nouveau
paramètre et l'IANA n'a pas forcément les compétences nécessaires pour
cette évaluation. Elle délègue alors cette tâche à un expert
(designated expert). Par exemple, pour le registre des langues, défini par le RFC 4646, l'expert actuel est Michael Everson. Ce registre utilise également une autre
possibilité décrite dans cette section, une liste de discussion qui sert à un examen collectif des requêtes
(pour le registre des langues, cette liste est
ietf-languages@iana.org
). La section 3 discute
des autres choix qui auraient pu être faits (par exemple un examen par le groupe de travail qui a
créé le RFC, ce qui n'est pas possible, les groupes de travail IETF
ayant une durée de vie limitée). Elle explique ensuite les devoirs de
l'expert (comme la nécessité de répondre relativement rapidement,
section 3.3, chose qui est loin d'être toujours faite).
La section 4 est consacrée à la création d'un nouveau registre. Si un RFC doit demander une telle création, il doit préciser quelle politique d'enregistrement devra suivre l'IANA. C'est une des parties les plus intéressantes du RFC, notamment sa section 4.1 qui explique les politiques possibles, par exemple :
iso.org.dod.internet.private.enterprise
sont un
bon exemple (https://www.iana.org/assignments/enterprise-numbers
mais
attention, le registre est lourd à charger). C'est sans doute la plus
« libérale » des politiques d'enregistrement.Parmi les autres points que doit spécifier le RFC qui crée un nouveau registre, le format de celui-ci (section 4.2). À noter que l'IANA n'utilise pas d'outils pour tester ce format (les registres IANA étaient de simples fichiers texte, maintenus avec un éditeur ordinaire mais ont migré pour la plupart vers XML, depuis la publication de ce RFC) et que des erreurs de syntaxe sont parfois apparues dans des registres.
La section 5 couvre l'enregistrement de nouveaux paramètres dans un registre existant. C'est elle qui précise, entre autres, que l'IANA ne laisse normalement pas le choix de la valeur du paramètre au demandeur (mais, en pratique, l'IANA est sympa et a accepté beaucoup de demandes humoristiques comme le port TCP n° 1984 pour le logiciel Big Brother...)
Enfin, diverses questions sont traitées dans la section 6, comme la récupération de valeurs qui avaient été affectées mais qui ne le sont plus (le RFC 3942 l'avait fait mais c'est évidemment impossible dès que les paramètres en question ont une... valeur, ce qui est le cas entre autres des adresses IP).
Bien que la plupart des allocations effectuées par l'IANA ne sont guère polémiques (à l'exception des noms de domaine et des adresses IP, qui sont des sujets très chauds), notre RFC 5226 prévoit une procédure d'appel, décrite en section 7. Cela n'a pas suffit à régler quelques cas pénibles comme l'enregistrement de CARP.
Ce RFC 5226 remplace le RFC 2434 (et a lui-même été remplacé depuis par le RFC 8126). Les principaux changements sont détaillés dans la section 10. Par exemple, le terme de propagande IETF Consensus a été remplacé par le plus neutre IETF Review. (Les organisations qui parlent de leur consensus policy le font en général pour faire taire les critiques, en prétendant que tout le monde est d'accord.) Les changements sont en général de simples clarifications, le nouveau RFC étant plus directif que l'ancien. Les autres changements sont souvent l'ajout de questions nouvelles, comme la récupération de valeurs qui avaient été allouées.
Les relations entre l'IETF et l'IANA sont fixées par le MOU contenu dans le RFC 2860. À noter que tout n'est pas couvert dans ce RFC, notamment des limites aux demandes de l'IETF. Que se passerait-il par exemple si l'IETF demandait à l'IANA, qui ne facture pas ses prestations, de créer un registre de milliards d'entrées, très dynamique et donc très coûteux à maintenir ? Pour l'instant, l'IANA ne peut pas, en théorie, le refuser et la question s'est parfois posée à l'IETF de savoir si tel ou tel registre n'était pas trop demander.
Puisque l'IANA est un acteur important de l'Internet, rappelons aussi que, bien que la fonction de l'IANA soit actuellement assurée par l'ICANN, la tâche de gestion des protocoles et des registres n'a rien à voir avec les activités, essentiellement politiciennes, de l'ICANN.
Première rédaction de cet article le 18 mai 2008
Sur une machine Unix, on a souvent envie de lancer des programmes qui durent longtemps, parfois des jours ou des semaines, et qu'on souhaite regarder de temps en temps, sans pour autant bloquer un terminal (d'autant plus qu'on travaille depuis différents postes). screen est un outil assez peu connu pour assurer cette tâche. Il permet de suivre un programme en cours d'exécution, puis de se détacher de lui tout en le laissant tourner et de se rattacher ensuite à volonté.
Si le programme est prévu pour tourner sans surveillance, directe, si c'est un démon, screen n'est pas nécessaire. Mais si on lance une grosse compilation sur sa machine Gentoo ou FreeBSD ? Si on a lancé un client BitTorrent pour télécharger des fichiers et qu'on veut voir de temps en temps où il en est ? Si c'est sur la machine de son bureau, on peut toujours laisser un xterm ouvert. Mais si c'est sur une machine dédiée hébergée chez OVH ou Slicehost ?
Avec la solution du xterm ouvert, je ne peux pas regarder dans la journée au bureau et le soir à la maison. Même chose avec des trucs comme nohup. Avec screen, par contre, je peux lancer le programme, regarder s'il tourne, me détacher du programme (screen continuera à tourner, même sans terminal, et le programme avec lui) puis plus tard me ré-attacher, depuis une toute autre machine.
Les trois commandes de base avec screen dont donc :
screen
pour lancer une nouvelle session. On
peut aussi taper screen MONPROGRAMME
pour lancer
le programme immédiatement (screen se terminera lorsque le programme
MONPROGRAMME se terminera).Control-a d
(par défaut, mais c'est
modifiable) pour se détacher.screen -r
pour reprendre une session en cours.
Personnellement, j'utilise aussi beaucoup l'option
-S
qui permet de donner un nom à une session
screen. screen -list
permet ensuite d'afficher
les sessions et screen -r NOMSESSION
de reprendre
celle désirée :
~ % screen -S toto [Ici, on fait un Control-a d] [detached] ~ % screen -list There are screens on: 8116.toto (Detached) 3509.BitTorrent (Detached) 2 Sockets in /var/run/screen/S-stephane.
(screen permet aussi d'avoir plusieurs fenêtres dans une même session mais je n'utilise pas cette possibilité.)
L'un des intérets de screen est de surveiller des programmes
bavards (comme une grosse compilation) et il peut donc être utile de
remonter dans les messages précédemment affichés. Control-a
<escape>
fera passer en mode Copy
et on pourra chercher en arrière avec Control-r
.
screen peut se configurer, notamment via son fichier
~/.screenrc
. Par exemple, certains utilisateurs
d'Emacs n'apprécie pas le
Control-a
qui commence les commandes (dans Emacs,
cette séquence permet d'aller au début de la ligne) et le
reconfigurent dans .screenrc
:
# Control-z, plutôt escape ^Zz
L'excellent site dotfiles.org
a une section sur des exemples de tels
fichiers.
Un dernier truc amusant qu'un utilisateur m'a signalé. screen peut
aussi s'attacher à un terminal physique et peut donc servir
d'émulateur de terminal, de
concurrent de minicom. Ici,
la machine preston
est accessible par une liaison
série :
% screen -S preston /dev/ttyS0 NetBSD/sparc64 (preston) (console) login: [Control-A d et on est détaché]
J'ai aussi écrit un article sur screen spécifique à BitTorrent. On peut trouver une excellente introduction à screen http://linuxgazette.net/147/appaiah.html
ou une plus courte en
http://www.mattcutts.com/blog/a-quick-tutorial-on-screen/
ou bien http://www.redhatmagazine.com/2007/09/27/a-guide-to-gnu-screen/
.
Le principal concurrent de screen est tmux. Un tableau des commandes comparées donne une idée des fonctions supplémentaires de tmux (c'est vu par les gens de tmux, attention). Il existe un autre article de comparaison.
Auteur(s) du livre : Patrick Andries
Éditeur : Dunod
978-2-10-051140-2
Publié en 2008
Première rédaction de cet article le 17 mai 2008
Unicode est un jeu de caractères permettant de représenter toutes les écritures du monde. Il serait donc logique qu'il soit documenté dans plusieurs langues mais, sauf erreur, ce livre de Patrick Andries est le premier à parler d'Unicode en français.
Le sujet est très riche et très complexe. Certaines personnes,
ignorant l'ampleur du problème, disent parfois
qu'Unicode est « trop complexe ». La réalité
est que le monde est complexe ; Unicode choisissant de suivre les
usages existants (au lieu que les usages se plient aux limites de la
technique), il doit traiter d'innombrables cas et le résultat est
certainement complexe, mais pas inutilement complexe. Patrick Andries
connait bien Unicode pour être membre du Consortium
Unicode depuis des années et pour être un promoteur de
cette norme en français (son site http://hapax.qc.ca/
regorge d'informations sur Unicode). Il s'est donc attaqué à la tâche
d'écrire le premier livre en français sur Unicode.
Cela suppose quelques défis, notamment de trouver des traductions correctes et compréhensibles pour certains termes. Je n'ai pas reconnu du premier coup le word joiner (U+2060) derrière le « gluon de mots » et les « seizets d'indirection » m'ont également dérouté, même si le terme est bien plus correct que l'anglais surrogates. D'une manière générale, ce livre est peut-être un peu trop difficile à lire à force de vouloir être exact et de toujours utiliser des termes corrects, en évitant raccourcis et approximations. Il parait que la langue française est bien adaptée à cela...
Le plan du livre est classique ; concepts de base sur les écritures (chapitre 1) ; les jeux de caractères (chapitre 2) ; les concepts de base d'Unicode (chapitres 3 et 4) ; grand tour d'horizon des caractères dont on dispose dans Unicode (chapitres 5 à 8) ; applications d'Unicode, notamment dans le monde des protocoles et formats Internet (chapitres 9 à 11) ; l'internationalisation de logiciels (chapitre 12, très intéressant mais dont le lien avec Unicode est ténu) ; Unicode et les polices (chapitre 13, dont je n'ai vu aucun équivalent dans les autres livres sur Unicode).
Les exemples de programmation du chapitre 12 sont presque tous empruntés à C# ou à Java, des langages plutôt « costard / cravate », qui ont souvent l'avantage d'un grand nombre de bibliothèques pour manipuler l'Unicode (par exemple via un accès facile à ICU) et le défaut d'un modèle de caractères peu Unicodien (par exemple, dans Java, les caractères en dehors du Plan Multilingue de Base ne sont pas des caractères Unicode comme les autres, contrairement à Python ou Haskell). Pour avoir une petite idée du support Unicode dans d'autres langages, on peut regarder mon article Unicode en divers langages.
De même, la plupart des exemples concrets, par exemple sur la saisie de caractères Unicode, ne concernent que MS-Windows et les utilisateurs d'Unix qui ont des difficultés avec Unicode ne trouveront pas beaucoup à se mettre sous la dent.
L'écriture même d'un tel livre est un exploit, dans un monde où les systèmes informatiques sont encore rares d'avoir un parfait support d'Unicode. Peu de logiciels permettent de composer un ouvrage avec d'innombrables exemples Unicode (LaTeX en est hélas peu capable). Le livre a été écrit avec MS-Word, puis porté sur InDesign pour l'édition finale. InDesign s'est parfois montré trop intelligent, par exemple en remplaçant des caractères qu'il pensait inadaptés par d'autres. C'est ainsi qu'un exemple discutant le guillemet anglo-saxon, " (U+0022), présente en fait un guillemet français, le « (U+00AB). Une page Web d'errata présente les erreurs recensées dans le livre.
Au final, c'est un livre que je recommande chaudement. Les programmeurs qui veulent mettre en œuvre Unicode (et pas seulement l'utiliser) trouveront plus d'informations dans le livre de Gillam mais ceux qui veulent se servir d'Unicode dans un contexte Internet/XML seront au contraire bien plus satisfaits avec le livre d'Andries (qui est plus proche, par le public visé, du livre - en anglais - de Korpela).
Date de publication du RFC : Mai 2008
Auteur(s) du RFC : RFC Editor
Pour information
Première rédaction de cet article le 16 mai 2008
Ce RFC, héritage d'une époque où le Web
n'existait pas, était simplement un récapitulatif des normes actuelles
de l'Internet, récapitulatif qui se trouve désormais en ligne en
http://www.rfc-editor.org/rfcxx00.html
. Mais c'est l'occasion de revenir sur les normes
Internet et leur signification.
Autrefois, il n'était pas facile d'accéder à l'information en ligne, ou bien elle n'était tout simplement pas accessible et l'état de bases de données comme la base du registre IANA ou bien la liste des RFC étaient publiées sous forme de RFC. Pour la base des numéros et noms de protocoles, ce furent les RFC 317, puis le RFC 604, puis plusieurs autres jusqu'au dernier, le RFC 1700 en 1994. Après, cette information n'a plus été distribuée qu'en ligne (le RFC 3232 explique pourquoi). Mais la liste des protocoles normalisés continue à être publiée, en plus de la version en ligne, sous forme de RFC, comme notre RFC 5000, qui remplace le RFC 3700. C'est finalement le RFC 7100 qui a annoncé officiellement la fin de la publication de cette liste sous forme de RFC. Désormais, seule la version en ligne fait foi.
Que contient ce RFC 5000 ? Une liste de RFC, classés selon leur statut. Sur le chemin des normes, un RFC pouvait à l'époque avoir trois statuts, proposition de norme, projet de norme et norme complète (le nombre a été réduit à deux par le RFC 6410). Mais ces trois statuts, décrits dans le RFC 2026, sont peu significatifs. En effet, l'IETF étant fondée sur le volontariat, le passage d'un protocole d'un statut à un autre nécessite une action volontaire, pour un gain douteux (peu de gens font attention au niveau de normalisation). On voit donc des protocoles très utilisés rester au statut de proposition et des protocoles abandonnés depuis longtemps garder leur statut de norme complète. L'IETF n'a pas de ramasse-miettes pour les reclasser.
Parmi les normes complètes, on trouve évidemment IPv4 (RFC 791) et le DNS (RFC 1034 et RFC 1035) mais aussi les désormais quasiment abandonnés RARP (RFC 903) ou bien complètement abandonnés comme le serveur de citations (RFC 865) ou comme IP sur ARCnet (RFC 1201). En revanche, HTTP n'y figure pas (le RFC 2616 n'est que « projet de norme ») et SMTP y est représenté par une version dépassée, le RFC 821 (la version actuelle est dans le RFC 2821 mais qui n'est pas considéré comme « norme complète »). Tout ceci décrédibilise sérieusement le classement.
Le RFC contient également la liste des RFC de « bonnes pratiques » comme le RFC 2870 (qui était BCP 40 à l'époque, depuis remplacé par le RFC 7720) sur le fonctionnement des serveurs de noms de la racine ou comme le RFC 2277 (BCP 18) sur la politique de l'IETF concernant les jeux de caractères et les langues.
Notre RFC 5000 contient aussi des RFC expérimentaux, qui ne sont pas sur le chemin des normes. Il est exceptionnel que, une fois l'expérience terminée, elle soit documentée et que le RFC soit reclassifié en « historique » (une des exceptions est le RFC 3197 qui a documenté l'échec du RFC 1611). On y trouve par conséquent une très longue liste d'expériences assez amusantes comme le défunt RFC 1383 qui tentait de remplacer BGP par le DNS...
Date de publication du RFC : Mai 2008
Auteur(s) du RFC : P. Jayaraman (Net.Com), R. Lopez (Univ. of Murcia), Y. Ohba (Toshiba), M. Parthasarathy (Nokia), A. Yegin (Samsung)
Pour information
Réalisé dans le cadre du groupe de travail IETF pana
Première rédaction de cet article le 14 mai 2008
Appliquant le cahier des charges qui avait été défini dans le RFC 4058, le protocole PANA vient d'être normalisé dans le RFC 5191 et notre RFC accompagne cette spécification, pour décrire les caractéristiques de haut niveau du protocole.
PANA sert à transporter un protocole d'authentification, typiquement EAP (RFC 3748), entre une machine qui veut accéder à un réseau (la PaC, PANA Client) et une machine d'authentification, le PAA (PANA Authentication Agent). (Ces rôles sont expliqués dans la section 2 du RFC, la section 3 détaillant les différentes communications entre eux.) Après le succès de l'authentification, le PAA indiquera à l'EP (Enforcement Point, typiquement un routeur ou un commutateur) qu'il peut laisser passer le trafic du client, du PaC.
Ces rôles peuvent être situés sur des machines différentes ou pas. Par exemple, en ADSL, le PAA et l'EP seront typiquement situés dans le même BRAS. Le protocole PANA ne spécifie que la communication entre le PaC et le PAA.
À noter que, pour prendre sa décision, le PAA pourra être lui-même client d'un protocole d'AAA comme Radius (RFC 2865) ou Diameter (RFC 6733).
PANA a été conçu pour s'adapter à des environnements très différents, notamment du point de vue de la sécurité (section 4 du RFC). Par exemple, il peut y avoir un canal sûr entre le PaC et le PAA, avant même que PANA ne tourne ou pas. S'il existe un tel canal sûr (cas du WiFi avec WPA ou bien cas où la liaison physique entre le PaC et le PAA est considérée comme sûre), PANA est très simple. Dans le cas contraire, il est important d'utiliser des méthodes EAP résistantes à l'espionnage ou à la modification des paquets.
Auteur(s) du livre : Olivier Iteanu
Éditeur :
Eyrolles
978-2-212-12255-8
Publié en 2008
Première rédaction de cet article le 13 mai 2008
Aujourd'hui, les questions d'identités
numériques sont partout sur
Internet. Est-il légal de donner un nom qui
n'est pas celui de l'état civil lorsqu'on
remplit un de ces milliers de formulaires qui existent sur le Web ?
Est-ce grave que les contributeurs de Wikipédia
soient identifiés par des « pseudos » comme
Cereales Killer
ou Anthere
?
Est-ce normal de devoir se souvenir de dizaines de mots de passe
différents ? Pourquoi ne pas utiliser son compte
Google pour tout, de ma banque en ligne aux
blogs où je mets des commentaires ? Si mon
avatar dans
Second Life
tue quelqu'un, suis-je responsable ? Toutes ces questions sont
relatives au concept d'identité numérique. La notion d'identité
paraissait simple dans le monde physique où beaucoup de gens (à tort
selon Olivier Iteanu) l'assimilaient à la seule identité délivrée par
l'État. Comment faire désormais sur les réseaux ?
Le livre répond réellement à toutes ces questions et à bien d'autres. Olivier Iteanu est un avocat, expert reconnu des aspects juridiques des NTIC et défenseur des droits des citoyens face à des dangers comme l'utilisation abusive de leurs données personnelles ou comme leur traçage excessif.
Ce livre est court et n'épuise pas la question, qui est très vaste. Mais il éclaire bien des aspects de celle-ci. Mon chapitre préféré est le 4, sur le « pseudo », où Iteanu défend l'idée que le pseudo est une identité valable, reconnue mais soumise à certaines limites (ne pas choisir un pseudo dans le but de tromper, se méfier du droit des marques).
Mais il y a aussi l'intéressante introduction du livre, sur le manque d'un service d'identité générique sur Internet, manque probablement dû (c'est une des hypothèses évoquées) au choix de la simplicité. Des projets comme OpenID tentent d'apporter une partie de la solution de ce manque.
Parmi les autres chapitres utiles, le chapitre 2 est une explication et une défense de l'anonymat, dont Iteanu pense que, bien que légal actuellement, il pourrait être mieux reconnu par la loi. Le chapitre 9 est consacré aux menaces liées à l'usurpation d'identité comme le hameçonnage et le chapitre 10 à la redoutable efficacité du moteur de recherche Google, « plus fort que le casier judiciaire » car il n'oublie rien et n'est soumis à aucun contrôle.
La conclusion du livre est un appel à maîtriser nos identités numériques, plutôt que des les voir créées, copiées et volées par des forces peu sympathiques. Cela implique, dit Iteanu, un vrai droit à l'anonymat, une meilleure définition juridique de l'identité et le déploiement de techniques d'identité décentralisées permettant à chacun de créer et de contrôler ses identités sur le réseau.
Un peu de publicité personnelle pour finir : j'ai fait un article sur OpenID à JRES, article qui place cette technique au milieu des grandes manœuvres sur l'identité numérique. OpenID pourrait être une des briques permettant de construire le système d'identité distribué dont parle Iteanu.
Première rédaction de cet article le 12 mai 2008
La Compagnie Jolie Môme a, une fois de plus, fait un remarquable spectacle à la fête annuelle de Lutte Ouvrière le 12 mai. C'était chaud, coloré, collectif (pas une vedette unique toujours mise en avant, chaque artiste a son tour) et nouveau aussi.
Parmi les chansons, un sketch/chanson très drôle sur les fermetures de maternités dans les petites villes, où le futur père et la future mère doivent conduire jusqu'à la grande ville ; une chanson NTIC sur la disparition du numéro de téléphone des renseignements, le 12 ; une nouvelle orchestration des Nouveaux Partisans de Dominique Grange, et une autre de Sans la nommer de Georges Moustaki ; une chanson très méchante (mais pas forcément injuste) sur l'écologie, dédiée à Dominique Voynet ; une chanson sur la grève des employés de McDonald's ; un hilarant « conseil aux athlètes français aux Jeux Olympiques » leur montrant comment chanter l'Internationale sur l'air de la Marseillaise au cas où ils gagneraient.
En conclusion : « Il faudra lutter plus pour gagner plus. ».
Date de publication du RFC : Avril 1998
Auteur(s) du RFC : John Moy (Ascend Communications)
Chemin des normes
Première rédaction de cet article le 11 mai 2008
OSPF est le protocole de routage interne de l'IETF. Si RIP est encore utilisé à certains endroits, si des protocoles non-standard, spécifiques à un fabricant de routeurs sont parfois utilisés sur des sites où l'intérêt des normes ouvertes n'a pas été compris, si son concurrent ISO 10589, IS-IS a connu quelques déploiements, OSPF est de loin le plus répandu. Ce RFC est la spécification normative d'OSPF version 2, la version pour IPv4.
Par définition, les IGP, comme OSPF, sont utilisés uniquement à l'intérieur d'un système autonome. Il est donc toujours difficile de produire des statistiques fiables directes, rien ne permettant de dire, vu de l'extérieur, quel IGP utilise une organisation. Mais il n'y a pas de doute qu'OSPF est de loin le plus répandu. Son histoire a parfois été cahotique, et vient d'une grande discussion à l'IETF pour créer un IGP moderne, discussion très chaude qui avait opposé les partisans des protocoles à vecteur de distance, comme RIP aux protocoles à état des liens, comme OSPF. (Christian Huitema, dans son excellent livre « Et Dieu créa l'Internet » décrit ce débat. Le premier article sur un protocole à états des liaisons dans l'ancien Arpanet est l'excellent An Overview of the New Routing Algorithm for the ARPANET en 1979.)
OSPF a finalement été normalisé dans le RFC 1131 en octobre 1989, qui connaitra plusieurs successeurs, les plus récents étant le RFC 2178, et son successeur, notre RFC 2328. L'annexe G décrit les différences avec le RFC 2178, aucune n'étant vitale (il s'agit bien du même protocole).
Notre RFC 2328 est un des plus longs jamais publiés par l'IETF, avec presque deux cent pages. Il n'est pas spécialement pédagogique, son but étant de permettre le développement d'implémentations compatibles du protocole. Il ne cherche pas à aider l'administrateur réseau, ni à informer le curieux de passage. La table des matières est déroutante, conçue selon une logique qui a un sens, mais pas celui du nouveau venu. Pour une explication de plus haut niveau (mais pas forcément facile) d'OSPF, on peut consulter le livre écrit par l'auteur du RFC. Pour une présentation plus orientée vers l'ingénieur en charge du réseau, on peut citer mon cours OSPF. Mais, de toute façon, OSPF est compliqué, il ne faut pas se faire d'illusions.
Quels sont les principes de base d'OSPF ? Comme décrit dans le résumé du RFC et dans la section 1, OSPF est un protocole à état des liens (link state et ce terme se retrouve partout dans le RFC). Chaque routeur diffuse par inondation ( flooding) l'état de ses interfaces réseaux et tout routeur connait donc l'état de tout le réseau, tous les routeurs ont la même information. À partir de celle-ci, chaque routeur fait tourner l'algorithme SPF pour trouver les routes à suivre. Le fait que tous les routeurs aient la même information facilite le calcul de routes sans boucles.
Le routage proprement dit se fait ensuite uniquement sur les en-têtes IP, sans encapsulation ultérieure.
Comme le système autonome a en général des connexions avec d'autres systèmes autonomes, certains des routeurs apprennent également des routes par d'autres protocoles comme BGP (RFC 4271) et OSPF permet d'importer ces routes dans la base de données, comme « routes externes ».
OSPF dispose d'un mécanisme hiérarchique, les zones (areas), qui permet de limiter la diffusion de l'information, rendant ainsi ce protocole moins sensible aux changements d'échelle. La règle « tous les routeurs ont exactement la même base de données des états des liens » doit donc être nuancée : elle n'est valable qu'à l'intérieur d'une seule zone.
Tout le vocabulaire d'OSPF est rassemblé dans la section 1.2. Comme souvent avec les documents informatiques en anglais, il n'y a pas une seule traduction en français qui fasse autorité. J'ai repris ici le vocabulaire de mon cours.
Vue la taille du protocole, il est impossible de citer toutes les sections du RFC. Seules celles qui me semblent les plus importantes sont listées ici.
La section 2 du RFC détaille la base des états de liens, le cœur d'OSPF. Sa section 2.1 précise comment sont représentés les routeurs et les réseaux. Ces derniers peuvent être point à point, à diffusion comme Ethernet, ou bien NBMA (Non-Broadcast Multiple Access, qui font l'objet de la section 2.1.1 et pour lesquels les choses sont assez complexes) comme le relais de trames. La représentation du lien dépend du type de réseau auquel le routeur est connecté.
La section 2.1.2 illustre tout ceci avec un exemple de base de données pour un réseau petit mais relativement complexe. La section 2.2 montre ensuite le résultat du SPF sur ce réseau.
La 2.3 explique la modélisation des informations externes, obtenues depuis un autre protocole. Elles sont de deux types, le type 1 pour les informations venant du système autonome (et donc dont le coût peut être comparé aux coûts OSPF) et le type 2 pour les informations extérieures, non seulement à OSPF, mais également au système autonome, et pour lesquelles le coût est toujours supérieur au coût OSPF.
La section 4 décrit le fonctionnement du protocole : chaque routeur OSPF, au démarrage, rassemble les informations sur ses propres interfaces réseau, puis apprend l'existence de ses voisins, et forme une adjacence sur chaque réseau. Il échange ensuite l'information sur l'état des liens avec le routeur adjacent (rappelons que tous les voisins ne sont pas adjacents, seuls le DR - Designated Router - et le BDR - Backup Designated Router le sont).
Cette information sur les états des liens est transmises sous forme d'unités nommés LSA (Link State Advertisement), qui sont transmis par inondation (procédure décrite en détail en section 13), jusqu'à ce que tous les routeurs de la zone aient la même information.
Plus concrète, la section 4.3 normalise le format des paquets OSPF. Celui-ci fonctionne directement sur IP, avec le numéro de protocole 89. Les champs du protocole sont de taille fixe, pour faciliter la mise en œuvre. Les détails du format sont renvoyés à l'annexe A. Le traitement des paquets figure dans la section 8.
La section 5 est dédiée aux différentes structures de données que doit manipuler le routeur OSPF. Par exemple, le Router ID est un entier de 32 bits qui identifie de manière unique un routeur du système autonome. Cet entier est en général représenté avec la même syntaxe qu'une adresse IPv4 (même pour la version d'OSPF conçue pour IPv6). D'autres structures de données sont décrites dans les sections 9 (les interfaces réseaux) ou 10 (les routeurs voisins).
La section 7 explique le protocole par lequel les routeurs OSPF
d'un même segment de réseau se trouvent et s'échangent des
informations. Tous les routeurs du lien envoient des paquets de type
Hello
à une adresse de diffusion restreinte,
224.0.0.5
(les valeurs numériques nécessaires au
protocole, comme cette adresse, sont dans l'annexe A). Ici,
tcpdump montre ces paquets émis par le routeur
de Router ID 192.134.7.252
, de
la zone 0 (l'épine dorsale) :
22:29:04.906209 IP (tos 0xc0, ttl 1, id 22064, offset 0, flags [none], proto OSPF (89), length 64) 192.134.7.252 > 224.0.0.5: OSPFv2, Hello, length: 44 Router-ID: 192.134.7.252, Backbone Area, Authentication Type: none (0) Options: [External] Hello Timer: 10s, Dead Timer 40s, Mask: 255.255.255.240, Priority: 1 Designated Router 192.134.7.252
Sur un réseau à diffusion comme Ethernet, un routeur est élu routeur principal (Designated Router, DR, section 7.3 mais l'algorithme d'élection figure, lui, dans la section 9.4). Les adjacences ne se forment qu'avec lui et tous les échanges OSPF passent par lui (il existe aussi un routeur de secours, le BDR, Backup Designated Router, section 7.4).
La section 12 présente les paquets LSA (Link State Advertisement, ou annonces de l'état des liens), par lesquels les routeurs OSPF se tiennent au courant de leur situation. La section est très longue car il y a beaucoup d'informations possibles à transmettre !
Une fois que les routeurs ont toute l'information nécessaire, ils peuvent faire tourner l'algorithme SPF de Dijkstra et calculer ainsi les routes, selon la procédure que décrit la section 16. (RIP utilisait Bellman-Ford.)
D'autres sections couvrent des parties plus « exotiques » du protocole, moins nécessaires en première approche.
La section 3 est consacrée au découpage en zones. (Notez toutefois que seuls les plus grands réseaux OSPF en ont besoin. Dans un document plus pédagogique, les zones auraient été reléguées à la fin.) Les routeurs d'une zone ne connaissent pas la topologie interne aux autres zones, seulement le moyen de joindre un routeur ABR (Area Border Router, section 3.3) attaché à cette zone. Les zones OSPF sont forcément attachées à une zone principale, numérotée 0 (section 3.1), qui sert d'épine dorsale au réseau.
La section 14 explique le mécanisme d'expiration des LSA dans la base (ils ne restent en effet pas éternellement).
La section 15 spécifie les liens virtuels qui permettent de connecter des parties physiquement disjointes d'une zone.
Les annexes B et C contiennent les paramètres d'OSPF, les valeurs numériques
qui gouvernent le comportement du routeur. L'annexe B décrit les
constantes, dont la valeur est fixe, comme
MaxAge
, la durée de vie maximale d'un LSA (fixée
à une heure). L'annexe C contient les variables, que l'on peut
modifier via la configuration du routeur (attention, il est souvent
nécessaire que tous les routeurs du lien, ou bien tous les routeurs de
la zone, soient d'accord sur la valeur). Par exemple, avec
Quagga, on peut changer Interface
output cost
(le « coût » d'une interface réseau) en mettant
dans le fichier ospfd.conf
:
interface xxx0 ! Ligne lente, son usage est découragé ip ospf cost 10000
L'annexe D est consacrée à l'authentification. OSPF trouvant ses voisins par diffusion, un routeur méchant peut assez facilement s'insérer dans un réseau et diffuser de fausses informations. Sur un réseau partagé par plusieurs organisations, par exemple un point d'échange Internet, il n'est pas rare de voir passer des paquets OSPF, émis, espérons-le, suite à une erreur de configuration et pas par malveillance. Pour éviter que les adjacences ne se forment entre deux voisins, OSPF permet d'utiliser un secret partagé que doivent connaitre les routeurs.
Il existe aujourd'hui deux mises en œuvre libres d'OSPF :
mais on trouve évidemment ce protocole dans tous les routeurs, des Cisco aux Juniper en passant par les Vyatta.
Première rédaction de cet article le 7 mai 2008
Dernière mise à jour le 12 mai 2008
Tous (ou presque tous ?) les langages de programmation permettent de noter une donnée qui n'existe pas, le rien, le néant. Mais chacun utilise un symbole différent.
En SQL, c'est le
NULL
. Ainsi, un booléen en
SQL est tri-valué : vrai, faux ou
NULL
. Cela agace prodigieusement certains
théoriciens comme Date. Voici un
exemple avec une valeur égale à NULL
:
tests=> CREATE TABLE Data (Name TEXT, Ready BOOLEAN); CREATE TABLE tests=> INSERT INTO DATA Values ('toto', false); INSERT 0 1 tests=> INSERT INTO DATA Values ('tata', true); INSERT 0 1 tests=> INSERT INTO DATA (Name) Values ('truc'); INSERT 0 1 tests=> SELECT * FROM Data; name | ready ------+------- toto | f tata | t truc | (3 rows) tests=> SELECT * FROM Data WHERE Ready IS NULL; name | ready ------+------- truc | (1 row)
Et un exemple illustrant bien que NULL
n'est ni
vrai ni faux. La troisième ligne, avec le nom truc
, n'apparaitra pas :
tests=> SELECT * FROM Data WHERE Ready; name | ready ------+------- tata | t (1 row) tests=> SELECT * FROM Data WHERE NOT Ready; name | ready ------+------- toto | f (1 row)
PHP utilise également NULL
.
Python utilise
None
. N'importe quelle variable peut prendre la
valeur None
. Par contre, Python est typé, même
si c'est dynamiquement typé, et on ne peut pas effectuer n'importe
quelle opération sur None
:
>>> 2 + None Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
Si on essaie avec des booléns, None
a un
comportement qui peut être déroutant : il est quelque part entre
True
et False
.
>>> x = True and False >>> print x False >>> x = True and None >>> print x None >>> x = False and None >>> print x False >>> x = False or None >>> print x None
Perl utilise
undef
. N'importe quelle variable peut prendre
cette valeur. Contrairement à Python, toutes les combinaisons sont
possibles avec undef
:
% perl print 2 + undef, "\n"; 2 % perl print 2 and undef, "\n"; 2
Lisp utilise traditionnellement
nil
, qui sert aussi à noter le booléen
Faux (merci à Emmanuel Saint-James pour son aide sur Lisp). #f
qui sert à noter « faux » et uniquement
« faux » a été introduit par Scheme, qui a
supprimé la confusion qui existait dans Lisp sur ce sujet. La liste vide ()
convient aussi. Voici un exemple en Common Lisp :
; Renvoie Faux donc nil > (or (= 2 3) (= 2 1)) NIL > (or (= 2 3) (= 2 2)) T ; La liste vide est fausse > () NIL ; On peut l'utiliser avec les opérateurs booléens > (or (= 2 3) ()) NIL > (or (= 2 2) ()) T
Pascal désigne les pointeurs invalides par
nil
. Pascal est statiquement et assez fortement typé et les
variables des autres types n'ont pas de valeur
nil
possible. Ada est très proche de Pascal sur ce point, mais utilise null
au lieu de nil
.
Ruby utilise également
nil
.
Haskell est typé et ne permet pas de valeur
« nulle » sauf si on utilise la monade Maybe qui permet d'avoir une valeur
Nothing
. Peu de fonctions sont définies sur les
variables Maybe
(à part tester si elles
contiennent quelque chose et, si oui, quoi).
Visual Basic a le même terme,
Nothing
.
C utilisait
traditionnellement 0
, valable aussi bien pour les
entiers, les caractères et les pointeurs. Aujourd'hui, la bonne pratique
est plutôt d'utiliser la macro NULL
.
À noter que les langues, pas seulement les langages de programmation, peuvent avoir ce souci de noter l'inexistence. Le lojban a zo'e pour cela. Pour dire « je parle en lojban », où il faut normalement spécifier le public et le sujet avant la langue utilisée, une des méthodes est d'indiquer les arguments manquants par zo'e donc, ici mi tavla zo'e zo'e la lojban.
Merci à Bertrand Petit pour sa suggestion originale.
Première rédaction de cet article le 7 mai 2008
Le VCS Subversion s'est largement imposé comme la référence en matière de VCS centralisé, c'est-à-dire reposant sur un dépôt unique de données. Contrairement à son prédécesseur CVS, Subversion permet, par exemple, de déplacer facilement un fichier ou un répertoire à l'intérieur du dépôt, sans perdre l'historique. Mais ce déplacement n'est pas possible entre dépôts différents. Il existe une manipulation pour le faire mais elle nécessite quelques efforts.
Pour Subversion, le monde se réduit à un
dépôt à la fois. Si on a un dépôt B
(https://svn.nic.fr/ReD-AFNIC/Etudes
dans
l'exemple ci-dessous) et qu'on souhaite y importer des fichiers venus d'un dépôt
A
(svn+ssh://bortzmeyer@foobar.example.com/home/bortzmeyer/AFNIC-Subversion
dans l'exemple ci-dessous), en gardant leur historique (donc, sans
utiliser les fonctions d'importation classiques), la simple copie ne
marche pas :
% svn copy svn+ssh://bortzmeyer@foobar.example.com/home/bortzmeyer/AFNIC-Subversion \ https://svn.nic.fr/ReD-AFNIC/Etudes svn: Source and dest appear not to be in the same repository (src: 'svn+ssh://bortzmeyer@foobar.example.com/home/bortzmeyer/AFNIC-Subversion'; dst: ' https://svn.nic.fr/ReD-AFNIC/Etudes')
La manipulation exacte est possible mais plus complexe. Il faut :
svnadmin
: svnadmin dump
/home/bortzmeyer/AFNIC-Subversion > svn.dump
svndumpfilter
pour ne garder que le
sous-arbre qui nous intéresse. Attention, le chemin à donner en
paramètre est un chemin absolu dans le dépôt (ici, on garde trois
sous-arbres, anycast
, EPP
et
dDOS-February-2007
). La commande utilisée est
svndumpfilter
include /RD/anycast /RD/EPP /RD/dDOS-February-2007 < svn.dump >
svn-filtered.dump
Node-path
et, s'il y eu des copies, par exemple des branches, les champs Node-copyfrom-path
). Par exemple, si le fichier
dump contient Node-path:
IETF/Behave/tests-socket
, et qu'on charge ce fichier dans
le répertoire /ReD-AFNIC
, le fichier résultant
sera en /ReD-AFNIC/IETF/Behave/tests-socket
. Ce changement peut se faire avec la fonction
de rechercher / remplacer d'un éditeur
ordinaire (les fichiers de dump de Subversion sont
de simples fichiers texte) ou bien avec un outil comme
sed ou perl.svn
commit
) ou bien directement dans le dépôt avec
svn mkdir URL
.svnadmin
: svnadmin load --parent-dir
/ReD-AFNIC /home/Subversion-Repository <
svn-filtered.dump
. L'option
--parent-dir
permet d'indiquer à quel endroit on
accroche le sous-arbre. Cette commande peut échouer partiellement et il est donc prudent de la tenter d'abord sur une copie du dépôt.Les deux commandes svnadmin
nécessitent
d'avoir les droits pour accéder aux fichiers du dépôt Subversion, en
lecture pour la première étape et en écriture pour la seconde. Par
exemple, si le dépôt final n'est accessible qu'en
HTTP et que les données sont propriétaires de
l'utilisateur sous le nom duquel tourne le serveur HTTP (cet
utilisateur est www-data
par défaut sur une
Debian), il faudra exécuter la commande sous
l'identité de www-data
par exemple avec
sudo : sudo -u www-data svnadmin load ...
.
Si svnadmin load
échoue avec un message du genre :
<<< Started new transaction, based on original revision 4 svnadmin: File not found: transaction '92-1', path '/ReD-AFNIC/Etudes/two' * adding path : ReD-AFNIC/Etudes/two ... %
c'est qu'un répertoire manque. Il faut, comme indiqué ci-dessus, changer les noms dans le fichier de dump ou bien créer le répertoire. C'est le point le plus délicat de la manipulation.
Une fois copié l'ancien dépôt, il est prudent de faire un
svn delete
sur cet ancien dépôt, pour éviter de
continuer à l'utiliser par accident.
Quelques avertissements, enfin :
Bref, pour résumer, cette manipulation n'est pas idéale. Avec Subversion, il vaut mieux réfléchir avant de mettre les fichiers dans des dépôts séparés, copier entre dépôts restera toujours un pis-aller !
Merci beaucoup à Kevin Grover pour ses explications détaillées sur la manipulation à faire, merci aussi à Les Mikesell pour des détails utiles. Je signale aussi le court article « Moving a Folder Across SVN Repositories ».
Blair Zajac me suggère qu'on peut aussi utiliser la propriété
svn:externals
de Subversion pour « copier »
l'ancien dépôt sans réellement le fusionner (pas tout à fait ce dont
j'avais besoin mais cette technique peut être utile dans d'autres cas).
Pour tester différentes idées, j'ai écrit un script shell qui réalise cette manipulation sur des dépôts « bidons ».
Première rédaction de cet article le 4 mai 2008
Vous aimez le café ? Comme moi, comme les informaticiens, vous en buvez plusieurs fois par jour ? Cela vous aiguise l'esprit et vous rend plus efficace ? Alors, vous êtes comme Miguel Lienzo, le héros du roman « Le marchand de café » de David Liss.
Miguel est marchand à Amsterdam au 17ème siècle, lors d'un des moments de plus grande splendeur de la ville, où se développe le lieu de travail de Miguel, la Bourse, où se vendent les premiers contrats à terme, où les Juifs portugais comme Miguel bénéficient d'une relative liberté. La Bourse est un univers impitoyable, Miguel a des dettes, a provoqué la colère d'un homme important, et va tenter d'utiliser le café, que pratiquement aucun européen ne boit encore, pour « se refaire »...
Argent, amour, trahison, récits de voyages, navires chargés de riches cargaisons, rien ne manque à cet excellent roman de vacances.
Auteur(s) du livre : Wolfgang Kleinwächter (éditeur)
Éditeur : Germany land of ideas
Publié en 2007
Première rédaction de cet article le 4 mai 2008
Ce livre est un recueil d'articles produits par différents acteurs de la gouvernance Internet un peu partout dans le monde. On n'y trouvera aucune unité, chacun a juste dévelopé un thème qui lui tenait à cœur (comme Latid Latif expliquant qu'IPv6 va sauver le monde). Il n'y a pas non plus grande originalité dans un livre où la plupart des auteurs avaient déjà eu de nombreuses occasions de faire connaitre leur point de vue.
Les articles sont courts et il y a peu de questions originales traitées. Le spectre des idées politiques est large, personne n'a été oublié, ce qui fait qu'un article d'Anriette Esterhuysen de l'APC, qui appelle à l'intervention publique pour s'assurer que tous les citoyens sont connectés, et qui met en garde contre les extensions des privilèges des titulaires de propriété intellectuelle est immédiatement suivi d'un article de George Sadowsky, de l'ISOC, qui explique que seul le Dieu Marché doit être autorisé à intervenir et qu'il est crucial de maintenir et d'étendre les droits déjà exorbitants dont jouissent les titulaires de propriété intellectuelle.
La plupart des articles n'apprendront rien à celui qui a déjà un peu étudié la gouvernance Internet, d'autant plus que la langue de bois est fort active (articles de Vint Cerf ou de Hamadoun Touré). Seuls quelques auteurs se sont aventurés hors de leur domaine habituel (comme Louis Pouzin qui écrit sur les identités numériques).
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : G. Pelletier, 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 2 mai 2008
ROHC est un mécanisme de description des compressions possibles des en-têtes des paquets IP. Ce RFC décrit les profils de compression qui peuvent être utilisés pour un certain nombre des protocoles les plus courants (la définition de ROHC lui-même étant dans le RFC 5795, la section 3 de notre RFC fait quelques rappels).
Mettant à jour les RFC précédents, le RFC 3095, mais aussi les RFC 3843 et RFC 4019, ce RFC est l'état de l'art en ce qui concerne la compression d'en-têtes. La principale innovation est l'utilisation du langage formel ROHC-FN du RFC 4997 (la section 4.2 résume les principaux changements).
Le gros du RFC commence avec la section 5 qui expose les principes de chaque profil. Un canal ROHC relie un compresseur et un décompresseur. Le compresseur indique les changements par rapport aux prévisions, l'absence de changements signifiant au décompresseur qu'il peut appliquer la règle par défaut. Les systèmes de compression en réseau doivent toujours faire un compromis entre la robustesse (qui nécessite de la redondance, donc de ne pas trop comprimer) et l'efficacité (qui impose de supprimer toute la redondance). Voir par exemple la section 5.1.2, qui discute ce compromis.
Enfin, la section 6 contient les profils eux-mêmes, exprimés en
partie en ROHC-FN. Cette section contient des
fonctions de compression et les règles ROHC-FN qui les
utilisent. Parmi les fonctions primitives, qui ne sont pas en ROHC-FN,
la section 6.6.6 (fonction inferred_ip_v4_length
) dit comment comprimer
la champ Length
d'IPv4. Étant déductible de la longueur du
datagramme, il n'est pas indispensable et peut
donc être comprimé à une taille de... zéro bits. La section 6.6.9
décrit une méthode bien plus complexe (fonction
timer_based_lsb
) pour les champs dont la valeur
change approximativement en fonction linéaire du temps (elle nécessite donc que les
horloges du compresseur et du décompresseur ne dérivent pas trop l'une
par rapport à l'autre).
Un exemple en ROHC-FN est au contraire la définition de la fonction
scaled_ts_lsb
(qui sert pour RTP), qui s'exprime ainsi :
scaled_ts_lsb(time_stride_value, k) { UNCOMPRESSED { timestamp [ 32 ]; } COMPRESSED timerbased { ENFORCE(time_stride_value != 0); timestamp =:= timer_based_lsb(time_stride_value, k, ((2^k) / 2) - 1); } COMPRESSED regular { ENFORCE(time_stride_value == 0); timestamp =:= lsb(k, ((2^k) / 4) - 1); } }
L'annexe A est une excellente étude des en-têtes de divers protocoles, avec une classification de leur comportement, selon qu'il permet la compression ou pas. C'est une lecture recommandée pour tous ceux qui s'intéressent à la compression d'en-têtes mais n'ont pas envie de relire le RFC original du protocole. Ils trouveront résumées de façon claire les caractéristiques de chaque champ de l'en-tête. Par exemple, pour IPv6 (annexe A.2) :
STATIC-KNOWN
c'est-à-dire
constante pour toute la durée du flot et à une valeur « bien connue »,
en l'occurrence 6.RACH
(RArely CHanging),
c'est-à-dire changeant rarement (ce nombre ne bouge que lorsque les
routes sont modifiées)STATIC-DEF
, c'est-à-dire constant pour toute la
durée du flot et pouvant d'ailleurs servir à définir le flot.Il n'existe apparemment pas d'implémentation libre de ROHC. Mais plein de déploiements sont déjà faits dans les téléphones portables. La thèse d'Ana Minaburo contient une bonne introduction à ROHC.
Première rédaction de cet article le 26 avril 2008
Un rapport de Greg Kroah-Hartman publié sur lwn.net le 7 avril fait le point sur l'état du Linux Driver Project (LDP), un projet qui vise à augmenter le nombre de pilotes de périphériques pour le noyau Linux. Ce rapport est très optimiste, est-ce justifié ?
Greg Kroah-Hartman résume la situation ainsi :
Tout le monde partage t-il cette vision optimiste ? Non, comme le montre, par exemple, la discussion qui a suivi sur le site. Les remarques critiques les plus fréquentes concernent les performances et l'étendue des fonctions gérées. Par exemple, dans certains cas, le pilote Linux ne fait que du polling et délivre donc des performances inférieures au pilote Windows qui accepte les interruptions. Ou bien le pilote Linux ne gère pas telle ou telle fonction comme la 3D pour une carte graphique. Dans les deux cas, un Linuxien zélé peut dire « Ce matériel fonctionne sous Linux » alors qu'il marche moins bien que sous Windows.
Mais Greg Kroah-Hartman oublie également d'autres problèmes fréquents :
Greg Kroah-Hartman, pour mieux appuyer sa démonstration, ne parle que du noyau proprement dit et « élimine » les cartes graphiques, une source fréquente de problèmes, car leurs pilotes sont en général dans X.Org, pas dans le noyau, et les scanneurs et imprimantes, pour la même raison.
Donc, on ne peut certainement pas dire que la situation des pilotes de périphérique avec Linux soit aussi rose que la peint cet article. Mais la faute à qui s'il y a tant de problèmes ? Il faut se rappeler que l'origine du mal n'est pas à chercher du côté des développeurs Linux comme Greg Kroah-Hartman, mais plutôt du côté des entreprises qui ne produisent pas de documentations pour leurs matériels, ou bien exigent la signature de NDA pour y avoir accès, quant elles ne refusent pas purement et simplement tout pilote libre, de peur que la lecture du source ne révèle comment fonctionne leur matériel.
Première rédaction de cet article le 22 avril 2008
Les DHT sont un moyen entièrement pair-à-pair de stocker de l'information dans le réseau. Leur force est la résistance aux attaques, leur faiblesse le fait qu'on ne puisse pas garantir l'authenticité des données stockées, puisque le mécanisme classique de « faire confiance au serveur qui fait autorité », utilisé par exemple pour le DNS, ne s'applique pas aux DHT où on ignore même sur lequel des milliers de serveurs de la DHT nos précieuses données seront stockées.
Il faut donc utiliser la cryptographie et signer les données.
Voici donc un protocole possible, suivi de son application au service OpenDHT. L'expérience prouve largement que les amateurs (et même parfois les professionnels) ne voient jamais les failles de sécurité des protocoles cryptographiques qu'ils conçoivent : les critiques sont donc les bienvenues.
Pour éviter les collisions sur le mot « clé », je ne l'utilise que pour la clé cryptographique. Je nomme « nom de l'attribut » (ou index) l'« endroit » où on veut stocker et « valeur de l'attribut » la chose qu'on veut stocker.
Chaque entité qui veut stocker des trucs dans la DHT a une clé cryptographique asymétrique. Pour un protocole comme HIP (RFC 5201), la clé serait le HI (Host Identifier).
Notez qu'on n'a pas dit comment on connaissait les clés publiques de ses partenaires. Le mécanisme pour cela est en dehors de ce protocole.
Les failles que je vois pour l'instant :
Le programme qui écrit la donnée, d'abord. Il s'utilise ainsi :
% python put.py -k 82AEEF63 quelquechose.example.org 192.0.2.42
La ligne ci-dessus stocke la valeur 192.0.2.42
dans la DHT, indexée par le nom
quelquechose.example.org
, en signant avec la clé
OpenPGP 0x82AEEF63
. Il fabrique les deux noms
(celui composé de la clé et de l'attribut et celui qui sert à stocket
la signature) :
key = Binary(sha.new(pgp_key + attribute).digest()) key_for_sig = Binary(sha.new(pgp_key + attribute + ".SIGNATURE").digest())
puis écrit dans la DHT :
proxy.put(key, bin_value, ttl, "put-authentic.py")] proxy.put(key_for_sig, Binary(signature), ttl, "put-authentic.py")
Le programme qui lit les données vérifie les signatures. Il s'utilise ainsi :
% python get.py -k 82AEEF63 quelquechose.example.org
À noter que rien n'empêche plusieurs écritures sur le même nom (les attributs sont multi-valués dans OpenDHT) donc le programme doit boucler sur tous les résultats obtenus. Autrement, il fait simplement l'inverse du programme d'écriture :
signatures, pm = proxy.get(key_for_sig, maxvals, pm, "get-authentic.py") vals, pm = proxy.get(key, maxvals, pm, "get-authentic.py")
Si un méchant a essayé d'insérer de fausses données, cela se voit tout de suite (rappelons qu'on ne peut pas empêcher cette insertion, juste la détecter a posteriori) :
% python get.py -k 82AEEF63 quelquechose.example.org Good signature from: uid: OpenDHT Authenticity Test (Test only, not a real user) <stephane+opendht@sources.org> Value is "192.0.2.42" BAD signature from: uid: OpenDHT Authenticity Test (Test only, not a real user) <stephane+opendht@sources.org> Value is "102.0.2.42"
Date de publication du RFC : Mars 2005
Auteur(s) du RFC : R. Arends (Telematica), R. Austein (ISC), M. Larson (Verisign), D. Massey (Colorado State University), S. Rose (NIST)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF dnsext
Première rédaction de cet article le 22 avril 2008
Complétant la série des RFC sur DNSSEC, ce
RFC 4034 décrit les types d'enregistrements utilisés par ce
protocole, DNSKEY
, RRSIG
,
DS
et
NSEC
.
DNSSEC, décrit dans les RFC 4033 et RFC 4035, permet de signer cryptographiquement les enregistrements DNS de façon à garantir leur authenticité. Pour cela, DNSSEC ne modifie pas le format des paquets DNS, mais il ajoute plusieurs types d'enregistrement nouveaux. Notre RFC fait partie de la série de RFC qui décrit DNSSEC-bis (la première version de DNSSEC, assez différente, n'ayant eu aucun succès) et il succède au RFC 2535.
La plupart des exemples ci-dessous ont été obtenus pour la zone
sources.org
qui est désormais signée. Vous pouvez
interroger en DNSSEC ses serveurs de noms (dig NS
sources.org.
vous en donnera la liste).
Chacun des nouveaux types d'enregistrement va faire l'objet d'une section. La
section 2 est consacrée à DNSKEY
, les clés publiques des
zones. Un de ces enregistrements stocke notamment l'algorithme de chiffrement
utilisé et la clé. La représentation texte officielle (chaque type
d'enregistrement DNS a une représentation binaire, utilisée sur le
câble, et une représentation texte, utilisée par exemple dans les
fichiers de zone de BIND), décrite en section
2.2, affiche la clé encodée en Base64 :
sources.org. 86400 DNSKEY 256 3 3 ( CL9vwM+5gCMZdycMOYJQ7lSspHDTsaZmZkDR l+KNx/VytmbPSfcdYmhJJHyTdGpzqXmm6qEd 4Kpyqbd59RXv9JCVVM3MntiX/hruxbB3WsV0 hlVej1IuWFDncJFLWhaD9UjgGm+UoqlQJGVJ rGZf7KvwL4iKZhr1fiDEJFD7e9cxU8dojhHp mmAOZLjEYKytDMB0rj8/Mnm5cVVu29UFS+0y jvkdbQD0EJ9FwF/8MwG4DHj6ZtFwxeNp2NCD 6oj0kxDi5ktY0rQtSv506aAMmGBqS6tNno+g 9KgCLZ5jk5e8fpl9Rlmd2SlVMAyf8E3C9joB ZqCqYX+VcooSrcvgn/4m6CTDPxK+DuE+KW5/ NiE062MKdID7xAxiCj14Suj9K9TKL60buuFa gJ3qTjhS5C62uPk8U9+zHpQ0qjcb0gv3/M+l RcXi46g0OF17cTLy83lgU6s2ApMmaboeUbm2 3lfCEl8B6R2BhE98mfoDNg+Xlj63X8w93LCo XP/c1SZivNolol/Ky6apULe3euFuwdOFfYCR ) ; key id = 55957
Ici, la clé 55957 utilise
DSA/SHA-1 (valeur 3). Ces
clés peuvent être générées, par exemple, par le programme
dnssec-keygen
,
qui fait partie de BIND. Bien lire la liste des algorithmes
utilisables pour une zone dans l'annexe A.1 sinon, on aura un message du genre
a key with algorithm 'HMAC-SHA256' cannot be a zone key.
Les enregistrements RRSIG
sont le cœur
de DNSSEC, puisqu'ils stockent les signatures des autres
enregistrements. Ce sont les RRSIG
que vérifie un
validateur DNSSEC. Un enregistrement RRSIG
contient notamment :
Sous la forme texte décrite en section 3.2, voici un tel enregistrement :
laperouse.sources.org. 86400 IN MX 10 aetius.bortzmeyer.org. 86400 RRSIG MX 3 3 86400 20080522104407 ( 20080422104407 55957 sources.org. CIxBOzsaxBexcAQQE1ukqNfBz5yDnPBVhgxr MNR7FrfM2iH/AOWoO/8= )
Ici, ce RRSIG
signe un MX
.
La section 4 est consacrée à NSEC
, un type
d'enregistrement qui va résoudre un problème délicat, la « preuve de
non-existence ». En effet, DNSSEC fonctionne en joignant une signature
aux enregistrements existants, ce qui permet de prouver leur
existance. Mais si un nom n'existe pas et que le serveur veut renvoyer
NXDOMAIN
(No Such Domain) ? On
ne peut pas signer un enregistrement qui n'existe pas. La solution
DNSSEC est de créer des enregistrements NSEC
qui
sont signés et qui indiquent l'enregistrement
suivant (l'ordre est défini dans la section
6, c'est simplement l'ordre des codes ASCII). Ainsi, si je demande nexistepas.example.org
et que je récupère :
lulu.sources.org. 43200 IN NSEC patou.sources.org. AAAA RRSIG NSEC
je sais que nexistepas.sources.org
n'existe pas,
puique le NSEC
ci-dessus me garantit qu'il n'y a
rien entre lulu
et patou
.
Un autre type d'enregistrement permettant la « preuve de
non-existence », le NSEC3
, est décrit dans le
RFC 5155. En effet, le NSEC
a un gros
inconvénient, il permet l'énumération complète de
la zone, en suivant simplement les NSEC
. Cette
faiblesse des NSEC est
une des raisons pour lesquelles DNSSEC n'a pas été d'avantage
déployé.
C'est très bien de signer sa zone mais ensuite, comment les
résolveurs partout dans le monde vont-ils connaitre sa clé ? Ils ont
pu l'obtenir par un autre moyen et la mettre dans leur configuration
(ce qu'on nomme une trust anchor). Mais un tel
mécanisme ne se généralise évidemment pas à tout l'Internet. Il faut
donc un seul trust anchor, la clé de la racine, et un système de
délégations. Ces délégations sont mises en œuvre par les
enregistrements DS
, décrits en section 5. Ces
enregistrements contiennent un condensat
cryptographique de la clé :
sources.org. IN DS 55957 3 1 A12F149F84B34E09501C32CC9F984FB9E1ED196A
Ici, 55957 est l'identité de la clé, 3 l'algorithme de la clé et 1 celle du condensat (SHA-1, la liste complète est maintenue par l'IANA).
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : P. Nikander (Ericsson), J. Laganier (DoCoMo)
Expérimental
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 21 avril 2008
Le protocole HIP n'avait pas encore de mécanisme pour trouver l'identificateur d'une machine distante. C'est désormais chose faite grâce à ce RFC qui permet de trouver l'identificateur dans le DNS (RFC qui a depuis été remplacé par le RFC 8005).
HIP fait partie de la famille des protocoles qui visent à séparer l'identificateur du localisateur. Les identificateurs HIP se nomment les HI (Host Identifier) et, jusqu'à présent, le seul moyen de trouver l'HI d'une autre machine était d'attendre qu'elle vous contacte, ou bien de le configurer manuellement. Désormais, avec ce RFC, on peut trouver l'HI, comme une adresse IP, dans le DNS.
Notre RFC crée donc un nouveau type d'enregistrement DNS, nommé logiquement HIP, qui stocke, en échange d'un nom de domaine, le HI, son résumé cryptographique - le HIT (Host Identifier Tag) - et les éventuels serveurs de rendez-vous, serveurs qui, dans le protocole HIP, servent d'intermédiaires facultatifs lorsqu'on veut contacter une machine distante (cf. RFC 5204).
Notre RFC permet de trouver l'identificateur à partir du nom mais pas le localisateur ; les serveurs de rendez-vous sont une solution possible pour cela ; une autre est d'utiliser les traditionnels enregistrements A et AAAA du DNS, le localisateur HIP étant une adresse IP.
Curieusement (pour moi), le HIT est donc stocké dans les données DNS, alors que celles-ci n'offrent aucune sécurité au point que le RFC exige en section 4.1 de recalculer le HIT qui vient d'être obtenu dans le DNS.
Le tout ressemble donc aux enregistrements IPSECKEY du RFC 4025, ce qui est normal, le HI étant une clé cryptographique publique.
Voici un exemple d'enregistrement HIP tel qu'il apparaitrait dans le fichier de zone de BIND. On y trouve l'algorithme cryptographique utilisé (2 = RSA), le HIT (en hexadécimal), le HI (encodé en Base64) et les éventuels serveurs de rendez-vous (ici, deux, indiqués à la fin) :
www.example.com. IN HIP ( 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p 9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example.com. )
L'ensemble du RFC est assez court, ce mécanisme d'annuaire qu'est le DNS étant simple et bien connu.
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : J. Laganier (DoCoMo), L. Eggert (NEC)
Expérimental
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 21 avril 2008
HIP, par défaut, nécessite que l'initiateur d'une association connaisse le localisateur, l'adresse IP du répondeur. Si celui-ci bouge souvent, et qu'il n'est donc pas pratique de mettre cette adresse dans le DNS, une solution est d'utiliser le mécanisme de rendez-vous, décrit par ce RFC, où l'initiateur contacte un serveur de rendez-vous qui relaie vers le répondeur. (Ce RFC a depuis été remplacé par le RFC 8004.)
Le schéma est clairement expliqué dans la section 3 du RFC. En fonctionnement habituel de HIP, l'initiateur trouve l'identificateur et le localisateur du répondeur (typiquement, dans le DNS, cf. RFC 5205), puis le contacte directement. Si le localisateur n'est pas connu (ce qui est fréquent si le répondeur est un engin mobile, changeant souvent d'adresse IP), l'initiateur envoie le premier paquet (I1) au serveur de rendez-vous, qui le relaie au répondeur. Les autres paquets (R1, I2 et R2) seront transmis directement entre les deux machines HIP. Le mécanisme est détaillé dans la section 3.3 (il faut notamment procéder avec soin à la réécriture des adresses IP, en raison entre autre du RFC 2827).
Et comment l'initiateur trouve t-il le serveur de rendez-vous ? En général dans le DNS, via les enregistrements de type HIP. Et comment le répondeur avait-il fait connaitre au serveur de rendez-vous son adresse IP ? Via le protocole d'enregistrement du RFC 5203, comme l'explique la section 4.
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : R. Moskowitz (ICSAlabs), P. Nikander, P. Jokela (Ericsson Research NomadicLab), T. Henderson (The Boeing Company)
Expérimental
Réalisé dans le cadre du groupe de travail IETF hip
Première rédaction de cet article le 21 avril 2008
HIP, décrit dans ce RFC, est un protocole très ambitieux, puisqu'il vise à compléter IP en fournissant une séparation de l'identificateur et du localisateur, permettant d'améliorer la sécurité (notamment la résistance aux DoS) et de mieux gérer la mobilité et le multi-homing. La version 1, décrite dans ce RFC, a depuis été remplacée par la v2, dans le RFC 7401.
L'architecture générale de HIP est décrite dans le RFC 9063. Notre RFC normalise, lui, le protocole concret. HIP repose d'abord sur la séparation entre un nouvel identificateur, le HI (Host Identifier) et un localisateur, plus concret, qui sera simplement l'adresse IP, réduite à un rôle moins visible, sans exigence de stabilité. Par exemple, HIP permettra le changement de localisateur (d'adresse IP) en cours de connexion, sans rompre celle-ci, ce qui sera précieux pour la mobilité.
HIP est donc déployable uniquement en modifiant les machines terminales du réseau (si les coupe-feux le laissent passer), sans toucher aux routeurs. Il en existe des mises en œuvres pour FreeBSD et Linux. Le projet OpenHIP adapte également des logiciels comme Wireshark pour qu'ils aient un support HIP. InfraHIP travaille également à l'infrastructure HIP. L'article HIP Implementation for FreeBSD donne des détails intéressants sur la mise en œuvre de HIP, notamment sur les questions liées à l'API.
Si on ne veut pas lire le RFC 9063, on peut néanmoins avoir une bonne introduction à HIP en lisant les sections 1 et 2 de ce RFC. Elles expliquent le vocabulaire (par exemple, HIP, étant un protocole situé en haut de la couche 3 n'utilise pas le terme de connexion mais celui d'association), le nouvel espace de nommage et les principes du protocole.
L'espace de nommage fait l'objet de la section 3. On distingue les
HI (Host Identifier), qui sont des clés
publiques d'un couple clé privée / clé publique et qui sont de
taille variable, et les HIT (Host Identifier Tag,
décrits dans la section 3.1), qui sont un résumé
cryptographique des HI. Ils sont de taille fixe (donc plus
faciles à traiter), 128 bits, la taille d'une adresse
IPv6. Un préfixe ORCHID
(RFC 4843), le 2001:10::/28
, sert à éviter toute collision avec
les « vraies » adresses IPv6. Avec OpenHIP, la clé peut être générée par le programme hitgen
qui fabrique un fichier XML ressemblant à ceci :
<?xml version="1.0" encoding="UTF-8"?> <my_host_identities> <host_identity alg="RSA" alg_id="5" length="128" anon="no" incoming="yes" r1count="10"> <name>horcrux-1024</name> <N>C6EBA2894C33A1312B38853A8ECC0D7967496237A65529807EDF23C4DA753EE88F8FBF71BE38B6910181D5B75DB075B9962326D9BB50C65121DBFD712F1B7F4E2B035953AD650EB5C96B56295FE2731B3B36E8AFED7FB5CD48B73C31A224D4CE4F097D84888EC2E3CA8F3A78939D89B7BCFC5E6DEEAF670695349BFFFE8445F1</N> <E>010001</E> <D>383A51165838DBDE872611DACC94775692D09677BE87A214954843D7181D3E2C04B0905FF9721481069909AD2C497DED78B7F4FA64CD5F517DADAE8538D89FF21B0498A72F1132545328ABD371B1BAC8ED46441D900921523B78BA55F3FC227F432F2061C92CE9665CB99C1CF425AA90CFC6345FA4E7DA43E477EAF69F86A801</D> <P>FF03F93454C9C2D8EC47FE8C9DBF0D82F05E13905F304A5ACA42C45E579F917B4C8CEFEF6B06AAB9BCB7A911D5514B7AEE685DA91E7CC60DDC4C37BA94A22E71</P> <Q>C7B0394EB5506B2B75E19E5654262E843659BB76A465C2A7AC47A430749944378E3161FF805B4C6CB037B5CB111F0EF49FF03047FB1CFC51DC0D72DEDAD64F81</Q> <dmp1>7426C128DEBD8EEBF2A2D004080D6F0006AF32C5FD352788B6BB3669AA0B59DE08FDE082F202755C67E25735722DB6ED650D502BA961376C34BCDA5D3739AF61</dmp1> <dmq1>1B97DE5361FA9AD4869586ABA7351F78658A40BD443A4B8B9FE2C66D6BAF421DEB2827C2869A17156DC444FAAA83002E0D6BC3402F12F24ADD7D7E420D3B5001</dmq1> <iqmp>7499A27F59CA1746F1A6E5DE832592F8ACF80B814DD511C490614C44DC92B5CD1650AC944ED5751F28846487C221E8C17E68264DFEF748B86E38EB1F238D94A9</iqmp> <HIT>2001:1f:cd4:7125:2427:f77c:d1b6:e15f</HIT> <LSI>1.182.225.95</LSI> </host_identity> </my_host_identities>
Notez bien que le fait d'utiliser XML est un choix de OpenHIP, qui
n'est utilisé qu'en local. Il n'est pas imposé par la norme qui, sur
le câble, n'utilise que du binaire. Les éléments comme
P
, Q
ou
iqmp
sont les éléments d'une clé
RSA (HIP peut utiliser d'autres formats que
RSA). Le HIT est représenté en utilisant la syntaxe des adresses
IPv6, puisqu'il a la même taille et a été conçu pour
être stocké comme une adresse par les applications.
La section 3.2 explique comment générer un HIT à partir du HI. Étant un résumé cryptographique (fait avec SHA-1), il est sûr, on ne peut pas fabriquer facilement un HI qui aurait le même HIT.
Pour signer les paquets, les deux machines utiliseront au début un échange de Diffie-Hellman.
La section 4 donne une vision générale du protocole, qui sera ensuite détaillée dans les sections ultérieures. HIP a reçu le numéro de protocole 139.
La section 4.1 décrit comment former une association entre deux machines HIP. Celle qui demande l'association est nommée l'initiateur, celle qui l'accepte le répondeur. Le protocole d'association nécessite quatre paquets. En effet, avec seulement trois paquets, comme le fait TCP (RFC 793) lors de l'établissement d'une connexion (Three-way handshake), on ne peut pas à la fois se protéger contre les DoS et permettre des options par connexion. Se protéger contre les DoS nécessite de ne pas garder d'état tant que le pair n'est pas authentifié, même faiblement. Les techniques qui permettent à TCP de ne pas garder d'état sur le « répondeur », telles que les SYN cookies du RFC 4987 sont incompatibles avec les options TCP.
Voici pourquoi les protocoles plus récents comme SCTP (RFC 3286) ou comme HIP nécessitent quatre paquets.
Dans HIP, ils sont nommés I1, R1, I2 et R2. Les paquets I sont envoyés par l'initiateur et les paquets R par le répondeur.
L'établissement d'une association se passe donc comme ceci :
Le puzzle, détaillé en section 4.1.1, est un petit problème de calcul que l'initiateur doit résoudre pour montrer qu'il est près à « payer », à faire un effort pour que l'association soit acceptée. La difficulté du puzzle peut être réglée par le répondeur. En pratique, il est très difficile d'imaginer un puzzle qui soit dissuasif contre des attaquants disposant d'un botnet entier, tout en étant soluble par des appareils simples, genre téléphone portable, ne possédant guère de puissance de calcul. (La section 4.1.1 détaille ce problème et les solutions possibles.)
La section 4.1.3 détaille l'utilisation du Diffie-Hellman.
Une des grandes forces de HIP est la possibilité de mettre à jour une association existante (section 4.2). À tout moment, pendant la session, un paquet de type UPDATE peut être envoyé pour changer certains paramètres de la session, comme les localisateurs (les adresses IP) utilisées. La signature des paquets permet de s'assurer que le paquet UPDATE est authentique.
La section 5 est longue car elle détaille le format, bit par bit, de tous les paquets échangés. Il y a huit types de paquets (section 5.3) comme I1, R1, I2, R2 ou comme UPDATE, présenté plus haut.
Enfin, la section 6 détaille le traitement des paquets, ce qu'il faut faire en les recevant, les erreurs et la façon de les gérer (règle simple : ne pas renvoyer de paquets HIP en cas d'anomalie, seulement des ICMP, et avec un débit limité, car on ne peut pas être sûr du pair s'il y a une erreur), etc.
Première rédaction de cet article le 18 avril 2008
Lors de la réunion Sparkling Point du 17 avril, j'ai fait un exposé sur « Les conséquences politiques des choix techniques », suivant l'observation de Lawrence Lessig que « The code is the law » (l'architecture - d'un système technique - est la loi).
Je développe trois exemples, empruntés au monde de l'Internet, les politiques d'allocations d'adresses IP, la révision de la norme sur les noms de domaines en Unicode et les débats sur la nouvelle architecture de routage et d'adressage de l'Internet.
Les transparents de cet exposé sont visibles :
Première rédaction de cet article le 14 avril 2008
Il y a traditionnellement deux moyens de donner des noms à des
engins connectés à un réseau (que ces engins soient des ordinateurs,
des PDA, des téléphones, etc) : un système
d'allocation hiérarchique comme le DNS et un
système complètement local comme le NBP d'Apple
ou comme le LLMNR du RFC 4795. Le premier est lourd, très chargé politiquement et administrativement et échappe aux contrôles des
engins connectés. Le second ne marche que sur un réseau local et ne
présente aucune sécurité (n'importe quelle machine peut dire qu'elle
se nomme FileServer
). Cet excellent
article détaille un mécanisme qui permet des allocations
locales, utilisables globalement, et sûres.
L'article Persistent Personal Names for Globally Connected Mobile Devices, de Bryan Ford, Jacob Strauss, Chris Lesniewski-Laas, Sean Rhea, Frans Kaashoek et Robert Morris (MIT) décrit leur système UIA (Unmanaged Internet Architecture). L'idée de base est de tenir compte des réseaux sociaux et du fait que les gens qui communiquent se rencontrent physiquement de temps en temps. Du fait de ce point de départ, UIA ne remplace donc pas toutes les fonctions du DNS. Le principe d'UIA est que chaque machine s'attribue un nom et que ce nom, pour être utilisable depuis une autre machine, nécessite une introduction, qui nécessite le rapprochement physique. Une fois l'identité de chaque machine apprise, elles peuvent s'éloigner, UIA maintient une correspondance entre l'identité et l'adresse IP actuelle, et diffuse cette correspondance aux autres machines connues (un tel système ne convient donc que pour des petits groupes, par pour tout l'Internet). Cette correspondance est authentifiée par cryptographie, comme dans HIP (RFC 9063).
Le système se généralise à d'autres utilisateurs, en indiquant le
nom de ces autres utilisateurs. Si Bob a une machine nommée
myPDA
, Alice pourra, après introduction du groupe
Bob
, utiliser le nom
myPDA.Bob
.
Le protocole n'est pas purement théorique, une implémentation est disponible.
Première rédaction de cet article le 13 avril 2008
Dans ce film de César Charlone et Enrique Fernández, (El baño del papa dans la version originale), on fait beaucoup de vélo mais pas pour s'amuser comme le cadre parisien stressé qui se détend en faisant du Vélib'. Ici, on est dans la campagne uruguayenne et les cyclistes sont des contrebandiers, qui profitent des différences de prix entre l'Uruguay et le Brésil proche pour gagner quelques petits sous.
Pas de la contrebande de haute volée, avec des marchandises précieuses, encore moins d'armes ou de drogue, les héros du film transportent de l'huile, du sucre, parfois une bouteille de whisky. Il faut pédaler sur une piste difficile, parfois en pleine nature pour éviter les contrôles, il faut risquer la rencontre avec la douane qui confisque parfois les marchandises, selon son arbitraire.
Mais tout va changer, espèrent les habitants de Melo : le pape Jean-Paul II va venir faire un discours dans leur village et les voisins brésiliens ne vont pas manquer d'affluer par milliers. Tout le village se met donc au travail pour valoriser cette visite papale. La plupart créent des stands de nourriture ou de boisson, mais un des contrebandiers a une meilleure idée. Il va installer des toilettes et faire payer très cher leur usage.
Tous investissent leurs maigres économies, empruntent à la banque, vendent leur outil de travail (leur vélo) pour investir dans ce grand projet. Les quantités de nourriture achetées sont énormes, alors qu'on ne connait que la future affluence que ce que promet la télévision locale. Non seulement ils prennent des risques à se faire pâmer les propagandistes du MEDEF, qui n'ont jamais vus de tels risquophiles, mais ils travaillent comme des fous pendant des jours, dans l'espoir de gagner un peu plus.
Je ne vous dis pas la fin, mais ceux qui ont déjà vus des films latino-américains se doutent que cela se terminera moins bien que dans les films états-uniens, où l'esprit d'entreprise est toujours récompensé.
Première rédaction de cet article le 13 avril 2008
Dernière mise à jour le 1 octobre 2009
Après des années passées à administrer des machines Debian où la mise à jour vers une nouvelle version du système est simple et marche à (presque) tous les coups, passer un ordinateur NetBSD de la version 3 à la version 4 est un amusant retour en arrière, comme de faire un stage dans une île déserte avec juste un briquet et un couteau.
La machine est une Sun UltraSparc 10. Elle était en NetBSD 3.1 et vient de passer en NetBSD 4 puis, avec la même méthode, en NetBSD 5. Ce que j'ai fait, sur les excellents conseils de Mark Weinem :
http://ftp.netbsd.org/pub/NetBSD/NetBSD-5.0.1/sparc64/binary/sets/
. J'ai utilisé pour cela la commande
wget --mirror --no-parent --execute robots=off
http://ftp.netbsd.org/pub/NetBSD/NetBSD-5.0.1/$(uname -m)/binary/sets/
. Pour le reste de la manipulation, on va supposer
qu'on a tout copié dans /var/tmp/netbsd5
. On se
rend dans ce répertoire.
pax -zrf
kern-GENERIC.tgz
. pax est simplement
un frontal aux différents formats d'archivage comme tar.mv /netbsd /netbsd.old
et mettre le nouveau
noyau, récupéré à l'étape précédente avec mv netbsd /netbsd
. On pourra redémarrer sur
l'ancien noyau, si nécessaire, avec la commande boot
netbsd.old
de l'invite de démarrage de la Sparc./ofwboot
, puis copier le
nouveau (qu'on trouve dans l'ensemble base.tgz
,
en ./usr/mdec/ofwboot
).etc.tzg
et
xetc.tgz
contiennent, comme leur nom l'indique,
des fichiers de configuration. On ne les installera pas directement,
la machine étant déjà configurée.cd
/
) et on installe : for set in $(ls
/var/tmp/netbsd5/*.tgz | grep -v etc | grep -v kern); do; pax -zrf
$set; done
.postinstall check
. Ce programme va vérifier
que tout est bien en place. Exécuter ensuite la commande qu'indiquera postinstall
.etcupdate
ainsi :
etcupdate -s /var/tmp/netbsd5/etc.tgz -s
/var/tmp/netbsd5/xetc.tgz
. etcupdate
est interactif et, pour chaque fichier de configuration pour lequel il
y a une nouveauté, il demandra s'il doit garder l'ancien, installer le
nouveau ou bien fusionner interactivement les deux (le système est
nettement moins intelligent que son équivalent Debian, qui regarde si
l'ancien fichier a été modifié localement, avant de poser la question).
À noter que cette opération n'a mis à jour que le système de base. Autre différence avec Debian, le système est coupé en deux, le système de base et les applications, qui se gèrent à la main, ou bien via un système comme pkgsrc.
Il existe d'autres méthodes pour mettre à jour un système NetBSD. Citons notamment la possibilité de démarrer la machine sur un CD-ROM NetBSD et de choisir l'option de mise à jour (merci à Marc Baudoin pour ses explications). Cela simplifie le processus mais ne peut pas s'effectuer à distance.
Une autre solution, pour ceux qui aiment le compilateur, est de compiler soi-même le système de base (attention, je ne l'ai pas fait moi-même, l'opération est trop lente et consomme trop de place disque, je recopie juste une documentation) :
cd /usr/src
cvs update
MAMACHINE
) et ./build.sh -U -u
kernel=MAMACHINE
.cp /netbsd /netbsd.old
puis cp
/usr/src/sys/arch/$(uname -m)/compile/obj/MAMACHINE/netbsd
/netbsd
cd /usr/src
./build.sh -U tools
./build.sh -U -u distribution
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : C. Reed (Open Geospatial Consortium)
Pour information
Première rédaction de cet article le 12 avril 2008
Régulièrement, un nouveau RFC vient enrichir
la grande famille des URN (RFC 8141, qui décrit les règles d'enregistrement), ces identificateurs
prévus pour être stables et pérennes. Cette fois, les URN
ogc
viennent s'ajouter, pour stocker les normes
et schémas de l'Open Geospatial
Consortium.
Ce consortium produit des normes utilisés dans le monde de la géographie comme le format GML et qui servent à communiquer des informations spatiales, utilisées dans de nombreux secteurs (sections 1 et 5 du RFC).
Les URN de l'OGC utiliseront le NID (Namespace
IDentifier) ogc
. Ce NID sera suivi d'un
type de ressource et des coordonnées de la ressources (section
2). L'OGC mettra en place un résolveur permettant de transformer ces
URN en URI, à l'adresse
http://urn.opengis.net/
. Le reste de la section
décrit les procédures de l'OGC, notamment pour garantir l'unicité de
ces URN.
Un exemple des nouveaux URN (section 3) est
urn:ogc:specification:gml:doc-is(02-023r4):3.0.0
qui identifiera une version particulière de la norme GML (d'où
l'utilisation de la ressource « specification »).
Première rédaction de cet article le 10 avril 2008
Dernière mise à jour le 13 juillet 2011
Un utilitaire très pratique, pgtop, permet de voir l'activité des processus de PostgreSQL, de regarder les requêtes SQL en cours d'exécution, les statistiques, etc.
pgtop ressemble (délibérement) à la commande
top d'Unix. Sur une Debian "lenny" avec
PostgreSQL 8.3, j'ai testé la version
(actuellement beta) 3.6.2-beta3. configure &&
make
pour le compiler (j'ai juste dû ajouter
LDFLAGS = -lcurses
dans le Makefile, voilà ce que
c'est que d'utiliser des versions beta). Sur une Debian "squeeze", il est désormais dans un paquetage normal (nommé ptop
). Puis je le lance avec
pg_top -p 5433 -d MABASE
et, merveille, je vois
l'activité de mon SGBD. Je vais maintenant
savoir, lorsque ça rame, pourquoi ça rame.
On trouve de nombreux exemples en http://ptop.projects.postgresql.org/screenshots/
.
Il y a bien d'autres façons de voir ce que son SGBD favori est en train de faire, par exemple via des requêtes SQL :
> SELECT current_query FROM pg_catalog.pg_stat_activity WHERE datname='MABASE'; ... CREATE INDEX qname_idx_DNS_Packets_1 ON DNS_Packets_1(qname); ...
Merci à Nicolas Delvaux pour ses informations.
Première rédaction de cet article le 10 avril 2008
L'adoption par l'ISO de la norme Open XML, proposée par Microsoft, a fait couler beaucoup d'encre, notamment en raison des manœuvres peu glorieuses qui ont permis le retournement de veste du représentant français, malgré les faiblesses techniques de la proposition (des méthodes analogues ont été utilisées dans d'autres pays). La conclusion de la plupart des observateurs, à juste titre, était que l'approbation d'une norme à l'ISO dépendait plus des qualités du lobbyiste que de celles de la norme. (Voir par exemple le communiqué de l'APRIL.) C'est juste mais, dans ce cas, pourquoi diable le monde du logiciel libre, qui avait fait approuver peu de temps auparavant OpenDocument à l'ISO a t-il choisi cet organisme ?
Il existe de nombreuses organisations de normalisation dans le monde. Les tenants du logiciel libre, y compris des grosses entreprises comme Sun ou IBM avaient choisi de porter le format OpenDocument à l'ISO et s'étaient bruyamment vantés de son approbation par cet organisme. C'était tendre la perche à Microsoft : utiliser ses moyens pour faire approuver n'importe quoi par une bureaucratie est le principal domaine de compétence du géant de Redmond. Il n'y a donc pas de quoi s'étonner du succès de la proposition Microsoft à l'ISO. À l'ISO, les participants aux groupes de travail (qui sont parfois de réels experts du domaine) ne sont pas ceux qui votent. Le vote est fait par des représentants des gouvernements, dont on ne sait pas trop bien qui les a désigné où à qui ils répondent. Il est en général impossible de savoir qui a voté quoi. Par exemple, la France a t-elle voté OUI ou NON à la norme ISO 639-3 ? Je vous laisse chercher.
Un tel système favorise les bons lobbyistes, qui ont l'oreille des gouvernements. C'est le terrain où Microsoft est fort et où le monde du logiciel libre a étrangement choisi de se rendre.
Il existe des organisations de normalisation plus ouvertes, où les experts du domaine ont un poids plus important et où les décisions sont davantage transparentes, comme le W3C, l'IETF ou OASIS. Pourquoi être allé à l'ISO ? Pourquoi découvrir seulement maintenant que l'ISO « manque de crédibilité » ? L'ISO a toujours été fermée, bureaucratique, ne rendant pas de compte au public et ne distribuant même pas ses normes sur Internet. Faire normaliser un format ouvert à l'ISO, c'est comme faire voter la déclaration des Droits de l'Homme par le parlement tunisien !
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : E. Wilde (UC Berkeley), M. Dürst (Aoyama Gakuin University)
Chemin des normes
Première rédaction de cet article le 10 avril 2008
Les URI disposent depuis longtemps d'un
moyen de désigner une partie d'un document, par
les biais des « identificateurs de fragments », précédés d'un
dièse, comme par exemple
http://www.example.org/foobar.html#section3
.
Entièrement interprétés par le client Web, ces
identificateurs étaient définis seulement pour XML et
HTML et notre RFC ajoute le texte brut.
La façon classique d'utiliser ces identificateurs est de modifier le document cible pour y ajouter un élément à viser, par exemple :
<p id="avertissement-sante">Fumer est dangereux pour la santé.</p>
fera qu'un navigateur pourra, lorsqu'on lui demandera
http://www.example.org/document.html#avertissement-sante
,
aller directement à ce paragraphe. On peut aussi utiliser, au lieu
d'un simple nom comme avertissement-sante
,
utiliser une expression XPath, si le navigateur
accepte XPointer. En outre, avec
XLink, on peut même pointer vers un document
qu'on ne peut ou ne veut modifier, ce qui évite de devoir ajouter des
attributs id
ou name
.
Le texte brut (normalisé dans MIME par le RFC 2046) n'étant pas, lui, structuré, on ne pouvait pas compter sur des « marques » particulières. D'où le choix de notre RFC de compter les caractères ou bien les lignes.
C'est ainsi que les URI de ce RFC
ressembleront à
http://library.example/2007/11/5311.txt#char=6234
(le curseur du navigateur ira sur le 6234ème caractère) ou bien
http://library.example/2004/03/228.txt#line=534,580
(le navigateur affichera le texte compris entre la 534ème ligne et la
580ème).
Mais les documents accessibles sur le Web tendent à changer. De
tels identificateurs de fragments sont clairement moins robustes que
ceux utilisant un attribut du document XML (comme
avertissement-sante
plus haut), ou bien que ceux
utilisant une expression XPath. Comment détecter le cas où un
paragraphe a été ajouté, faussant ainsi les liens ? Cette norme permet
d'ajouter à l'URI un mécanisme de contrôle d'intégrité, en indiquant
la longueur ou bien la somme de contrôle MD5 (RFC 1321) du document. Si elles
ne correspondent pas, le navigateur sait qu'il ne doit pas utiliser
l'identificateur de fragment. Ainsi,
http://www.myblog.example/2006-12/mespensees.php#line=50;length=19576,UTF-8
amènera le navigateur à compter le nombre de caractères du document et
à ignorer l'identificateur de fragment s'il ne trouve pas 19576 caractères.
Notre RFC doit aussi traiter des problèmes plus subtils comme la façon de compter les fins de ligne du document (il existe plusieurs façons de les représenter, et la norme décide qu'une fin de ligne compte toujours pour un caractère).
Un autre problème subtil est la nécessité de tenir compte de
l'encodage des caractères. En effet,
char=
compte bien le nombre de
caractères, pas le nombre
d'octets.
Deux implémentations existent, une dans Amaya et une en Python, incomplète mais quand même utile: TextFrag.py
.
À noter aussi une présentation par un des auteurs, un amusant et intéressant article de Tim Bray, Matthew-6:9.txt#line=,1 et un intéressant texte de Karl Dubost élargissant le problème.
Date de publication du RFC : Février 2008
Auteur(s) du RFC : R. White, B. Akyol (Cisco)
Pour information
Première rédaction de cet article le 8 avril 2008
La sécurité du protocole BGP, par lequel les routeurs Internet échangent l'information sur les routes existantes, est depuis longtemps un sujet de préoccupation. Actuellement, BGP (RFC 4271) n'offre quasiment aucune sécurité contre les usurpations (un routeur annonce une route qu'il n'a pas « le droit » d'annoncer, comme lors de la récente usurpation perpétrée par Pakistan Telecom). Pourquoi ne valide t-on pas les routes annoncées ? En partie parce que c'est plus compliqué que ça n'en a l'air, comme l'explique ce récent RFC.
Beaucoup de gens, étonnés qu'un technicien incompétent à Karachi puisse stopper l'activité d'un site Web stratégique et essentiel uniquement en détournant son trafic grâce à BGP, réclament des mesures drastiques et notamment la validation des routes annoncées par BGP. Certains opérateurs, rares, font une validation partielle, en général basée sur le contenu des IRR. Pourquoi cette pratique n'est-elle pas plus répandue ?
Les mécanismes existants de sécurité comme BGP-MD5 (RFC 2385) ou TCP-AO (RFC 5925) ne sécurisent que le canal de communication entre deux routeurs. Ils permettent d'être sûr de l'identité du pair BGP, mais pas de valider ce qu'il annonce. Le routeur de Pakistan Telecom était authentique, il était aussi menteur et BGP-MD5 ne protège pas le message, uniquement le canal.
Notre RFC fait donc la liste des points à vérifier lors d'une validation. Le premier (section 1.1) est évidemment de savoir si l'AS d'origine est autorisé à annoncer cette route. C'est un point crucial mais qui n'est pas le sujet de notre RFC, qui se consacre au devenir ultérieur de cette annonce. Plusieurs autres questions sont ensuite posées dans le RFC. Par exemple, la section 1.3 demande « Est-ce que l'annonce par un routeur qui n'est pas de l'AS d'origine est autorisée ? » et explique que la question est bien plus subtile qu'elle ne le semble puisqu'il y a en fait trois sous-questions derrière cette question apparemment simple :
192.0.2.128/25
(route authorization).192.0.2.0/24
(reachability
authorization).Ces trrois autorisations, à première vue équivalentes, peuvent en fait donner des résultats différents, comme le montrent les exemples ultérieurs.
Citons uniquement un exemple, présenté en section 2.2, qui exploite le fait que la route réellement empruntée n'est pas contrôlée par la source mais par chaque AS intermédiaire. Un AS annonce à son voisin une route avec un chemin d'AS, mais, en interne, il a une route statique qui prend un autre chemin. L'annonce est-elle valide ? L'AS annonceur était autorisé à annoncer cette route (route authorization et reachability authorization) mais il est impossible de déterminer s'il y avait transit authorization puisque le chemin réellement emprunté n'apparait pas dans l'annonce.
Globalement, ce RFC fait à mon avis œuvre utile en expliquant la complexité du routage Internet. Il donne parfois un peu trop dans le pinaillage en montant en épingle des cas intéressant mais très rares. Le vrai problème de la validation des routes en BGP est plutôt l'absence d'un système de « droit d'usage » permettant de savoir qui a le droit d'annoncer telle route. Sans un tel système, les protocoles sécurisés de diffusion de routes (qui existent, et reposent sur la cryptographie) n'ont rien sur lequel se baser. (Un groupe de travail de l'IETF, RPSEC, travaille actuellement à un cahier des charges pour un routage sécurisé. Un exemple de mécanisme permettant de valider les annonces de route a été publié début 2012.)
Première rédaction de cet article le 7 avril 2008
Le consortium Unicode vient d'annoncer la sortie de la version 5.1 de la célèbre norme de jeu de caractères. 1 624 caractères de plus, permettant à Unicode de dépasser les 100 000 caractères.
Parmi les nouveaux venus, un certain nombre de caractères
arabes (notamment pour
écrire le persan) ou cyrilliques, le Eszett
allemand en majuscule (la précédente majuscule de ß était la chaîne
SS, ce sera désormais le caractère Unicode
U+1E9E
, que votre navigateur ne sait probablement
pas encore afficher), l'alphabet Sundanese (que
je ne connaissais pas), d'autres alphabets nouveaux comme le
Cham, les caractères du
Mah-jong (cf. le roman « Sous les vents de
Neptune » de Fred Vargas), et plein d'autres
caractères rigolos comme U+2B3D
, « LEFTWARDS
TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE » ou
U+2E2A
, « TWO DOTS OVER ONE DOT PUNCTUATION ».
La majuscule du Eszett a suscité bien des controverses (cf. http://de.wikipedia.org/wiki/Versal-Eszett
), certains
germanophones expliquant que cette lettre n'existe pas. On peut consulter
la proposition initiale en http://std.dkuug.dk/jtc1/sc2/wg2/docs/n3227.pdf
, avec des
exemples d'utilisation, pris par exemple sur des pierres tombales.
Le programme de conversion de la base Unicode en SQL est un excellent outil pour explorer cette nouvelle version :
ucd=> SELECT count(*) AS Total FROM Characters; total -------- 100713 (1 row) ucd=> SELECT To_U(codepoint) AS Codepoint, name FROM Characters WHERE version = '5.1'; codepoint | name -----------+----------------------------------------------------------------------- U+1E9E | LATIN CAPITAL LETTER SHARP S U+A66E | CYRILLIC LETTER MULTIOCULAR O ... U+372 | GREEK CAPITAL LETTER ARCHAIC SAMPI U+373 | GREEK SMALL LETTER ARCHAIC SAMPI ... U+520 | CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK U+521 | CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK U+522 | CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK U+523 | CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK U+606 | ARABIC-INDIC CUBE ROOT U+607 | ARABIC-INDIC FOURTH ROOT U+608 | ARABIC RAY ...
Première rédaction de cet article le 7 avril 2008
Dernière mise à jour le 4 décembre 2008
Pour faire du TLS sur un serveur
HTTP Apache, la solution
la plus connue est le module mod_ssl
. Mais il en
existe une autre, le module
GnuTLS.
GnuTLS est une mise en œuvre libre du protocole TLS (ex-SSL, protocole normalisé dans le RFC 5246). Étant sous licence GPL, il peut être utilisé par des programmes GPL (alors que OpenSSL a une licence incompatible avec la GPL, ce qui a entrainé des problèmes pour plusieurs projets). GnuTLS offre également des possibilités qui sont absentes d'OpenSSL, comme la possibilité d'utiliser des clés PGP (RFC 5081) en sus des certificats X.509.
Sur une machine Debian, où tout est déjà
compilé et empaqueté, l'installation du module
mod_gnutls
d'Apache est triviale. Un coup de
aptitude install,
puis ln -s ../mods-available/gnutls.load
/etc/apache2/mods-enabled
(Sébastien Tanguy me fait
remarquer à juste titre qu'il existe une méthode de plus haut niveau,
la commande a2enmod
) et recharger Apache. Sa
configuration peut être aussi courte que :
GnuTLSEnable on GnuTLSCertificateFile /etc/ssl/certs/ssl-cert-Example.pem GnuTLSKeyFile /etc/ssl/private/ssl-cert-Example.key GnuTLSPriorities NORMAL
Et hop, ça marche avec des clients HTTP utilisant GnuTLS comme avec ceux utilisant OpenSSL comme Konqueror.
Une des forces de GnuTLS est qu'il permet l'utilisation de
l'extension de TLS SNI (Server Name Indication) qui
permet de mettre plusieurs certificats différents à des
Virtual Host Apache se partageant une seule adresse
IP. Il suffit de mettre une directive
GnuTLSCertificateFile
différente par
Virtual Host :
<VirtualHost _default_:443> # Site par défaut. Son certificat sera envoyé aux clients # non-SNI ... GnuTLSCertificateFile /etc/ssl/certs/ssl-cert-DEFAULT.example.net.pem ... <VirtualHost *:443> ... ServerName svn.example.net GnuTLSCertificateFile /etc/ssl/certs/ssl-cert-svn.example.net.pem ... <VirtualHost *:443> ... ServerName viewvc.example.net GnuTLSCertificateFile /etc/ssl/certs/ssl-cert-viewvc.example.net.pem ...
Date de publication du RFC : Octobre 2004
Auteur(s) du RFC : Peter Saint-Andre (Jabber Software Foundation)
Chemin des normes
Première rédaction de cet article le 7 avril 2008
Jabber est le nom original, et XMPP le nom IETF d'un protocole d'échange d'informations encodées en XML, protocole surtout connu pour son utilisation dans la messagerie instantanée.
La messagerie instantanée est une application très populaire surtout chez les moins de dix ans. Elle permet d'échanger des messages sans prendre le temps de réfléchir et en général sans craindre qu'ils soient archivés (contrairement au courrier électronique où il faut réfléchir car ce que l'on écrit restera). Elle sert à de nombreux usages, discussions entre geeks, systèmes de surveillance avec notification des problèmes, etc. À l'exception du vénérable protocole IRC (décrit - insuffisamment - dans le RFC 2810 et suivants), les systèmes existants de messagerie instantanée sont tous basés sur des protocoles privés et fermés comme MSN. La normalisation qui fait le succès du courrier électronique n'a pas réussi ici.
D'où le vieux projet (RFC 2779) de développer un protocole moderne et ouvert, adapté à cette application. C'est ce qu'on fait les développeurs du protocole Jabber en 1999, projet adopté ultérieurement par l'IETF, rebaptisé XMPP en 2002 et qui était normalisé dans ce RFC (l'annexe D liste les différences entre Jabber et XMPP, la plupart liées à la sécurité et à l'internationalisation). Depuis, il a été remplacé par le RFC 6120. Notre RFC décrit un protocole généraliste, un RFC compagnon, le RFC 3921, normalise les aspects spécifiques à la messagerie instantanée.
Quels sont les principes de XMPP ? Les données sont encodées en
XML (avec quelques bémols notés en section 11), dans des
strophes (stanzas) qui sont des petits paquets
d'information. Ces strophes sont transmises sur une connexion TCP
(section 4.2) entre
client et serveur, ou bien entre serveur et serveur. Les entités qui
communiquent (ce ne sont pas forcément des humains, Jabber ayant été
conçu pour permettre également la communication entre programmes) sont
identifiées par une adresse, qui a une forme syntaxique proche de
celle du courrier électronique. Par exemple, mon adresse XMPP est bortzmeyer@gmail.com
.
XMPP, comme le courrier électronique, fonctionne par le connexion de serveurs, chacun chargé d'un ou plusieurs domaines. Les clients transmettent les messages aux serveurs, qui se chargent de les acheminer au serveur suivant (section 2.1 du RFC).
Les adresses (JID pour Jabber Identifier) sont décrites dans la section 3. Outre le classique
nom@domaine
, elles peuvent comporter une
ressource, indiquée après la barre oblique (par
exemple bortzmeyer@gmail.com/AFNIC
).
La représentation des données en XML est décrite dans la section
4. Un flux de données, un stream, est un
élément XML <stream>
,
qui comporte une ou plusieurs strophes,
<stanza>
. Il existe de nombreux types de
strophes (section 9) sans compter les messages d'erreur, décrits en 4.7. Voici un
exemple classique d'un échange (C étant le client et S le serveur), avec des strophes de type
message
:
C: <message from='juliet@example.com' to='romeo@example.net' xml:lang='en'> C: <body>Art thou not Romeo, and a Montague?</body> C: </message> S: <message from='romeo@example.net' to='juliet@example.com' xml:lang='en'> S: <body>Neither, fair saint, if either thee dislike.</body> S: </message>
Contrairement à beaucoup d'autres protocoles de messagerie instantanée, conçus uniquement pour jouer, XMPP, étant prévu aussi pour le travail, dispose de fonctions de sécurité très riches. La section 5 précise l'utilisation de TLS et la 6 celle de SASL.
La section 9 détaille les types de strophes disponibles. Trois
types sont définis dans ce RFC, <message>
,
<presence>
et
<iq>
. <message>
,
dont la sémantique est décrite en section 9.2.1, transporte
un... message, tandis que <iq>
(section
9.2.3) est une interrogation (Info / Query). Ces éléments XML ont un certain
nombre d'attributs par exemple l'attribut
to
, section 9.1.1, qui spécifie l'adresse du destinataire
(romeo@example.net
dans la pemière strophe de
l'exemple ci-dessus). La syntaxe complète, exprimée en W3C
Schema, figure dans l'annexe C.
XMPP est aujourd'hui mis en œuvre dans de nompbreux logiciels. C'est ainsi que le service de messagerie instantanée Google Talk utilise XMPP. Le client XMPP (qui est aussi un client de nombreux autres protocoles) le plus populaire sur Unix est sans doute Pidgin (ex-Gaim). Côté serveurs, le plus pittoresque (et pas le moins utilisé) est sans doute ejabberd, écrit en Erlang.
Les développeurs liront avec intérêt le livre Programming Jabber qui explique comment utiliser Jabber/XMPP dans ses propres programmes.
Première rédaction de cet article le 6 avril 2008
Ce film de Rodrigo Plá montre une zone protégée de Mexico, un terrain privé entouré de murs et de barbelés, protégé par les gadgets les plus modernes de la technologie, dans le but d'échapper à la violence permanente de la ville. Comme aux États-Unis, comme déjà en France, le « désir de ghetto » mène à inscrire dans l'espace la volonté de séparation avec les « classes dangereuses ». Si les femmes de ménage indiennes ont l'autorisation de rentrer pour leur travail, le reste de la ville, même la police, est interdite d'accès.
Trois jeunes issus des bidonvilles vont rentrer dans la zone pour un cambriolage, déchaînant la violence des résidents de la Zona qui tiennent à maintenir la stricte pureté de leur communauté. À une ou deux exceptions près, ils ne sont pas des fascistes ou des brutes sadiques, mais ils paniquent à l'idée de tout contact avec le monde extérieur.
Étonnante zone protégée où les riches se sont enfermés eux-même, étonnante île privée, où les résidents pratiquent une stricte démocratie entre eux, tout en excluant tout le reste de la population (ils tiennent une assemblée générale avant de décider d'aller à la chasse à l'homme).
Fiche du film sur IMDB : http://www.imdb.com/title/tt1039652/
.
Date de publication du RFC : Novembre 1996
Auteur(s) du RFC : Ned Freed (Innosoft International, Inc.), Nathaniel S. Borenstein (First Virtual Holdings)
Chemin des normes
Première rédaction de cet article le 4 avril 2008
Autrefois, du temps des dinosaures, les internautes vivaient dans des cavernes et gravaient au silex des courriers en texte seul, sur des écorces d'arbre. En 1992, MIME a été inventé et, depuis, les humains sont civilisés et envoient du spam en HTML, des vidéos débiles et des photos ratées par courrier électronique. Notre RFC 2045 est l'actuelle norme MIME.
À l'origine du courrier électronique, la
norme (aujourd'hui le RFC 5322) décrivait surtout les
métadonnées, les en-têtes du message, comme
From:
(l'expéditeur) ou
Date:
(la date d'envoi). Le
corps du message, lui, était laissé au seul
texte brut, dans le seul jeu de caractèrs
US-ASCII.
Pour transmettre du non-texte, par exemple des images de Carla Bruni, on se servait d'encodages non-standard, qui transformaient le fichier binaire en texte. C'était l'époque de uuencode (ou de Binhex pour les macounistes). Même pour le texte seul, dès qu'on dépassait les limites du jeu de caractères ASCII, donc, dès qu'on écrivait autre chose que l'anglais, on ne pouvait plus rester strictement dans les limites du RFC 822 (la norme du courrier de l'époque). Ces limites et les motivations pour MIME sont décrites dans la section 1 du RFC.
MIME a changé cela. Normalisé à l'origine dans le RFC 1341, puis dans le RFC 1521 (et suivants) et finalement dans notre RFC 2045 et ses compagnons suivants, MIME repose sur quatre piliers :
Pour le texte, MIME utilise la notion de character set (section 2.2). Comme l'explique une note de cette section, le terme est erroné, puisqu'il s'agit en fait, dans MIME, d'un encodage, pas simplement d'un jeu de caractères.
Avec la section 3, commence la description du format MIME lui-même. MIME ajoute quelques
nouveaux en-têtes à commencer par MIME-Version
(section 4)
qui indique qu'il s'agit d'un message MIME. La section 5 décrit
l'en-tête Content-type
qui spécifie le type MIME
du message ou de la partie du message. Il existe un zoo entier de ces
types, conservé dans un registre
à l'IANA. Le principe est que le type est
composé de deux parties, le type proprement dit, qui identifie le
genre de données (texte, image, son, ...) et le sous-type qui
identifie le format. Ainsi, image/png
est une
image au format PNG,
text/troff
est du texte au format
troff (RFC 4263). Plus complexes, les
types message
ou
application
. Le premier identifie un message MIME
inclus dans un autre message MIME (par exemple lors de l'envoi d'un
avis de non-réception (RFC 3461). Le second identifie des
données binaires qui ne peuvent être comprises que par une application
spécifique, indiquée par le sous-type. La classification MIME n'est
pas toujours aussi évidente et je n'ai personnellement jamais compris
pourquoi XML est en
application/xml
et pas
text/xml
. Enfin, des paramètres peuvent se
trouver dans cet en-tête, par exemple pour indiquer
l'encodage d'un texte (Content-Type:
text/plain; charset=utf-8
) ou bien pour indiquer le site où
récupérer un document pointé (comme dans le programme d'exemple
ci-dessous).
La section 6 introduit un autre en-tête,
Content-Transfer-Encoding
qui indique comment le
contenu a été emballé pour passer à travers des serveurs (qui peuvent
n'accepter que l'ASCII). Un Content-Transfer-Encoding:
8bit
spécifie que le contenu n'a pas été modifié du tout,
il faudra alors que tous les serveurs laissent passer le 8bits. À une
époque très lointaine, où les mammouths étaient encore fréquents en
France, certains serveurs mettaient le huitième bit à zéro ou autres
horreurs ; une longue polémique, au début des années 1990, avait
opposé ceux qui voulaient transmettre les textes en français en 8bits
(et tant pis pour les quelques serveurs archaïques) et ceux qui
préféraient l'encoder dans des systèmes comme
Quoted-Printable
(Content-Transfer-Encoding: quoted-printable
,
décrit en détail dans la section 6.7), qui étaient plutôt pires pour
les MUA de l'époque, qui affichaient caf=E9 au
lieu de café...
À titre d'exemple, voici un programme Python qui analyse un message MIME. Le
programme n'est pas récursif, bien que cela soit souvent utile pour
les messages MIME, la définition même du format étant récursive (un
message peut être composé de parties qui sont elles-mêmes composées de
parties, etc, cf. la note de la section 2.6). Ces messages contiennent
une partie de type message/external-body
qui
donne des instructions d'accès à un fichier par FTP :
import email from email.MIMEText import MIMEText ... # We receive the message on standard input (for instance through # procmail and its pipe action) message = email.message_from_file(sys.stdin) subject = message.get("subject") # A MIME message can be single-part but we are interested only in multi-parts if not message.is_multipart(): raise NotForMe("Not multipart") ... # The body of the message parts = message.get_payload() # Iterate over the parts of the message for part in parts: if part.get_content_type() == "message/external-body": params = dict(part.get_params()) if params["access-type"] == "anon-ftp": url = "ftp://%s/%s/%s" % (params["site"], params["directory"], params["name"]) ...
À l'époque du RFC 822, écrire un programme qui analysait les messages électroniques était trivial, on pouvait travailler directement avec le texte, même un simple grep suffisait. Avec MIME, les parties multiples (section 5.1 du RFC 2046), et les encodages variés, l'utilisation de bibliothèques comme email en Python devient indispensable. Par exemple, les spammeurs encodent souvent leurs messages en Base64 (section 6.8, désormais dans le RFC 4648), afin de trompeur les analyseurs de mots-clés naïfs.
On note que ce RFC, ce qui est relativement rare, contient également d'intéressantes notes (introduites par NOTE) sur les choix effectués par les concepteurs du format MIME. Leur lecture permet de mieux comprendre ces choix.
Première rédaction de cet article le 3 avril 2008
Dernière mise à jour le 6 avril 2008
Ce serait bien d'avoir des sélections de mon flux de
syndication (http://www.bortzmeyer.org/feed.atom
) par sujet
(PostgreSQL, XSLT,
Python, etc). Existe
t-il des services en ligne qui assurent ce genre de sélections ?
Comme je maitrise complètement le processus de production du flux, je pourrais bien sûr générer N flux selon le sujet mais cela représente du travail, alors que les critères de sélection évoluent tout le temps.
Je me demande s'il n'existe pas plutôt un service tiers de sélection à qui
on donnerait l'URL du flux, un critère de
sélection (mot-clé, expression rationnelle,
expression XPath) et qui renverrait un URL que
je pourrais donner à des sites d'agrégation comme http://planete.postgresql.fr/
ou comme http://fr.incubator.wikiblogplanet.com/
, qui n'acceptent que
les articles sur un certain sujet (PostgreSQL
dans le premier cas, Wikipédia dans le second).
J'ai testé trois de ces services mais d'autres adresses seraient bienvenues.
Le premier est http://www.filtermyrss.com/
. Il marche uniquement avec
RSS, alors que mon flux est en
Atom (RFC 4287). Il ne filtre que par mot-clés, pouvant
apparemment porter sur certains éléments (titre uniquement, par
exemple).
Puis j'ai testé http://feedrinse.com/
. Il
nécessite une inscription, certes gratuite mais c'est quand même pénible.
Après inscription, je dois être bête, je n'ai jamais pu le faire marcher.
Le service de référence le plus souvent cité pour ce genre d'opérations est Yahoo Pipes, un mécanisme de programmation graphique, permettant de définir des traitements sur des flux d'information. Yahoo Pipes nécessite apparemment un compte Yahoo et Yahoo me refuse l'inscription (This is not a valid email address, dit-il, et mon identifiant OpenID ne suffit apparemment pas donc j'ai abandonné tout espoir d'utiliser Yahoo). Un problème analogue m'empêche de tester Fwicki qui en outre se vante stupidement de ses brevets dès la page d'accueil.
Enfin, http://re.rephrase.net/filter/
est celui que j'ai
choisi. Il n'y a pas besoin d'inscription, il marche bien avec
Atom. Les recherches se font par mot-clés, portant sur le texte ou sur
une partie du texte (une documentation très complète est disponible). En
outre, le source du service est distribué par l'auteur.
C'est donc celui que j'utilise en ce moment. Par exemple http://re.rephrase.net/filter/?feed=http%3A%2F%2Fwww.bortzmeyer.org%2Ffeed.atom&filter=title%3Apostgresql+OR+title%3ASQL
sélectionne tous les articles du flux qui ont « postgresql » ou
« SQL » dans leur titre.
Les caractères composés du français
nécessitent un peu de bricolage. Rephrase, écrit en
PHP, n'a pas de support
d'Unicode et fait une recherche « bête » en
comparant les octets. Si le flux de syndication est en
UTF-8, il faut mettre de l'UTF-8 dans le
critère de tri. Ainsi, pour chercher tous les articles parlant de
Wikipédia, l'URL sera
http://re.rephrase.net/filter/?feed=http%3A%2F%2Fwww.bortzmeyer.org%2Ffeed.atom&filter=wikip%C3%A9dia
,
puisque le caractère « é » se code par 0xC3 et 0xA9 en UTF-8.
Depuis ce choix, mon blog a été muni d'un moteur de recherche. Donc, une
autre solution, à explorer, serait d'utiliser le moteur de recherche
pour produire des flux Atom dynamiques, avec des requêtes comme
. Toutefois,
le moteur de recherche de ce blog ne renvoyant que les N articles les
plus pertinents, ce n'est pas actuellement idéal pour faire une vue
d'un flux de syndication.http://www.bortzmeyer.org/search?pattern=postgresql&format=Atom
Merci à Benoit Deuffic, David Larlet et Olivier Mengué pour leur aide à trouver ces services. Merci à l'auteur de Rephrase, Sam Angove, pour sa rapidité à répondre aux questions des utilisateurs.
Date de publication du RFC : Avril 2008
Auteur(s) du RFC : M. Blanchet (Viagenie)
Pour information
Réalisé dans le cadre du groupe de travail IETF v6ops
Première rédaction de cet article le 3 avril 2008
Un certain nombre de préfixes IPv6 ont une signification spéciale et ce RFC les documente, pour éviter aux lecteurs de devoir fouiller dans les nombreux RFC originaux. (Depuis, ce RFC a été remplacé par le registre décrit dans le RFC 6890.)
Normalement, les préfixes des réseaux IPv6 sont attribués par l'IANA aux RIR qui les allouent ensuite aux LIR (qui sont en général des FAI). Ces allocations et les affectations aux utilisateurs finaux sont enregistrées par les RIR et sont publiquement accessibles via des protocoles comme whois.
Mais certains préfixes sont spéciaux et échappent à ce mécanisme. Ils ont été réservés par tel ou tel RFC et sont donc dispersés à plusieurs endroits. Notre RFC, écrit par l'IANA, rassemble toutes ces réservations en un seul endroit. (Il existe un RFC équivalent pour IPv4, le RFC 5737.)
Voici quelques exemples de préfixes ainsi documentés :
2001:DB8::/32
(section 2.6), réservé pour la documentation par le RFC 3849
(par exemple pour rédiger des manuels, sans craindre que les adresses
IP d'exemple soient utilisées),FE80::/10
, réservé pour les adresses
locales au lien par le RFC 4291,2001:20::/28
, réservé pour créer des identificateurs
(et non de simples adresses) sous le nom d'ORCHID (RFC 7343),FEC0::/10
, celles-ci
ayant été abandonnées par le RFC 3879.Première rédaction de cet article le 1 avril 2008
De nombreuses applications Internet ont besoin de connaitre la « distance » entre deux machines. Par exemple, un logiciel de pair-à-pair cherche quel pair est le plus « proche » avant de lui demander un fichier. Pour cela, la méthode utilisée est en général à la fois consommatrice en ressources et peu précise. Le déploiement de mécanismes de coordonnées Internet pourrait résoudre le problème élégamment.
Aujourd'hui, la métrique la plus courante est le RTT avec l'autre machine et la méthode de mesure la plus fréquente est la force brute : on écrit à tous les partenaires potentiels et le premier à répondre est considéré comme le plus proche et sera désormais davantage utilisé. C'est par exemple ainsi que fonctionne le résolveur DNS BIND ou la plupart des logiciels de pair-à-pair. La métrique n'est pas idéale (il existe des liens Internet à fort débit mais à latence élevée). Et cela consomme beaucoup de ressources réseau (il faut émettre des octets vers chaque pair potentiel) et pour une mesure qui n'est pas forcément très précise.
Les systèmes de coordonnées Internet traitent le problème d'une manière radicale. On ne « pingue » plus les pairs potentiels mais on obtient leurs coordonnées dans un espace cartésien à N dimensions. Connaissant ces coordonnées et les siennes propres, déterminer une distance, et donc la proximité d'un futur partenaire, est triviale.
Mais comment déterminer les coordonnées d'une machine ? En testant un petit nombre de machines cibles, les amers (beacons ou lighthouses, on peut aussi traduire par phare ou balise). Contrairement à un pair quelconque, les amers sont en petit nombre (donc on consomme moins de ressources à les tester), stables, et judicieusement placés. Chaque amer a, en testant les autres amers, déterminé ses coordonnées, ce qui permettra à la machine testeuse de déterminer la sienne avec un coût plus faible et une meilleure précision.
Il existe plusieurs systèmes concurrents de coordonnées Internet. À l'heure actuelle, aucun n'est encore réellement déployé et utilisé. L'excellent exposé de Marcelo Pias, Internet Coordinate Systems Tutorial expose les principaux et les compare. Les premiers utilisaient, pour calculer les coordonnées des amers, la minimisation d'erreur par le simplex downhill, alors que les plus récents, comme ICS décrit dans Constructing Internet Coordinate System Based on Delay Measurement utilisent l'analyse en composantes principales. Voici une liste pas du tout limitative de certains de ces systèmes, outre ICS :
Le projet P4P, très à la mode actuellement, est complémentaire de ces systèmes de coordonnées. Il vise à fournir un moyen de distribuer des informations de topologie (qui est connecté à qui) et de politique (le lien de peering est préféré au lien de transit) pour que les machines puissent décider judicieusement de leurs pairs. Mais il faut noter que plusieurs présentations de P4P comme celle de Pando sont biaisées dans leur façon de décrire le pair-à-pair actuel, en prétendant que les pairs sont aujourd'hui choisis plus ou moins au hasard, alors que ce choix (qui a l'avantage de simplifier l'implémentation) n'est pas universel.
Une autre approche possible à la question de la détermination d'un pair « proche » est Meridian.
Date de publication du RFC : Mai 2007
Auteur(s) du RFC : S. Hollenbeck (Verisign)
Chemin des normes
Première rédaction de cet article le 1 avril 2008
Dernière mise à jour le 7 mai 2008
Ce court RFC spécifiait comment utiliser le protocole d'avitaillement EPP au dessus d'une simple connexion TCP. Il a été remplacé depuis par le RFC 5734.
EPP, décrit dans le RFC 4930 est à sa base uniquement un format XML pour les requêtes d'avitaillement (création, mise à jour et destruction d'objets) et leurs réponses. Ces éléments XML peuvent être transmis de différence façon (au dessus de HTTP, de BEEP, par courrier électronique, etc), et notre RFC normalise la plus commune aujourd'hui, une simple connexion TCP. Il remplace le RFC 3734, avec uniquement des modifications de détail, portant notamment sur la sécurité (section 8).
Le RFC est court car il n'y a pas grand'chose à dire, juste
l'utilisation des primitives de TCP (ouverture et fermeture de
connexion, section 2 du RFC), l'ordre des messages (section 3) et le fait que chaque élément EPP soit précédé d'un entier
qui indique sa taille (section 4). Sans cet entier (qui joue le même rôle que
l'en-tête Content-Length
de HTTP), il faudrait,
avec la plupart des implémentations, lire les données
octet par octet (sans compter que la plupart des analyseurs XML ne
savent pas analyser de manière incrémentale, il leur faut tout
l'élément). En outre, sa présence permet de s'assurer que toutes les données ont été reçues (voir l'excellent article The ultimate SO_LINGER page, or: why is my tcp not reliable).
L'entier en question est fixé à 32 bits. Si on programme un client EPP en Python, l'utilisation brutale du module struct ne suffit pas forcément. En effet :
struct.pack("I", length)
force un entier (int
) mais pas forcément un
entier de 32 bits. Pour forcer la taille, il faut utiliser également,
comme précisé dans la documentation, les opérateurs < et >, qui servent aussi à forcer la
boutianité (merci à Kim-Minh Kaplan pour son
aide sur ce point).
Voici une démonstration (un "l" standard fait 4
octets alors que le type long de C peut faire 4 ou 8 octets) :
# Machine 32 bits : Python 2.4.4 (#2, Apr 5 2007, 20:11:18) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import struct >>> print struct.calcsize("l") 4 >>> print struct.calcsize(">l") 4
# Machine 64 bits : Python 2.4.5 (#2, Mar 11 2008, 23:38:15) [GCC 4.2.3 (Debian 4.2.3-2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import struct >>> print struct.calcsize("l") 8 >>> print struct.calcsize(">l") 4
Si on a quand même un doute, on peut tester la taille obtenue mais ce code est probablement inutile (merci à David Douard pour son aide ici) :
# Get the size of C integers. We need 32 bits unsigned. format_32 = ">I" if struct.calcsize(format_32) < 4: format_32 = ">L" if struct.calcsize(format_32) != 4: raise Exception("Cannot find a 32 bits integer") elif struct.calcsize(format_32) > 4: format_32 = ">H" if struct.calcsize(format_32) != 4: raise Exception("Cannot find a 32 bits integer") else: pass ... def int_from_net(data): return struct.unpack(format_32, data)[0] def int_to_net(value): return struct.pack(format_32, value)
L'algorithme complet d'envoi est :
epp_as_string = ElementTree.tostring(epp, encoding="UTF-8") # +4 for the length field itself (section 4 mandates that) # +2 for the CRLF at the end length = int_to_net(len(epp_as_string) + 4 + 2) self._socket.send(length) self._socket.send(epp_as_string + "\r\n")
et la lecture :
data = self._socket.recv(4) # RFC 4934, section 4, the length # field is 4 bytes long length = int_from_net(data) data = self._socket.recv(length-4) epp = ElementTree.fromstring(data) if epp.tag != "{%s}epp" % EPP.NS: raise EPP_Exception("Not an EPP instance: %s" % epp.tag) xml = epp[0]
Le code Python complet (qui ne met en œuvre qu'une petite partie de EPP, le but était juste de tester ce RFC 4934), utilisant la bibliothèque ElementTree, est disponible en ligne.
Date de publication du RFC : Juillet 2005
Auteur(s) du RFC : Paul J. Leach (Microsoft), Michael Mealling (Refactored Networks, LLC), Rich Salz (DataPower Technology, Inc.)
Chemin des normes
Première rédaction de cet article le 1 avril 2008
Ce RFC décrit un espace de noms URN pour les UUID, une famille d'identificateurs uniques, obtenus sans registre central. Il a depuis été remplacé par le RFC 9562.
Les UUID, également connus sous le nom de GUID, sont issus à l'origine du système des Apollo, adopté ensuite dans la plate-forme DCE. Ils ont une taille fixe, 128 bits, et sont obtenus localement, à partir d'un autre identificateur unique comme l'adresse MAC ou bien en tirant au hasard, la grande taille de leur espace de nommage faisant que les collisions sont très improbables (section 2 du RFC). Ce RFC reprend la spécification de DCE de l'Open Group (ex-OSF) et ajoute la définition d'un espace de noms pour des URN (section 3). (Il existe aussi une norme ITU sur les UUID et un registre des UUID, pour ceux qui y tiennent.)
Les UUID peuvent donc convenir pour identifier une entité sur le réseau, par exemple une machine mais aussi, vu leur nombre, comme identificateur unique pour des transactions (ce qui était un de leurs usages dans DCE). En revanche, ils ne sont pas résolvables.
Sur Unix, on peut fabriquer un UUID avec la
commande uuidgen
, qui affiche la représentation
texte standard que normalise notre RFC :
% uuidgen 317e8ed3-1428-4ef1-9dce-505ffbcba11a % uuidgen ec8638fd-c93d-4c6f-9826-f3c71436443a
On trouve les UUID à de nombreux endroits en informatique, par
exemple dans les logiciels Mozilla (cf. http://developer.mozilla.org/en/docs/Generating_GUIDs
).
Pour l'affichage sous forme d'URN (RFC 8141), on ajoute juste l'espace
uuid
par exemple urn:uuid:ec8638fd-c93d-4c6f-9826-f3c71436443a
.
La section 4 du RFC détaille le format interne de l'UUID (en dépit
des apparences, l'UUID n'est pas plat, il a une structure). Notamment,
la section 4.1.3 précise le champ Version (qui devrait plutôt
s'appeler Type), puisqu'un UUID peut être généré à partir d'une
estampille temporelle (version 1, option -t
de
uuidgen), d'une valeur aléatoire (version 4, option
-r
) ou d'un résumé
cryptographique (version 3).
L'UUID utilise également l'adresse MAC de la machine, si elle est présente (section 4.1.6).
La section 4.2, elle, décrit le processus de génération d'un UUID à base temporelle. Idéalement, il faut utiliser une graine enregistrée sur le disque (pour éviter de générer des UID identiques) ainsi que l'instant de la génération. Mais lire sur le disque prend du temps (alors qu'on peut vouloir générer des UUID rapidement, par exemple pour identifier des transactions) et l'horloge de la machine n'a pas toujours une résolution suffisante pour éviter de lire deux fois de suite le même instant. Cette section contient donc également des avis sur la génération fiable d'UUID, par exemple (section 4.2.1.2) en gardant en mêmoire le nombre d'UUID générés, pour les ajouter à l'heure. Si on préfère des UUID créés par résumé cryptographique, la section 4.3 est là pour cela.
La section 6, consacrée à la sécurité, rappelle qu'un UUID ne doit pas être utilisé comme capacité (car il est trop facile à deviner) et qu'il ne faut pas demander à un humain de comparer deux UUID (ils se ressemblent trop pour un œil humain).
L'annexe A est une excellent mise en œuvre, en langage C, des principes décrits dans la section 4. Si on préfère utiliser Python, il existe, depuis la version 2.5, un module UUID qui offre des fonctions de génération d'UUID de différentes versions :
import uuid myuuid = uuid.uuid1() # Version 1, Time-based UUID otheruuid = uuid.uuid4() # Version 4, Random-based UUID yetanotheruuid = uuid.uuid5(uuid.NAMESPACE_DNS, "www.example.org") # Version 5, a name hashed by SHA1 if (myuuid == otheruuid or \ myuuid == yetanotheruuid or \ otheruuid == yetanotheruuid): print "They are equal, PANIC!" print myuuid print otheruuid print yetanotheruuid
À noter que le SGBD PostgreSQL, à partir de la version 8.3, inclus un type UUID.
essais=> CREATE TABLE Transactions (id uuid, value INT); CREATE TABLE essais=> INSERT INTO Transactions VALUES ('74738ff5-5367-5958-9aee-98fffdcd1876', 42); INSERT 0 1 essais=> INSERT INTO Transactions VALUES ('88e6441b-5f5c-436b-8066-80dca8222abf', 6); INSERT 0 1 essais=> INSERT INTO Transactions VALUES ('Pas correct', 3); ERROR: invalid input syntax for uuid: "Pas correct" essais=> SELECT * FROM Transactions; id | value --------------------------------------+------- 74738ff5-5367-5958-9aee-98fffdcd1876 | 42 88e6441b-5f5c-436b-8066-80dca8222abf | 6 (2 rows)
Il existe plusieurs exemples d'utilisation des UUID. Par exemple,
Linux s'en sert pour identifier les disques
attachés à la machine, de préférence à l'ancien système où l'ajout
d'un nouveau disque pouvait changer l'ordre des numéros sur le bus et
empêcher le système de trouver un disque. Un
/etc/fstab
typique sur Linux contient donc
désormais des :
UUID=da8285a0-3a70-413d-baed-a1f48d7bf7b2 /home ext3 defaults ...
plutôt que les anciens :
/dev/sda3 /home ext3 defaults
car sda3
n'est pas un identificateur
stable. L'UUID, lui, est dans le système de fichiers et ne changera
pas avec les changements sur le bus. On peut
l'afficher avec dumpeéfs :
# dumpe2fs -h /dev/sda3 ... Filesystem UUID: da8285a0-3a70-413d-baed-a1f48d7bf7b2 ...
Date de publication du RFC : Mars 2008
Auteur(s) du RFC : P. Srisuresh (Kazeon), B. Ford (MIT), D. Kegel (kegel.com)
Pour information
Réalisé dans le cadre du groupe de travail IETF behave
Première rédaction de cet article le 30 mars 2008
Pour faire face à la plaie du NAT, les applications pair-à-pair ont développé de nombreuses techniques pour pouvoir passer à travers les routeurs NAT. Ce RFC les documente.
Le groupe de travail Behave de l'IETF travaille à normaliser les techniques permettant de contourner les NAT et les nombreux problèmes qui leur sont associés. Quoique certains à l'IETF auraient préféré qu'aucun travail permettant de rendre les NAT plus supportables ne soit effectué, le consensus a finalement été qu'il valait mieux travailler à faire fonctionner les applications malgré les NAT, plutôt que de rêver supprimer ceux-ci.
Ce RFC ne normalise pas un protocole mais examine l'état de l'art, en matière de fonctionnement en présence de NAT. Il rappelle que les NAT n'apportent rien en matière de sécurité mais, comme cette technique est largement déployée, il est préférable de documenter les bricolages divers qu'utilisent les applications forcées de vivre derrière un NAT.
Il existe deux grandes catégories de techniques pare-NAT. Celles qui reposent sur une signalisation explicite de l'application au routeur NAT. La plus connue est UPNP. L'IETF a son MIDCOM (cf. RFC 4097) pour le même rôle. Ces techniques ne sont pas étudiées dans notre RFC.
Les autres techniques pare-NAT sont celles qui ne nécessitent pas forcément de communication explicite entre l'application et le routeur NAT. Chacune est détaillée dans une section de ce RFC.
La terminologie utilisée est celle du RFC 2663, pas celle des « cônes » du RFC 3489 et la section 2 est entièrement occupée à débroussailler les questions de vocabulaire.
Les techniques décrites ensuite sont :
La section 5 résume ces techniques et les recommandations des auteurs. Le perçage est la technique la plus efficace à l'heure actuelle.
La section 6, consacrée à la sécurité, est très détaillée car les NAT crée de nombreux problèmes de sécurité.
Notre RFC contient aussi, en section 4, une bonne liste des articles sur le sujet, afin d'aider l'auteur d'applications qui veut maximiser les chances de fonctionnement dans toutes les circonstances.
Date de publication du RFC : Mars 2008
Auteur(s) du RFC : J. Klensin, M. Padlipsky
Chemin des normes
Première rédaction de cet article le 30 mars 2008
Il ne reste plus beaucoup de normes Internet qui soient limitées à l'ASCII et elles tombent une à une. Un des problèmes rencontrés pour éliminer les dernières est que certains protocoles transmettent du texte et que « texte », à l'IETF, voulait toujours dire seulement ASCII. Voici que ce RFC introduit un nouveau type de texte, utilisant Unicode.
Pendant longtemps, plusieurs normes comme le RFC 959 sur FTP faisaient référence à des données de type texte, c'est-à-dire sans formatage, avec des lignes terminées par la séquence CRLF (Carriage Return puis Line Feed). Cette définition du texte, souvent nommé « NVT », datant du RFC 854, limitait le texte au jeu de caractères ASCII, jeu de caractères qui ne permet pas de représenter toutes les écritures du monde. Où est le problème ? peut-on se demander. Pourquoi ne pas simplement remplacer ASCII par Unicode partout dans le texte ? C'est en effet la bonne solution mais le diable est dans les détails et, Unicode étant beaucoup plus riche qu'ASCII et n'étant pas figé, traiter ces détails a pris du temps. (Et ce RFC a fait l'objet de nombreuses controverses.) Unicode a plusieurs encodages, plusieurs façons de représenter une fin de ligne et même plusieurs façons de représenter le même caractère.
Le RFC pose donc comme règles (section 2) :
Le choix d'UTF-8 provient de sa large utilisation dans beaucoup de protocoles Internet, due en partie au fait qu'il est un sur-ensemble de l'encodage ASCII.
Le choix du CRLF comme indicateur d'une fin de ligne est également
dû à sa large utilisation aujourd'hui. Bien qu'Unicode aie des
caractères plus adaptés (Line separator,
U+0028
et Paragraph separator,
U+0029
), ils sont très peu utilisés. La
passionnante annexe C
discute en détail ce choix.
La normalisation fait l'objet d'une section 3 détaillée. Elle est
nécessaire car Unicode permet de représenter un caractère de plusieurs
façons. Ainsi, U+2126
, Ohm
sign, Ω, a une forme canonique qui est
U+03A9
, Greek capital letter
omega , Ω, (les symboles scientifiques ne sont normalement pas
codés séparément dans Unicode et ceux qui le sont sont normalisés dans
une lettre ordinaire). Cas plus connu, deux caractères peuvent se
combiner par exemple U+0061
U+0300
se combinent, par le mécanisme NFC, en
U+00E0
(la première séquence est faite d'un petit
a et de l'accent grave combinant, la seconde est donc juste un
à). L'obligation de normalisation rendra donc plus facile la
comparaison des textes (la section 6 sur la sécurité note toutefois
que le pare-feu prudent ne doit pas supposer que l'envoyeur respectera
la norme).
La section 4 couvre un autre problème délicat, celui des versions d'Unicode. Contrairement à ASCII, qui était figé dès le début, des nouveaux caractères sont ajoutés dans Unicode régulièrement, ainsi que de nouvelles règles de normalisation. Si on ne fait pas attention, une nouvelle version d'Unicode pourrait rendre invalides (car non normalisés) des textes auparavant valables. Pour éviter cela, notre RFC interdit l'utilisation des points de code non affectés. Les politiques de stabilité du consortium Unicode garantissent que, dans ce cas, la normalisation NFC est stable (la section 5.2 discute également ce choix).
La section 5 explique quelles normes pourrait tirer profit de ce nouveau RFC. Celles qui utilisent déjà UTF-8, comme LDAP, ne sont pas concernées. Mais, outre FTP, déjà cité, cette nouvelle référence pourrait intéresser des protocoles comme whois (dont le RFC 3912 note que, en théorie, il est limité à ASCII).
Cas rare chez les RFC, il se termine par des annexes traitant d'histoire. L'excellente annexe A revient sur l'histoire tourmentée des jeux de caractères dans Internet, du RFC 20, qui imposera ASCII, au RFC 318 qui sera le premier à mentionner le « NVT » (Network Virtual Terminal). L'annexe B, elle, extrait de différents RFC, ce qui est à ce jour la définition la plus complète et la plus correcte de la norme NVT... que notre RFC remplace. Bel hommage du présent au passé.
Première rédaction de cet article le 26 mars 2008
Dernière mise à jour le 30 novembre 2008
Si on gère de nombreux ordinateurs multi-utilisateurs, on se pose forcément la question de la centralisation des comptes, des informations sur les utilisateurs. Il est très pénible de devoir créer un compte sur N machines dès qu'un nouvel employé arrive ou de devoir se rappeler des M mots de passe précédents parce qu'on ne les a pas changé sur toutes les machines.
Il existe plusieurs solutions techniques à ce problème, et je présente ici l'utilisation de LDAP pour gérer une base centralisée de comptes, notamment pour des machines Unix.
Première rédaction de cet article le 26 mars 2008
Si on produit un format quelconque à partir de XML, par exemple du CSV ou bien du LaTeX, on est souvent confronté au cas de caractères qui, sans créer de problèmes dans le source XML, sont « spéciaux » pour le format de destination et nécessitent donc d'être protégés (to be escaped, dans la langue de J. K. Rowling). Comment le faire en XSLT ?
La technique présentée ici est largement inspirée d'un excellent article de Jenni Tennison. Les exemples ci-dessous concernent la production de LaTeX pour lequel on peut trouver une liste des caractères « spéciaux ». On définit d'abord un espace de noms XML pour les données sur ces caractères spéciaux :
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tolatex="http://www.bortzmeyer.org/xmlns/tolatex" ...
puis on définit ces caractères et leur remplacement. On note que cette définition est complètement séparée du code qui fait le remplacement, pour faciliter la maintenance :
<tolatex:replacements> <tolatex:replacement search="$">DOLLAR-TO-ESCAPE</tolatex:replacement> <tolatex:replacement search="\">$\backslash$</tolatex:replacement> <!-- Difficult circularity in escaping --> <tolatex:replacement search="DOLLAR-TO-ESCAPE">\$</tolatex:replacement> <tolatex:replacement search="#">\#</tolatex:replacement> <tolatex:replacement search="%">\%</tolatex:replacement> <tolatex:replacement search="_">\_</tolatex:replacement> ... <tolatex:replacement search=" ">~</tolatex:replacement> <tolatex:replacement search="&">\&</tolatex:replacement> <tolatex:replacement search="œ">\oe{}</tolatex:replacement> <tolatex:replacement search="€">\EUR{}</tolatex:replacement> </tolatex:replacements> <xsl:variable name="replacements" select="document('')/xsl:stylesheet/tolatex:replacements" />
Quand on rencontre du texte, le gabarit
suivant est appelé. Il appelle alors replace
en
passant un paramètre qui est la position dans l'élément
<tolatex:replacements>
(au début, un) :
<xsl:template name="escape_text" match="text()"> <xsl:variable name="position" select="1"/> <xsl:call-template name="replace"> <xsl:with-param name="position" select="$position"/> <xsl:with-param name="content" select="string(.)"/> </xsl:call-template> </xsl:template>
En quoi consiste le gabarit replace
? Il est
récursif, utilisant pour cela le paramètre
position
. Il parcourra ainsi la totalité des <tolatex:replacement>
.
<xsl:template name="replace"> <xsl:param name="position" select="1"/> <xsl:param name="content"/> <xsl:variable name="transformed"> <xsl:call-template name="string_replace"> <xsl:with-param name="string" select="$content" /> <xsl:with-param name="search" select="$replacements/tolatex:replacement[$position]/@search" /> <xsl:with-param name="replace" select="$replacements/tolatex:replacement[$position]" /> </xsl:call-template> </xsl:variable> <xsl:choose> <xsl:when test="$position < count($replacements/tolatex:replacement)"> <!-- There are still replacements to perform. Call myself. --> <xsl:call-template name="replace"> <xsl:with-param name="position" select="$position + 1"/> <xsl:with-param name="content" select="$transformed"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <!-- No more replacements to do --> <xsl:value-of select="$transformed"/> </xsl:otherwise> </xsl:choose> </xsl:template>
Pour une position donnée dans l'élément
<tolatex:replacements>
, le gabarit
replace
appelera
string_replace
qui va parcourir une chaîne de
caractères en effectuant le remplacement indiqué :
<xsl:template name="string_replace"> <xsl:param name="string"/> <xsl:param name="search"/> <xsl:param name="replace"/> <xsl:choose> <xsl:when test="contains($string, $search)"> <xsl:variable name="rest"> <xsl:call-template name="string_replace"> <xsl:with-param name="string" select="substring-after ($string, $search)"/> <xsl:with-param name="search" select="$search"/> <xsl:with-param name="replace" select="$replace"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="concat(substring-before($string, $search), $replace, $rest)"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string"/> </xsl:otherwise> </xsl:choose>
Ce gabarit string_replace
est lui aussi récursif,
pour pouvoir effectuer plusieurs remplacements dans la chaîne de
caractères, au cas où un caractère spécial apparaitrait plusieurs fois.
Une version complète se trouve dans les sources de ce blog, voir notamment le fichier schema/common-latex.xsl
.
Première rédaction de cet article le 26 mars 2008
Après dix-huit ans d'utilisation d'Emacs, je découvre encore des choses sur cet éditeur. J'ai parfois à examiner un fichier à la recherche de caractères pas évidents à voir à l'œil nu, comme l'espace insécable et un mode special d'Emacs permet de faire très facilement.
M-x hexl-mode
et on est lancé dans le mode
hexadécimal où apparait tout à fait à gauche le
nombre d'octets depuis le départ, puis la
valeur en hexadécimal du contenu du fichier puis ce même contenu en
mode normal. En pointant un des caractères, le curseur clignote sur
l'emplacement de sa valeur en hexadécimal. On peut aussi rentrer un caractère quelconque en tapant sa valeur en hexadécimal (C-M-x
, l'aide du mode fonctionne avec la commande habituelle, C-h m
).
Contrairement à d'autres éditeurs binaires, c'est Emacs, toutes les commandes habituelles fonctionnent, il est donc très facile d'explorer un fichier à la recherche de caractères inhabituels.
C-c C-c
ramène au mode normal.
Première rédaction de cet article le 25 mars 2008
Dernière mise à jour le 2 avril 2009
Malgré les avantages de la lecture sur écran, notamment pour la préservation des forêts, la lecture sur papier a des bienfaits considérables, notamment le fait qu'on puisse la pratiquer debout dans le métro ou allongé dans son bain. Une version PDF des articles de ce blog n'était donc pas inutile. Elle existe désormais et est accessible depuis chaque article.
Le plus agaçant avec les soi-disants e-books, outre leur limitation aux textes distribués par un éditeur payant, est leur prix : pas question de les emporter sur la plage, au risque de perdre ou de se faire voler un engin dont le prix évoque plutôt l'ordinateur que le livre.
Lorsqu'un article en ligne est un peu long, et que je préférerai le
lire à loisir ailleurs que dans mon bureau, il m'arrive donc, plutôt
que d'utiliser un engin électronique, de
l'imprimer. Ce blog dispose d'une feuille de
style CSS
spécifique à l'impression, qui permet notamment de ne pas imprimer le
menu (#left-column { display: none; }
). On peut
ainsi imprimer depuis son navigateur et avoir un résultat
acceptable. (C'est un excellente pratique, que j'ai empruntée à
Wikipédia, où l'impression des articles depuis
le navigateur est très bien conçue.)
Mais on peut obtenir une qualité typographique encore meilleure en utilisant LaTeX. C'est ainsi que j'ai modifié les programmes qui gèrent ce blog pour produire du PDF en passant par LaTeX.
Le résultat est visible sous forme d'un lien discret en bas de chaque page. Si vous voulez voir la version PDF d'un
article, vous pouvez aussi simplement éditer l'adresse en remplaçant le
.html
par un .pdf
. N'hésitez
pas à me tenir au courant d'éventuels problèmes.
Première rédaction de cet article le 25 mars 2008
Pour produire des documents de grande qualité typographique, surtout si on veut le faire de manière massive, sans passer par un cliquodrome nécessitant plusieurs clics par fichier, LaTeX reste imbattable. Mais si les documents contiennent de l'Unicode ?
LaTeX dispose depuis longtemps de moyens de formater du texte écrit dans différentes langues et différentes écritures. Par exemple, avec le paquetage Babel, on peut écrire des choses comme :
\usepackage[latin1]{inputenc} \usepackage[french]{babel}
et typographier ainsi du français correct, directement saisi en Latin-1. Si on veut faire du grec, qui utilise un autre alphabet, ce n'est pas plus difficile :
\usepackage[greek]{babel} ... \textgreek{...}
Mais ces techniques (décrites dans Langues exotiques [sic]) nécessitent de marquer le texte en connaissant sa langue. Elles ne reposent pas sur le modèle Unicode, où on peut représenter de manière non ambigüe tout caractère utilisé dans le monde. Écrire ces caractères en LaTeX n'est pas très difficile. On peut utiliser l'encodage UTF-8 ainsi :
\usepackage[utf8]{inputenc}
et taper ensuite de l'UTF-8. Mais cela ne règle que l'entrée dans le
moteur TeX, pas la sortie, le rendu. En effet,
les caractères non latins sont transformés en
commandes LaTeX, mais pour un sous-ensemble d'Unicode seulement. Et ça
ne marche pas à tous les coups. Ainsi, si le texte contient le
caractère Ω (U+03A9
, grand oméga), LaTeX proteste :
... (/usr/share/texmf-texlive/tex/latex/ucs/data/uni-33.def) (/usr/share/texmf-texlive/tex/latex/ucs/data/uni-3.def) ! Undefined control sequence. \u-default-937 #1->\textOmega l.135 omega}" , ... , (les symboles scientifiques ne sont normalement pas ?
Le grand oméga a été transformé en une commande LaTeX,
textOmega
... qui n'existe pas. (Ironie, le
Ω - U+2126, Ohm - passe sans problème.)
Pour afficher ce caractère grec, il faudrait installer des polices
grecques comme cbgreek
ou
cm-lgc
et marquer ces
caractères avec une commande comme textgreek
,
plus haut.
Même chose avec des caractères cyrilliques (ici le И, U+418, le grand I de Ivan) :
(/usr/share/texmf-texlive/tex/latex/ucs/data/uni-4.def) ! Undefined control sequence. \u-default-1048 #1->\CYRI l.98 programmes. En prenant l'exemple du ... ?
Pire, il n'y a pas de solution de repli, permettant de dire à LaTeX « si tu ne sais pas afficher un caractère, mets un joli carré blanc à la place ». Un caractère inexistant stoppe le programme LaTeX !
Si on tape directement en LaTeX, cela peut être supportable. Mais un programme qui recevrait de l'Unicode devrait décider d'une langue avant de pouvoir produire du LaTeX. Il devrait tester chaque caractère et faire quelque chose du genre (en pseudo-code) :
case groupe(le_caractère) is: when greek => ... when russian => ... when arabic => ...
Des extensions complètement Unicode avaient été prévues comme Omega mais ont toutes été abandonnées. À l'heure actuelle, produire du LaTeX à partir de données contenant de l'Unicode quelconque est donc très pénible. C'est pour cela que la version PDF de mon blog contient souvent un triste remplacement « Caractère Unicode non affiché ».
Merci à Erwan David, Ollivier Robert, Marc Baudoin, Bertrand Petit et Kim-Minh Kaplan pour leur aide et explications.
Date de publication du RFC : Mars 2008
Auteur(s) du RFC : J. Goodwin (ISO), H. Apel (ISO)
Pour information
Première rédaction de cet article le 22 mars 2008
Un nouveau venu dans la famille des NID (Namespace identifier), les autorités qui gèrent un groupe d'URN, l'ISO, organisme international de normalisation, qui pourra ainsi enfin donner à ses textes, notamment aux normes, un identifiant unique et automatiquement analysable.
La section 1 du RFC présente l'ISO et ses procédures. Cette présentation est un peu idéalisée et oublie de signaler que l'ISO est renommée pour sa fermeture. Il est difficile d'en faire partie (l'ISO est une fédération d'organismes nationaux comme l'AFNOR en France, eux-mêmes en général tout aussi fermés), les processus sont compliqués et sans transparence.
Les
normes produites ne sont pas distribuées sur Internet, sauf exceptions. Cette mentalité
a beaucoup contribué à l'échec des protocoles
OSI par rapport à ceux de l'Internet,
normalisés dans des RFC librement
accessibles. Outre les exceptions citées plus haut, parfois, les
auteurs ou les agences de maintenance de la norme distribuent une
version non officielle de la norme à partir de leur site (par exemple,
Schematron, norme n° 19757 , est distribuée par
son auteur en http://www.schematron.com/spec.html
.) La section 4 du RFC parle entre
autres de cette question, en faisant porter la responsabilité de cet
état de fait sur les organisations membres de l'ISO ou associées, tout
en prétendant que la disponibilité de la norme n'est finalement pas
une question si importante (« Only the product engineer or
software tool builder actually needs access to the text »).
Comme le détaille cette section, le vote à l'ISO est par pays. Ce ne sont pas les participants aux groupes de travail (souvent de vrais experts, comme cela a été le cas pour le groupe qui a donné à RelaxNG le statut de norme ISO) qui votent mais les représentants officiels de chaque pays. Ces votes étant non publics, le citoyen français n'a aucun moyen de savoir ce qu'a voté son pays. Par exemple, la rumeur dit que la France avait voté NON à ISO 639-3 mais on ne peut pas le vérifier, les votes n'étant pas connus.
Le cahier des charges de ces identificateurs ISO apparait dans l'excellente section 3 du RFC. Il s'agit d'avoir des identificateurs uniques, stables dans le temps, lisibles par des humains (d'autres critères figurent dans cette section). Chacun de ces choix est justifié en détail et on ne peut que recommander la lecture de cette section à tous ceux qui travaillent sur un projet de famille d'identificateurs. L'annexe A contient un examen d'autres identificateurs qui avaient été envisagés et rejetés, comme les OID du RFC 3061.
Avec la section 2 commence la description de ce nouveau groupe
d'URN (RFC 8141). Le
NID (Namespace Identifier) sera iso
et le reste
de l'URN identifiera le texte (pas forcément une norme), son statut,
l'édition actuelle, la langue, etc.
Par exemple, la norme C, d'origine
ANSI (l'ANSI est le membre états-unien de
l'ISO), développée avec
l'IEC et portant le n° 9899, seconde édition,
en anglais, sera urn:iso:std:iso-iec:9899:ed-2:en
(elle n'est apparemment pas disponible en ligne mais on peut la
trouver sur eDonkey sous le nom
ISO-C99-final-ISO9899-ed2.pdf
). La norme
ISO 15924 sur les
écritures pourrait, elle, se noter
urn:iso:std:iso:15924:en,fr
(on notera qu'elle
est disponible en deux langues, français et anglais et elle fait
partie des normes distribuées par
son agence de maintenance, le consortium
Unicode).
La section 2.8 décrit une correspondance entre ces URN et des URI
http
, ce qui permettrait de résoudre les URN,
grâce à une passerelle que l'ISO envisage de déployer (apparemment,
elle n'est pas encore en service). (Cela ne veut pas dire qu'on aura
accès à la norme, mais seulement aux métadonnées sur celle-ci.)
Ainsi, la norme « Codes de représentation des sexes
humains » (1 pour les hommes et 2 pour les femmes) dont l'URN serait
urn:iso:std:iso-iec:5218:ed-1:en,fr
aurait un
URL de http://standards.iso.org/iso-iec/5218/ed-1/en,fr
.
Première rédaction de cet article le 17 mars 2008
Dernière mise à jour le 16 avril 2008
Sur l'Internet, les données qui circulent peuvent être modifiées ou écoutées à tout moment. Il est donc nécessaire d'utiliser la cryptographie pour protéger ces données. Mais cette technique est difficile et pleine de pièges. Il vaut donc mieux utiliser une bibliothèque comme GPGME, qui permet au programmeur non spécialiste de cryptographie d'ajouter des fonctions de cryptographie à ses programmes.
Première rédaction de cet article le 9 mars 2008
Dernière mise à jour le 16 avril 2008
Dans la grande famille des solutions de virtualisation, permettant de faire tourner un système d'exploitation sur un autre, KVM, spécifique à Linux, permet d'exécuter du code natif, donc avec de bonnes performances, mais sans nécessiter d'aide de la part du système d'exploitation hébergé (donc on peut lancer un autre système que Linux).
KVM est un module du noyau Linux qui offre un certain nombre de services de virtualisation permettant à sa partie en mode utiliseur, l'émulateur Qemu de parler au matériel avec efficacité. Notamment, si le processeur de la machine hôte est le même que celui de la machine hébergée, il n'y a pas besoin d'une phase d'interprétation, le code peut être évalué directement, donc à vitesse normale (Qemu seul est très lent).
Le fait que KVM+Qemu présentent une véritable machine virtuelle permet de faire tourner des systèmes d'exploitation non modifiés, dont on n'a qu'un binaire, comme par exemple Microsoft Windows. Si le système hôte doit être un Linux, le système hébergé est libre, contrairement à User-Mode-Linux. Contrairement à Xen, il ne nécessite pas de modifier le système d'exploitation invité. Je fais ainsi tourner un FreeBSD sans aucune modification sur un PC Ubuntu Linux.
KVM ne fonctionne pas entièrement en logiciel. Il a besoin d'un support du processeur (qui est légèrement différent entre Intel et AMD, toutes les instructions ultérieures sont pour un Intel). Sur mon Dell Latitude D430, ce support n'est pas activé automatiquement, il faut le faire dans le BIOS. Même chose sur les gros serveurs Dell Poweredge, il faut activer l'option Virtualization dans les options CPU. On peut ensuite tester qu'il est bien activé avec :
% grep vmx /proc/cpuinfo
Prenons maintenant l'exemple de l'installation de FreeBSD 7. Je télécharge une image ISO. On doit d'abord créer le fichier qui servira de disque dur à la machine virtuelle :
% qemu-img create -f qcow Machines-Virtuelles/snape-freebsd.qemu-cow 1400M
Ensuite, je lance KVM avec le script suivant (pour charger les modules noyau nécessaires) :
#!/bin/sh cd $HOME/Machines-Virtuelles sudo modprobe kvm sudo modprobe kvm-intel kvm -m 512 -hda snape-freebsd.qemu-cow -cdrom $HOME/tmp/7.0-RELEASE-i386-bootonly.iso -boot d
(Les options de la commande kvm
sont les mêmes
que celles de qemu
.) Le programme d'installation de FreeBSD se lance alors et on peut
installer FreeBSD comme d'habitude. Une fois que cela est fait, on
peut désormais lancer KVM sur le « disque dur » sans CDROM :
% kvm -m 512 -hda snape-freebsd.qemu-cow -boot c
À noter que, si on ne veut pas installer soi-même, on trouve énormément d'images toutes prêtes, pour les principaux systèmes libres, sur Free OS Zoo.
Pour le réseau, c'est un peu plus compliqué. Il existe de
nombreuses méthodes (décrites dans la documentation de
Qemu). J'utilise ici tap
, qui malheureusement nécessite
d'être root pour lancer
kvm
, mais fournit le plus de possibilités. Le script est donc modifié ainsi :
sudo kvm -m 512 -hda snape-freebsd.qemu-cow -net nic -net tap -boot c
KVM lancera
/etc/kvm/kvm-ifup
qui, chez moi, contient :
#!/bin/sh -x # My code: iface=$1 # The Qemu host myipv4addr=$(ip addr ls eth0 | awk '/inet / {print $2}' | cut -d/ -f1) remipv4addr=10.1.1.42 # IPv4 sudo /sbin/ifconfig $iface $myipv4addr netmask 255.255.255.255 sudo route add -host $remipv4addr dev $iface # activate ip forwarding sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward' # activate ARP proxy to "spoof" arp address sudo sh -c "echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp" sudo sh -c "echo 1 > /proc/sys/net/ipv4/conf/${iface}/proxy_arp" # set "spoofed" arp address sudo arp -Ds $remipv4addr eth0 pub
Si on veut gérer plusieurs machines virtuelles, chacune avec sa propre adresse, une solution possibe est de modifier le début du script ainsi :
if [ $iface == "tap0" ]; then remipv4addr=10.1.82.3 elif [ $iface == "tap1" ]; then remipv4addr=10.1.82.4 else exit 1 fi
Les numéros des interfaces tap
seront attribués
dans l'ordre de démarrage. Si on veut éviter que les machines ne
changent d'adresse IP selon cet ordre, on peut définir un numéro
explicitement en remplaçant -net tap
par
-net tap,ifname=tapN
. (Il serait bien agréable
que la valeur de l'option -name
soit passée au
script kvm-ifup
mais cela ne semble pas être le cas.)
Et pour IPv6 ? C'est plus complexe car l'équivalent du proxy ARP est très pénible :
myipv6addr=$(ip addr ls ${lan_iface} | awk '/inet6 / {print $2}' | \ cut -d/ -f1 | head -n1) if [ $iface == "tap0" ]; then ... remipv6addr=2001:660:3003:3::1:3 ... # IPv6 sudo /sbin/ifconfig $iface add $myipv6addr sudo route add -Ainet6 $remipv6addr dev $iface # Proxy NDP (Neighbor Discovery Protocol) sudo ip -6 neigh add proxy $remipv6addr dev ${lan_iface} # Apparently, you need to put *every* IPv6 address of the LAN here :-( # http://gentoo-wiki.com/IPV6_And_Freebox lanipv6addr="2001:660:3003:3::1 2001:660:3003:3::1:1 2001:660:3003:3::1:2 2001:660 :3003:3:219:b9ff:fee4:25f9" for addr in $lanipv6addr; do sudo ip -6 neigh add proxy $addr dev $iface done
On notera que la console par défaut de KVM ne permet pas le
copier/coller, ce qui est très pénible si on veut signaler une bogue
en donnant tous les détails. La méthode que j'utilise alors est la
console série. On ajoute l'option -serial
file:tmp/MAMACHINE.log
au lancement de KVM et, aux options
de démarrage du noyau Linux (si on utilise
Grub, ces options peuvent se changer en tapant
'e' comme Edit), console=ttyS0,115200
.
Auteur(s) du livre : Michel Pinçon, Monique Pinçon-Charlot
Éditeur : Seuil
978 2 02 088920 9
Publié en 2008
Première rédaction de cet article le 8 mars 2008
Depuis plusieurs ouvrages (dont le plus connu est « Dans les beaux quartiers »), Michel Pinçon et Monique Pinçon-Charlot étudient, en sociologues, la grande bourgeoisie. Des tas d'études sociologiques ont été faites sur les banlieues difficiles, sur les ouvriers, sur les chômeurs mais très peu sur la grande bourgeoisie, peut-être par acceptation aveugle du tabou comme quoi les classes sociales n'existeraient pas. Ce dernier ouvrage (car les auteurs prennent leur retraite) discute de l'occupation de l'espace et de sa défense.
Leurs sujets d'étude ne sont pas forcément faciles. Certes, les risques physiques sont plus faibles que lorsqu'on va étudier les délinquants de banlieue. Et on mange mieux lorsqu'on enquête au Jockey Club. Mais cela ne rend pas forcément l'enquête plus facile, face à des interlocuteurs qui, eux aussi, ont lu Bourdieu, et sont rompus à l'art difficile de se montrer sous son meilleur jour, tout le temps.
Dans ce livre, les deux auteurs s'attaquent plus particulièrement à la gestion de l'espace par la grande bourgeoisie. Si on reproche aux immigrés de vivre dans des ghettos, que dire de cette classe dont l'étude du Bottin mondain montre que ses membres ne vivent que dans trois arrondissements de Paris (7, 8 et 16), sans compter évidemment le vingt-et-unième ? À les fois très cosmopolites (le monde est leur terrain de jeu depuis toujours) et très attachés à leurs territoires, les sujets de l'étude mettent en œuvre tous les moyens à leur disposition pour rester entre eux et ne pas permettre de mélanges avec d'autres classes sociales. Leur dévouement militant, lorsque ce territoire est menacé, n'a rien à envier à la rage du caïd de banlieue s'opposant au passage dans « sa » cité d'autres exclus venus d'une cité différente...
Le seul jeu du marché, et les prix de l'immobilier qu'il entraine, sont déjà un bon moyen de limiter la mixité sociale. Encore faut-il veiller à ce que les politiques publiques ne contrarient pas trop ce marché. C'est alors que rentre en jeu le travail d'influence, rarement public, pour s'assurer qu'aucune loi n'aura de conséquences trop graves. C'est ainsi que la loi SRU a certes été votée (elle impose notamment un minimum de 20 % de logements sociaux par commune) mais est systématiquement violée, les sanctions étant bien trop faibles (Neuilly n'a ainsi que 2,6 % de logements sociaux).
Cette occupation de l'espace est particulièrement nette dans le cas du Bois de Boulogne, qui fait l'objet d'un article étonnant du livre. Une partie de cet espace public est en effet réservée depuis des dizaines d'années à un petit nombre de clubs ultra-fermés, où on n'entre que par cooptation, comme le Cercle du Bois de Boulogne ou le Polo de Paris.
Comment se pratique cette défense du territoire ? Pas de manifestations dans la rue, pas de voitures brûlées, même pas de complot international où de mystérieux financiers apatrides tireraient les ficelles. Non, c'est beaucoup plus simple, montrent nos deux sociologues. Ce monde est irrigué par un intense réseau de sociabilité. On dine ensemble à l'Interallié ou lors d'une réception chez l'un ou l'autre, on prend des vacances dans les mêmes palaces, à Gstaad ou à Marrakech et les problèmes sont réglés entre gens du même monde, discrètement. Il y a certes de nombreux conflits internes (l'associations de grands bourgeois qui s'oppose à une autoroute urbaine peut compter dans ses membres des actionnaires de Renault ou de Vinci...) mais la plupart se règlent « entre soi ».
Bref, un livre qui donne envie d'être riche, pour pouvoir profiter d'une telle entraide, et de territoires protégés, défendus avec une bonne conscience en béton : les quartiers où ils vivent étant souvent historiquement importants, ils ne défendent pas leurs intérêts, non, ils protègent le patrimoine national...
Date de publication du RFC : Février 2008
Auteur(s) du RFC : P. Saint-Andre (XSF)
Chemin des normes
Première rédaction de cet article le 7 mars 2008
Le protocole XMPP (RFC 6120)
fournit notamment la possibilité de services de messagerie instantanée. Les adresses qu'utilise XMPP (par exemple
bortzmeyer@gmail.com
puisque j'utilise
Google Talk, qui repose sur XMPP) ne sont pas
des URI et il y a des cas où il serait utile de
pouvoir désigner ces ressources XMPP par un URI, ce que fait notre
RFC.
Succédant au RFC 4622 (les seuls changements sont des
corrections d'erreurs), notre RFC décrit la syntaxe et la
sémantique des URI XMPP. Le RFC 3920 excluait les URI pour
désigner les ressources XMPP mais cette règle s'est avérée trop
contraignante pour les applications, comme l'explique les sections 1
et 2.1. La section 2.2 nous introduit à la syntaxe des URI (ou plutôt
des IRI, mais une raison compliquée liée aux
procédures IANA fait que le RFC doit mentionner
les deux familles) XMPP et leur formation à partir d'une
classique adresse XMPP (détaillée en 2.7). Il faut notamment ajouter le plan
xmpp:
et encoder les caractères qui ne sont pas
légaux dans un IRI. L'adresse XMPP donnée au premier paragraphe
devient donc l'URI xmpp:bortzmeyer@gmail.com
.
La section 2.3 couvre un cas délicat. La syntaxe des URI
génériques, décrite dans le RFC 3986, spécifie,
dans sa section 3.2,
une autorité optionnelle, précédée de deux barres
de division. Par exemple, dans
http://www.bortzmeyer.org/5122.html
,
www.bortzmeyer.org
est l'autorité. Il existe des
URI sans mention d'une autorité, comme
mailto:stephane+blog@bortzmeyer.olrg
. Les URI
XMPP, eux, peuvent avoir une autorité, qui a la forme d'un compte
XMPP. Si elle est absente, c'est le compte par défaut qui est
utilisé. C'est ainsi que xmpp:durand@example.net
n'indique pas d'autorité (on utilisera le compte par défaut) alors que
xmpp://martin@exemple.fr/durand@example.net
désigne la même ressource mais en spécifiant le compte qui doit être
utilisé.
Continuant dans les composants d'un URI, la section 2.4 traite le
chemin et 2.5 la requête, qui se trouve après un point
d'interrogation. Compte tenu de la variété des applications XMPP (ce
protocole ne traite pas que la messagerie instantanée, même si c'est
son utilisation principale aujourd'hui, voir le RFC 3921), le RFC ne spécifie pas de
sémantique précise pour cette requête, elle dépendra de
l'application. Par exemple
xmpp:nicolas@pauvre-con.fr?message;subject=Casse%20toi
pour déclencher l'envoi d'un message avec le sujet indiqué (on note
que le séparateur des arguments avec ce plan XMPP est le
point-virgule et pas l'habituelle
esperluète).
La section 2.8 détaille le traitement de tels URI par les logiciels (il y a beaucoup de subtilités à gérer) et la 2.9 les questions d'internationalisation ; les adresses XMPP sont en UTF-8 et peuvent donc être converties directement en IRI XMPP. Pour avoir un URI XMPP, les adresses contenant des caractères non-ASCII devront être encodées, par exemple lors de la transformation de l'IRI en URI.
La section 3 du RFC est simplement le formulaire réglementaire d'enregistrement d'un plan (scheme) d'URI auprès de l'IANA, suivant le RFC 4395.
Date de publication du RFC : Juin 2002
Auteur(s) du RFC : J. Rosenberg (dynamicsoft), H. Schulzrinne (Columbia U.)
Chemin des normes
Première rédaction de cet article le 7 mars 2008
Le protocole SIP est normalisé dans le RFC 3261 qui décrit en détail la communication entre un client et un serveur SIP. Mais comment le client trouve t-il un serveur ? C'est l'objet de ce RFC d'accompagnement.
SIP est surtout utilisé pour la
téléphonie sur Internet. L'ancien
numéro de téléphone y est remplacé par un
URI, tel que
sip:support@apnic.net
. Mais un client SIP (par
exemple un UAC, le logiciel avec lequel interagit directement
l'utilisateur, son téléphone : mais aussi un relais SIP que l'UAC
aurait utilisé) doit, pour établir une connexion avec le
serveur SIP, trouver son adresse, alors qu'il n'a que cet URI et donc
uniquement un nom de domaine (et que SIP peut
fonctionner sur plusieurs transports).
La méthode est donc d'utiliser le DNS. Le client va utiliser les
enregistrements NAPTR du RFC 3403 puis
les enregistrements SRV du RFC 2782. Suivons la section 4.1 du RFC qui nous donne un
exemple, où on cherche à joindre
sip:helpdesk@example.net
. Le domaine
example.net
contient les enregistrements NAPTR
suivants :
; order pref flags service regexp replacement IN NAPTR 50 50 "s" "SIPS+D2T" "" _sips._tcp.example.com IN NAPTR 90 50 "s" "SIP+D2T" "" _sip._tcp.example.com IN NAPTR 100 50 "s" "SIP+D2U" "" _sip._udp.example.com IN NAPTR 120 50 "s" "SIP+D2S" "" _sip._sctp.example.com
On notera que le champ regexp
est vide : quel que
soit l'URI de départ, le résultat est donné par le champ
replacement
. Ici, quatre NAPTR sont intéressants
(ceux dont le service est de type SIPx+D2x
). Le
premier spécifie un transport sécurisé par TLS
au dessus de TCP. Le second un transport TCP
simple, le troisième un transport UDP, le
quatrième un SCTP.
Une fois obtenu ces noms de domaines grâce aux NAPTR, on utilise
les enregistrements SRV pour avoir les serveurs et leurs numéros de
port. Par exemple, _sip._tcp.example.com
aura les
SRV suivants :
; Priority Weight Port Target IN SRV 0 1 5060 main-server.example.com. IN SRV 10 1 53456 backup-server.example.com.
Le client tentera alors de se connecter à
main-server.example.com
(on notera que cela
nécessitera une requête DNS supplémentaire, pour trouver son adresse
IP) se rabattant, s'il est inaccessible, sur
backup-server.example.com
.
Le prédécesseur de notre RFC, le RFC 2543, n'utilisait pas les NAPTR, uniquement les SRV. Dans l'exemple ci-dessus, les serveurs étant dans un domaine différent de celui de l'URI, il aurait donc échoué.
Notons enfin que la section 5 du RFC décrit comment un serveur SIP trouve un client. Si ce dernier le contacte directement en TCP, c'est trivial mais il existe des cas où le client est en fait un relais et où la réponse doit suivre un cheminement analogue (avec recherche de SRV - mais pas de NAPTR) pour le trouver.
Date de publication du RFC : Mars 2008
Auteur(s) du RFC : B. Laurie, G. Sisson, R. Arends (Nominet), D. Blacka (Verisign)
Chemin des normes
Première rédaction de cet article le 6 mars 2008
Dernière mise à jour le 1 septembre 2010
L'enregistrement NSEC3 permet de résoudre un problème agaçant de DNSSEC, le fait que ce dernier permette l'enumération de tous les noms de domaine d'une zone signée. NSEC3 permet donc d'établir la non-existence d'un domaine sans rien révéler sur les autres domaines.
DNSSEC (RFC 4033) authentifie les enregistrements DNS en ajoutant un enregistrement RRSIG (RFC 4034) qui contient une signature des enregistrements qu'on veut authentifier. Le problème est que, si le nom de domaine demandé n'existe pas (réponse NXDOMAIN pour No Such Domain), il n'y a pas d'enregistrement à signer. Ce problème est connu sous le nom de preuve de non-existence et c'est un des points les plus difficiles de DNSSEC (section 5.4 du RFC 4035). Le RFC 4034, section 4, le traitait en introduisant un enregistrement NSEC, signé par un RRSIG, qui indiquait le domaine suivant celui demandé. En vérifiant que ce domaine suivant était bien situé après celui demandé (et que le domaine demandé était situé après le nom en partie gauche du NSEC), le résolveur pouvait être sûr de la non-existence du nom qu'il avait demandé.
Mais le gros problème de NSEC est qu'il permet l'énumération. Une fois qu'on a découvert le nom de domaine suivant, on peut passer au suivant, puis à celui d'après et ainsi de suite, on a récupéré toute la zone, même si son administrateur ne le voulait pas.
Le registre de .uk, Nominet, a clairement indiqué que c'était inacceptable pour eux et qu'ils ne déploieraient pas DNSSEC sans une solution à ce problème politico-légal.
Le nouvel enregistrement NSEC3 résout le problème en ne donnant pas le nom du domaine suivant mais son résumé cryptographique, son empreinte.
Le principe de NSEC 3 est le suivant. Les résumés de tous les noms sont classés par ordre alphabétique (c'est arbitraire, l'important est que cela soit reproductible). La partie gauche (owner name) de l'enregistrement NSEC3 n'est pas un nom de domaine mais un résumé. Idem pour la partie droite.
L'enregistrement contient aussi quelques autres paramètres comme l'algorithme de calcul du résumé (section 3.1.1, les sections suivantes décrivant les autres paramètres). Voici un enregistrement NSEC3 au format suggéré section 3.3 :
2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. NSEC3 1 1 12 aabbccdd ( 2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG )
Le résolveur qui reçoit un NXDOMAIN peut calculer le résumé du nom qu'il a demandé et, si l'enregistrement NSEC3 est correct, ce résumé doit tomber entre les deux résumés du NSEC3 (celui de gauche et celui de droite). Ainsi, si la question est le nom D1, et que le résolveur reçoit :
... NXDOMAIN H0 NSEC3 H2 ... H0 RRSIG ...
il doit calculer H1, le résumé de D1 et vérifier que H0 < H1 < H2 (et naturellement vérifier le RRSIG, la signature). Ne connaissant que H0 et H2, il ne peut pas retrouver D0 et D2. Notez bien que l'ordre ne concerne que H0, H1 et H2, D0, D1 et D2 sont situés dans un ordre complètement différent. Comme avec NSEC, tout repose sur l'existence d'un ordre des éléments sauf que, avec NSEC3, ce sont les résumés cryptographiques qui sont ordonnés.
La méthode de calcul du résumé est détaillée en section 5. Par exemple, un sel est ajouté au nom, pour rendre plus difficile les attaques par dictionnaire. Sans ce sel (annexe C.1 pour les détails), un méchant pourrait, hors-ligne, générer tous les résumés pour tous les noms potentiels et vérifier ensuite simplement leur existence. Toujours pour rendre plus difficile les attaques par dictionnaire, l'opération de résume est recommencé plusieurs fois, en suivant un paramètre qui indique le nombre d'itérations (il y en a toujours au moins une, section 10.3). Notez toutefois qu'en 2022, le RFC 9276 a remis en cause ces techniques et que sel et itérations sont désormais très déconseillés.
Ce nombre d'itérations a une influence sur les performances du
résolveur et du serveur faisant autorité. Les chiffres exacts peuvent
être trouvés dans l'article de Yuri Schaeffer,
« NSEC3
Hash Performance ». En pratique, les zones
actuellement signées ont de une à dix itérations (dig
NSECPARAM $ZONE
pour le voir, il faut un dig >= 9.6).
Due à Kim-Minh Kaplan, voici une mise en œuvre en Perl du résumé :
use MIME::Base32; use Digest::SHA1 qw(sha1); my ($salt, $iteration, $name) = @ARGV; $salt = pack "H*", $salt; $name =~ y/A-Z/a-z/; $name =~ s/\.*$//; my @labels = split('\.', $name . ".", -1); @labels = map { pack("C", length($_)) . $_ } @labels; $name = join '', @labels; foreach (0..$iteration) { $name = sha1("$name$salt"); } print MIME::Base32::encode($name), "\n";
On doit appeler ce programme avec trois paramètres, le sel, le nombre d'itérations supplémentaires et le nom à résumer.
Notez que les dernières versions de BIND
(depuis au moins la 9.7) sont livrées avec un programme plus
perfectionné, nsec3hash
, qui comprend en plus
d'autres algorithmes que SHA-1. Voici un exemple d'utilisation :
[Récupérer les paramètres avec lesquels les noms sont résumés.] % dig +short NSEC3PARAM pm. 1 0 1 BADFE11A % nsec3hash BADFE11A 1 1 pm P3JUUU69O1AP1AI8DLNVO7L7A0SKT56S (salt=BADFE11A, hash=1, iterations=1) [Et on retrouve bien ce résumé dans les enregistrements NSEC3 : % dig +dnssec ANY nimportequoi.pm. ... P3JUUU69O1AP1AI8DLNVO7L7A0SKT56S.pm. 5400 IN NSEC3 1 1 1 BADFE11A \ L6U66FHPKD109EODA9R2SV8RGFSUAUQ3 NS SOA RRSIG DNSKEY NSEC3PARAM
NSEC3 contient plein d'autres fonctions intéressantes, par exemple la section 6 décrit un mécanisme de retrait (opt-out) permettant aux enregistrement NSEC3 de « sauter » par dessus les zones non signées (dans un TLD, comme .se, il est clair que la majorité des zones ne seront pas signées, au moins au début).
Les détails sont très complexes (et couverts dans les sections 7 et 8 du RFC) ce qui explique que certains auteurs de logiciels DNS comme Bert Hubert, auteur de PowerDNS, aient estimé qu'il serait difficile de faire du NSEC3 en pratique (voir aussi son bon article sur DNSSEC).
Mais NSEC3 est aujourd'hui mis en œuvre dans plusieurs logiciels comme BIND, NSD ou le résolveur UNBOUND. NSEC3 sera probablement plus complexe et plus lent que NSEC mais c'est le prix à payer pour garder le contrôle de ses données.
Avec BIND 9.6 (ou supérieur), voici comment on génère une clé RSA utilisable pour NSEC 3 :
% dnssec-keygen -a NSEC3RSASHA1 -b 1024 -n ZONE
et comment on signe :
dnssec-signzone -g -t -H 3 -3 babecafe $MYZONEFILE Kmykey.+007+30869
(babecafe
est le sel, en hexadécimal.)
Avec le retrait (opt-out), l'opération de signature prend une
option supplémentaire, -A
. Cette option permet de
réduire considérablement le temps de signature (pour une zone d'un
million de sous-zones, dont très peu sont signées, le retrait diminue
le temps de signature de dix minutes à vingt secondes), au prix de la
sécurité (il n'est désormais plus possible, si on utilise le retrait
de prouver l'existence ou la non-existence d'une sous-zone non signée).
Ici, si on a une zone example
comportant trois noms, example
(l'apex), preston.example
et central.example
:
@ IN SOA ns3.bortzmeyer.org. hostmaster.bortzmeyer.org. ( ... IN NS ns3.bortzmeyer.org. ... IN DNSKEY 256 3 7 AwEAAa...= central IN A 192.0.2.187 preston IN AAAA 2001:db8:8bd9:8bb0:a00:20ff:fe99:faf4
et qu'on la signe avec :
% dnssec-signzone -H 3 -3 babecafe -o example db.example Kmykey.+007+30869
(trois itérations supplémentaires, un sel qui vaut « babecafe »), on obtient un fichier db.example.signed
qui comprend trois NSEC3, un par nom :
FIDQ6ATJMOUCGLV3PNHS9694C1LFDSDT.example. 43200 IN NSEC3 1 0 3 BABECAFE JKNM5TRUGDISFPUU0CCLEMG2GTGOD2IP AAAA RRSIG JKNM5TRUGDISFPUU0CCLEMG2GTGOD2IP.example. 43200 IN NSEC3 1 0 3 BABECAFE O7FU7992IPFEUUUVC1A8NAF4255JF7JI NS SOA MX TXT RRSIG DNSKEY NSEC3PARAM O7FU7992IPFEUUUVC1A8NAF4255JF7JI.example. 43200 IN NSEC3 1 0 3 BABECAFE FIDQ6ATJMOUCGLV3PNHS9694C1LFDSDT A RRSIG
et le programme Perl ci-dessus permet de retrouver quel nom a été résumé pour donner la partie gauche de chacun de ces NSEC3 :
% perl hash-nsec3.pl babecafe 3 preston.example FIDQ6ATJMOUCGLV3PNHS9694C1LFDSDT
et on trouve ainsi que le premier NSEC3 de la liste était celui de preston.example
(mais l'opération inverse est impossible : c'est le principe du résumé).
Merci à Kim Minh Kaplan pour son aide à m'aider à comprendre ce difficile protocole et pour sa relecture.
Première rédaction de cet article le 2 mars 2008
Comment maintenir une configuration à peu près identique entre plusieurs comptes Unix sur des machines différentes ? En utilisant un logiciel de contrôle de versions, Subversion, pour gérer les fichiers de configuration personnels, les dotfiles.
Première rédaction de cet article le 1 mars 2008
Wikipédia est désormais largement utilisé par tout le monde, y compris par certains de ceux qui snobaient l'encyclopédie libre à ses débuts. On a même vu récemment Pierre Assouline dire du bien de Wikipédia, ce qui est un peu comme si le pape disait du bien du mouvement féministe. Mais une bonne partie de la presse écrite continue à remâcher ses rancœurs contre Wikipédia, comme le montre l'article de Sciences et Vie Junior de mars 2008. Quelles sont les deux plus grosses erreurs de l'article ?
L'article reprend les thèmes classiques des autres campagnes de presse contre Wikipédia comme le soi-disant anonymat des auteurs, ou comme le manque de fiabilité de l'encyclopédie libre (parfaitement réel, tout comme le manque de fiabilité des autres sources, à commencer par les médias classiques). Mais deux arguments sont particulièrement développés. L'un est une erreur sur la capitale de l'état mexicain de Nayarit. Jouissant d'une moins grande célébrité que le Yucatán ou le Chiapas, cet état peu connu (et dont l'article était donc peu relu) s'était en effet vu affubler d'une capitale erronée. L'erreur a été corrigée, par un internaute mexicain, bien avant la publication de Sciences et Vie Junior (ce que l'article ne dit pas). Comme tout l'historique des modifications est accessible sur Wikipédia, voici le changement en question. Contrairement à ce que prétendent ceux qui parlent de Wikipédia sans connaitre, ce ne sont pas en général les articles sur les grands sujets, très souvent relus et corrigés, qui comptent le plus d'erreurs mais plutôt les articles sur les sujets obscurs, où une erreur peut trainer des mois, tout simplement parce que personne ne lit l'article.
L'autre angle d'attaque évoque les théories complotistes sur l'accord secret entre Wikipédia et Google, aux termes duquel Google placerait systématiquement Wikipédia en premier dans les résultats de recherche. L'article de Sciences et Vie Junior ne reprend pas cette théorie paranoïaque telle quelle mais il affirme que, Google donnant la priorité aux pages vers lesquelles pointent beaucoup de liens (le fameux Page Rank), Wikipédia l'emporte à cause de ses nombreux liens internes, entre articles ! C'est bien sûr tout à fait faux (autrement, ce blog, qui a beaucoup de liens internes, serait souvent premier chez Google). S'il suffisait de faire des liens internes pour être bien classés, tout le monde le ferait ! Il est au contraire très probable que de tels liens, qui ne prouvent rien quant à la qualité de la page pointée, sont ignorés par Page Rank.
L'article tenait un sujet bien plus intéressant avec le manque de style de certains articles de Wikipédia, trop corrigés et modifiés pour avoir gardé un style agréable à lire, ce qui aurait nécessité un éditeur unique. Mais ce problème bien réel n'est guère développé, les anecdotes sur Britney Spears ou Harry Potter sont plus spectaculaires.
Date de publication du RFC : Février 2008
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 29 février 2008
Notre RFC propose un profil d'IRIS pour répondre à une question simple : ce domaine est-il libre ou pas ?
Aujourd'hui, l'enregistrement d'un nom de
domaine commence souvent par une recherche de sa
disponibilité. L'utilisateur final va sur le site Web du
registrar de son choix, tape
le nom convoité, le registrar interroge le
registre et
renvoie la réponse à l'utilisateur. Mais comment le
registrar contacte t-il le registre ? Il existe une
solution à moitié standard, le protocole whois
(RFC 3912). En analysant le résultat de la
requête, on peut trouver si le domaine est libre (ici, avec
.fr
) :
% whois vraimentnimportequoi.fr ... domain: vraimentnimportequoi.fr status: AVAILABLE
whois a quelques défauts. Le format de sortie n'est pas normalisé, donc il faut trouver une expression indiquant la disponibilité, et la trouver pour chaque registre. Ce manque de normalisation est encore plus gênant si le domaine n'est pas libre et qu'on veut trouver pourquoi. Est-il déjà réservé ? Est-ce un terme interdit ? Ensuite, whois nécessite un traitement assez importante du côté du serveur, puisqu'il doit extraire de la base de données du registre beaucoup d'informations, beaucoup plus que ce qu'on désirerait pour simplement connaitre la disponibilité d'un domaine.
Cette lourdeur des traitements d'un serveur whois fait que les registres mettent en général en place des limitations strictes à son usage, par exemple en limitant le rythme d'accès.
Quelles sont les solutions propres, donc ? Pour le cas des
registrars, les registres proposent en général des
outils spécifiques comme un service EPP, dont
la commande <epp:check>
permet de récupérer
des informations utiles (section 2.9.2.1 du RFC 4930). Souvent, ces outils utilisent un protocole privé, par
exemple, pour .fr
, ce
programme Python
utilisant SOAP trouve
la disponibilité d'un domaine :
import SOAPpy # In some versions, a bug prevents authentication, you have to # add "import base64" yourself import sys, os, string SOAPpy.Config.debug = False hostname = "XXXXXX.nic.fr" path = "" user = "REGISTRAR-NAME" password = "REGISTRAR-PASSWORD" namespace = 'http://soap.nic.fr/Domain' action = 'check_domain' if len(sys.argv) > 1: domain = string.lower(sys.argv[1]) else: print "Usage: %s domain-name" % sys.argv[0] sys.exit(1) server = SOAPpy.SOAPProxy("https://%s:%s@%s/%s" % (user, password, hostname, path), namespace=namespace, soapaction = namespace + '#' + action) domain_reply = server.check_domain (domain); if domain_reply["free"]: print "%s is available" % domain else: print "%s is NOT available because \"%s\" (%s)" % (domain, domain_reply["message"], domain_reply["reason"])
Mais, si on n'est pas registrar ? Quelles sont les solutions pour le public, surtout s'il veut pouvoir effectuer un grand nombre de requêtes, à des fins plus ou moins légitimes ?
Une première solution est de proposer une version réduite de
whois. C'est ce que fait
.nl
, avec l'option
is
:
% whois "is amsterdam.nl" amsterdam.nl is active % whois "is certainlynonexistent.nl" certainlynonexistent.nl is free
Ne fournissant qu'une information limitée, ce service charge moins le serveur et est donc disponible avec des limites plus larges.
Et enfin, une autre solution fait l'objet de ce RFC 5144 : utiliser le protocole IRIS (RFC 3981) et un sous-ensemble de son schéma de données pour les domaines, DREG, au dessus d'un transport le plus léger possible. DCHK est donc un sous-ensemble de DREG (RFC 3982), limité à quelques informations, la disponibilité, bien sûr, mais aussi la date d'enregistrement, le statut, etc. Voici un exemple de réponse à une requête DHCK (ici, le domaine n'est pas libre) :
<domain> <domainName>example.org</domainName> <status><active/></status> </domain>
Le registre qui déploie DCHK le rendra typiquement plus accessible (limites moins strictes) que son service IRIS/DREG complet ou bien que son service whois.
Le protocole de transport recommandé, section 3.3, pour sa légèreté, est LWZ (RFC 4993), basé sur UDP.
Denic avait annoncé la disponibilité de ce service et la distribution du code source du client. Mais, finalement, DENIC a renoncé marquant la fin d'IRIS, qui n'a jamais été sérieusement déployé.
Date de publication du RFC : Juin 2005
Auteur(s) du RFC : Eric Rescorla (RTFM)
Pour information
Première rédaction de cet article le 28 février 2008
Écrire un protocole réseau n'est pas facile. La description doit être suffisamment rigoureuse pour qu'elle puisse être mise en œuvre sans ambiguïté et elle doit être suffisamment lisible pour être compréhensible par le lecteur pressé. Les implémenteurs des protocoles préfèrent la précision et l'exactitude, les simples lecteurs, par exemple ceux qui relisent le protocole avant sa publication, préfèrent un texte plus littéraire et de plus haut niveau. Ce RFC, publié par l'IAB, estime que les normes IETF, publiées dans les RFC, sont allées trop loin vers les besoins des seuls implémenteurs et que les RFC récents manquent d'un modèle, d'une description de haut niveau du protocole.
Les normes écrites par l'IETF et publiées dans les RFC sont toutes soumises à un examen public, avant leur officialisation. Relire des projets de RFC, comme l'explique la section 1, n'est pas une tâche facile. Si les RFC d'autrefois étaient courts et souvent écrits de manière assez littéraire, les RFC modernes sont bien plus longs, souvent écrits par plusieurs personnes et le style s'en ressent. Plus corrects dans leur description du protocole, ils sont bien plus difficiles à lire. Si on doit programmer le protocole en question, on doit lire tout le RFC de toute façon. Mais si on veut juste faire une analyse du document, il est pénible de « rétro-ingénierer » les concepts à partir du texte.
La section 2 explique donc qu'il faudrait, dans chaque RFC qui normalise un protocole, un modèle, qui décrive le protocole à un niveau plus élevé et qui permette de répondre à trois questions :
Le modèle doit se fonder sur les caractéristiques essentielles du protocoles. Par exemple, le fait que Kerberos (RFC 1510) utilise un système KDC (Key Distribution Center) est essentiel mais le fait que la syntaxe soit décrite en ASN.1 est un détail, les S-expressions auraient aussi bien convenu.
La section 3 décrit ensuite en quoi consiste un modèle. Le principe essentiel est que le modèle est plus court que le protocole complet. C'est une carte, pas un territoire. Il va donc abstraire le protocole et n'en garder que ce qui est essentiel.
La section 4 parle ensuite de l'écriture concrète de ces modèles. Elle recommande une approche très graphique, avec « des boîtes et des flèches » (même si la section 5 note que l'obligation de publier les RFC uniquement en texte brut en ASCII ne facilite pas les choses ; j'en profite pour signaler l'excellent outil Graph::Easy, pour générer des diagrammes en art ASCII à partir d'une description de haut niveau).
D'abord (section 4.1), le modèle doit décrire le problème qu'on essaie de résoudre. L'exemple que donne notre RFC est celui de STUN (RFC 3489), qui ne contient pas cette description. Notre RFC 4101 en propose donc une, avec un diagramme des différents composants des entités qui tentent de communiquer malgré le NAT et de leurs échanges.
Ensuite (section 4.2), le modèle doit donner une vue générale du protocole. L'exemple est pris dans le protocole DCCP (RFC 4340) dont RFC 4101 propose une telle vue de DCCP.
Enfin (section 4.3), le modèle doit pointer du doigt les
caractéristiques importantes du protocole, surtout si elles ne sont
pas évidentes à première vue. Ainsi, dans l'exemple de
WebDAV, RFC 4918,
contrairement à ce qu'on pourrait croire en lisant rapidement le RFC
sur WebDAV, notre RFC 4101 montre qu'une discussion détaillée
de la différence entre un renommage d'une ressource (commande
MOVE
de WebDAV) et sa copie suivie de la
destruction de l'original (commandes COPY
et
DELETE
de WebDAV) ne sont pas équivalents (mais
le RFC sur WebDAV décrivant chaque commande séparément, ce n'est pas
évident à voir).
La section 6 du RFC synthétise toutes ses recommandations en fournissant un exemple d'un modèle complet pour le protocole IKE (RFC 4306), l'un des plus complexes de l'IETF.
Si les auteurs de RFC suivent ces recommandations, les RFC deviendront encore plus lisibles et accessibles.
Première rédaction de cet article le 27 février 2008
Dans le cadre du cours d'Informatique en Biologie de l'Institut Pasteur, j'ai fait un exposé de trois heures sur les réseaux infomatiques et notamment Internet.
Ce cours s'adresse à un public de biologistes non familiers avec la
programmation ou avec le fonctionnement desdits réseaux. Contrairement à pas mal de cours sur ce sujet, cet exposé ne part pas des couches basses, du matériel par exemple, mais d'un petit
programme Python très
simple, qui appelle urlli2.urlopen()
pour récupérer une ressource sur le Web, et descend ensuite petit à petit vers des couches de plus en
plus basses. Voici les transparents de cet exposé :
Un autre exposé de la même série a porté sur systèmes d'exploitation.
Première rédaction de cet article le 27 février 2008
Dernière mise à jour le 23 août 2024
Le jeu de caractères Unicode est vaste (149 000 caractères la dernière fois que j'ai compté et cela augmente régulièrement). Il est donc souvent difficile de trouver un caractère donné. Quels sont les outils pour cela ?
Prenons l'exemple des caractères permettant une citation comme les guillemets en français. Cela se dit quotation dans la langue de Donald Westlake. Peut-on trouver tous les caractères de citation facilement ?
Mon outil en ligne préféré, utilisant toutes les techniques modernes du Web est Uniview. Taper quotation dans le moteur de recherche permet d'avoir la liste et leur apparence (si la bonne police est bien connue du navigateur). Une alternative possible est Unicode-Explorer.
Autre outil en ligne, moins convivial mais plus adapté pour des extractions de masse du genre « Tous les caractères de ponctuation qui sont identiques à leur forme canonique » : Unicode Utilities. Ainsi, on peut extraire facilement, par exemple, tous les caractères introduits entre les version 4.1 et 6.0 incluses.
Si on connait le
point de code, https://www.fileformat.info/info/unicode/index.htm
permet,
entre autre chose, d'y accéder directement via un
URL qui contient ce point de code. Regardez
https://www.fileformat.info/info/unicode/char/1f304/index.htm
, https://www.fileformat.info/info/unicode/char/e9/index.htm
ou https://www.fileformat.info/info/unicode/char/fe94/index.htm
.
On peut aussi vouloir chercher dans les documents officiels et le consortium Unicode a une excellente page pour cela.
Pour le cas où on connait la forme du caractère et où on cherche
son nom et son point de code, l'excellent reconnaisseur de formes
https://www.shapecatcher.com/
peut aider.
Et si on préfère travailler en local, sans nécessiter un accès à Internet, et avec ses propres outils ?
Pour ceux qui aiment Emacs, le plus simple
est certainement de charger le fichier de la norme (sur une
Debian, et les dérivés comme Ubuntu, il est dans
/usr/share/unicode/UnicodeData.txt
si on a
installé le paquetage unicode-data
- voici
l'intérêt des normes
gratuites, leurs fichiers peuvent être inclus dans un système
de paquetages). On peut alors utiliser la fonction de recherche
d'Emacs, C-s
et c'est parti :
00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;*;;; ... 00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;*;;;
Bertrand Petit me signale d'autres façons de faire avec Emacs :
C-X 8 RET *quot TAB
affiche la liste des
caractères comprenant « quot », et permet de les
insérer. Pour un caractère déjà présent dans le fichier, C-X
=
permet d'obtenir son point de code Unicode en diverses
syntaxes (mais pas son nom).
Pour ceux qui préfèrent SQL, une approche possible est décrite dans mon article La base de données Unicode en SQL.
ucd=> SELECT To_U(codepoint) AS U_Codepoint, name FROM Characters WHERE name LIKE '%QUOTATION%' ORDER BY codepoint; u_codepoint | name -------------+---------------------------------------------------- U+22 | QUOTATION MARK U+AB | LEFT-POINTING DOUBLE ANGLE QUOTATION MARK U+BB | RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK U+2018 | LEFT SINGLE QUOTATION MARK
En local et en graphique, l'excellent Gucharmap permet de naviguer très agréablement dans les tables Unicode.
Enfin, pour les Vrais Hommes qui préfèrent
la Ligne de Commande, l'excellent programme
unicode
, écrit pour Debian (mais qui tourne sans
doute sur d'autres Unix) :
# Available at https://packages.debian.org/stable/unicode % unicode quotation U+0022 QUOTATION MARK UTF-8: 22 UTF-16BE: 0022 Decimal: " " Category: Po (Punctuation, Other) Bidi: ON (Other Neutrals) U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK UTF-8: c2 ab UTF-16BE: 00ab Decimal: « ...
Première rédaction de cet article le 27 février 2008
Aujourd'hui où on peut récupérer plein de fichiers vidéos sur Internet ou bien via sa LibreBoîte, il est courant de les regarder sur son ordinateur. Mais le lecteur de DVD traditionnel a encore des avantages (prix, disponibilité, facilités pour regarder en famille) et il est donc intéressant de pouvoir produire des DVD-Vidéo à partir de ces fichiers vidéo. Disons-le franchement, ce n'est pas facile mais c'est possible. Ici, j'utiliserai une machine Unix, en l'occurrence une Ubuntu.
On trouve beaucoup de documentations et de
HOWTO sur le réseau pour cette tâche. La
plupart sont très complexes et supposent que l'utilisateur est prêt à
concevoir et à écrire des commandes comme
mencoder -o $OUTPUT -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd -vf harddup -srate 48000 -ofps 25 -lavcopts acodec=ac3:abitrate=192:vcodec=mpeg2video:aspect=4/3:keyint=15:vrc_buf_size=183 5:vrc_maxrate=9800:vbitrate=$BITRATE:trell:mbd=2:precmp=2:subcmp=2:cmp=2:dia=-10:predia=-10:cbp:mv0:vqmin=1:lmin=1:dc=10 $INPUT
. D'autres documentations supposent au
contraire qu'on veut utiliser un outil à GUI
qui va tout faire pour nous, sans nous dire comment. Je me situe entre
les deux : je veux quelque chose de simple (je ne suis pas
professionnel de la vidéo) mais je veux aussi quelque chose en ligne
de commande, qu'on puisse adapter et programmer.
Avant de voir la solution que j'utilise, expliquons un peu les étapes. Il faut faire quatre choses pour avoir un DVD-Vidéo :
VIDEO_TS
et
AUDIO_TS
),Chacune de ces étapes peut être faite à la main, avec une commande Unix, mais la création de ces commandes est souvent cauchemardesque. C'est pour cela que je préfère utiliser les scripts du paquetage ToVid, simples et particulièrement bien documentés. Prenons le cas d'un film nommé « Parle à ma main » qu'on a récupéré en AVI et qu'on voudrait mettre sur DVD. Les quatre étapes citées ci-dessus correspondent à trois commandes de ToVid (la dernière commande fait deux étapes) :
# Ré-encoder le fichier. Le résultat sera bien plus gros, car les # algorithmes de compression que comprennent les lecteurs DVD de salon # ne sont pas aussi efficaces. tovid -dvd -in parle-a-ma-main.avi -out parle-a-ma-main # Créer le menu du DVD makexml /var/tmp/parle-a-ma-main.mpg -out parle-a-ma-main # Créer le système de fichiers UDF et graver (makedvd appelle # genisoimage pour cela) makedvd -burn parle-a-ma-main.xml
Et c'est tout et ça fonctionne. Il n'y a pas de vrai menu, puisqu'un seul film est présent, ToVid crée un DVD qui démarre automatiquement sur l'unique film.
Et si on a plusieurs films et qu'on veut des menus ? Supposons
qu'on a escaladé deux montagnes en Antarctique,
l'Erebus et le Kirkpatrick. Pendant l'ascension, on a filmé et
enregistré erebus.avi
et
kirpatrick.avi
. On veut faire un menu présentant
le choix entre les deux films :
# Réencoder les deux fichiers tovid -dvd -in erebus.avi -out erebus tovid -dvd -in kirkpatrick.avi -out kirkpatrick # Faire le menu makemenu -pal "Mont Erebus" "Mont Kirkpatrick" -out Antarctique # Générer le fichier XML qui décrit le DVD makexml -dvd -menu Antarctique.mpg erebus.mpg kirkpatrick.mpg -out Antarctique # Graver makedvd -burn Antarctique.xml
Cela donnera un DVD avec un menu d'introduction proposant les deux
choix « Mont Erebus » et « Mont
Kirkpatrick ». makemenu
dispose de nombreuses
options (très bien expliquées). Par exemple, ici, on mettra vent.mp3
en
musique de fond du menu et neige.jpg
en image de
fond.
makemenu -pal "Mont Erebus" "Mont Kirkpatrick" -audio vent.mp3 \ -background neige.jpg -fontsize 38 -out Antarctique
La première étape, celle du réencodage n'est pas forcément nécessaire si le lecteur de DVD sait lire le format utilisé. Attention, les formats vidéo sont typiquement en deux couches, un encodage des données vidéo et un emballage de la vidéo et d'autres informations dans un container. Par exemple, un AVI est un container, les données étant en général encodées en MPEG. Le script MediaInfo permet d'afficher le contenu d'un fichier multimédia, ici l'AVI contient une vidéo MPEG-4 et une piste audio :
% MediaInfo monfilm.avi General #0 Complete name : /tmp/monfilm.avi Format : AVI Format/Info : Audio Video Interleave Format/Family : RIFF File size : 5.76 MiB PlayTime : 1mn 47s Bit rate : 444 Kbps StreamSize : 176 KiB Writing library : VirtualDub build 24415/release Video #0 Codec : XviD Codec/Family : MPEG-4 Codec/Info : XviD project Codec settings/Packe : Yes Codec settings/BVOP : Yes Codec settings/QPel : No Codec settings/GMC : 0 Codec settings/Matri : Default PlayTime : 1mn 47s Bit rate : 313 Kbps Width : 576 pixels Height : 336 pixels Aspect ratio : 16/9 Frame rate : 25.000 fps Resolution : 8 bits Chroma : 4:2:0 Interlacement : Progressive Bits/(Pixel*Frame) : 0.063 StreamSize : 3.99 MiB Writing library : XviD0041 Audio #0 Codec : MPEG-1 Audio layer 3 Codec profile : Joint stereo PlayTime : 1mn 47s Bit rate : 125 Kbps Bit rate mode : VBR Channel(s) : 2 channels Sampling rate : 48 KHz Resolution : 16 bits StreamSize : 1.59 MiB Writing library : Xing (new)
(mplayer -identify
donne également des
informations mais moins détaillées et semble difficile à utiliser de
manière non-interactive.)
L'étape de la gravure est souvent la plus délicate (je n'ai jamais réussi à relire un DVD gravé avec wodim, par exemple.). Les erreurs à la gravure sont fréquentes, surtout avec les DVD bas de gamme. Il est recommandé d'utiliser des DVD RW (réinscriptibles), certes plus chers mais qui permettent de réessayer plusieurs fois. On peut aussi, avant la gravure, tester le DVD « virtuel » avec gxine ou codeine.
Une autre description de la même technique peut être trouvée (en anglais) dans DVD Authoring with Linux qui note, comme moi, que la méthode manuelle est vraiment pénible. Si on préfère quand même procéder à la main, et écrire un script à soi, on trouvera des informations utiles en français dans MPEG to DVD ou en anglais dans Some thoughts on DVD authoring ou Authoring PC media To DVD using the Linux Operating System.
On notera que le monde de la vidéo est particulièrement difficile
pour les partisans du logiciel libre. Certains
programmes ne sont pas accessibles sous une licence libre, d'autres
sont sous l'épée de Damoclès des
brevets logiciels, fréquents sur les formats
vidéo (peu sont des formats vraiment
ouverts). C'est ainsi que la documentation de ToVid note, à
propos de l'installation sur Debian, que
tovid isn't in the official Debian distribution because it
depends on packages that don't comply with the Debian philosophy (and
so it's very likely it never will be officially included in
Debian) (les commandes utilisées ici ont été testées sur une
Ubuntu, avec les jeux de paquetages
universe
et multiverse
dont
le statut n'est pas toujours clair).
Merci à Jean-Philippe Pick et à Emmanuel Chantreau pour m'avoir guidé dans mes débuts dans le monde merveilleux et hostile de la vidéo numérique.
Date de publication du RFC : Mai 1997
Auteur(s) du RFC : Ryan Moats (AT&T)
Chemin des normes
Première rédaction de cet article le 26 février 2008
Dans la grande famille des URI, il y a les URL et les URN, dont la syntaxe faisait l'objet de ce RFC, remplacé depuis par le RFC 8141.
Le RFC 3986, qui normalise la syntaxe générique des URI, délègue les détails des familles particulières d'URI à d'autres RFC comme celui-ci. Le RFC 2141 précisait la syntaxe générique pour le cas des URN, des URI dont les propriétés sont a priori la persistence et la non-résolvabilité (donc, plutôt des noms que des adresses, cf. RFC 1737 et RFC 3305).
La section 2, Syntax, forme donc l'essentiel de
ce court RFC. Un URN est formé avec le plan urn
,
un NID (Namespace IDentifier) qui indique
l'organisme qui gère la fin de l'URN, le NSS (Namespace
Specific String), tous séparés par des
deux-points. L'enregistrement des autorités
identifiées par le NID était traité dans le RFC 3406, également remplacé depuis par le RFC 8141.
Par exemple, si on prend les URN néo-zélandais du RFC 4350, le NID est nzl
et un URN
ressemble donc à
urn:nzl:govt:registering:recreational_fishing:form:1-0
.
Comme avec les autres URI, les caractères considérés comme « spéciaux » doivent être protégés avec l'encodage pour cent (section 2.3).
La section 5, consacrée à l'équivalence
lexicale de deux URN, explique comment on peut
déterminer si deux URN sont égaux ou pas, sans connaitre les règles
particulières de l'organisme qui les enregistre. Ainsi,
urn:foo:BAR
et urn:FOO:BAR
sont lexicalement équivalents (le NID est insensible à la casse) mais
urn:foo:BAR
et urn:foo:bar
ne le sont pas, le NSS étant, lui, sensible à la casse (les deux URN
sont peut-être fonctionnellement équivalents mais cela dépend de la
politique d'enregistrement de l'organisme désigné par foo
).
Première rédaction de cet article le 25 février 2008
Ce dimanche 24 février, YouTube a été inaccessible depuis une bonne partie de la planète pendant une à deux heures. Ce n'était pas une panne, mais le résultat d'une action délibérée en provenance du Pakistan.
Un bon résumé de l'affaire peut être trouvé sur site de la BBC. Le gouvernement du Pakistan a annoncé un blocage de YouTube. Pakistan Telecom a exécuté l'ordre. Ce qui est intéressant, c'est que, incompétence, méchanceté ou bien volonté de tester, Pakistan Telecom a réussi à couper YouTube sur l'ensemble de la planète.
La technique employée est très banale et des tas de méchants l'ont déjà
utilisée (le cas le plus célèbre est connu sous le nom d'AS 7007). Elle se nomme « détournement d'adresse » (IP
hijacking) et consiste à annoncer une route
plus spécifique, pour les adresses IP de la victime. Les
routes sur Internet sont
propagées d'opérateur en opérateur (par le protocole BGP, RFC 4271) et peu d'entre eux limitent ce
qu'on peut annoncer. N'importe quel routeur BGP de l'Internet peut
tout à coup se mettre à dire « Envoyez tous les paquets IP à
destination de 208.65.153.0/24
- l'adresse de
YouTube - vers moi ». Cette annonce aura même la priorité sur celle,
légitime, de YouTube, car elle est plus spécifique (la longueur du
préfixe est de 24 bits, contre 22 pour l'annonce
légitime - notez qu'elle a changé depuis le
détournement). Authentifier le pair BGP en face ne sert à rien,
puisque cela ne garantit pas qu'il aura authentifié ses propres pairs
(avec BGP, la confiance doit être transitive).
Quelles sont les leçons à en tirer ? L'insécurité de BGP est bien connue depuis longtemps et devrait, logiquement, susciter plus d'inquiétudes pour la sécurité et la stabilité de l'Internet que les débats politiciens de l'ICANN ou de l'IGF. Elle n'est pas facile à résoudre, le problème n'étant pas technique mais politique et organisationnel. Mikael Abrahamsson, qui travaille pour un opérateur suédois, a bien expliqué pourquoi personne ne filtre les annonces BGP (de manière très injuste, certains avaient reproché à PCCW, le fournisseur de Pakistan Telecom, son absence de filtrage) : « Using pure routing-registry based filtering just isn't cost efficient today, as these borks (unintentional mostly) we see sometimes are few and fairly far between, but problems due to wrong or missing information in the routing registries is plentyful and constant. » Bref (et c'est une leçon à retenir pour d'autres protocoles de sécurité comme DNSSEC), il y a plus de coupures si on protège que si on ne protège pas.
Ce ne sont donc pas les solutions techniques qui manquent (il y en a au moins deux, Secure BGP et soBGP) mais le modèle de confiance à déployer derrière. Pour prendre une comparaison, il ne sert à rien qu'un document d'identité soit infalsifiable si les services administratifs attribuent ces documents n'importe comment.
Si on veut éviter de se faire détourner ainsi, il n'y a guère de
solutions, notons toutefois qu'il existe des services d'alerte, qui
peuvent vous prévenir lorsqu'ils détectent une annonce de
votre réseau par un nouvel opérateur : voir http://www.ris.ripe.net/myasn.html
et http://cs.unm.edu/~karlinjf/IAR/index.php
. Il est amusant de
noter que ces services utilisent la même propriété que l'attaque :
BGP est ouvert à tous, tout le monde peut y participer, tout le monde
peut regarder (par exemple via les looking glasses).
L'attaque (même si elle était involontaire, elle ne se distinguait pas d'une réelle attaque) a réactivé dans la communauté des opérateurs l'intérêt pour du filtrage politique (filtrer les opérateurs asiatiques et/ou musulmans) ou pour du filtrage économique (tout accepter des gros opérateurs et filtrer sévèrement les « petits », ceux qui n'ont pas YouTube pour client).
Cette attaque a été très médiatisée, puisqu'elle touchait une infrastructure critique de l'Internet : si on ne peut plus regarder des vidéos débiles tournées avec les pieds, la sécurité internationale est menacée. Trois semaines après, une bavure similaire a touché l'opérateur kenyan Africa on line et, là, cela n'a ému personne (voir un bon résumé de ce cas).
Trois très bons articles, sur des blogs de référence, résument la
situation technique : http://www.cs.columbia.edu/~smb/blog//2008-02/2008-02-24.html
, http://www.potaroo.net/ispcol/2008-03/routehack.html
,
et http://www.renesys.com/blog/2008/02/pakistan_hijacks_youtube_1.shtml
. Une
étude plus
détaillée a été faite par la suite par le
RIPE-NCC, utilisant RIS, leur système de surveillance de BGP.
Sur BGP, on peut aussi lire mon cours pratique. Une solution technique à des problèmes de sécurité comme celui-ci a été normalisée en 2012, sous le nom de RPKI+ROA.
Date de publication du RFC : Février 2008
Auteur(s) du RFC : J. Klensin
Première rédaction de cet article le 24 février 2008
Idéalement, aujourd'hui, tous les protocoles Internet devraient être complètement internationalisés et notamment devraient accepter que les données soient exprimées dans un des encodages classiques d'Unicode, comme UTF-8. Mais ce n'est pas encore le cas. Ce RFC propose une approche pour utiliser des caractères Unicode dans les derniers protocoles dinosauriens qui n'acceptent normalement que l'ASCII.
La section 1.1 explique bien que ce RFC ne s'applique pas aux protocoles qui acceptent déjà un ou plusieurs encodages Unicode, ce qu'ils feront tous dans le futur, espérons-le. Mais, en attendant ce jour, ce RFC s'applique aux vieux protocoles. Actuellement, ceux-ci acceptent presque tous une forme d'échappement qui leur permet de transporter plus ou moins d'Unicode. L'idée est de mettre un peu d'ordre dans ces formes, sans aller jusqu'à les standardiser complètement (ce que tentaient de faire les premières versions de l'Internet-Draft qui a donné naissance à ce RFC).
Le cas de textes parlant de caractères Unicode (« Les citations en français doivent commencer par un demi-cadratin, le U+2013 ») n'est pas non plus couvert : de tels textes, conçus pour les humains et non pour les programmes, doivent utiliser la notation Unicode traditionnelle U+nnnn comme ci-dessus (section 3).
Notre RFC recommande donc finalement deux formes pour les caractères Unicode dans les fichiers conçus pour être lus par des programmes. En prenant l'exemple du И cyrillique (U+0418, grand I), les deux formes recommandées sont :
Pourquoi ces deux formes ? Comme l'explique la section 2, il existe de nombreuses solutions. Un premier principe qui a guidé celle choisie est qu'il fallait encoder des points de code Unicode (les index dans la table Unicode comme le 418 hexadécimal ci-dessus) et surtout pas des octets d'un encodage particulier comme le font, malheureusement, les URI (section 2.1 du RFC 3986).
Un deuxième principe est d'utiliser des délimiteurs explicites, pour éviter toute ambiguïté, sans forcer les caractères à être représentés par un nombre fixe de chiffres (section 4).
Plusieurs formes couramment recontrées dans la nature sont discutées dans le RFC et rejetées (section 6 et annexe A) :
\u0418
qui viole le premier principe (c'est un
sur-encodage d'UTF-16, ce qui n'est pas gênant
pour notre grand I cyrillique, qui fait partie du Plan Multilingue de
Base d'Unicode, mais complique les choses pour les caractères en dehors de ce plan),\u0418
, mais qui utilise un grand U et huit
chiffres pour les caractères en dehors du Plan Multilingue de Base,
une astuce bien dans la ligne de ce langage,\x{418}
, qui avait personnellement ma préférence,
notamment par ses délimiteurs symétriques, mais qui a été écartée car
certains craignaient une ambiguïté possible due à la possibilité en
Perl d'utiliser d'autres encodages.Enfin, on notera que le RFC ne spécifie pas d'échappement standard
si on veut écrire, par exemple \u'0418'
sans qu'il soit
interprété comme un caractère Unicode. Le truc classique du \\ est
recommandé mais pas imposé.
Date de publication du RFC : Septembre 2003
Auteur(s) du RFC : P. Calhoun (Airespace), J. Loughney (Nokia), E. Guttman (Sun), G. Zorn (Cisco), J. Arkko (Ericsson)
Chemin des normes
Première rédaction de cet article le 22 février 2008
Pendant longtemps, le seul protocole standard d'authentification entre un NAS et sa base d'utilisateurs était Radius. Diameter, normalisé dans notre RFC, vise à le remplacer, et est bien plus riche en fonctions. Ce RFC était le premier sur Diameter, il a été remplacé depuis par le RFC 6733.
Traditionnellement, lorsqu'un client PPP ou d'un protocole similaire se connecte à son FAI, sa session est terminée sur un NAS, équipement qui ne possède en général pas de base des utilisateurs autorisés. Il y a plusieurs raisons à cela, comme le fait que le NAS n'est en général pas un ordinateur généraliste, il a peu de moyens, notamment en place disque ou bien comme le fait qu'un FAI a typiquement plusieurs NAS (au moins un par POP), et qu'il souhaite centraliser l'authentification. (Dans le monde 802.11, le NAS est typiquement nommé AP (Access Point.)
Le mécanisme habituel est donc que le NAS soit client d'un protocole d'authentification et que le FAI gère un serveur de ce protocole, serveur qui connaitra les utilisateurs autorisés. Le même protocole assure en général également des fonctions de comptabilisation des accès, d'où le sigle AAA (Authentication, Authorization and Accounting). Le premier protocole standard en ce sens est Radius (RFC 2865), que Diameter vise à remplacer. (Un protocole privé, Tacacs, qui sera documenté dans le RFC 1492, avait également été utilisé.)
Que reproche Diameter à Radius ? La section 1 de notre RFC détaille les faiblesses de Radius perçues par les auteurs de Diameter. Une analyse plus détaillée figure dans le RFC 3169 :
Diameter est donc plus riche et plus complexe que Radius.
Diameter reprend aussi plusieurs idées de Radius comme le codage en doublets Attribut / Valeur (AVP pour Attribute-Value Pairs) ou comme l'utilisation des NAI du RFC 7542 pour coder l'identité vérifiée.
Le RFC est donc bien plus long et compliqué que son équivalent Radius. La section 1 introduit le protocole, et ses usages, et le compare aux exigences listées dans le RFC 2989..
La section 2 précise le protocole, par exemple le mécanisme de transport fait l'objet de la sous-section 2.1, qui impose au minimum TCP et SCTP (les détails sont dans le RFC 3539). Diameter écoute par défaut sur le port 3868. La 2.4 introduit le nouveau concept d'Application Identifier, valeur enregistrées auprès de l'IANA qui identifie un usage particulier de Diameter (plus riche que Radius, Diameter permet davantage d'usages). Par exemple, l'usage en tant que service d'authentification pour un NAS (Application Identifier n° 1) n'est pas dans le cœur du protocole, il est délégué au RFC 4005. D'autres RFC décrivent des applications de Diameter comme le RFC 4740 qui parle de son usage pour SIP. 2.5 parle de la différence entre connexions et sessions, une connexion étant un concept de la couche 4 alors qu'une session Diameter peut impliquer plusieurs connexions. En 2.8, on trouve le bestiaire des agents Diameter, les clients et les serveurs bien sûr mais également les relais ou bien les traducteurs, pour parler à des agents d'autres protocoles, notamment Radius.
La section 3 décrit l'en-tête des paquets
Diameter et les codes de commande qu'ils contiennent comme
Capabilities-Exchange-Request
. Seuls les codes
communs à toutes les applications sont définis dans la section 3.1,
des codes aussi importants que AA-Request
(demande d'authentification, l'équivalent du Access-Request
de Radius) sont délégués à d'autres RFC (comme le RFC 4005).
En section 4, nous arrivons aux AVP eux-même, les doublets
attributs-valeur qui portent l'information. On notera en 4.1 un
concept désormais fréquent dans les protocoles réseaux, l'option
Mandatory qui indique pour un AVP, s'il doit
absolument être connu de l'implémentation (le dialogue Diameter avorte
autrement) ou bien s'il peut tranquillement être ignoré, par exemple
par une vieille implémentation qui ne connait pas ce nouvel AVP. La
sous-section 4.3
décrit, entre autre, les URI Diameter, de
plan aaa:
,
comme
aaa://host.example.com:666:transport=stcp;protocol=diameter
.
Les sections 5 à 8 spécifient les nombreuses machines à état qui doivent être mises en œuvre par les agents Diameter. Au contraire de Radius qui, comme le DNS, est purement requête/réponse, Diameter nécessite un vrai automate dans chaque agent.
La sous-section 5.2 explique comment un agent Diameter peut en trouver un autre. Avec Radius, la configuration (par exemple du serveur d'authentification) devait être manuelle. Avec Diameter, on peut utiliser SLP (RFC 2165) ou NAPTR combiné avec SRV (RFC 2782).
La section 13, sur la sécurité, est très stricte. On y notera qu'un agent Diameter doit disposer d'IPsec.
Une bonne introduction à Diameter a été publié en http://www.interlinknetworks.com/whitepapers/Introduction_to_Diameter.pdf
.
Il n'existe que deux implémentations de serveur Diameter en
logiciel libre, Open Diameter et OpenBlox, et
elles semblent peu maintenues.
Le bilan opérationnel de Diameter est mince : beaucoup plus complexe que Radius, il ne l'a pas réellement remplacé dans son secteur, l'authentification via un NAS. Diameter semble bien être une nouvelle victime de l'effet « Deuxième système ». (À noter qu'une deuxième version de Diameter est sortie, peu différente, dans le RFC 6733.)
Première rédaction de cet article le 20 février 2008
Une logique manageriale impeccable fait que la capitaine Le Floch a été envoyé en Bretagne pour élucider un meurtre assez particulier. Certes, elle est très compétente mais son chef s'est surtout dit que son nom la rendait particulièrement adaptée aux villages des monts d'Arrée.
Raté, la capitaine n'a jamais connu son père, à qui elle doit son nom, et tient de sa mère japonaise une allure peu bretonne. Cela ne se passera donc pas tout seul dans ce roman de Vanessa Fuks. De toute façon, n'importe quel flic parisien aurait eu du mal dans cette Bretagne noire à plaisir où presque tout le monde est abruti, violent, bigot et croit à l'Ankou.
C'est court, c'est écrit avec beaucoup de verve et de style et les personnages sont extra, surtout Akiko Le Floch essayant de comprendre quelque chose à ces meurtres (oui, il y en aura d'autres).
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : T. Showalter, N. Freed (Sun)
Chemin des normes
Première rédaction de cet article le 20 février 2008
Le langage de filtrage du courrier électronique
Sieve repose sur un socle minimum, que doivent
comprendre toutes les implémentations de Sieve, et un certain nombre
d'extensions, couvrant des besoins
supplémentaires. Ce RFC déclare l'extension
vacation
, qui permet de mettre en place un
répondeur automatique.
La section 4 du RFC détaille l'extension et son mode
d'emploi. Comme toute extension Sieve, elle
doit être introduite par un require
. Elle prend
comme paramètre une chaîne de caractères qui sera envoyée à
l'expéditeur et diverses options comme :addresses
qui indique les adresses de destinataire que le script Sieve
considérera comme locales (car un répondeur automatique ne doit pas
répondre à n'importe quel message, seulement ceux où son maître est
listé dans les champs comme To:
, cf. section
4.5). Voici un exemple :
require "vacation"; vacation :addresses ["stephane@bortzmeyer.org", "bortzmeyer@gmail.com"] "Je suis parti, je lirai avec plaisir votre message plus tard.";
Comme l'avertit le RFC 3834, un répondeur
automatique est un programme dangereux, et tout le monde a déjà reçu
des réponses stupides, par exemple alors qu'on avait écrit à une liste
de diffusion, pas directement au destinataire. Ou bien des réponses
multiples alors qu'on avait déjà été prévenu. D'où la section 4.2 qui
précise qu'une mise en œuvre de vacation
doit se souvenir de qui a déjà été prévenu, pendant au moins sept
jours (valeur modifiable par l'option
:days
). Cette section est très détaillée car la
règle exacte est plus complexe, elle doit prendre en compte le
résultat des autres tests Sieve.
La section 5 décrit le message de réponse lui-même, les en-têtes
qu'il doit avoir (comme In-Reply-To
, section
5.8).
Ces messages de réponse étant destinés à des humains, la question
de leur internationalisation est cruciale. L'expéditeur qui écrit en
zazaki à un zazakophone serait surpris de
recevoir un message en anglais ! C'est l'objet de la section 7 qui
précise comment utiliser les en-têtes du RFC 3282 comme
Content-Language
:
if header :contains ["accept-language", "content-language"] "fr" { vacation "Je ne suis pas là."; } else { vacation "I am away."; }
Date de publication du RFC : Mars 1999
Auteur(s) du RFC : Robert E. Gilligan (FreeGate Corporation), Susan Thomson (Bell Communications Research), Jim Bound (Compaq Computer Corporation), W. Richard Stevens
Pour information
Première rédaction de cet article le 19 février 2008
A priori, l'IETF ne normalise pas d'API (et c'est pour cela que ce RFC n'a que le statut de « pour information »), se limitant aux « bits qu'on voit passer sur le câble ». Mais le monde de la normalisation n'est pas toujours si simple et, à l'époque, il était important de publier rapidement une documentation sur la nouvelle API nécessaire aux applications pour faire de l'IPv6.
Les API Unix et réseaux sont typiquement gérées par l'IEEE, via sa norme POSIX. Mais POSIX n'est pas librement téléchargeable sur le réseau, ce qui limite son utilité. Pour cette raison et pour d'autres, l'IETF a donc publié ce RFC, dont on notera qu'un des auteurs est W. Richard Stevens, auteur de Unix network programming, le livre de référence sur le sujet. Il succède à un premier RFC sur la question, le RFC 2133 et a lui-même été remplacé par le RFC 3493.
Depuis leur apparition, les prises (socket dans la langue de Stevens) sont le principal mécanisme d'accès au réseau pour les programmes. Les programmes qui les utilisent sont relativement portables, bien au delà du système BSD où elles sont nées. Traditionnellement multi-protocoles, les prises ne permettaient néanmoins pas d'accéder à IPv6. C'est désormais le cas et l'interface décrite dans ce RFC est désormais largement présente (MacOS X a été le dernier système d'exploitation à la proposer).
Elle ne concerne que le langage C. Les autres langages disposent souvent de mécanismes de plus haut niveau que les prises comme les Streams de Java.
Idéalement, la plupart des applications ne devrait pas avoir besoin de savoir si elles utilisent IPv4 ou IPv6. Concentrée dans la couche Réseau, le protocole utilisé ne devrait pas concerner l'application. Mais C est un langage de bas niveau, et expose donc le protocole de couche 3 utilisé (même si la section 2 du RFC explique que l'API cherche à être la plus générale possible).
La section 2.1 résume les principaux changements qui ont été faits
pour permettre l'utilisation d'IPv6. Ils incluent une nouvelle
constante (section 3.1) pour indiquer les adresses IPv6
(AF_INET6
, puisque AF_INET
, comme
son nom ne l'indique pas clairement, étant spécifique à IPv4) et une
pour le protocole IPv6 (PF_INET6
). Notons que le
RFC documente aussi PF_UNSPEC
, qui permet à
l'application de dire qu'elle se moque du protocole utilisé (ce qui
devrait être le cas le plus courant). Il y a bien sûr une nouvelle
structure de données (section 3.3) pour placer les adresses IPv6,
quatre fois plus grandes. Les sockaddr
sont
désormais des représentations de la prise, indépendantes de la famille
d'adresses, les sockaddr_in6
étant spécifiques à
IPv6. Elles contiennent :
struct sockaddr_in6 { sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* transport layer port # */ uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* set of interfaces for a scope */ };
Les appels système sur les prises, décrits dans la section 3.5, eux, ont peu changés, socket, connect, bind, continuent comme avant.
Les sections 3.6. et 3.7 concernent l'interopérabilité avec
IPv4. Le monde des applications a une forte inertie. Les développeurs,
déjà très occupés, ne portent pas leurs applications vers la nouvelle
interface instantanément. Ces deux sections expliquent donc comment
assurer le recouvrement des deux protocoles. On notera qu'avec cette
interface, pour faire un serveur qui écoute en
IPv4 et IPv6, il faut créer une prise IPv6, les
clients IPv4 recevront alors des adresses
IPv4-mapped comme
::FFFF:192.0.2.24
. Ce n'est pas très
intuitif... (Heureusement, c'est plus simple pour un client.)
La section 6 du RFC parle des fonctions de bibliothèque pour
effectuer les traductions de noms en adresses et
réciproquement. L'ancienne gethostbyname, très spécifique
à IPv4 et souffrant d'autres limitations, ne devrait plus être
utilisée depuis des années (le nombre de programmes qui l'utilisent
encore ou de tutoriels qui l'expliquent donne une idée de l'extrême
inertie d'un secteur qui se prétend novateur et réactif). Les
« nouvelles » fonctions getaddrinfo et
getnameinfo (section 6.4) la remplacent. Le RFC propose
également en sections 6.1 et 6.2 getipnodebyname
et
getipnodebyaddr
, qui seront supprimées dans le
RFC suivant, le RFC 3493. Un programme
typique désormais fait :
char *server = "www.example.org"; char *port_name = "42"; int mysocket; /* addrinfo est défini dans netdb.h et inclus une "struct sockaddr" (une prise, incluant l'adresse IP) dans son champ ai_addr. Sa description figure dans la section 6.4 du RFC. */ struct addrinfo hints, *result; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(server, port_name, &hints, &result); if (error) { err_quit("getaddrinfo error for host: %s %s", server, gai_strerror(error)); } /* La première adresse IP sera dans result->ai_addr, pour les suivantes, il faudra suivre result->ai_next */ mysocket = socket(...); error = connect(mysocket, result->ai_addr, result->ai_addrlen); ...
Un des rares cas où un client réseau a besoin de manipuler des adresses IP (pas seulement de les stocker et de les passer d'une fonction à une autre) est lors de l'affichage, par exemple en mode bavard. Pour éviter que le programme ne doive connaitre les détails de syntaxe des adresses (celle d'IPv4 n'a jamais été normalisée, celle d'IPv6 est décrite dans le RFC 4291), notre RFC décrit en section 6.6 des fonctions de conversion de et vers un format texte, inet_ntop et inet_pton.
L'inertie des programmeurs étant très forte, et celle des enseignants également, on peut parier, bien que ce RFC soit vieux de neuf ans, que beaucoup de cours de programmation réseaux sont encore donnés avec la vieille interface, qui ne marche qu'en IPv4...
Date de publication du RFC : Février 2003
Auteur(s) du RFC : R. Gilligan, S. Thomson, J. Bound, J. McCann, W. Stevens
Pour information
Première rédaction de cet article le 19 février 2008
A priori, l'IETF ne normalise pas d'API (et c'est pour cela que ce RFC n'a que le statut de « pour information »), se limitant aux « bits qu'on voit passer sur le câble ». Mais le monde de la normalisation n'est pas toujours si simple et, à l'époque, il était important de publier rapidement une documentation sur la nouvelle API nécessaire aux applications pour faire de l'IPv6.
Les API Unix et réseaux sont typiquement gérées par l'IEEE, via sa norme POSIX. Mais POSIX n'est pas librement téléchargeable sur le réseau, ce qui limite son utilité. Pour cette raison et pour d'autres, l'IETF a donc publié ce RFC, dont on notera qu'un des auteurs est W. Richard Stevens, auteur de Unix network programming, le livre de référence sur le sujet. Il succède au RFC 2553 et est complété par un RFC sur l'interface « avancée », le RFC 3542.
Depuis leur apparition, les prises (socket dans la langue de Stevens) sont le principal mécanisme d'accès au réseau pour les programmes. Les programmes qui les utilisent sont relativement portables, bien au delà du système BSD où elles sont nées. Traditionnellement multi-protocoles, les prises ne permettaient néanmoins pas d'accéder à IPv6. C'est désormais le cas et l'interface décrite dans ce RFC est désormais largement présente (MacOS X a été le dernier système d'exploitation à la proposer).
Elle ne concerne que le langage C. Les autres langages disposent souvent de mécanismes de plus haut niveau que les prises comme les Streams de Java.
Idéalement, la plupart des applications ne devrait pas avoir besoin de savoir si elles utilisent IPv4 ou IPv6. Concentrée dans la couche Réseau, le protocole utilisé ne devrait pas concerner l'application. Mais C est un langage de bas niveau, et expose donc le protocole de couche 3 utilisé (même si la section 2 du RFC explique que l'API cherche à être la plus générale possible).
La section 2.1 résume les principaux changements qui ont été faits
pour permettre l'utilisation d'IPv6. Ils incluent une nouvelle
constante (section 3.1) pour indiquer les adresses IPv6
(AF_INET6
, puisque AF_INET
, comme
son nom ne l'indique pas clairement, étant spécifique à IPv4) et une
pour le protocole IPv6 (PF_INET6
). Notons que le
RFC documente aussi PF_UNSPEC
, qui permet à
l'application de dire qu'elle se moque du protocole utilisé (ce qui
devrait être le cas le plus courant). Il y a bien sûr une nouvelle
structure de données (section 3.3) pour placer les adresses IPv6,
quatre fois plus grandes. Les sockaddr
sont
désormais des représentations de la prise, indépendantes de la famille
d'adresses, les sockaddr_in6
étant spécifiques à
IPv6. Elles contiennent :
struct sockaddr_in6 { sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* transport layer port # */ uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* set of interfaces for a scope */ };
Les appels système sur les prises, décrits dans la section 3.5, eux, ont peu changés, socket, connect, bind, continuent comme avant.
Les sections 3.6. et 3.7 concernent l'interopérabilité avec
IPv4. Le monde des applications a une forte inertie. Les développeurs,
déjà très occupés, ne portent pas leurs applications vers la nouvelle
interface instantanément. Ces deux sections expliquent donc comment
assurer le recouvrement des deux protocoles. On notera qu'avec cette
interface, pour faire un serveur qui écoute en
IPv4 et IPv6, il faut créer une prise IPv6, les
clients IPv4 recevront alors des adresses
IPv4-mapped comme
::FFFF:192.0.2.24
. Ce n'est pas très
intuitif... (Heureusement, c'est plus simple pour un client.)
La section 6 du RFC parle des fonctions de bibliothèque pour effectuer les traductions de noms en adresses et réciproquement. L'ancienne gethostbyname, très spécifique à IPv4 et souffrant d'autres limitations, ne devrait plus être utilisée depuis des années (le nombre de programmes qui l'utilisent encore ou de tutoriels qui l'expliquent donne une idée de l'extrême inertie d'un secteur qui se prétend novateur et réactif). Les « nouvelles » fonctions getaddrinfo et getnameinfo (section 6.4) la remplacent. Un programme typique désormais fait :
char *server = "www.example.org"; char *port_name = "42"; int mysocket; /* addrinfo est défini dans netdb.h et inclus une "struct sockaddr" (une prise, incluant l'adresse IP) dans son champ ai_addr. Sa description figure dans la section 6.4 du RFC. */ struct addrinfo hints, *result; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(server, port_name, &hints, &result); if (error) { err_quit("getaddrinfo error for host: %s %s", server, gai_strerror(error)); } /* La première adresse IP sera dans result->ai_addr, pour les suivantes, il faudra suivre result->ai_next */ mysocket = socket(...); error = connect(mysocket, result->ai_addr, result->ai_addrlen); ...
Un des rares cas où un client réseau a besoin de manipuler des adresses IP (pas seulement de les stocker et de les passer d'une fonction à une autre) est lors de l'affichage, par exemple en mode bavard. Pour éviter que le programme ne doive connaitre les détails de syntaxe des adresses (celle d'IPv4 n'a jamais été normalisée, celle d'IPv6 est décrite dans le RFC 4291), notre RFC décrit en section 6.6 des fonctions de conversion de et vers un format texte, inet_ntop et inet_pton.
Enfin, la section 9 liste les différences avec son prédécesseur, le RFC 2553. Rien de très important ici.
L'inertie des programmeurs étant très forte, et celle des
enseignants également, on peut parier, bien que le premier RFC sur le
sujet soit vieux de onze ans, que beaucoup de cours de programmation
réseaux sont encore donnés avec la vieille interface, qui ne marche
qu'en IPv4... À l'appui de ce pari, notons que le service Code Search de Google
trouve 255 000 occurrences de gethostbyname
contre seulement 78 200 de getaddrinfo
.
Première rédaction de cet article le 13 février 2008
Mesurer les performances d'un service informatique est un art difficile mais néanmoins indispensable à l'administrateur système. Parmi ces services, le DNS présente la particularité que plusieurs serveurs répondent pour une zone donnée. De même, une machine connectée à l'Internet a souvent le choix entre plusieurs serveurs comme résolveurs. Dans un groupe, quel est le plus rapide de ces serveurs ? Un petit programme permet de répondre à cette question.
Supposons que je m'interroge sur le temps de réponse d'un service
dont le nom figure dans la zone example.com
. Le
temps de réponse du DNS doit être pris en
compte. Ou bien je me demande si je dois utiliser les résolveurs
fournis par mon FAI, ou bien un
BIND que j'ai installé sur ma machine, ou bien
encore un service tiers comme OpenDNS, qui
résout gratuitement des noms de domaine en échange d'une manipulation des réponses pour insérer de la
publicité. Quel résolveur est le plus rapide ?
On peut mesurer le temps de réponse d'un serveur avec echoping :
% echoping -n 3 -m dns c.nic.fr -t SOA fr Elapsed time: 0.118128 seconds Elapsed time: 0.074891 seconds Elapsed time: 0.047331 seconds --- Minimum time: 0.047331 seconds (5409 bytes per sec.) Maximum time: 0.118128 seconds (2167 bytes per sec.) Average time: 0.080116 seconds (3195 bytes per sec.) Standard deviation: 0.029137 Median time: 0.074891 seconds (3418 bytes per sec.)
Ou bien on peut utiliser dig qui affiche, tout à la fin, le temps écoulé :
% dig @c.nic.fr SOA fr. ... ;; Query time: 55 msec
Mais pour comparer N serveurs, c'est un peu pénible. D'autant plus que dig, contrairement à echoping, ne permet pas de répéter un test, ce qui est indispensable lorsqu'on fait des mesures sur Internet, où les temps de réponse varient souvent considérablement.
Joe Abley a donc développé pour cela qtest
, le programme décrit plus bas,
programme que j'ai un peu amélioré. Ce programme prend comme argument
une requête DNS par exemple MX elysee.fr.
ou bien
ANY www.example.com.
et une liste de serveurs à
tester. Il affiche les N serveurs les plus rapides (N vaut 1 par
défaut mais on peut le changer avec l'option -n
)
ainsi que leur temps de réponse en milli-secondes. Par exemple :
% qtest "SOA fr." a.nic.fr c.nic.fr e.nic.fr 46 c.nic.fr/192.134.0.129
Ce test permettra de comparer les temps de réponse de ces trois
serveurs de l'AFNIC (bien sûr, le résultat
dépendra de l'endroit où on se trouve, d'autant plus que
e.nic.fr
est à la
Réunion). Pour tester pour une zone donnée
(ici, la racine), on peut utiliser la
possibilité qu'à le shell d'exécuter une commande et d'utiliser son
résultat comme variable, ici avec la syntaxe $(commande
arguments...)
:
% qtest "SOA ." $(dig +short NS .) 3 F.ROOT-SERVERS.NET./2001:500:2f::f
f.root-servers.net
a répondu le premier, en trois milli-secondes. Pour voir davantage de serveurs :
% qtest -n 5 "SOA ." $(dig +short NS .) 3 F.ROOT-SERVERS.NET./2001:500:2f::f 3 M.ROOT-SERVERS.NET./2001:dc3::35 6 F.ROOT-SERVERS.NET./192.5.5.241 21 I.ROOT-SERVERS.NET./192.36.148.17 21 K.ROOT-SERVERS.NET./193.0.14.129
qtest
est écrit en
shell. Après analyse de ses arguments avec
getopt, il boucle sur les serveurs de noms passés en
argument. Pour chacun d'eux, il cherche l'ensemble des adresses
IPv4 et IPv6 (les temps
de réponse peuvent être très différents entre les deux protocoles),
stocke chaque couple <nom de machine, adresse IP> dans une
chaîne de caractères, la barre oblique servant
de séparateur (le shell Unix n'a pas de structures de données perfectionnées). Pour chaque couple,
qtest
fait trois essais avec
dig. Les calculs statistiques (moyenne, tri,
hélas pas de médiane) sont
faits avec awk.
Ici, on va comparer un résolveur
local, ceux fournis par le FAI, et ceux de deux services commerciaux,
OpenDNS et DNS Advantage de
Neustar. Cette fois, on fait appel à des serveurs
récursifs, ayant un cache des réponses
précédemment obtenues, et le choix de la question est donc
important. Si la réponse est dans le cache (ce qui est typiquement le
cas si on demande l'adresse de www.google.com
),
tout ira bien plus vite ! Essayons d'abord avec un nom qui est
probablement dans le cache. 172.19.1.1
est un
résolveur local, ceux commençant par 62.4
sont
les résolveurs de mon FAI, ceux commençant par
208.67.222
sont à OpenDNS et ceux commençant par
156.154
sont ceux de
DNS advantage. qtest
affiche toujours l'adresse IP
après la barre oblique même lorsque, comme ici, c'est inutile puisque
l'identité du serveur était déjà une adresse IP :
% qtest -n3 "A a.gtld-servers.net" 172.19.1.1 62.4.16.70 62.4.17.69 208.67.222.222 208.67.220.220 156.154.70.1 156.154.71.1 3 172.19.1.1/172.19.1.1 49 62.4.17.69/62.4.17.69 61 208.67.222.222/208.67.222.222
On voit que les résolveurs les plus proches sont les plus
rapides (un test avec un nom inexistant, donc pas dans le cache, donne
le même résultat) contrairement aux prétentions des vendeurs d'OpenDNS
ou de Neustar. Il ne faut jamais se fier à la publicité. Le test a été
fait depuis une machine en Europe, où OpenDNS et DNS Advantage ont peu de
serveurs. Est-ce mieux aux États-Unis ? Non (ici, les serveurs du
fournisseur d'hébergement sont ceux commençant par
208.75
et 208.78
:
0 127.0.0.1/127.0.0.1 0 208.78.97.155/208.78.97.155 1 208.75.87.250/208.75.87.250 23 156.154.70.1/156.154.70.1 25 156.154.71.1/156.154.71.1 29 208.67.220.220/208.67.220.220 29 208.67.222.222/208.67.222.222
Bref, si on veut des temps de réponse rapides, rien ne vaut les serveurs de son FAI.
Vous pouvez récupérer le programme qtest. Plus riche, plus graphique et plus complexe, il y a l'excellent Namebench.
Date de publication du RFC : Décembre 1998
Auteur(s) du RFC : Kathleen Nichols (Cisco), Steven Blake (Torrent Networking Technologies), Fred Baker (Cisco), David L. Black (EMC Corporation)
Chemin des normes
Première rédaction de cet article le 13 février 2008
Dernière mise à jour le 18 février 2008
La question du traitement differencié des paquets IP occupe beaucoup de monde depuis les débuts de l'Internet. En gros, il s'agit de savoir si les routeurs et autres équipements intermédiaires vont traiter tous les paquets IP de la même manière, où bien si certains auront la priorité, ou en tout cas un traitement particulier selon certains critères. Si la question a un aspect politique, lié à la revendication de neutralité du réseau, pour savoir qui va décider quels paquets seront sacrifiés, notre RFC ne couvre que l'aspect technique : il change complètement un des champs du paquet IP, pour tenir compte de l'échec qu'avait été ce champ Type Of Service.
Avant de mettre en œuvre des traitements differenciés, encore
faut-il savoir à quels paquets les appliquer. Dans le
RFC original sur IPv4,
le RFC 791, un champ du paquet,
TOS, Type Of Service était
réservé au marquage du paquet. Il permettait d'indiquer la priorité
souhaitée et les critères les plus importants pour ce paquet (débit,
coût, latence, etc). La norme Posix prévoit
des moyens pour les applications de définir ces champs (un programme
comme echoping les
met en œuvre avec ses options -p
et
-P
). Voici un exemple en C de définition
du champ TOS avec setsockopt :
result = setsockopt(mysocket, IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, sizeof(int)); /* IPTOS_THROUGHPUT vaut 0x08 et était censé maximiser le débit. Cf. RFC 791, section 3.1 */
Pour voir les capacités des différents systèmes d'exploitation à fixer ces valeurs, on peut regarder mon article sur la fixation d'options IP depuis un programme.
Ce mécanisme n'a eu aucun succès, peu d'applications fixent ce champ et peu de routeurs le traitaient comme spécifié. Il y a plusieurs raisons à cet échec, et toutes ne sont pas techniques, loin de là. Par exemple, comment empêcher une application de toujours demander la plus forte priorité ? (La question est discutée dans le section 7.1 de notre RFC.)
Parmi les raisons techniques, il y avait le fait que le mécanisme du RFC 791 était trop rigide. Par exemple, les critères exprimables étaient en nombre limité et trop vagues. Une nouvelle architecture pour la qualité de service, Differentiated Services, connue sous l'abréviation de Diffserv a été définie dans le RFC 2475. Ses conséquences pratiques sur le format des paquets font l'objet de notre RFC 2474, qui met donc à jour le RFC 791 et qui s'applique également à son équivalent IPv6, le RFC 2460, pour la définition du champ Traffic class (équivalent IPv6 du champ TOS).
Le champ TOS de IPv4 change donc de nom. Il devient DS
(Differentiated Services) et la
sémantique n'est plus fixée par le RFC. Un TOS de
0x08
voulait toujours dire « Je cherche à
maximiser le débit » alors qu'un DS de 0x08
aura une signification donnée par les routeurs du domaine
administratif où le paquet passe. Aux frontières de ces domaines, par
exemple pour passer d'un opérateur à un autre, il faudra changer le
champ (section 2 du RFC) ou bien utiliser des valeurs attribuées par un accord entre
opérateurs (Diffserv définit un mécanisme, pas une politique). La
section 1 de notre RFC prévient que, si le
forwarding de chaque paquet est un problème bien
connu, l'attribution et la gestion de politiques de qualité de service
est un problème bien plus ouvert. Neuf ans après la sortie du RFC, il
ne semble pas en voie de résolution. La même section 1 rappelle que
des politiques simples et appliquées statiquement sont peut être la
meilleure solution.
La section 3 décrit le nouveau champ DS. Voici l'ancien champ ToS, sur huit bits, du RFC 791 :
0 1 2 3 4 5 6 7 +-----+-----+-----+-----+-----+-----+-----+-----+ | | | | | | | | PRECEDENCE | D | T | R | 0 | 0 | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+
Et voici le nouveau champ DS (Differentiated Services) :
0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | DSCP | CU | +---+---+---+---+---+---+---+---+ DSCP: differentiated services codepoint CU: currently unused
(La partie réservée a été remplie ultérieurement par l'ECN du RFC 3168.) Le champ DSCP contient un index dans une table des PHB (per-host behavior) qui sont les traitements que le routeur applique. Des exemples de PHB sont « fait passer ce paquet devant tout le monde dans la queue » ou bien « n'hésite pas à jeter ce paquet si le réseau est congestionné ». Le PHB par défaut (section 4.1) étant le traditionnel « faire de son mieux » des routeurs IP. Certains RFC définissent des PHB comme le RFC 2597 sur le Assured Forwarding.
On voit sur les schémas que, contrairement à l'ancien TOS, le DSCP n'a pas de structure interne. 64 valeurs différentes sont possibles, et les sections 4 et 5 discutent de leur allocation, la section 6 couvrant d'éventuelles standardisations de certaines valeurs.
Si on regarde ce qui passe sur le réseau avec tshark (option -V
), on verra :
Internet Protocol, Src Addr: 172.19.1.1 (172.19.1.1), Dst Addr: 172.19.1.2 (172.19.1.2) ... Differentiated Services Field: 0x08 (DSCP 0x02: Unknown DSCP; ECN: 0x00) 0000 10.. = Differentiated Services Codepoint: Unknown (0x02) .... ..0. = ECN-Capable Transport (ECT): 0 .... ...0 = ECN-CE: 0
On voit que le 0x08
mis dans le champ équivaut à
un DSCP de 0x02
, qui ne correspond pas à une
valeur connue de manière standard (d'où le Unknown DSCP).
L'informatique est un monde très conservateur et, neuf ans après la sortie de ce RFC, on continue couramment à utiliser des mots comme TOS, normalement abandonnés (cf. par exemple la bogue echoping #1892544). La norme Posix continue à définir uniquement des constantes pour l'ancien comportement (comme IP_TOS ou IPTOS_THROUGHPUT, utilisés plus haut). Il n'est pas facile de changer une API si utilisée !
Sur Linux, on peut aussi changer la valeur
du champ DSCP avec Netfilter et sa commande
iptables. Cela se fait en modifiant la table
mangle
(qui permet de modifier un paquet, pas
seulement de l'accepter ou de le refuser), avec la pseudo-chaîne de
destination DSCP
. Par exemple :
# iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 0x02
va changer le DSCP de tous les paquets à destination du port 22. Pour les raisons expliquées plus haut, tcpdump va afficher ce DSCP de 0x2 en 0x8 :
17:50:35.477598 IP (tos 0x8, ttl 64, id 1040, offset 0, flags [DF], proto TCP (6), length 60) 192.168.2.1.36067 > 10.22.58.30.22: Flags [S], cksum 0xe4b2 (correct), seq 3255303173, win 5840, options [mss 1460,sackOK,TS val 8714261 ecr 0,nop,wscale 6], length 0
Pour mettre en œuvre le traitement différencié sur un routeur Cisco, on peut consulter Implementing Quality of Service Policies with DSCP.
Aujourd'hui, DSCP ne semble pas avoir eu beaucoup plus de succès que son prédécesseur. Il est difficile de mesurer le taux de déploiement car tous sont internes à une organisation. Certains RFC comme le RFC 4504 (section 2.12) ont rendu obligatoire l'utilisation de DSCP mais ils n'ont pas forcément été respectés. Si une entreprise qui déploie de la VoIP utilise DSCP en interne pour permettre aux coups de téléphone de passer même lorsqu'un gros transfert de fichiers est en cours, tout en simplifiant la configuration de ses routeurs, cela ne se voit pas à l'extérieur.
Première rédaction de cet article le 12 février 2008
Le VCS (logiciel de gestion de versions) CVS est bien vieux et souffre de nombreux inconvénients (voir par exemple l'introduction de mon article à JRES sur les nouveaux VCS). Une fois prise la décision de migrer vers Subversion, comment convertir les données existantes ?
Si on part de zéro, migrer vers Subversion est très simple, les commandes pour l'utilisateur étant quasiment identiques à celles de CVS. Mais si on a déjà des années de développement logiciel ou d'écriture de documents derrière soi et qu'on ne veut pas abandonner l'historique ? Si on est hébergé par un service tel que SourceForge, ce service fournit probablement un mécanisme de conversion (celui de SourceForge est bien documenté et marche très bien). Mais si on gère l'hébergement soi-même ? Alors, il faut utiliser un logiciel de conversion. Il en existe un très grand nombre, le plus spectaculaire étant sans doute tailor, qui peut convertir de n'importe quel VCS vers n'importe quel autre. Toutefois, tailor n'est pas sans bogues et, si on veut simplement passer de CVS à Subversion, le plus simple cvs2svn suffit largement. Il a l'intérêt d'être très robuste et de gérer tous les cas, à commencer par les branches.
L'utilisation est très simple. Si mon dépôt CVS se trouve dans
CVS_REPOSITORY
et que je veux mettre le futur
dépôt Subversion en SVN_REPOSITORY
, je tape
juste :
cvs2svn -s $SVN_REPOSITORY $CVS_REPOSITORY
Il détaille alors l'opération de conversion. Je n'ai plus qu'à tester le dépôt obtenu :
svn log file://$SVN_REPOSITORY/
et, si j'obtiens correctement l'historique, c'est que tout est bon.
Les dépôts CVS en France ont parfois des messages de commit avec des encodages variés. Si c'est le cas, il faut l'indiquer au convertisseur :
cvs2svn --encoding iso-8859-1 -s $SVN_REPOSITORY $CVS_REPOSITORY
Je ne connais pas de moyen de convertir la copie de travail (le résultat du checkout). Il faut donc vérifier, avant la conversion, que tout a bien été committé, puis effacer chaque copie de travail et refaire un checkout.
Première rédaction de cet article le 12 février 2008
Le protocole IP permet d'indiquer dans l'en-tête des paquets plusieurs options, qui peuvent indiquer au routeur un traitement spécifique du paquet. Pour un programme ordinaire, utilisant les API standard, quelles options peuvent être facilement définies à l'émission, et lues à la réception ?
La question a surgi dans le groupe de travail Behave de l'IETF, à propos du protocole TURN (depuis normalisé dans le RFC 5766). TURN relaie des paquets, notamment UDP entre deux clients qui ne peuvent pas se parler directement. Le serveur TURN doit-il respecter les en-têtes des paquets IP ? Si le RFC impose cette contrainte, pourra t-on programmer un serveur TURN en n'utilisant que les API standard ? Si le serveur tourne sur Unix, devra t-il le faire en étant root ?
Les bits en question sont définis dans divers RFC. Ainsi, le RFC 791, qui définissait IPv4 à l'origine, définit un groupe de bits nommé le TOS (Type Of Service), qui permet de fixer la priorité du paquet et ses choix (privilégier le débit, le coût, etc). Ce groupe a été remplacé par le DSCP (Differentiated Services Code Point) dans le RFC 2474. Puis le RFC 3168 a utilisé deux autres bits pour ECN (Explicit Congestion Notification). D'autres bits sont modifiables potentiellement comme le TTL ou comme DF (Don't Fragment).
Mais une application typique ne fabrique pas les paquets IP à la main, bit par bit. Elle compte sur une API standard, typiquement sur Posix. (Sur un système comme Unix, faire des paquets entièrement soi-même et les envoyer nécessite d'être root de toute façon.) Que nous permet cette API ?
C'est pour répondre à cette question que j'ai développé un ensemble
de petits programmes, qu'on peut récupérer dans le fichier tests-socket.tar.gz
. Ces programmes sont prévus pour être
compilés et exécutés sur un grand nombre de machines et ils affichent
un rapport détaillé qui peut être transmis au groupe de travail.
Pour les compiler et les exécuter, voir les instructions dans le
fichier README
qui est joint. Voici des exemples
d'exécution du programme ip-header-set
qui teste
s'il peut demander avec succès les options :
% ./ip-header-set Testing of the abilities to set bits in the IP header My UID is 1000 The system is Linux 2.6.18-5-686, the machine is i686 TTL successfully set to 10 TOS successfully set to 8 ECN successfully set to 2 [PROBLEM] Cannot set the precedence to 160: (Operation not permitted) DF set through PMTU successfully set to 2 DF clear through PMTU successfully set to 0 Warning: we only tested that setsockopt was happy, not that the actual packet headers were changed
On voit que, sur Linux, on peut apparemment presque tout fixer à la valeur souhaitée, sauf la priorité qu'on ne peut pas augmenter (si on est root, ça marche). Sur un autre système, les succès et les échecs ne sont pas les mêmes :
Testing of the abilities to set bits in the IP header My UID is 54131 The system is FreeBSD 6.2-RELEASE, the machine is i386 TTL successfully set to 10 TOS successfully set to 8 ECN successfully set to 2 precedence successfully set to 160 No known way to set the DF bit on this system Warning: we only tested that setsockopt was happy, not that the actual packet headers were changed
Donc, la fonction de définition des options a marché. Mais le
paquet IP émis a t-il réellement changé ? Pour le savoir, nous
utilisons désormais deux programmes, sender
qui
va fixer les options et envoyer les paquets et
receiver qui va les
lire. sender
affiche à peu près la même chose que
ip-header-set
mais il envoie réellement le paquet
UDP :
% ./sender test.example.org 10000 Testing of the abilities to set bits in the IP header My UID is 1000 The system is Linux 2.6.18-5-686, the machine is i686 TTL successfully set to 10 TOS successfully set to 8 ECN successfully set to 2 [PROBLEM] Cannot set the precedence to 160: DF set through PMTU successfully set to 2 DF clear through PMTU successfully set to 0
et, sur la machine de réception (ici, identique) :
% ./receiver 10000 Testing of the abilities to read bits in the IP header My UID is 1000 The system is Linux 2.6.18-5-686, the machine is i686 Received 5 bytes The TTL is 10 The TOS/DSCP is 0 Received 5 bytes The TTL is 64 The TOS/DSCP is 8 Received 5 bytes The TTL is 64 The TOS/DSCP is 2 Received 5 bytes The TTL is 64 The TOS/DSCP is 0 Received 5 bytes The TTL is 64 The TOS/DSCP is 0 Received 5 bytes The TTL is 64 The TOS/DSCP is 0
On voit que l'API disponible sur Linux permet de lire les options, et qu'elles ont la bonne valeur. Si on n'a pas confiance, on peut vérifier avec un sniffer comme tcpdump :
09:44:00.127838 IP (tos 0x0, ttl 10, id 35166, offset 0, flags [DF], proto: UDP (17), length: 33) 192.0.2.69.47491 > 192.0.2.69.10000: UDP, length 5 09:44:00.127873 IP (tos 0x8, ttl 64, id 35166, offset 0, flags [DF], proto: UDP (17), length: 33) 192.0.2.69.47491 > 192.0.2.69.10000: UDP, length 5
Sur cette trace des deux premiers paquets, on voit le changement du TTL à 10, et on voit le TOS mis à 8.
Comment travaillent ces programmes ? Pour définir les options comme
le TOS/DSCP ou comme ECN, ils utilisent l'appel système
setsockopt
ainsi :
myecn = 0x02; /* ECN-capable transport */ result = setsockopt(mysocket, IPPROTO_IP, IP_TOS, myecn, sizeof(int));
On note que Posix appelle toujours TOS (cf. la constante
IP_TOS
) ce qui se nomme normalement DSCP depuis
le RFC 2474 il y a neuf ans. Ce n'est pas facile de faire
évoluer une API ! Cela explique un certain manque de rigueur dans mes
programmes, où TOS et DSCP sont utilisés simultanément.
Pour fixer le TTL, le principe est le même. Mais pour mettre le bit DF (Don't Fragment, voir les RFC 1191 et RFC 2923) à un, il faut le faire indirectement, en demandant d'activer ou non la découverte de la MTU du chemin (et cela ne marche que sur Linux) :
result = setsockopt(mysocket, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO, sizeof(int));
Et pour lire les options ? C'est nettement plus compliqué. Une méthode assez peu standard existe, qui dépend des messages de contrôle des prises (cf. cmsg) et de recvmsg :
const int One = 1; ... /* On demande à *recevoir* les messages de contrôle avec le TTL */ result = setsockopt(mysocket, IPPROTO_IP, IP_RECVTTL, &One, sizeof(One)); ... /* Et, pour chaque paquet reçu */ memset(message, 0, sizeof(*message)); message->msg_iov = malloc(sizeof(struct iovec)); /* Les données seront mises dans "buffer" */ message->msg_iov->iov_base = buffer; message->msg_iov->iov_len = length; message->msg_iovlen = 1; /* Et les messages de contrôle dans "control_buffer" */ message->msg_control = control_buffer; message->msg_controllen = control_length; result = recvmsg(mysocket, message, 0); if (result <= 0) { err_ret("[PROBLEM] Cannot receive data (%s)", sys_err_str()); } else { fprintf(stdout, "Received %i bytes\n", result); for (c_msg = CMSG_FIRSTHDR(message); c_msg; c_msg = (CMSG_NXTHDR(message, c_msg))) { if (c_msg->cmsg_level == IPPROTO_IP && c_msg->cmsg_type == IP_TTL) { fprintf(stdout, "\tThe TTL is %i\n", *(int *) CMSG_DATA(c_msg));
Merci au regretté W. Richard Stevens pour son excellent livre sur la programmation réseau sur Unix.
Date de publication du RFC : Février 2008
Auteur(s) du RFC : P. Chimento (JHU Applied Physics Lab), J. Ishac (NASA)
Pour information
Réalisé dans le cadre du groupe de travail IETF ippm
Première rédaction de cet article le 12 février 2008
Ce RFC définit un concept important en matière de métrologie du réseau, le concept de capacité qui remplace celui, ambigu, de bande passante.
Le groupe de travail IP Performance Metrics de l'IETF continue à ajouter au savoir commun d'intéressants RFC normalisant notamment les concepts utilisés, afin que des comparaisons puissent être faites entre les mesures effectuées par des équipes différentes. Ce RFC s'attaque au concept de capacité (capacity), qui a vocation à remplacer celui, flou et peu exact, de bande passante.
Une des raisons du flou est la volontée délibérée par certains acteurs de présenter des chiffres plus favorables. On voit ainsi souvent, sur le marché de l'accès Internet par ADSL des chiffres donnés en débit de la couche physique, pas en débit des couches plus hautes, pourtant les seules qui intéressent les utilisateurs. Le concept de bande passante avait aussi d'autres défauts, comme son origine dans le monde de l'analogique qui faisait que, même utilisé correctement, son étymologie était source de confusion. Ainsi, la section 3.4 donne l'exemple d'un lien 802.11b où l'électronicien annoncera une « bande passante » de 25 Mhz, l'ingénieur réseaux une « bande passante » de 11 Mbps, alors que l'utilisateur final ne pourra pas obtenir plus de 8 Mbps de débit.
La section 1 de notre RFC donne d'autres exemples des différences de capacité selon les couches. Par exemple, le codage Manchester de l'Ethernet classique fait perdre une bonne partie de la capacité théorique. Tout mécanisme de somme de contrôle consomme également des bits qui sont perdus pour les couches hautes. Les mécanismes d'accès au réseau peuvent encore réduire la capacité théorique. C'est ainsi que le CSMA/CD de l'Ethernet classique ne permet pas d'utiliser toute la capacité théorique. Des chiffres de 35 % d'utilisation maximale de l'Ethernet avaient circulé à une époque mais ils ne reposaient, ni sur un calcul théorique, ni sur des expériences ; et ils étaient totalement faux. Ceci dit, on ne peut pas atteindre les 100 %.
Bref, la capacité ne peut être sérieusement définie que pour une couche donnée.
La section 2 s'attaque aux définitions proprement dites. Reprenant les notions de lien et de chemin du RFC 2330, ainsi que la notion de « paquets de type P » (paquets d'un type donné, pour tenir compte du fait que le débit mesuré peut dépendre du type de paquets, TCP plutôt que UDP, par exemple) notre RFC définit :
La section 3 est ensuite consacrée à discuter de cette terminologie et des difficultés de mesure. C'est là par exemple qu'est traité le cas de la compression (par exemple avec ROHC, RFC 3095) ou bien le rapport entre la capacité et les grandeurs définies par le RFC 3148 (ce dernier RFC traite de la capacité utile, c'est-à-dire des données effectivement transmises par le protocole de transport).
Date de publication du RFC : Novembre 1996
Auteur(s) du RFC : Kim Hubbard (InterNIC Registration Services), Mark Kosters (InterNIC Registration Services), David Conrad (Asia Pacific Network Information Center), Daniel Karrenberg (RIPE NCC), Jon Postel (USC/Information Sciences Institute)
Première rédaction de cet article le 10 février 2008
Les règles d'affectation des adresses IP sont un des sujets chauds (ou qui devraient l'être) de la gouvernance de l'Internet. Comme toute ressource critique et limitée, sa gestion fait l'objet d'âpres débats. Ce RFC est le seul qui parle de cette gestion, domaine réservé des RIR. (Il a depuis été remplacé par le RFC 7020.)
Ce n'est pas l'IETF mais le groupe des
RIR existants à l'époque qui a écrit ce RFC. Une
note de l'IESG en tête précise d'ailleurs que
ce RFC documente une politique, sans forcément l'approuver. En effet,
les politiques d'attribution des adresses IP sont actuellement
entièrement gérées au sein des RIR, même si des organismes comme
l'ICANN ou, plus récemment,
l'ITU ont parfois essayé de s'en mêler. Mais
pourquoi des décisions aussi techniques que l'attribution des adresses
du bloc 192.0.2.0/24
devraient-elles poser des
problèmes politiques ?
Il y a deux problèmes avec ces adresses : l'un est la taille limitée du registre. Si un protocole prévoit huit bits pour un champ indiquant une option, cela ne laisse que 256 valeurs possibles et l'organisme qui gère ces valeurs (l'IANA pour les protocoles Internet) doit les attribuer avec prudence, pour ne pas épuiser trop tôt la ressource. Or, les adresses IPv4 étant sur 32 bits (quatre milliards de valeurs), on ne peut pas en affecter une à chaque habitant de la planète. En pratique, il y a même moins de quatre milliards d'adresses possibles, en raison du facteur H (expliqué en RFC 1715 et RFC 3194). IPv6 résout complètement ce problème, avec ses adresses sur 128 bits.
Mais il existe aussi un autre problème : les préfixes d'adresses IP sont manipulés par les routeurs, échangés avec le protocole BGP (RFC 4271) et stockés dans les tables de routage desdits routeurs. Il existe des limites, aussi bien à la taille de ces tables (les routeurs de haut de gamme n'utilisent typiquement pas de la mémoire standard mais des ASIC spécialisés, très rapides mais plus limités en taille), qu'à la quantité de données échangées en BGP si les tables grossissent « trop ». La controverse technique fait rage entre certains gros opérateurs acharnés à limiter la taille des tables de routage et certains utilisateurs qui pensent que les limites ne sont pas purement techniques et que le désir de limiter la concurrence entre opérateurs joue également un rôle (voir par exemple le RFC 4984 pour une passionnante discussion sur le sujet).
Cela explique que gérer des adresses IP ne soit pas une tâche purement administrative d'enregistrement. Les RIR, émanation des opérateurs Internet, ont donc des politiques d'allocation, qui sont en IPv4 très restrictives, et qui le deviendront encore plus au fur et à mesure que la pénurie s'aggrave.
Ce RFC, qui succède au RFC 1466, décrit ces politiques, dans leurs grands principes (les politiques précises sont décrites sur le site Web de chaque RIR, elles changent assez souvent). Sa section 1 pose les buts, qui découlent des problèmes décrits plus haut :
La même section 1 présente les différents acteurs, de l'IANA (fonction actuellement assurée par l'ICANN), qui alloue des adresses aux RIR, jusqu'aux LIR (en général des FAI) qui les reçoivent des RIR.
Notons que l'IANA n'a traditionnellement jamais mis de critères à la distribution d'adresses IP aux RIR. Malgré la très théorique section 6, qui donne aux utilisateurs le droit de faire appel des décisions auprès de l'IANA, le pouvoir reste concentré aux mains des RIR.
La section 2 décrit le mécanisme de distribution des adresses. Celles-ci sont allouées aux LIR par les RIR, en larges blocs, puis affectées aux clients finaux par les LIR, en blocs plus petits. Normalement, l'affectation, contrairement à l'allocation, est réversible : le client final n'est pas propriétaire de ses adresses (on parle d'adresses PA pour Provider-Aggregatable, les autres sont PI, Provider-Independent, et attribuées directement par le RIR).
Pour satisfaire les buts énumérés dans la section 1, le RFC énonce des règles comme le principe que les adresses soient prêtées et pas données. Il comporte aussi des micro-règles comme de spécifier que les clients finaux ne devraient pas avoir d'adresses IP statiques !
La section 2.2 est consacrée à l'enregistrement et insiste sur l'importance que les informations soient correctes et à jour. Comme pour les registres de noms de domaine, il s'agit d'un vœu pieux et les serveurs whois des RIR distribuent quotidiennement des informations dépassées, voire fausses.
La section 3 est plus spécifiquement consacrée à l'affectation,
c'est à dire à la distribution des adresses des LIR vers les clients
finaux. C'est elle qui explique les règles devant lesquelles va
plancher l'utilisateur, comme « 25 % des adresses affectées doivent
être pour un usage immédiat » ou comme la nécessité de fournir un plan
d'adressage (section 3.2) comme le fameux ripe-141
(aujourd'hui 381 mais souvent connu sous son ancien numéro).
Notez que, contrairement à ce que prétend la section 4.4, où le RIR s'autorise à enquêter sur l'utilisation effective des adresses, il n'y a jamais de contrôle et bien des organisations ont obtenu des quantités importantes d'adresses IP avec des plans mirobolants d'accès Internet par ADSL pas cher avec des dizaines de milliers d'abonnés en quelques semaines. Les règles des RIR favorisent donc ceux qui savent bluffer avec talent.
Le RFC 2050 n'a jamais été mis à jour. Pour voir les politiques d'allocation actuelles des RIR, il faut consulter leurs sites Web :
On peut comparer facilement les différentes politiques en http://www.nro.net/documents/nro46.html
.
Lors de forums de discussion sur la gouvernance de l'Internet, relativement peu de discussions ont eu lieu sur l'allocation d'adresses IP, si on compare avec la gestion de la racine du DNS. Parce que les RIR, plus anciens et beaucoup plus efficaces, ont une meilleure légitimité que l'ICANN ? Parce que les RIR ont réussi à convaincre les participants à ces forums de regarder ailleurs ? Parce que la question est trop technique pour les politiciens et les avocats qui remplissent ces forums ? En tout cas, aujourd'hui où l'épuisement rapide des adresses IPv4 pose de manière encore plus aigüe l'allocation des adresses restantes, on peut s'inquiéter de ce qui va se produire dans les prochaines années. Certains proposent déjà ouvertement un marché des adresses IP, permettant aux pays du Nord, qui ont obtenu le plus d'adresses au début de l'Internet, de les vendre. C'est officiellement interdit par les RIR, mais cette interdiction tiendra t-elle face aux forces du marché ?
Première rédaction de cet article le 7 février 2008
Dernière mise à jour le 13 février 2008
Les auteurs de l'ouvrage de référence sur les calendriers, Calendrical Calculations recommandent à ceux qui veulent vraiment comprendre les calculs calendaires de les programmer eux-mêmes. Et ils ajoutent qu'il est préférable de ne pas regarder le code source qu'ils fournissent, pour suivre réellement l'algorithme. C'est ce que j'ai fait ici.
Calendrical Calculations décrit les algorithmes en langage mathématique, joliment mis en page, et qui se prête bien à une implémentation dans un langage fonctionnel. Les auteurs avaient choisi Common Lisp, j'ai refait une petite partie de leur travail (uniquement les calendriers arithmétiques, les astronomiques sont bien plus complexes) en Haskell. La plupart des formules mathématiques du livre se traduisent directement en Haskell, ce qui facilite leur vérification. Par exemple, la définition d'une année bissextile dans le calendrier grégorien se dit simplement :
gregorianLeapYear y = (y `mod` 4) == 0 && ((y `mod` 100) /= 0 || y `mod` 400 == 0)
ce qui est, à quelques détails de syntaxe près, la définition donnée dans le livre.
Haskell dispose de grands entiers, Integer
, dépassant les limites des
entiers de la machine (Int
en Haskell), ce qui est pratique pour certains calculs (les
calculs astronomiques dépassent facilement les capacités d'une machine
de 32 bits). On définit donc :
type Fixed = Integer
Les structures de données (par exemple, une date est composée d'une année, d'un mois et d'un jour) se fait avec les constructeurs de tuples de Haskell. Par exemple, une date du compte long maya se définit avec :
data MayanLongCount = MayanLongCountData {baktun::Fixed, katun::Fixed, tun::Fixed, uinal::Fixed, kin::Fixed} deriving (Eq, Show)
qui se lit ainsi : une date est composée d'un baktun, d'un katun, d'un tun, d'un uinal, et d'un kin. Tous sont de type
Fixed
. Ce type MayanLongCount
dérive des classes de type
Eq
et Show
ce qui lui assure
automatiquement une fonction d'égalité (utile pour les tests
automatiques) et un affichage sommaire, notamment dans
l'interpréteur. Si on ne veut pas de cet affichage par défaut, on omet
Show
et on crée sa propre instance. Ici, pour le
calendrier grégorien, on choisit l'affichage à la syntaxe
ISO 8601 (le code présenté ici est une version
simplifiée ; ISO 8601 imposant une taille fixe aux champs comme le
mois, qui doit tenir sur deux caractères, le code réel - voir le lien
à la fin pour le télécharger - est plus complexe) :
data Gregorian = GregorianData {gregorian'year::Fixed, gregorian'month::Fixed, gregorian'day::Fixed} deriving (Eq) -- We do not derive Show because ours is better (ISO 8601 look) instance Show Gregorian where show = \g -> show (gregorian'year g) ++ "-" ++ show (gregorian'month g) ++ "-" ++ show (gregorian'day g)
L'utilisation de la construction let
qui
permet de définir des variables, nous autorise à coller d'encore plus
près aux définitions du livre. Ainsi, la fonction du
calendrier révolutionnaire français modifié,
modifiedFrenchRevFromFixed
est presque
entièrement composée de let
, le corps de la
fonction appelant juste un constructeur (la dernière ligne) :
modifiedFrenchRevFromFixed f = let approx = floor (fromIntegral (f - frenchRevEpoch + 2) / (1460969 / 4000)) + 1 in let year = if f < fixedFromModifiedFrenchRev (FrenchRevolutionaryData approx 1 1) then approx - 1 else approx in let month = floor (fromIntegral (f - fixedFromModifiedFrenchRev (FrenchRevolutionaryData year 1 1)) / 30) + 1 in let day = f - fixedFromModifiedFrenchRev (FrenchRevolutionaryData year month 1) + 1 in FrenchRevolutionaryData year month day
(floor
est la fonction pré-définie en
Haskell pour calculer une partie entière.)
L'un des points sur lequel Haskell est plus contraignant que Common
Lisp est la différence de type entre entiers et
réels, qui nous oblige à des conversions
explicites avec la fonction pré-définie fromIntegral
.
Testons maintenant ces fonctions avec l'environnement interactif ghci. Mettons qu'on veuille traduire le 7 novembre 1917 du calendrier grégorien en « date fixe » :
% ghci Gregorian ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6.1, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done. Ok, modules loaded: Calendar.Global, Calendar.Gregorian. Prelude Calendar.Gregorian> fixedFromGregorian (GregorianData 1917 11 7) 700115
On charge le module correspondant au calendrier julien et on convertit la date ci-dessus vers ce calendrier :
Prelude Calendar.Gregorian> :load Julian Ok, modules loaded: Calendar.Global, Calendar.Gregorian, Calendar.Julian. Prelude Calendar.Julian> julianFromFixed 700115 1917-10-25
Donc, le 7 novembre 1917 est le 25 octobre et voilà pourquoi la révolution d'Octobre a eu lieu en novembre... (La Russie tsariste n'avait pas adopté le calendrier grégorien.)
Le fait que Haskell soit un langage statiquement typé (mais où la
déclaration de types est facultative grâce à l'inférence) protège contre les
mauvaises utilisations de ces fonctions. Si j'essayais la fonction
mayanLongCountFromFixed
, qui prend normalement un
Fixed
en paramètre, sur une chaîne de caractères, Haskell le refuserait :
*Calendar.Mayan> mayanLongCountFromFixed "3 may 1998" <interactive>:1:24: Couldn't match expected type `Fixed' against inferred type `[Char]'
On peut demander à ghci le type qu'il a inféré :
*Calendar.Mayan> :t mayanLongCountFromFixed mayanLongCountFromFixed :: Fixed -> MayanLongCount
On le voit dans les exemples précédents, la faute de frappe est vite arrivée et les erreurs sont fréquentes dans les logiciels de calcul calendaires. D'où la nécessité de disposer de jeux de tests. J'en ai fait deux sortes, des tests avec des données connues et des tests aléatoires. Les tests avec des données connues reposent sur un système d'assertions et la bibliothèque HUnit. Des exemples d'assertions sont :
testsIslamic = TestList [ TestCase (assertBool "Today" (fixedFromIslamic (IslamicData 1429 1 21) == 733071)), TestCase (assertBool "Go to Medina" (islamicFromFixed islamicEpoch == IslamicData 1 1 1)), TestCase (assertBool "One day offset" (fixedFromIslamic (IslamicData 1613 11 26) - fixedFromIslamic (IslamicData 1613 11 25) == 1)), TestCase (assertBool "One day offset over a month" (fixedFromIslamic (IslamicData 2453 8 1) - fixedFromIslamic (IslamicData 2453 7 30) == 1)), TestCase (assertBool "One day offset over a year" -- 4532 is leap year (fixedFromIslamic (IslamicData 4533 1 1) - fixedFromIslamic (IslamicData 4532 12 30) == 1)), TestCase (assertBool "Non leap year 1429" (fixedFromIslamic (IslamicData 1430 1 1) - fixedFromIslamic (IslamicData 1429 12 29) == 1)) ]
(Le point de départ du calendrier musulman, l'epoch, est le départ de Mahomet pour Médine.) L'une des difficultés des tests à assertion est qu'il faut trouver des données fiables. On l'a vu, s'il existe plein de logiciels de calculs calendaires, beaucoup contiennent des bogues et il pourrait être imprudent de bâtir ses tests sur eux. J'ai surtout utilisé les tables données dans Calendrical calculations, annexe C, ce qui est insuffisant, rien ne dit que ces tables n'ont pas elles-mêmes des erreurs.
Un autre mécanisme de tests consiste à tester des propriétés des fonctions et non plus de données particulières. Pour vérifier ces propriétés, la bibliothèque Quickcheck va les vérifier sur un grand nombre de données aléatoires. Par exemple, une propriété évidente est la possibilité d'un aller-retour avec la « date fixe » :
prop_mayanLongCountRoundtrip = forAll generateFixed $ \f -> let m = mayanLongCountFromFixed f in ((fixedFromMayanLongCount . mayanLongCountFromFixed) f == f && (mayanLongCountFromFixed . fixedFromMayanLongCount) m == m)
Par défaut, les données générées par Quickcheck sont trop proches de
zéro pour nos besoins (les bogues ne se manifestent souvent que pour
les valeurs éloignées de l'origine du calendrier). On crée donc un
générateur à nous,
generateFixed
, défini avec les
combinateurs de QuickCheck :
generateFixed = do i <- frequency [ (5, choose(10000,1000000)), (3, choose(-1000000,-10000)), (2, choose(-1000,1000)) ] return i
Ce système a ses propres faiblesses puisque les différentes fonctions dépendent les unes des autres, empêchant ainsi de détecter certaines erreurs (le résultat sera cohérent même si la fonction est fausse).
Il vaut donc mieux ajouter d'autres propriétés. Une que j'ai trouvé utile est de vérifier que le jour suivant a incrémenté le jour ou le mois (et dans ce cas que le jour est le premier du mois). Pour le calendrier grégorien, cela s'écrit :
prop_gregorianNextDay = forAll generateFixed $ \f -> let nextFixed = f + 1 in let gday = gregorianFromFixed f in let nextGday = gregorianFromFixed nextFixed in ( ( -- Same month (gregorian'year gday == gregorian'year nextGday) && (gregorian'month gday == gregorian'month nextGday) && (gregorian'day gday + 1 == gregorian'day nextGday) ) || ( -- Next month (gregorian'year gday == gregorian'year nextGday) && (gregorian'month gday +1 == gregorian'month nextGday) && (gregorian'day nextGday == 1) ) || ( -- Next year (gregorian'year gday + 1 == gregorian'year nextGday) && (gregorian'month nextGday == 1) && (gregorian'day nextGday == 1) ))
Une telle propriété attrape beaucoup d'erreurs. Ainsi, l'erreur du livre, enregistrée sous le numéro 331 dans l'erratum de l'édition 2000 de Calendrical Calculations, et qui affecte le calendrier républicain en faisant sauter certains premiers Vendémiaire (on passe directement du dernier jour complémentaire au deux Vendémiaire) est vite détectée et Quickcheck nous dit pour quelle valeur une propriété est fausse (ici, le 810373, donc le jour qui devrait être le premier Vendémiaire 428) :
... French revolutionary roundtrip: OK, passed 1000 tests. French revolutionary next day: Falsifiable, after 199 tests: 810373
Pour réaliser des fonctions de conversion aisément, on passe par un pivot. En effet, si on a N calendriers, écrire N-au-carré fonctions de conversion serait trop lourd. On écrit donc, pour chaque calendrier deux fonctions de et vers les dates fixes. Par exemple, pour le calendrier égyptien, on a :
fixedFromEgyptian :: Egyptian -> Fixed egyptianFromFixed :: Fixed -> Egyptian
Désormais, pour convertir de n'importe quel calendrier vers n'importe quel autre, il suffit de passer par la date fixe, qui sert de pivot (ce qu'on avait déjà fait pour la conversion grégorien -> julien plus haut). Ainsi, si je veux convertir du calendrier musulman vers le républicain, j'écris :
islamic2republican = modifiedFrenchRevFromFixed . fixedFromIslamic
(".
" étant l'opérateur de
composition de fonctions). Cette fonction peut
s'utiliser ainsi :
*Calendar.Utils> Calendar.FrenchRevolutionary.prettyShow (islamic2republican (IslamicData 1288 1 6)) "7 Germinal 79"
(Le 7 germinal 79 étant la date du rétablissement du calendrier républicain par la Commune de Paris.)
Une fois muni de toutes les fonctions de conversion, on peut les
utiliser dans un programme principal qui affichera la date du
jour. Pour lire l'horloge, on utilisera la fonction
System.Time.getClockTime
qui, comme elle réalise
une entrée/sortie, est dans la monade
IO
:
getToday = do (TOD seconds _) <- getClockTime return (floor(fromIntegral seconds/86400) + systemTimeEpoch) main = do today <- getToday let todayIslamic = islamicFromFixed today let todayGregorian = gregorianFromFixed today ... putStrLn "Today is... " putStrLn ("Fixed: " ++ (show today)) putStrLn ("Gregorian: " ++ Calendar.Gregorian.prettyShow todayGregorian ++ " (" ++ show todayGregorian ++ ")") ...
Le résultat est montré ici, pour aujourd'hui :
% ./today Today is... Fixed: 733079 Egyptian: EgyptianData {egyptian'year = 2756, egyptian'month = 10, egyptian'day = 22} Gregorian: 7 February 2008 (2008-2-7) Julian: 2008-1-25 Islamic: Muharram 29, 1429 (1429-1-29) Mayan (long count): 12.19.15.1.1 French revolutionary: 19 Pluviôse 216
Le même opérateur de composition de fonctions peut nous permettre de construire d'innombrables fonctions utiles. Supposons qu'on veuille une fonction pour connaitre le jour suivant du calendrier grégorien. Il suffit de composer les fonctions « conversion en fixe », « incrémentation de 1 » et « conversion en grégorien » :
*Calendar.Gregorian> let nextDay = gregorianFromFixed . (+1) . fixedFromGregorian *Calendar.Gregorian> :t nextDay nextDay :: Gregorian -> Gregorian *Calendar.Gregorian> nextDay (GregorianData 2008 2 11) 2008-2-12 *Calendar.Gregorian> nextDay (GregorianData 1999 12 31) 2000-1-1 *Calendar.Gregorian> nextDay (GregorianData 2000 2 28) 2000-2-29 *Calendar.Gregorian> nextDay (GregorianData 2000 2 29) 2000-3-1
Pour donner une petit idée de la mise en œuvre originale, voici la même fonction de conversion d'une « date fixe » vers le calendrier républicain en Common Lisp :
(defun modified-french-from-fixed (date) ;; TYPE fixed-date -> french-date ;; French Revolutionary date (year month day) of fixed ;; $date$. (let* ((approx ; Approximate year (may be off by 1). (1+ (quotient (- date french-epoch -2) 1460969/4000))) (year (if (< date (fixed-from-modified-french (french-date approx 1 1))) (1- approx) approx)) (month ; Calculate the month by division. (1+ (quotient (- date (fixed-from-modified-french (french-date year 1 1))) 30))) (day ; Calculate the day by subtraction. (1+ (- date (fixed-from-modified-french (french-date year month 1)))))) (french-date year month day)))
Vous pouvez télécharger le code de ces programmes en Calendar.tar.gz
.
Auteur(s) du livre : Edward Reingold, Nachum Dershowitz
Éditeur : Cambridge University Press
0-521-77752-6
Publié en 2000
Première rédaction de cet article le 6 février 2008
Le moindre téléphone portable, aujourd'hui, beaucoup de sites Web (réservations de train ou d'avion), de nombreux autres logiciels, disposent de fonctions de calendrier. Les nombreuses bogues constatées dans ces logiciels montrent que des questions aussi simples que « Le 1er mars 2000 est-il un mardi ou un mercredi ? » ne sont pas si triviales qu'elle en ont l'air. Ce livre est l'ouvrage de référence sur les calculs calendaires, pour de nombreux calendriers existants ou disparus, avec tous les détails nécessaires pour programmer soi-même ces calculs.
Les auteurs sont deux experts, Nachum Dershowitz a écrit de nombreux articles sur le sujet et Edward Reingold est le mainteneur du paquetage calendar d'Emacs. L'ampleur de l'érudition nécessaire pour couvrir, non seulement le traditionnel calendrier grégorien mais aussi les calendriers chinois, hindou, musulman, maya et bien d'autres, est impressionnante. Les amateurs d'anecdotes seront ravis. Par exemple, ils apprendront que les chinois incrémentent l'âge des enfants, non pas à leur anniversaire, mais au nouvel an. De plus, un enfant a un an à sa naissance. S'il nait la veille du nouvel an chinois, il aura deux ans au bout de quelques jours de vie. Autre exemple amusant, dans le calendrier maya Tzolkin, les numéros des jours et ceux des « mois » varient ensemble, mais sur des cycles de taille différentes. Ainsi, le 1 Imix est suivi du 2 Ik, lui-même suivi du 3 Akbal, etc jusqu'au 13 Ben (le cycle des jours a une longueur 13) qui est suivi du 1 Ix...
Mais la variété des calendriers permet aussi de philosopher sur le nombre de solutions possibles à un problème donné. Vivant sur la même Terre, avec les mêmes alternances de jour et de nuit et le même parcours du Soleil et de la Lune, les différentes civilisations ont développé des calendriers très différents. Il y en a deux grandes familles : les calendriers arithmétiques et les calendriers astronomiques. Les premiers obéissent à des règles arithmétiques simples (les seules opérations nécessaires pour les mettre en œuvre sont les quatre opérations de base, plus la fonction partie entière) et sont donc les plus simples à programmer. Mais, ignorant des cycles astronomiques et utilisant leurs propres cycles, incommensurables avec ceux des astres, il sont voués à un décalage grandissant avec le temps. C'est ainsi que notre calendrier grégorien, archétype des calendriers arithmétiques, a remplacé le calendrier julien, devenu trop décalé. Et il devra à son tour être réformé ou remplacé.
Les européens ne sont pas les seuls à avoir conçu un calendrier arithmétiques. Les Mayas ou les musulmans l'ont également fait. Mais d'autres peuples ont choisi une voie différente, notamment les chinois avec un calendrier astronomique, c'est-à-dire où le passage d'une période à une autre (par exemple d'un mois au suivant) dépend d'un événement astronomique (la nouvelle Lune dans le cas chinois). Ainsi, le calendrier est toujours synchronisé avec les astres. En revanche, si on veut calculer des dates futures, pour lesquelles il n'est pas encore possible de faire des observations astronomiques, les calculs sont nettement plus compliqués (rien n'est simple en astronomie, même la durée du jour diminue avec le temps). (Les hindous ont également un calendrier astronomique.)
Il existe aussi des calendriers qui ont emprunté aux deux systèmes. Par exemple, le calendrier civil musulman est arithmétique, mais les dates des événements importants comme le début du Ramadan dépendent de phénomènes astronomiques. Les chrétiens ont un système similaire pour déterminer Pâques (mais pas Noël, qui survient à date fixe). De même, le calendrier révolutionnaire français est astronomique : la méthode pour déterminer les années bissextiles ne dépend pas d'un algorithme mais d'observations. On ne peut donc pas prévoir facilement si une année future sera bissextile ou pas. Une réforme tardive de ce calendrier introduisait un mécanisme algorithmique et le transformait donc en calendrier arithmétique (mais elle n'a pas eu le temps d'être déployée avant le coup d'État de Bonaparte).
Comme tous les bons geeks, les auteurs ont inventé leur propre calendrier, le « date fixe » (Rata Die), qui compte le nombre de jours depuis le début de l'ère commune. La préface nous apprend ainsi que le livre a été terminé le 730 120 en « date fixe ».
Les auteurs ne perdent pas de vue les implémentations pratiques. Leurs algorithmes sont décrits en langage mathématique, sous une forme qui permet une programmation assez directe dans un langage de programmation fonctionnel. C'est ce que j'ai fait pour une partie des calendriers, en Haskell. (La composition du livre, elle, a dû exiger une bonne compétence en LaTeX.) On notera que le livre est accompagné d'un CD d'une implémentation complète en Common Lisp (attention, elle n'est pas du tout sous une licence libre).
On notera que les erreurs dans la seconde édition, publiée en 2000, sont nombreuses et l'erratum, publié sur leur site, est un impressionnant document. (Une troisième édition a été publiée fin 2007 mais je ne l'ai pas lue, merci à Damien Wyart pour son information.)
Cet article a été terminé le 6 février 2008 du calendrier grégorien, le 733 078 en « date fixe », le 18 pluviôse an 216 de la Révolution française, le 28 Muharram 1429 du calendrier musulman, le 12.19.15.1.0 du long compte maya et le 78-24-12-30 du calendrier chinois.
Auteur(s) du livre : W. Richard Stevens
Éditeur : Prentice-Hall
0-13-490012-X
Publié en 1998
Première rédaction de cet article le 5 février 2008
Dernière mise à jour le 6 février 2008
Ce livre est la référence absolue pour la programmation réseau en C sur Unix. Trés détaillé, très concret, avec énormément de code source, il a formé beaucoup de programmeurs réseaux. (Il s'agit du volume 1, le volume 2 étant consacré à la communication entre processus.)
Hélas, il n'y aura plus de livre écrit par W. Richard Stevens, il est décédé en 1999. Mais ses épais ouvrages ont formé des milliers de programmeurs et d'administrateurs réseaux. La seconde édition d'Unix network programming, volume 1, ajoutait notamment la description détaillée de la programmation IPv6, Stevens étant un des auteurs de l'API (RFC 3493). (Le livre a été repris par deux autres auteurs, qui ont publié une troisième édition, que je n'ai pas lue, merci à Damien Wyart pour l'information.)
Unix network programming couvre en près de mille pages l'interface des prises, l'écriture de clients et de serveurs, l'utilisation intelligente d'UDP et de TCP, et d'innombrables services plus avancés comme l'utilisation des options IP. Rien à voir avec le cours de réseau universitaire classique, avec son obligatoire modèle en couches. Ici, tous les programmes ont été testés et le code source est distribué (voir adresse plus haut).
Sans doute la plupart des programmeurs n'ont pas besoin d'autant d'informations, il est même peut-être préférable qu'ils programment à niveau plus élevé. Mais celui ou celle qui veut approfondir tous les mystères de la programmation réseau aura toujours intérêt à se plonger dans ce livre.
Première rédaction de cet article le 3 février 2008
Rapportée par ma fille de l'école, une jolie poésie de Jean Rousselot sur l'ordinateur et l'éléphant, animal réputé pour sa mémoire (ce qui lui a valu de devenir le logo de PostgreSQL).
On peut la trouver en ligne sur le site de l'école publique de Saint Paul de Varces. C'est rare, les poésies pour enfants où on parle d'ordinateur...
Date de publication du RFC : Avril 2007
Auteur(s) du RFC : J. Salowey, R. Droms
Chemin des normes
Première rédaction de cet article le 3 février 2008
Une des grandes forces du protocole Radius est la possibilité d'ajouter de nouveaux attributs, par exemple pour spécifier des paramètres supplémentaires à une session. C'est ainsi que ce RFC normalise l'attribut qui permet de déléguer un préfixe IPv6 entier, pas une seule adresse.
Avec IPv4, l'utilisateur typique n'a qu'une
adresse IP en tout et pour tout et l'attribut traditionnel de
Radius (RFC 2865),
Framed-IP-address
, suffit largement. Mais avec
IPv6, comme recommandé dans le RFC 6177, l'utilisateur, même simple particulier, peut avoir un
préfixe (de longueur 48, disait le RFC 3177, même si tous les FAI n'en donnent
pas autant, entre 48 et 64 pour le RFC 6177). Lorsqu'un utilisateur se connecte au
NAS, il faut donc trouver un moyen pour le
serveur Radius qu'interroge ce NAS de transmettre le préfixe et sa
longueur.
Rien d'extraordinaire et ce RFC est très court : il définit
(section 3)
l'attribut Delegated-IPv6-Prefix
qui contient le
préfixe et sa longueur. Cet attribut apparait typiquement dans les
réponses mais il peut aussi être présent dans la question, pour
indiquer une préférence de l'utilisateur. Une fois reçu par le NAS, il
peut être
transmis à l'utilisateur, par exemple en DHCP
(RFC 3633) puis être ensuite être diffusé sur le
réseau local dudit utilisateur, par exemple avec les annonces
RA du RFC 4862.
On note que cet attribut peut aussi être utilisé pour le concurrent de Radius, Diameter (RFC 6733), la section 5 expliquant comment.
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : B. Claise (Cisco)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF ipfix
Première rédaction de cet article le 1 février 2008
Le système IPFIX, successeur de Netflow est désormais normalisé. Des routeurs de différentes marques peuvent donc désormais envoyer des informations statistiques à des machines d'administration de différentes origines.
Un cahier des charges pour IPFIX avait été spécifié dans le RFC 3917. Le système lui-même est désormais normalisé, ce RFC prenant en charge le protocole d'autres RFC s'occupant du modèle d'informations ou bien de l'architecture des différents composants d'IPFIX. Une nouvelle série de RFC IPFIX est sortie en septembre 2013 donc ce RFC n'a plus qu'un intérêt historique, il faut désormais consulter le RFC 7011.
Notre RFC normalise donc le format des paquets (section 3). Comme avec d'autres protocoles, les paquets commencent par un numéro de version, 10 ici, IPFIX marquant sa descendance depuis Netflow, dont la dernière version était la 9. Le RFC décrit aussi l'encodage des données exportées par l'observateur IPFIX (section 6).
Enfin, notre RFC décrit le mécanisme de transport, au dessus d'UDP, le protocole traditionnel de Netflow, mais aussi de TCP ou bien du protocole recommandé, SCTP. Pour répondre au cahier des charges, qui insistait sur la sécurité, la section 10.4 décrit aussi l'utilisation de TLS.
IPFIX est déjà mis en œuvre dans plusieurs systèmes et l'annonce de l'IESG approuvant le RFC précise que deux tests d'interopérabilité ont eu lieu, avec cinq logiciels différents, et que tout marchait bien. Un exemple de mise en œuvre en logiciel libre est Maji. Toutefois, mi-2012, des années après la sortie du RFC, il semble que peu de routeurs soient capables de faire de l'IPFIX (v10). La plupart sont restés bloqués sur Netflow (v9).
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : D. Crocker (Brandenburg InternetWorking), P. Overell (THUS plc.)
Chemin des normes
Première rédaction de cet article le 1 février 2008
Ce RFC fait partie des RFC ancillaires, qui ne spécifient pas directement un protocole IETF mais fournissent des outils pour les "vrais" RFC. En l'occurrence, il normalise le mini-language pour écrire des grammaires.
Beaucoup de RFC doivent spécifier un langage, en général assez simple (jamais de la taille d'un langage de programmation) mais néanmoins suffisamment important pour que les descriptions informelles du langage soient risquées. Depuis longtemps, on utilise en informatique des notations dérivées du langage BNF pour spécifier formellement un langage. Le problème est qu'il existe plusieurs dialectes de BNF (comme EBNF) et que les RFC ont besoin d'une référence stable. À une époque, chaque RFC définissait approximativement sa grammaire formelle et l'utilisait ensuite. ABNF est issue d'un effort de Dave Crocker de regroupement de la définition de la grammaire en un seul RFC, le RFC 2234 en 1997, devenu ensuite le RFC 4234 en 2006. Notre RFC succède au fameux RFC 4234 (avec très peu de changements, le principal étant le passage au statut de norme IETF à part entière, Full Standard) et qui décrit ABNF, le dialecte IETF de BNF. Classique sur beaucoup de points, ce dialecte a quand même quelques variations, issues d'une histoire très ancienne. Par exemple, le signe | pour le choix est remplacé par /.
Quelques outils sont disponibles pour aider les auteurs de grammaires (la page oublie de mentionner Dapar). Mais je trouve que c'est encore insuffisant. S'il existe deux vérificateurs (qui peuvent tester qu'une grammaire est cohérente), il n'existe guère de générateurs d'analyseurs syntaxiques. En revanche, à des fins de test, il existe au moins deux programmes, Eustathius et abnfgen, qui génèrent automatiquement des exemples à partir d'une grammaire. Vous trouverez de nombreux exemples de grammaires ABNF dans les sources d'Eustathius.
Notre RFC normalise non seulement le format des grammaires mais aussi une bibliothèque de productions prêtes à l'emploi comme HEXDIG pour les caractères utilisables pour écrire de l'hexadécimal ou ALPHA pour les lettres de l'alphabet latin. Baptisée Core, cette bibliothèque est décrite dans l'appendice B.
À titre d'exemple, voici la spécification de SPF (décrit dans le RFC 4408) en ABNF :
record = version terms *SP version = "v=spf1" terms = *( 1*SP ( directive / modifier ) ) directive = [ qualifier ] mechanism qualifier = "+" / "-" / "?" / "~" mechanism = ( all / include / A / MX / PTR / IP4 / IP6 / exists ) all = "all" include = "include" ":" domain-spec A = "a" [ ":" domain-spec ] [ dual-cidr-length ] MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ] PTR = "ptr" [ ":" domain-spec ] IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ] IP6 = "ip6" ":" ip6-network [ ip6-cidr-length ] exists = "exists" ":" domain-spec modifier = redirect / explanation / unknown-modifier redirect = "redirect" "=" domain-spec explanation = "exp" "=" domain-spec unknown-modifier = name "=" macro-string ip4-cidr-length = "/" 1*DIGIT ip6-cidr-length = "/" 1*DIGIT dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ] ip4-network = qnum "." qnum "." qnum "." qnum qnum = DIGIT ; 0-9 / %x31-39 DIGIT ; 10-99 / "1" 2DIGIT ; 100-199 / "2" %x30-34 DIGIT ; 200-249 / "25" %x30-35 ; 250-255 ; conventional dotted quad notation. e.g., 192.0.2.0 ip6-network = <as per [RFC 3513], section 2.2> ; e.g., 2001:DB8::CD30 domain-spec = macro-string domain-end domain-end = ( "." toplabel [ "." ] ) / macro-expand toplabel = ( *alphanum ALPHA *alphanum ) / ( 1*alphanum "-" *( alphanum / "-" ) alphanum ) ; LDH rule plus additional TLD restrictions ; (see [RFC3696], Section 2) alphanum = ALPHA / DIGIT explain-string = *( macro-string / SP ) macro-string = *( macro-expand / macro-literal ) macro-expand = ( "%{" macro-letter transformers *delimiter "}" ) / "%%" / "%_" / "%-" macro-literal = %x21-24 / %x26-7E ; visible characters except "%" macro-letter = "s" / "l" / "o" / "d" / "i" / "p" / "h" / "c" / "r" / "t" transformers = *DIGIT [ "r" ] delimiter = "." / "-" / "+" / "," / "/" / "_" / "=" name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." ) header-field = "Received-SPF:" [CFWS] result FWS [comment FWS] [ key-value-list ] CRLF result = "Pass" / "Fail" / "SoftFail" / "Neutral" / "None" / "TempError" / "PermError" key-value-list = key-value-pair *( ";" [CFWS] key-value-pair ) [";"] key-value-pair = key [CFWS] "=" ( dot-atom / quoted-string ) key = "client-ip" / "envelope-from" / "helo" / "problem" / "receiver" / "identity" / mechanism / "x-" name / name identity = "mailfrom" ; for the "MAIL FROM" identity / "helo" ; for the "HELO" identity / name ; other identities dot-atom = <unquoted word as per [RFC2822]> quoted-string = <quoted string as per [RFC2822]> comment = <comment string as per [RFC2822]> CFWS = <comment or folding white space as per [RFC2822]> FWS = <folding white space as per [RFC2822]> CRLF = <standard end-of-line token as per [RFC2822]>
On notera qu'ABNF ne spécifie pas la représentation sous forme de bits, mais une structure abstraite. Ce point, qui n'était pas clair dans les premières versions de la norme, et qui est souvent oublié par les utilisateurs d'ABNF, est décrit dans la section 2.4. ABNF spécifie des caractères, pas des octets, et la production :
comment-start = %3b
décrit bien le caractère point-virgule, pas forcément qu'il sera représenté par un octet de valeur numérique 3B (59 en décimal). Un encodage d'Unicode comme UTF-32, par exemple, le codera différemment
L'un des rares changements par rapport à son prédécesseur, le RFC 4234, aura été l'ajout d'un avertissement à la production LWSP (Linear White SPace, qui permet des espaces en début de ligne). Cette production, décrite dans l'appendice B, qui définit la bibliothèque standard de productions, a en effet été critiquée comme trop puissante : des auteurs de RFC l'ont utilisée sans comprendre ses conséquences. La définition comprend désormais l'avertissement suivant, qui a été négocié à la virgule près, avec acharnement : Use of this linear-white-space rule permits lines containing only white space that are no longer legal in mail headers and have caused interoperability problems in other contexts. Do not use when defining mail headers and use with caution in other contexts.
Notons qu'il n'y a pas grand'chose d'obligatoire à l'IETF. Aucune autorité ne peut dire aux auteurs de RFC « Désormais, vous êtes obligés d'utiliser ABNF ». Ceux qui le font le choisissent volontairement. La principale « dissidence » venait du RFC 2616, qui normalise HTTP, et qui utilisait un langage différent. Mais, depuis, les nouveaux RFC sur HTTP ont supprimé cette exception et utilisés l'ABNF standard.
Notons aussi que, bien que l'un des principaux avantages des langages formels soit la possibilité de vérification automatique, cette possibilité n'est pas utilisée systématiquement. C'est ainsi que certains RFC ont été publiés avec des bogues dans leur grammaire ABNF...
Le RFC 2234 était « Proposition de norme », le RFC 4234 était « Projet de norme ». Pour franchir l'étape supplémentaire menant au statut de « Norme » tout court, ABNF a dû subir tout un processus, malgré l'extrême ancienneté de cette norme.
Notamment, ABNF a dû subir l'examen des programmes qui le mettent en
œuvre, examen décrit en http://ietf.org/IESG/Implementations/RFC4234_implem.txt
.
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : J. Quittek (NEC), S. Bryant, B. Claise, P. Aitken (Cisco), J. Meyer (PayPal)
Chemin des normes
Première rédaction de cet article le 1 février 2008
Le protocole IPFIX d'envoi par un routeur de résumés statistiques sur le trafic qu'il voit passer (RFC 5101, depuis remplacé par le RFC 7011), dépend d'un modèle de données, que décrivait notre RFC (depuis remplacé par le RFC 7012).
Le RFC 5101 qui normalisait le protocole IPFIX indique comment transporter les données de l'exporteur (typiquement un routeur) vers le récolteur (typiquement la machine d'administration du réseau) mais n'indique pas quelles données sont transportées. Notre RFC va jouer ce rôle, équivalent à celui du SMI du RFC 2578 pour SNMP.
Notre RFC est très long mais il est surtout composé d'une longue
liste (section 5) des informations qui peuvent être transmises en
IPFIX. En fait, il est
assez simple. Un élément d'information a un nom (par exemple
destinationTransportPort
), une description (cet
élément indique le port de destination du flot), un type
(ici unsigned16
, nombre entier sur 16 bits) et d'autres informations utiles comme un ElementID qui
identifie de manière unique un élément d'information. Les types sont décrits en détail dans la section 3 mais sont
très classiques (entiers, booléens, adresses
MAC, etc). Plus originaux sont les sémantiques de la
section 3.2, qui précisent, par exemple, que les éléments ayant une
sémantique de totalCounter
repartent de zéro
lorsqu'ils ont atteint leur valeur maximale.
Voici un exemple complet, tiré de la section 5.10.4 :
octetTotalCount Description: The total number of octets in incoming packets for this Flow at the Observation Point since the Metering Process (re-)initialization for this Observation Point. The number of octets include IP header(s) and IP payload. Abstract Data Type: unsigned64 Data Type Semantics: totalCounter ElementId: 85 Status: current Units: octets
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : P. Savola (CSC / FUNET)
Pour information
Première rédaction de cet article le 1 février 2008
Ce RFC tente de mettre un peu d'ordre dans la galaxie des protocoles Internet liés au multicast en indiquant lesquels sont aujourd'hui encore en utilisation et lesquels doivent être considérés comme abandonnés.
Ce RFC ne mérite pas tout à fait son titre. Il ne présente pas une vision de haut niveau du multicast aujourd'hui, simplement une liste des protocoles qui concourent à la diffusion multicast, avec les recommandations associées. Ainsi, les techniques normalisées dans les RFC 3913 ou RFC 1584 sont officiellement indiquées comme abandonnées. Gérer un réseau multicast a en effet nécessité une grande souplesse, les techniques ayant souvent changé.
Comme IPv6, le multicast n'a jamais connu de déploiement significatif sur Internet (certains réseaux privés, en revanche, l'utilisent intensivement, par exemple pour la diffusion de chaînes de télévision). Il existe un grand contraste entre l'intérêt que suscite le multicast chez les experts, le nombre étonnant de RFC sur le sujet, son enseignement massif à l'Université, les analyses de consultant prévoyant son déploiement massif, et son peu d'utilisation dans le monde réel. Une des raisons est que le multicast est surtout adapté aux cas où un grand nombre de gens veulent le même contenu pile en même temps (cas des chaînes de télévision traditionnelles) et pas au cas où les demandes sont décalées dans le temps (cas de la vidéo à la demande), même si les demandes sont proches (cas de la distribution d'un nouveau gros logiciel, où BitTorrent domine).
Pour diffuser en multicast, il faut plusieurs familles de protocoles et la section 2 du RFC est découpée selon ces familles. Ainsi, la section 2.1 est consacrée à la distribution de l'état d'aiguillage (forwarding), c'est-à-dire les règles qui permettent à chaque routeur de savoir où envoyer un flot multicast donné. Le protocole dominant ici est PIM-SM (RFC 4601), l'ancêtre DVRMP ayant été largement abandonné.
La section 2.2, elle, se consacre aux protocoles qui permettent de distribuer l'information topologique, pour que les routeurs apprennent leurs liaisons (en raison des tunnels, la topologie multicast n'est pas forcément congruente à la topologie unicast). C'est aujourd'hui le domaine de BGP dont les extensions multi-protocoles (décrites dans le RFC 4760) permettent de distribuer l'information multicast, ou bien d'IGP comme OSPF (RFC 4915).
Il existe encore d'autres familles de protocoles pour les routeurs multicast, dans les sections suivantes. La section 2.6, elle, passe aux interactions avec les machines finales, comme les protocoles permettant à celles-ci de signaler leur désir de joindre un groupe multicast, pour recevoir les flots associés. Ces protocoles sont IGMP (RFC 3376) en IPv4 et MLD (RFC 3810) en IPv6.
La section 2.7, elle, parle en détail de la réduction de la diffusion sur le réseau local. Si un commutateur réseau reçoit un paquet multicast, il doit en théorie l'expédier sur tous ses ports, même si aucune machine finale n'y écoute le flot. Diverses techniques comme l'« espionnage » des messages IGMP (RFC 4541) permettent de réduire cette diffusion aux seuls ports menant à une machine intéressée.
Date de publication du RFC : Juin 2000
Auteur(s) du RFC : C. Rigney, S. Willens, A. Rubens, W. Simpson
Chemin des normes
Première rédaction de cet article le 31 janvier 2008
Radius, normalisé dans ce RFC, est un protocole très simple d'AAA, conçu pour des serveurs d'accès à l'Internet (NAS, Network Access Server ou Access Point, ce dernier terme étant davantage utilisé dans le monde du sans-fil) qui sous-traitent l'authentification des utilisateurs à un serveur Radius. La machine qui accède à Internet n'a donc pas besoin de Radius, ce protocole ne sert qu'entre le NAS et le serveur d'authentification.
Radius fait partie de la famille des protocoles simples, certains disent simplistes, qui font peu de choses mais les font bien et, comme résultat, sont indélogeables. Normalisé d'abord dans le RFC 2058, puis le RFC 2138, il est désormais défini par notre RFC. Son principe est simple : lorsqu'une machine cliente se connecte au serveur d'accès (le NAS), ce dernier envoie un paquet UDP au serveur d'authentification, paquet qui contient l'information sur le client (et, dans le cas le plus simple, le mot de passe que celui-ci a indiqué). Le serveur d'accès est donc client Radius. Le serveur Radius répond par une acceptation ou un refus, accompagné, si c'est une acceptation, par la valeur de certaines options de configuration (par exemple une adresse IP).
La section 2 du RFC décrit plus en détail ce modèle. Le client Radius doit mettre dans la requête toute l'information nécessaire (nom ou NAI de l'utilisateur, numéro de port du NAS, etc). Il est également responsable, comme pour le DNS, de la réémission des demandes, s'il n'y a pas de réponse (UDP ne garantit en effet pas la délivrance des requêtes). Le RFC précise que le serveur ne doit accepter que les clients connus, configurés avec un secret partagé, il n'existe pas de serveur Radius public. Le serveur Radius authentifie ensuite l'utilisateur par les mécanismes de son choix (les bons serveurs Radius offrent d'innombrables techniques d'authentification).
La section 2.1 explique comment Radius peut être utilisé même si la requête ne contenait pas tous les éléments pour l'authentification, par exemple parce qu'on a choisi d'utiliser une authentification défi/réponse. Radius permet de transmettre le défi au client.
La section 2.4 est d'explication : elle donne les raisons pour lesquelles UDP a été choisi comme protocole de transport, choix qui a beaucoup été critiqué.
La section 3 est consacré au format de paquet, la 4 décrivant en
détail les
différents types de paquet (notamment Acceptation et Rejet). Radius
utilise les ports suivants (extraits d'un /etc/services
) :
radius 1812/udp radius-acct 1813/tcp radacct
C'est également cette section qui décrit le secret que partagent le client et le serveur Radius, secret qui servira notamment à xorer le mot de passe de l'utilisateur (section 5.2) pour se protéger contre l'espionnage de la ligne.
La section 5 liste tous les attributs standard, mais Radius est extensible et permet d'en décrire d'autres comme les attributs spécifiquement Microsoft du RFC 2548 ou bien comme le préfixe IPv6 délégué du RFC 4818. Cette extensibilité est une des propriétés les plus importantes de Radius.
Un des attributs les plus répandus est
User-Name
(type 1), décrit dans la section
5.1. Sa valeur est le nom de l'utilisateur (par exemple
p.dupont
) ou bien son NAI
(RFC 7542, par exemple stephane@gold.example.net
). Si c'est un nom, il est stocké en
UTF-8 (les précédentes versions de Radius
n'acceptaient que l'ASCII).
L'attribut Service-Type
(section 5.6), permet
de demander un service particulier, par exemple que le NAS rappelle
l'utilisateur pour lui épargner les frais de communication (à
Internatif, j'utilisais ainsi, pour les tâches d'administration
système effectuées à distance, la valeur
Callback-Framed
à l'époque où le téléphone était
presque toujours facturé à la minuté).
Les attributs sont encodés en TLV.
La section 7 du RFC donne plusieurs exemples d'échanges Radius. Prenons un cas typique :
nemo
) et mot de passe.Access-Request
, attributs
User-Name = nemo
, User-Password =
<masqué par le secret partagé>
, Nas-Port =
3
(pour le cas où le serveur veuille enregistrer cette
information, ou même l'utiliser dans son processus de
décision).Access-Accept
,
avec les attributs Service-Type = Framed
,
Framed-Protocol = PPP
(le
PPP du RFC 1661),
Framed-IP-address = 255.255.255.254
(une
convention courante pour dire « prends une adresse IP dynamique dans
ton pool »),
Framed-MTU = 1500
.Notre RFC 2865 a plusieurs compagnons, notamment le RFC 2866 qui spécifie la comptabilité (le troisième A, Accounting, du sigle AAA), et RFC 2869 le mécanisme d'extensions.
Radius a été très critiqué pour sa simplicité et un protocole concurrent, Diameter, a été développé et décrit dans le RFC 3588 (remplacé ensuite par le RFC 6733). Sur le créneau des serveurs d'accès à Internet, Diameter n'a eu aucun succès.
Il existe d'innombrables mises en œuvre de Radius, un protocole qu'on trouve aujourd'hui dans tous les NAS. Radius avait à l'origine été conçu par Livingston (et mes débuts personnels avec Radius, au CNAM, étaient avec un Livingston Portmaster, avant de passer, chez Internatif, à l'US Robotics Total Control) mais est aujourd'hui une norme très répandue. Livingston a depuis été rachetée par Lucent.
Côté serveur Radius, le serveur d'origine, fait par Livingston, est
toujours d'actualité (paquetage radiusd-livingston
dans Debian), mais le plus courant est désormais
Free Radius, basé sur la version de
Cistron. Free Radius est
l'Apache des serveurs Radius : très riche en
possibilités, pratiquement tout est configurable.
(Un autre serveur basé sur celui de Cistron, xtradius ne semble plus maintenu, il est par exemple très bogué sur machines 64bits.)
Côté client (NAS), voici par exemple comment se configure un
Cisco en client Radius du serveur 192.168.8.8
:
radius-server host 192.168.8.8 auth-port 1812 key THESHAREDSECRET aaa group ...
Si le NAS est une machine Unix, elle peut
utiliser le greffon Radius livré avec le démon
pppd
, qui permet à pppd
d'authentifier avec
Radius.
Pour déboguer le serveur, il vaut mieux utiliser d'abord un
client en ligne de commande, comme le radclient
qu'on trouve avec Free Radius. On peut aussi facilement construire un
client à soi en Python
avec pyrad (le
code d'exemple marche du premier coup). Restons avec radclient :
% echo "User-Name = bortzmeyer\nUser-Password = foobar" | radclient MYRADIUSSERVER auth toto
17:31:54.679926 IP 10.1.82.1.32772 > 10.1.82.2.1812: RADIUS, Access Request (1), id: 0xcd length: 32
et le radius.log
du serveur (si on veut déboguer Free Radius, il est recommandé de suivre les conseils en http://wiki.freeradius.org/index.php/FAQ#Debugging_it_yourself
) :
Fri Jan 25 17:32:21 2008 : Error: Ignoring request from unknown client 10.1.82.1:32772
En effet, rappelons que Radius impose que le serveur ne communique qu'avec des clients qui ont été enregistrés. Avec Free Radius, cela se fait dans le clients.conf
:
client MYNAS.generic-nic.net { secret = toto shortname = MYNAS }
Et, cette fois, ça marche :
% echo "User-Name = bortzmeyer\nUser-Password = foobar" | radclient MYRADIUSSERVER auth toto Received response ID 233, code 2, length = 44 Service-Type = Framed-User Framed-Protocol = PPP Framed-IP-Address = 172.16.3.33 Framed-IP-Netmask = 255.255.255.0
tcpdump a vu :
16:13:09.963566 IP 10.1.82.1.32774 > 10.1.82.2.1812: RADIUS, Access Request (1), id: 0xec length: 50 16:13:09.963914 IP 10.1.82.2.1812 > 10.1.82.1.32774: RADIUS, Access Accept (2), id: 0xec length: 44
Si on l'avait lancé avec l'option -vvv
pour qu'il soit plus bavard :
16:13:25.477228 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 78) 10.1.82.1.32774 > 10.1.82.2.1812: [udp sum ok] RADIUS, length: 50 Access Request (1), id: 0xee, Authenticator: eb33a21f4d8fc351898adc0b47b90c87 Username Attribute (1), length: 12, Value: bortzmeyer 0x0000: 626f 7274 7a6d 6579 6572 Password Attribute (2), length: 18, Value: 0x0000: 727b 82e4 ccab a138 a5cb 368e 8829 1555 16:13:25.477607 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 72) 10.1.82.2.1812 > 10.1.82.1.32774: [bad udp cksum f482!] RADIUS, length: 44 Access Accept (2), id: 0xee, Authenticator: 779e320bca7cda5972412ee6b53b10dc Service Type Attribute (6), length: 6, Value: Framed 0x0000: 0000 0002 Framed Protocol Attribute (7), length: 6, Value: PPP 0x0000: 0000 0001 Framed IP Address Attribute (8), length: 6, Value: 172.16.3.33 0x0000: ac10 0321 Framed IP Network Attribute (9), length: 6, Value: 255.255.255.0 0x0000: ffff ff00
On peut aussi tester la santé d'un serveur Radius (attention, tous ne le mettent pas en œuvre, sur Free Radius, il faut un status_server = yes
dans la configuration) avec les requêtes de type Status-Server
:
% echo "Message-Authenticator = 42" | radclient MYRADIUSSERVER status toto Received response ID 131, code 2, length = 49 Reply-Message = "FreeRADIUS up 0 days, 00:02"
Si on souhaite ajouter des attributs à soi sur un serveur Radius Unix, cela se fait en général en éditant le fichier dictionary
, qui décrit les attributs. Imaginons un attribut indiquant la témpérature, je mets dans le /etc/freeradius/dictionary
:
ATTRIBUTE Temperature 3000 integer
Un exemple de réalisation d'un service Radius est décrit en http://lehmann.free.fr/Contributions/FreeRADIUS/
Première rédaction de cet article le 30 janvier 2008
J'ai été ingénieur système sur VMS de 1986 à 1988. C'était même mon premier vrai métier dans l'informatique. Signe de l'extrême permanence des choses en informatique, VMS est toujours là et des machines VMS consomment du courant et produisent des résultats aujourd'hui.
Difficile de se débarasser d'un système d'exploitation à succès, même lorsque la boîte qui l'a créé a été rachetée deux fois (Digital a été acheté par Compaq puis par HP). VMS a eu trente ans en novembre 2007 et marche toujours. Le nombre d'applications sur VMS est tel, surtout dans le secteur Banque & Assurances qu'on ne peut pas envisager d'arrêter, même si VMS n'a plus le vent en poupe. Des passionnés ont même développé une version libre.
On peut même aujourd'hui avoir un compte gratuit sur une machine
VMS, sur la ferme de
compilation Test Drive. Je suis un peu rouillé, j'avais même
oublié qu'il fallait faire précéder les commandes par
RUN
mais je me souvenais encore de la syntaxe
baroque des noms de répertoires. Voici comment j'ai compilé et exécuté
mon programme (je tape les noms complets des commandes mais bien sûr
l'interpréteur permet de les abréger, tant qu'il n'y a pas d'ambiguïté) :
Last interactive login on Tuesday, 29-JAN-2008 17:10:34.11 Last non-interactive login on Tuesday, 29-JAN-2008 09:49:04.69 Your default directory is USER1:[BORTZ] You also have a directory on an ODS-5 device. USER5:[bortz] $ $ set default [.tmp] $ directory Directory USER1:[BORTZ.TMP] ECHOPING-5_0_1.DIR;1 ECHOPING-5_0_1.TAR;1 IP-HEADER-SET.C;1 MAKEFILE.;1 Total of 4 files. $ cc IP-HEADER-SET $ link IP-HEADER-SET $ run IP-HEADER-SET Testing of the abilities to set bits in the IP header The system is OpenVMS 0, the machine is HP_rx2600__(1.40GHz/1.5MB) ...
On voit le numéro de version derrière chaque nom de fichier
(précédé d'un point-virgule). On note aussi que
l'extension du nom de fichier peut être omise
(link
cherche alors un .obj
).
Première rédaction de cet article le 30 janvier 2008
L'IETF, comme les autres acteurs de l'Internet, se pose depuis longtemps la question de l'attitude à adopter face au déploiement massif du NAT. Cette technique, qui permet de ne pas donner aux machines situées derrière le routeur NAT une « vraie » connectivité Internet, est très répandue. Au fur et à mesure de l'épuisement des adresses IPv4, on voit de plus en plus de FAI qui connectent leurs clients ainsi. À la maison, l'abonné moyen n'a, depuis longtemps, qu'une seule adresse IPv4 et donc pas beaucoup d'autres choix que le NAT (ou les relais applicatifs, qui posent des problèmes analogues). Or, le NAT brise le modèle de « connectivité de bout en bout » qui est à la base de l'Internet. Pour cette raison, et d'autres, il est très mal vu chez les concepteurs et implémenteurs de protocoles. Que doivent faire ceux-ci dans un monde où le NAT est si répandu ? C'est tout l'objet du groupe de travail BEHAVE.
En présence du NAT, les application strictement client/serveur comme le Web fonctionnent encore assez bien, lorsque le serveur n'est pas lui-même derrière un routeur NAT. Par contre, les applications pair-à-pair, où chacun doit pouvoir contacter chacun, ou bien les protocoles pour le multi-média comme SIP (RFC 3261), où l'appelé doit pouvoir envoyer son flot de données à l'appelant, sont très handicapés. Les programmes mettant en œuvre ces protocoles consacrent une grande partie de leur code à contourner les NAT. Divers bricolages sont parfois nécessaires pour que le monde extérieur puisse parler aux machines bloquées derrière le routeur NAT (par exemple le port fowarding comme documenté ici pour un routeur Linux). Bref, le NAT fait faire des économies aux opérateurs Internet (à qui il évite de déployer IPv6) mais coûte cher aux autres acteurs.
Aujourd'hui, le NAT est tellement largement déployé que, même si plus aucune installation n'était faite, l'Internet devrait vivre avec pendant des années. Alors, que doit faire un organisation de normalisation comme l'IETF ? Comme le NAT met en cause la connectivité de bout en bout, il est largement considéré à l'IETF comme un mal à éradiquer. Comme on ne pactise pas avec le mal, l'opinion dominante à l'IETF était qu'il ne fallait pas chercher à limiter les dégâts, à améliorer le NAT, puisqu'il ne méritait que d'être supprimé. Même la normalisation des moyens de contournement du NAT (rapidement apparus, vue la créativité des développeurs réseaux face aux obstacles) a été pendant longtemps tenue en suspicion. En novembre 2002, l'IAB, dans le RFC 3424 appelait ces moyens de contournement « UNSAF » (UNilateral Self-Address Fixing), laissant entendre que le danger venait d'eux et pas du NAT, et imposant dans sa section 4 une série de questions auxquelles devaient répondre tous les protocoles de contournement. Le but était d'éviter que le remède soit pire que le mal, que le NAT, mais cela revenait à jeter une suspicion contre ceux qui cherchaient à trouver des solutions partielles, comme STUN.
Finalement, c'est en septembre 2004 qu'a été créé le groupe de travail BEHAVE, avec une charte très prudente qui lui intimait de « ne pas encourager le déploiement de NAT » comme si le développement de la médecine encourageait les maladies. On touche là à un problème presque philosophique : tenter de soulager la misère du monde détourne t-il de la réalisation de changements de fond ?
BEHAVE a travaillé sur les points suivants :
draft-ietf-behave-p2p-state
, qui est notament
axé sur le pair-à-pair).draft-ietf-behave-nat-behavior-discovery
) qu'à la
traversée des NAT par les applications, par la technique du
hole punching (la description de cette technique n'est pas faite par BEHAVE
mais dans d'autres groupes de travail, plus orientés
applications). Une extension de STUN, TURN
(RFC 5766)
normalise le relais de toute la session via un serveur extérieur, ce
qui sera normalement le « dernier recours » pour communiquer, si les
deux pairs sont coincés derrière des routeurs NAT peu coopératifs.Première rédaction de cet article le 26 janvier 2008
mkisofs est un excellent logiciel
Unix pour créer des images ISO 9660 à partir d'un ou de plusieurs répertoires locaux,
images qu'on peut ensuite graver sur CD ou
DVD. Mais mkisofs a un défaut pénible : si on
lui indique plusieurs répertoires sur la ligne de commande, il met
tous les fichiers qu'ils contiennent ensemble, ce qui fait perdre le
rangement, et ne marche pas si certains fichiers ont le même nom. Une
solution possible est dans l'option
-graft-points
.
Cette option indique à mkisofs de garder la
structure en répertoires. Avec cette option, mkisofs regarde le nom de
chaque répertoire donné sur la ligne de commande, utilise le
signe égal comme séparateur, et prend ce qui
est à droite du séparateur comme nom local et ce qui est à gauche
comme nom sur le futur CD. On écrit donc, si on veut sauvegarder
/etc/X11
et /etc/network
:
% mkisofs -r -o /var/tmp/image.iso -graft-points xorg/=/etc/X11 net/=/etc/network
Bien sûr, il n'est pas agréable de taper à la main de tels noms avec leur « = ». Mais on peut utiliser le shell pour les fabriquer. Nous nous servirons pour cela des techniques suivantes :
$(COMMANDE)
qui insère le résultat la commande (comme
le fait `COMMANDE`
mais l'avantage de cette forme
est de permettre d'emboîter plusieurs commandes).
Voici la commande qui crée les paramètres à la syntaxe qu'attend
mkisofs (la liste des répertoires à sauvegarder est dans la variable DIRS
qui vaut ici X11 network
) :
% cd /etc % for dir in $(eval ls -d $DIRS); do echo "$dir/=$(pwd)/$dir"; done X11/=/etc/X11 network/=/etc/network
La commande complète, utilisant la boucle
ci-dessus est (j'ai mis toutes les options que j'ajoute habituellement
à mkisofs, mais seule -graft-points
est
importante ici) :
% cd /etc % DIRS="X11 network" % ISO=/var/tmp/backup.iso % mkisofs -A Backups -V Backups -publisher Stephane_Bortzmeyer \ -p Stephane_Bortzmeyer -graft-points -iso-level=3 \ -J -r -o $ISO \ $(for dir in $(eval ls -d $DIRS); do echo "$dir/=$(pwd)/$dir"; done)
On utilise eval au lieu de simplement indiquer
$DIRS
car $DIRS
peut
contenir des caractères spéciaux du shell comme
l'astérisque, qui sert de
joker. eval
est nécessaire
pour qu'ils soient interprétés.
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : J. Arkko (Ericsson), B. Aboba (Microsoft), J. Korhonen (TeliaSonera), F. Bari (AT&T/UBC
Pour information
Réalisé dans le cadre du groupe de travail IETF eap
Première rédaction de cet article le 26 janvier 2008
Ce RFC décrit l'ensemble du problème de la découverte et de la sélection d'un réseau particulier, lorsque plusieurs sont accessibles à la machine, ce qui est courant avec les équipements portables.
Un ordinateur portable, aujourd'hui se trouve fréquemment confronté au problème de trouver les réseaux disponibles et d'en choisir un. Placé dans une chambre d'hôtel, il est connecté par un câble Ethernet au réseau de l'hôtel, mais il reçoit aussi le signal de trois réseaux Wifi différents, certains de ces quatre réseaux n'étant pas forcément accessibles à l'utilisateur (pas d'autorisation) et les autres différant par leur prix, leur qualité et les services qu'ils offrent. Lequel choisir ? Notre RFC ne résout pas le problème mais l'analyse et y met un peu d'ordre.
La section 1 détaille de manière précise cette question. Par exemple, les protocoles actuels permettent de publier assez clairement les caractéristiques de la couche 2 du réseau d'accès (par exemple, en 802.11, si le réseau est ouvert ou pas) mais ne donnent pas d'information sur les couches supérieures. Peut-être que ce réseau ne me donne qu'une adresse IP privée et m'enferme derrière un coupe-feu très strict alors que cet autre réseau me donne un vrai accès Internet mais comment le savoir sans s'y connecter ?
La section 2 liste ensuite les problèmes précis, notamment :
stephane@fai.example.net
) et un
mis à ma disposition par mon entreprise
(bortzmeyer@boulot.com
), lequel utiliser ?La section 3 définit des principes qui devraient être suivis par les mécanismes permettant de traiter ces problèmes. Par exemple, les engins portables ayant souvent une autonomie limitée, il faudrait éviter les longs dialogues, qui peuvent vider la batterie plus vite. La sécurité y fait l'objet d'une attention particulière, car la sélection d'un réseau est un bon endroit où attaquer, par exemple en essayant de convaincre une machine de se connecter au réseau le moins sécurisé...
Enfin, la conclusion, en section 4, affirme qu'il reste beaucoup de travail à faire dans ce domaine et fournit quelques pistes de recherche. L'annexe A décrit en détail les travaux déjà effectués à l'IETF, les RFC 4284, RFC 4066, etc, mais aussi à l'IEEE ou dans 3GPP.
Un exemple d'un logiciel qui met en œuvre une telle sélection de réseau est NetworkManager sur Unix, logiciel qui est composé de deux parties, un démon tournant sous root qui détecte les événements réseau (comme l'insertion ou le retrait d'une carte) et une application graphique qui assure l'interface utilisateur, les deux communiquant via dbus. NetworkManager permet à l'utilisateur de sélectionner facilement un réseau mais ne semble pas lui-même capable de faire des choix à part des cas très simples comme « Un réseau filaire est préférable à un réseau sans-fil ».
Première rédaction de cet article le 25 janvier 2008
Le choix d'un langage de programmation pour une tâche de développement logiciel est souvent un choix difficile et qui suscite des débats passionnés. Utiliserons-nous Java ? Perl ? Caml ? Lua ? Ces débats sont parfois qualifiés de « religieux » du fait de l'enthousiasme qu'y mettent leurs participants, et de la rapidité avec laquelle ils écrasent les alternatives (« Java est le standard de l'industrie » ou « Python est trop lent ») sans trop chercher à collecter des faits précis. Mais appeler ces débats « religieux » est en fait souvent un moyen de nier l'importance de ce choix et de se moquer sans risques de ceux qui cherchent à défendre leur choix. C'est une fuite bien commode alors que, comme tout choix technique, celui d'un langage de programmation peut être basé sur des faits, à condition de chercher ces faits, non seulement dans le langage lui-même, mais aussi dans tout son environnement, technique et social.
On pourrait vouloir un seul langage de programmation, qui éviterait la difficulté du choix (les discours sur tel langage qui serait « le standard de l'industrie » relèvent souvent de cette vision). Mais ce n'est pas le cas. Il y a donc un vrai choix et qualifier les débats sur ce choix de « religieux » est un moyen peu courageux de refuser la discussion. Par contre, il est exact qu'il faut un gros effort sur soi-même pour ne pas trop se laisser aveugler par la passion et pour étudier les faits. Cette passion est normale (heureusement que les programmeuses sont passionnées par la programmation) et elle est même raisonnable, dans la mesure où le choix de l'outil influe, non seulement sur la productivité (si le langage d'assemblage a presque disparu, ce n'est pas par hasard, c'est largement à cause de la plus faible productivité qu'il permet), mais également sur les modes de pensée. L'outil détermine le travail, même si les décideurs, ne comprenant pas les arguments techniques du choix d'un langage, continuent à prétendre qu'on peut réaliser n'importe quelle tâche, avec n'importe quel style, dans tous les langages. C'est factuellement exact mais cela ne mène pas loin. C'est comme dire que tous les moyens de transport se valent et qu'on peut traverser l'Amérique à pied. Oui, on peut. Comme on peut réécrire un SGBD en assembleur. Et alors ? Qui va le faire ?
Il y a donc bien des arguments techniques au choix d'un langage. Un langage où il faut gérer la mémoire soi-même (allocation et désallocation, éviter les pointeurs pendants) comme C est une source de bogues sans fin. Un langage où les variables sont automatiquement déclarées (comme les vieux Basic ou comme Perl ou PHP par défaut) permet des bogues très difficiles à détecter en cas de faute de frappe sur le nom d'une variable. Ces arguments sont très importants et doivent être pris en compte.
Mais certains professionnels des langages de programmation, emportés par leur goût pour ces analyses et ces discussions, oublient un autre aspect : le langage lui-même, tel que spécifié dans son manuel de référence, n'est qu'une partie du système avec lequel les programmeurs vont travailler. Il y a aussi la disponibilité de bibliothèques, l'existence de plusieurs implémentations de qualité (et, si on développe du logiciel libre, sous une licence acceptable), la taille de la communauté, qui conditionne la facilité à recruter, l'aide qu'on pourra trouver...
Parmi ces critères non strictement liés au langage, on trouve la disponibilité de bibliothèques toutes faites pour assurer des tâches courantes comme parler à un serveur LDAP ou bien calculer une somme de contrôle SHA. Un langage comme Ada avait beaucoup souffert du manque de telles bibliothèques. À l'inverse, Haskell en a trop sur chaque sujet, et aucune n'étant « standard » (il existe par exemple de nombreuses façons de traiter du XML en Haskell). Lua a de telles bibliothèques mais elles ne sont pas installées par défaut. À l'inverse, un langage comme Perl doit une partie de son succès à la CPAN, un immense ensemble de bibliothèques de qualité, documentées, cohérentes et facilement disponibles.
Parmi les critères plus sociaux, il y a par exemple la taille de la communauté, qui gouverne la facilité à trouver des programmeurs ou de l'aide. Encore que la taille puisse avoir des effets pervers comme le fait que les listes de diffusion d'un langage très populaire seront trop actives pour qu'on puisse s'en servir. Ou comme le fait qu'un langage « trop » populaire attirera des masses de programmeurs sans éclat (le paradoxe Python).
Je pense que, dans le choix d'un langage de programmation pour une tâche pratique (i.e. écrire un programme), on ne prend pas en compte que le langage lui-même mais aussi ce que j'appelle la « mentalité de la communauté ». Certes, cette mentalité n'est pas obligatoire (on peut choisir le langage et ignorer cette mentalité) mais elle influence fortement la documentation, les programme écrits par les autres (qu'on lira et dont on récupérera du code), l'aide qu'on peut avoir sur des listes de diffusion, etc.
Cette mentalité est la culture du langage. Si on ne travaille pas tout seul, si on est dans un environnement de logiciel libre, il faut bien en tenir compte. Par exemple, je conseille à tous les débutants en programmation de lire des programmes. Avec Perl, cela va les amener à lire du code illisible même si « on peut programmer proprement en Perl » (on peut, de même qu'on peut construire soi-même le bateau avec lequel on va traverser l'Atlantique).
Donc, en pratique, c'est surtout la « mentalité de la communauté » qui me tient à l'écart de PHP et Java, bien plus que les problèmes de ces langages. Par exemple, la culture PHP est de bricolage, sans réfléchir, sans faire attention aux problèmes de sécurité. Bien sûr qu'on peut écrire des programmes sûrs en PHP. Mais la culture du monde PHP ne s'y intéresse pas et donc ne le fait pas. Inversement, j'apprécie beaucoup la mentalité des Pythoniens ou des Haskelliens, qui peuvent discuter de questions avancées et répondre aux questions des débutants. Ah, et pour ajouter une note humoristique, la fameuse « hiérarchie des programmeurs » contient beaucoup d'éléments de vérité...
Pour finir sur une note concrète, un excellent article de l'équipe de Bugzilla illustre très bien une bonne méthode de choix de langage. Contrairement à beaucoup de cas de choix d'un langage, ici les auteurs savent de quoi ils parlent et connaissent bien tous les langages impliqués.
Date de publication du RFC : Décembre 1994
Auteur(s) du RFC : Tim Berners-Lee (CERN, World-Wide Web project), Larry Masinter (Xerox PARC), Mark McCahill (University of Minnesota)
Intérêt historique uniquement
Première rédaction de cet article le 24 janvier 2008
En même temps qu'étaient normalisés les URI, dans le RFC 1630, un effort était en cours pour normaliser leurs prédécesseurs, les URL et cet effort a donné ce RFC.
Ce RFC a aujourd'hui essentiellement un intérêt historique, puisque
la spécification des URI, RFC 3986, le
remplace en grande partie. Il a gardé longtemps son intérêt (et son
statut de norme, désormais perdu) du fait qu'il normalisait certains
plans d'URL comme
news:
. Ceux-ci sont désormais dans le RFC 5538.
Les URL sont issus du travail dont le cahier des charges est décrit
dans le RFC 1737. Contrairement aux URI, plus généraux, ils
sont supposés ne servir que lorsqu'on connait la localisation exacte
d'une ressource, de façon à pouvoir la récupérer, ou la mettre à jour
(section 2). En pratique, la distinction n'est pas évidente. Certains
URL ne donnent pas de moyen de récupérer une ressouce (comme
news:
que spécifie notre RFC ou bien
mailto:
, désormais dans le RFC 6068). Et
même des URL de plan http:
peuvent être utilisés
uniquement pour identifier, pas pour récupérer une ressource (c'est
notamment courant dans le monde XML).
Notre RFC décrit donc la syntaxe des URL (sections 2.1 et 5), bien connue désormais qu'on voit des URL même sur le flanc des autobus, et leur encodage (section 2.2, où est documentée la très mauvaise décision d'encoder les octets et pas les caractères Unicode).
La section 3 décrit ensuite les éléments communs à tous les URL
(comme la syntaxe host:port
), puis des plans
(scheme) pour plusieurs catégories d'URL. Ces plans
ont presque tous été mis à jour dans des RFC ultérieurs mais certains
restent normalisés uniquement ici comme ftp:
.
On trouve des plans très
utilisés comme le célébrissime http:
, section 3.3
(désormais dans la section 3.2 du RFC 2616), mais aussi d'autres désormais dépassés comme son défunt
concurrent gopher:
(section 3.4, désormais dans le RFC 4266) ou comme l'ancêtre wais:
(section 3.9, officiellement abandonné par le RFC 4156).
Le plan news:
, section 3.6, permet
de récupérer un article d'Usenet sans indiquer
de nom de serveur NNTP.
L'IANA maintient le registre de ces plans.
Le plan file:
est désormais normalisé dans le
RFC 8089.
On notera que notre RFC 1738 normalisait également un
mécanisme pour décrire un URL au milieu de texte brut, en utilisant un
préfixe défini dans l'annexe A,
<URL:http://www.bortzmeyer.org/1738.html>
.
Ce mécanisme n'a pas eu de succès et a officiellement été abandonné
par le RFC 3986, annexe C.
Première rédaction de cet article le 23 janvier 2008
Dans le cadre du cours d'Informatique en Biologie de l'Institut Pasteur, j'ai fait un exposé de trois heures sur les systèmes d'exploitation.
Ce cours s'adresse à un public de biologistes non familiers avec la programmation ou avec le fonctionnement des systèmes d'exploitation. Contrairement à pas mal de cours sur les systèmes d'exploitation, il ne part pas des couches basses, du matériel par exemple, mais d'un petit programme Python très simple, et descend ensuite petit à petit vers des couches de plus en plus basses. Voici les transparents de cet exposé :
Un autre exposé de la même série a porté sur réseaux.
Date de publication du RFC : Juillet 2003
Auteur(s) du RFC : R. Droms, J. Bound, B. Volz, T. Lemon, C. Perkins, M. Carney
Chemin des normes
Première rédaction de cet article le 23 janvier 2008
Dernière mise à jour le 6 novembre 2012
DHCP est certainement un des plus grands succès de l'IETF. Le DHCP d'IPv4 est mis en œuvre dans tous les systèmes et présent dans presque tous les réseaux locaux. Mais, dans le monde IPv6, l'arrivée de DHCP est plus récente, et il est concurrencé par un autre système, l'autoconfiguration sans état. DHCP pour IPv6, initialement normalisé dans ce RFC, l'est désormais dans le RFC 8415.
DHCP permet à une machine (qui n'est pas forcément un ordinateur) d'obtenir une adresse IP (ainsi que plusieurs autres informations de configuration) à partir d'un serveur DHCP du réseau local. C'est donc une configuration « avec état », qui nécessite un serveur, par opposition aux systèmes « sans état », comme l'autoconfiguration du RFC 4862 qui ne dépendent pas d'un serveur (cette autoconfiguration sans état peut être utilisée à la place de, ou bien en plus de DHCP). Deux utilisations typiques de DHCP sont le SoHo où le routeur ADSL est également serveur DHCP pour les trois PC connectés et le réseau local d'entreprise où deux ou trois machines Unix distribuent adresses IP et informations de configuration à des centaines de machines.
Le DHCP spécifié par notre RFC (et remplacé depuis par le RFC 8415) ne fonctionne que pour IPv6, le RFC 2131 traitant d'IPv4.
DHCP fonctionne par diffusion restreinte. Un
client DHCP, c'est-à-dire une machine qui veut
obtenir une adresses, diffuse (DHCP fonctionne au
dessus d'UDP) sa demande à l'adresse
multicast locale au lien FF02::1:2
. Le serveur se
reconnait et lui répond. S'il n'y a pas de réponse, c'est, comme dans
le DNS, au client de
réémettre (section 14).
Le serveur choisit sur quels critères il alloue les adresses IP. Il peut les distribuer de manière statique (une même machine a toujours la même adresse IP) ou bien les prendre dans un pool d'adresses et chaque client aura donc une adresse « dynamique ». Le fichier de configuration ci-dessous montre un mélange des deux approches.
Il faut bien noter (et notre RFC le fait dans sa section 23) que DHCP n'offre aucune sécurité. Comme il est conçu pour servir des machines non configurées, sur lesquelles on ne souhaite pas intervenir, authentifier la communication est difficile. Un serveur DHCP pirate, ou, tout simplement, un serveur DHCP accidentellement activé, peuvent donc être très gênants. Les approches suggérées dans la section 21 ou dans la section 23 sont en général très complexes (comme l'IPsec du RFC 4301) et ne sont typiquement pas déployées.
Outre l'adresse IP, DHCP peut indiquer des options comme les adresses des serveurs DNS à utiliser (RFC 3646).
Notre version IPv6 de DHCP est assez différente de la version IPv4 (et le RFC est trois fois plus long). Par exemple, l'échange « normal » entre client et serveur prend quatre paquets IP (section 1.3) et non pas deux, l'encodage est très différent, il y a des nouveautés comme l'IA (Identity Association) de la section 10, etc. Il y a aussi des différences visibles à l'utilisateur comme le concept de DUID (DHCP Unique IDentifier), section 9, qui remplace les anciens client identifier et server identifier de DHCP v4. Les différences sont telles que le RFC précise que leur intégration n'est pas envisagée.
À l'heure actuelle, il semble qu'il existe au moins trois mises en œuvre de DHCPv6, Dibbler, celle de l'Institut Leibniz à Dresde et celle de l'ISC, à partir de la version 4.0. Le fichier de configuration de cette dernière ressemble beaucoup à ce qu'il est en v4 :
subnet6 2001:DB8:DEAD:BABE::/64 { range6 2001:DB8:DEAD:BABE::100 2001:DB8:DEAD:BABE::FFF; # On peut aussi utiliser préfixe/longueur au lieu d'indiquer les # adresses de début et de fin de la plage }
On doit lancer le serveur avec l'option -6 (le même démon ne peut pas servir le v4 et le v6 en même temps, les deux protocoles étant trop différents) :
# dhcpd -6 -d -f Internet Systems Consortium DHCP Server 4.0.0 ... Listening on Socket/eth0/2001:db8:dead:babe::/64 Sending on Socket/eth0/2001:db8:dead:babe::/64 [Puis arrive une requête] Solicit message from fe80::219:b9ff:fee4:25f9 port 546, transaction ID 0x4BB14F00 Picking pool address 2001:db8:dead:babe::fbb Sending Advertise to fe80::219:b9ff:fee4:25f9 port 546 Request message from fe80::219:b9ff:fee4:25f9 port 546, transaction ID 0x46B10900 Sending Reply to fe80::219:b9ff:fee4:25f9 port 546
(Le concept de transaction ID est décrit sections 6
et 15.1.) La requête est émise depuis une adresse
lien-local (ici
fe80::219:b9ff:fee4:25f9
) pas depuis une adresse
« tout zéro » comme en IPv4 (section 16 du RFC).
Vu avec tcpdump, la requête est :
15:07:43.455918 IP6 fe80::219:b9ff:fee4:25f9.546 > ff02::1:2.547: dhcp6 solicit 15:07:43.456098 IP6 fe80::219:b9ff:fee4:2987.547 > fe80::219:b9ff:fee4:25f9.546: dhcp6 advertise 15:07:44.512946 IP6 fe80::219:b9ff:fee4:25f9.546 > ff02::1:2.547: dhcp6 request 15:07:44.513233 IP6 fe80::219:b9ff:fee4:2987.547 > fe80::219:b9ff:fee4:25f9.546: dhcp6 reply
On note que l'échange a été celui à quatre messages (Solicit
- Advertise - Request - Reply
), décrit section 1.3. Le serveur n'a pas répondu directement avec
un Reply
, parce que le client n'a pas inclus
l'option Rapid Commit
(section 22.14). Cette
option n'est pas actuellement gérée par le client DHCP utilisé
(l'option dhcp6.rapid-commit
existe mais la
documentation précise qu'elle est ignorée).
Actuellement, l'attribution d'adresses statiques à une machine, en
la reconnaissant, par exemple, à son adresse
MAC est plus délicate avec le serveur de l'ISC (merci à Shane Kerr pour son aide). Il faut trouver le client
identifier (section 22.2 du RFC, deux méthodes possibles
pour le trouver sont expliquées plus
loin) et le mettre dans dhcpd.conf
:
host lilith { host-identifier option dhcp6.client-id 0:1:0:1:47:96:21:f7:0:19:b9:e4:25:f9; fixed-address6 2001:DB8:DEAD:BABE::2; }
et cette adresse IP fixe est donnée au client.
Pour trouver le client identifier, une méthode
spécifique au client DHCP de l'ISC est de regarder dans le fichier des
baux du client (typiquement
/var/db/dhclient6.leases
) :
... option dhcp6.client-id 0:1:0:1:47:96:21:f7:0:19:b9:e4:25:f9;
Il suffit alors de le copier-coller.
Une autre méthode, plus complexe, mais qui marche avec tous les clients DHCP est de lancer tcpdump en mode bavard :
# tcpdump -n -vvv ip6 and udp and port 547 12:24:15.084006 IP6 (hlim 64, next-header UDP (17) payload length: 60) fe80::219:b9ff:fee4:25f9.546 > ff02::1:2.547: dhcp6 solicit (xid=4323ac (client ID hwaddr/time type 1 time 1201021431 0019b9e425f9) (option request DNS DNS name)[|dhcp6ext])
Le client identifier, le DUID, se fabrique en concaténant le type de DUID (ici, 1, Link-layer Address Plus Time, section 9.2 du RFC), le type de matériel (1 pour Ethernet), le temps (ici 1201021431, notons que la version actuelle du client DHCP viole le RFC en comptant les secondes à partir de 1970 et pas de 2000) et l'adresse MAC, ce qui redonne le même résultat au prix de quelques calculs avec bc.
Mais l'utilisation exclusive du DUID, au détriment de l'adresse MAC, n'est pas une obligation du RFC (le RFC, section 9, dit juste « DHCP servers use DUIDs to identify clients for the selection of configuration parameters », ce qui n'interdit pas d'autres méthodes), juste un choix des développeurs de l'ISC. Le serveur de Dresde, dhcpy6d, permet d'utiliser les adresses MAC, comme on le fait traditionnellement en IPv4. En combinaison avec des commutateurs qui filtrent sur l'adresse MAC, cela peut améliorer la sécurité.
Première rédaction de cet article le 17 janvier 2008
Les règles d'intégrité des SGBD permettent un accès bien plus sécurisé à la base de données et documentent le schéma. Pourquoi mettre de telles règles et comment ?
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : P. Guenther (Sendmail), T. Showalter (Mirapoint)
Chemin des normes
Réalisé dans le cadre du groupe de travail IETF sieve
Première rédaction de cet article le 17 janvier 2008
L'utilisation massive du courrier électronique fait que, même sans compter le spam, chaque utilisateur professionnel reçoit désormais des dizaines et souvent des centaines de messages quotidiens dans sa boîte aux lettres. Il n'est donc plus question de les gérer entièrement à la main, il faut disposer d'un mécanisme de filtrage automatique.
On n'imagine plus aujourd'hui d'utiliser le courrier au bureau sans un tel mécanisme, permettant de mettre les messages dans des dossiers séparés selon, par exemple, la liste de diffusion concernée. Il en existe plusieurs, certains bâtis sur une interface graphique, d'autres autour d'un langage. Ces derniers, bien plus riches et puissants, sont variés. Le plus connu est procmail, célèbre pour son pouvoir expressif (on peut tout faire en procmail) mais aussi pour sa difficulté.
Sieve, l'objet de ce RFC, est nettement moins riche que procmail, ce qui peut être un inconvénient pour les utilisateurs avancés mais un avantage pour l'administrateur : permettre aux utilisateurs de configurer procmail revient à leur donner un accès shell alors que Sieve est plus contrôlable. Comme le note bien notre RFC, Sieve n'est pas un langage de Turing (par exemple, il ne connait pas les boucles). Ses capacités sont limitées, il est sandboxable, c'est-à-dire que l'administrateur système peut facilement limiter les choses que risquent de faire les auteurs de scripts Sieve.
Autre avantage par rapport à procmail, Sieve est normalisé et il en existe plusieurs mises en œuvre, dans Cyrus, dans Dovecot, dans GNU mailutils, dans Archiveopteryx...
Les scripts Sieve sont écrits par l'utilisateur avec un éditeur ordinaire ou bien via une interface graphique. Ils sont installés sur le serveur de messagerie via FTP ou bien par le protocole spécifique Manage Sieve (RFC 5804). Le programme de webmail SquirrelMail, par exemple, dispose d'une interface d'édition de scripts Sieve, qui gère le protocole Manage Sieve.
Voici un exemple de script Sieve inspiré du RFC et amélioré par Mathieu Arnold :
if header :contains "from" "jfc" { discard; } elsif header :contains ["subject"] ["money", "viagra"] { discard; } else { fileinto "INBOX"; }
Sieve lui-même est très limité mais le langage dispose d'un
mécanisme d'extensions (qui doivent être déclarées dans le script avec
require
). Certaines sont définies dès notre RFC (comme
fileinto
), d'autres sont définies via d'autres
RFC, par exemple pour utiliser des tests anti-spam ou antivirus (RFC 5235), ou bien pour tester sur des sous-adresses (RFC 5233).
Notre RFC est la mise à jour du RFC 3028, qui avait été le premier à normaliser Sieve. Les principaux changements (section 15) sont :
reject
, qui migrera vers
un RFC séparé, le RFC 5429.i;octet
et
i;ascii-casemap
sont directement dans Sieve, les
autres sont des extensions (et doivent donc être déclarées avec
require
).Pour les utilisateurs de procmail, il existe un script (que je n'ai
pas testé) pour migrer certaines règles : http://www.earth.ox.ac.uk/~steve/sieve/procmail2sieve.pl
). Si
vous êtes curieux des extensions Sieve, vous pouvez lire tous les articles de mon blog qui en
parlent.
Notez que certains hébergeurs de courrier permettent à leurs clients d'écrire des scripts Sieve, par exemple Gandi. (Ils ne pourraient pas le faire avec un langage plus général comme procmail, pour des raisons de sécurité.)
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : M. Mealling (Refactored Networks)
Pour information
Première rédaction de cet article le 17 janvier 2008
Deux nouveaux membres de la grande famille des
URN, epc:
et
epcglobal:
vont désormais apparaitre dans les
URN, notamment pour désigner les identificateurs portés par les
code-barres ou bien par les puces
RFID.
EPC est le cadre dans lequel sont gérés
plusieurs protocoles et plusieurs familles
d'identificateurs, liés en général à la notion
de chaîne d'approvisionnement. Le but est de suivre des objets physiques passant
dans les entrepôts, les containers, les magasins... Ces objets sont
identifiés par un lecteur de code-barres ou bien par un lecteur
RFID, qui détermine leur identificateur. Par exemple, les identificateurs
GTIN, utilisés dans les
code-barres en font partie (ils sont attribués
par GS1). Ce RFC spécifie
comment représenter ces identificateurs sous forme
d'URN (RFC 8141) commençant par
epc:
. Un autre espace de noms,
epcglobal:
, servira pour les espaces
de noms XML des protocoles
associés.
Le RFC ne fait que résumer la syntaxe de ces nouveaux URN, la
spécification complète est écrite par EPC sous le titre de
EPC Tag Data Standards et ne semble pas disponible
en ligne (EPCglobal est une organisation très fermée, la plupart des
références données par le RFC ne sont pas accessibles). Un exemple
d'un de ces URN est
urn:epc:id:sgtin:0614141.100743.2
, utilisant les
identificateurs SGTIN.
Notons que ces identificateurs pourront peut-être servir d'entrées dans le DNS pour accéder à des informations sur ces objets. C'est le système ONS, qui utilisera les NAPTR du RFC 3401.
Date de publication du RFC : Septembre 2000
Auteur(s) du RFC : K. Lahey
Pour information
Première rédaction de cet article le 16 janvier 2008
Au moment de sa nomalisation, dans le RFC 1191, la découverte de la MTU du chemin semblait une excellente idée, en permettant d'adapter la taille des paquets IP de façon à minimiser la fragmentation. Mais plusieurs problèmes sont surgis à l'usage, notre RFC faisant la liste de ceux qui affectent plus particulièrement TCP.
Pour chaque problème, notre RFC donne un nom, décrit la question, fournit des traces tcpdump et suggère des pistes pour la résolution. Le plus fréquent des problèmes n'est pas spécifique à TCP, c'est le trou noir (section 2.1). Comme la découverte de la MTU du chemin repose sur des paquets ICMP indiquant que le paquet TCP était trop grand pour le lien, tout ce qui empêche de recevoir ces paquets ICMP perturbera la découverte de la MTU. Les paquets TCP seront abandonnés par les routeurs mais on ne verra pas pourquoi, d'où le nom de trou noir.
Qu'est-ce qui peut créer un trou noir ? Il existe plusieurs raisons (le RFC 1435 en donne une particulière) mais la plus fréquente, de loin, est l'ignorance abyssale de certains administrateurs de coupe-feux, qui bloquent complètement tout ICMP pour des « raisons de sécurité » en général fumeuses (un bon test pour détecter cette ignorance est de leur demander si le ping of death est spécifique à ICMP. S'ils disent oui, cela montre qu'ils n'ont rien compris.)
Le problème est suffisamment répandu pour qu'il ai fallu développer un nouveau protocole, où TCP fait varier la taille des paquets pour voir si les gros ont davantage de pertes, protocole décrit dans le RFC 4821. Ce protocole a été développé bien après notre RFC 2923, qui donne des conseils en ce sens mais fait preuve de prudence en craignant que, si les mises en œuvre de TCP réparent ce genre de problèmes, la cause (le filtrage d'ICMP) risque de demeurer (la section 3 revient sur cette question).
Ce débat est récurrent à l'IETF. Faut-il pratiquer la politique du pire, en refusant de contourner les erreurs de configuration (tenter de faire corriger les sites mal configurés est une entreprise courageuse, voire folle), ou bien faut-il essayer de réparer ce qu'on peut, au risque de diminuer la pression sur ceux qui ont fait ces erreurs ?
D'autres problèmes sont, eux, réellement spécifiques à TCP comme les acquittements retardés (section 2.2) provoqués par un envoi des acquittements TCP en fonction de la MSS, qui peut être bien plus grande que la MTU du chemin (cf. RFC 2525). Ce problème n'a pas de solution simple et unique.
Un autre problème lié à la MSS est la détermination de celle-ci (section 2.3). Une implémentation naïve qui déduirait le MSS à partir de la MTU du chemin annoncerait une MSS trop faible et, surtout, ne pourrait pas l'augmenter si un nouveau chemin apparait. La solution est de déduire la MSS de la MTU du réseau local (qui est stable), pas de la MTU du chemin (RFC 1122).
Première rédaction de cet article le 15 janvier 2008
Les IEN (aujourd'hui abandonnés) ne sont pas aussi connus que les RFC mais ce sont souvent des documents utiles sur l'évolution de l'Internet. L'IEN 48, nommé The catenet model for internetworking et écrit par Vint Cerf est un passionnant exposé de l'architecture de l'Internet, avant qu'il ne reçoive ce nom (Cerf, suivant Pouzin, proposait catenet, qui n'a pas pris.)
Dans ce texte de 1978, on trouve une définition des règles que doivent suivre un réseau pour être connecté au catenet : offrir un service de datagrammes rapide, utilisant le format standard (le futur IP), faire tourner un protocole de routage avec le reste du catenet et pas grand'chose d'autres (notamment, il n'est pas exigé de préserver l'ordre des datagrammes, ni même de délivrer tous les datagrammes).
L'IEN discute de la différence entre routeur (nommé gateway à l'époque) et machine terminale, en concluant que les différences ne comptent pas pour le catenet : IP sera le même pour tous.
L'adressage était proche de ce qui sera IPv4, avec des adresses sur 32 bits, mais avec un préfixe de longueur fixe (8 bits).
Comme souvent avec les vrais chefs d'œuvre d'ingéniérie, ce sont les décisions sur ce qu'on ne garde pas qui sont importantes : l'IEN repousse à plus tard les questions de comptage des paquets ou de sécurité, et ce sont ces décisions qui ont permis à l'Internet de se développer, les routeurs pouvant router au lieu de faire la police.
Date de publication du RFC : Janvier 2005
Auteur(s) du RFC : Tim Berners-Lee (World Wide Web Consortium), Roy T. Fielding (Day Software), Larry Masinter (Adobe Systems Incorporated)
Chemin des normes
Première rédaction de cet article le 15 janvier 2008
Le Web repose sur trois piliers : le format HTML, le protocole HTTP et, surtout, le concept d'URI, une famille d'identificateurs à la fois compréhensibles par les humains et automatiquement analysables par les programmes. La syntaxe des URI est normalisée dans ce RFC.
Il y a des URI partout aujourd'hui. Sur le
côté des autobus, sur les cartes de visite, dans les documentations
techniques, dans les articles de la presse papier. Ils sont une des
marques les plus spectaculaires du succès du Web. Peu de gens il y a
quinze ans osaient dire qu'on verrait des URI à la devanture des
boulangeries et des teintureries. Le Minitel
n'avait pas d'équivalent (« Tapez 3615 JERAQUE puis choisissez le menu
Locations puis allez dans Dernières locations ») et même les
informaticiens connectés à Internet utilisaient souvent de telles
descriptions (avant les URI, il n'y avait pas de syntaxe standard et
analysable pour
un nom de fichier accessible en FTP, on disait
« ftp.sunet.se
, dans
/mirrors/macarchive/decoders/foobar.bin
». (Les URI ont été
normalisés pour la première fois dans le RFC 1630 en
1994.) Même si certains utilisateurs n'ont pas encore compris les URI
et donnent des instructions assez miniteliennes à leurs interlocuteurs
comme « Tapez
Locations en Bretagne dans Google » ou bien « Allez sur
www.exemple.fr
et choisissez Locations puis
Bretagne », ils sont largement diffusés, bien au-delà du cercle des
quelques informaticiens et physiciens qui les utilisaient en 1990.
Grâce aux URI, on a donc, pour la première fois, des identificateurs standards, à la syntaxe rigoureuse (donc pouvant être traités par un programme) mais décodables et mémorisables par des humains. Ils permettent de désigner sans ambiguïté une ressource (contrairement aux moteurs de recherche et aux systèmes de mots-clés, qui sont une référence floue et instable).
Aujourd'hui, qu'est-ce qu'un URI, du point de vue des normes ? URI
est le terme qui désigne toute la famille des identificateurs du
Web. Les deux membres les plus connus de cette famille sont les
URL (RFC 1738) et les URN mais
notre RFC préfère ne pas trop utiliser ces termes et ne parler que
d'URI (section 1.1.3, voir aussi RFC 3305), entre autres
parce que le statut de « localisateur » (locator)
n'est pas clair (un URI http
n'est pas forcément
un URL, voir section 1.2.2). La syntaxe qui est décrite dans le RFC est
générique, elle s'applique à tous les URI, quel
que soit leur plan (scheme), la partie de l'URI avant le
premier deux-points. Des
syntaxes plus précises et plus restrictives peuvent être spécifiées
par certains plans (le plus connu des plans est
http
). Notre RFC fournit, lui, ce qui est commun à tous
les plans.
Le « cahier des charges » avait été écrit dans les RFC 1736 et RFC 1737. Le premier RFC qui l'avait mis en œuvre était le RFC 2396, que notre RFC 3986 remplace. Les trois lettres du sigle URI indiquent bien la démarche (section 1.1) :
La section 1.1.1 décrit la syntaxe générique, détaillée en section 3 : un URI commence par un plan, suivi d'un deux-points, d'une autorité optionnelle (par exemple le nom de domaine d'une machine), puis d'un chemin (path), dont la syntaxe dépend du plan, d'une requête optionnelle et d'un fragment optionnel. Voici quelques exemples d'URI, inspirés du RFC :
http://fr.wikipedia.org/wiki/Jacques_Brel ldap://[2001:DB8::7:23A]/dc=example,dc=org?objectClass?one tel:+1-816-555-1212 urn:oasis:names:specification:docbook:dtd:xml:4.1.2
Ainsi,
droite://example.org:8042/par/ici?label=ChezMoi#note
se décompose en :
droite
: le plan,example.org:8042
: l'autorité,/par/ici
: le chemin,label=ChezMoi
: la requête,note
: l'identificateur d'un fragment.En Python, on peut facilement analyser un URI avec le module urlparse :
>>> from urlparse import urlparse >>> scheme,authority,path,params,query,fragment = urlparse("http://fr.wikipedia.org/wiki/Jacques_Brel#Discographie") >>> scheme 'http' >>> path '/wiki/Jacques_Brel' >>> fragment 'Discographie'
La section 1.2 revient sur les choix de conception. Elle part d'un scénario où deux personnes échangent des URI en les notant sur une nappe en papier dans un restaurant, ce qui nécessite des URI parlants, mais écrits dans un alphabet répandu (demande qui peut être contradictoire avec la précédente). D'une manière générale, il est préférable d'utiliser de beaux URI. C'est également dans cette section qu'est posé le principe que les URI n'utilisent qu'un jeu de caractères très limité, un sous-ensemble d'ASCII. Cette limite très contraignante est levée avec les IRI du RFC 3987.
La suite de la section parle du problème important de la
récupération (retrieval) d'une
ressource. Une des utilisations les plus courantes d'un URI est pour
accéder à une ressource. Cela nécessite que l'URI soit
résolvable (ce qui n'est pas, en général, le cas
des URN). Mais tous les URI ne sont pas forcément résolvables, ne
serait-ce que parce qu'ils peuvent n'être utilisés que comme
identificateurs (c'est le cas, par exemple, des URI identifiant un
espace de noms XML). Le RFC insiste aussi sur
le fait que le plan n'est pas, en général, un protocole réseau. Même quand
cela semble être le cas (URI http
), divers
mécanismes font que la ressource peut être récupérée par d'autres
moyens que le protocole indiqué (par exemple, pour les documents XML,
on utilise typiquement un catalogue qui indique
une correspondance entre un URI et un fichier local, de sorte que le
processeur XML n'aie pas besoin d'aller sur le réseau).
Puis cette section 1.2 discute le caractère hiérarchique des URI, avec ses composants allant du plus significatif, le plan, tout à fait à gauche, au moins significatif, à droite (à noter que les séparateurs des composants varient, ce que n'auraient pas apprécié Rob Pike et Peter J. Weinberger).
La section 2 est consacrée aux caractères utilisés pour former un
URI, uniquement ASCII, on l'a vu. La section 2.2 donne une liste des
caractères qui, quoique présents dans ASCII, ne peuvent pas être
utilisés pour un URI car ils ont une signification spéciale. C'est le
cas par exemple du # qui introduit
l'identificateur d'un
fragment de la ressource. La section 2.1 normalise le codage
« pour cent » où les caractères non-ASCII sont remplacés par le signe
% suivi de leur valeur en
hexadécimal. (C'est hélas la valeur de chaque octet, pas le point de
code Unicode.) Malheureusement, la section 2 précise qu'aucun
encodage particulier n'est choisi. Il est donc
très difficile de faire des URI utilisant des caractères non-ASCII,
même en utilisant le codage « pour cent » puisqu'il n'y a pas de moyen
d'indiquer l'encodage utilisé. Ainsi,
http://example.org/caf%E9
est sans doute du
Latin-1 mais sans qu'on puisse en être sûr. On
limite les risques en supposant que l'encodage est
UTF-8 comme dans l'URI
http://fr.wikipedia.org/wiki/caf%C3%A9
(C3 A9
est l'encodage en UTF-8 du e accent aigu).
L'encodage d'une chaîne de caractères pour en faire un URI peut être effectuée en XSLT par la fonction EXSLT str:encode-uri, par exemple ainsi :
<xsl:value-of select="str:encode-uri($word, true())"/>
ou bien en Python avec la fonction quote
de la bibliothèque
urllib :
>>> from urllib import quote >>> quote("foo # bar ?") 'foo%20%23%20bar%20%3F'
Voyons plus en détail les différents composants d'un URI. Le
plan, d'abord, décrit en section 3.1. Notre RFC ne contient pas de liste de
plans. Ils doivent être enregistrés à l'IANA,
comme indiqué dans le RFC 7595
(on peut aussi voir le RFC 2718). Les plans les plus connus
sont http
, mailto
et
urn
. tag
(RFC 4151) est moins connu mais est un de mes favoris.
L'autorité (section 3.2) indique quelle entité
va gérer le reste de l'URI. Pour un URN, c'est un simple nom (comme
isbn
pour les ISBN du RFC 8254).Pour le plan http
, l'autorité est
un nom de domaine ou une adresse IP. Dans ce cas, elle peut aussi inclure un nom
d'utilisateur, pour l'authentification. Si l'adresse IP est
IPv6, il faudra un échappement spécial (la
mettre entre crochets), décrit dans le RFC. Enfin, il peut y avoir un
numéro de port, bien que cela pose un problème
avec les enregistrements SRV
(RFC 2782) qui
peuvent aussi spécifier un port.
Le chemin (section 3.3) indique une ressource particulière
pour une autorité. Il est composé de plusieurs parties séparées par
une barre oblique (pour des raisons
historiques : c'est le séparateur de répertoires sur Unix). Si l'URI est de type http
et
que les pages Web sont des fichiers HTML
statiques, le chemin est un répertoire sur le disque dur, mais ce
n'est pas forcément le cas pour tous les URI, loin de là !
La requête (section 3.4), située après le ? est un composant optionnel de l'URI. Elle est utilisée typiquement pour les ressources générées dynamiquement, en réponse à la question que représente ce composant, mais rien dans la norme n'oblige à les utiliser pour cela.
Le fragment (section 3.5), qui se place après
le # désigne une partie
de la ressource. Si l'URI est résolvable, le fragment est interprété
par le client uniquement, le serveur ne le voit pas. L'exemple le plus
courant est un fragment composé d'un nom, par exemple, si la ressource
est en HTML, un attribut name
ou
id
d'un élément HTML.
La section 4 explique l'utilisation des URI par un programme. Elle
couvre le cas d'URI relatifs (la section 5
développe ce point) ou bien, dans la section
4.5, d'URI dont le début, par exemple le plan, manque. De tels URI sont
courants
dans la presse ou la publicité, par exemple
www.afnic.fr
au lieu de
http://www.afnic.fr/
. Le RFC note que cette
pratique, quoique courante, est dangereuse car elle dépend du contexte
pour une bonne résolution. Elle ne devrait pas être utilisé pour des
URI à longue durée de vie.
La section 6 s'attaque à un problème difficile, la
normalisation des URI. On a souvent besoin de
comparer deux URI. Par exemple, un navigateur
Web affiche les pages déjà visitées avec une couleur
différente. Pour cela, il doit comparer les URI présents dans la page
Web avec son historique des liens visités. Or, faire cette
comparaison octet par octet peut rater beaucoup d'égalités. Par
exemple, le plan est insensible à la casse donc
urn:bortzmeyer:exemple:1
est égal à
URN:bortzmeyer:exemple:1
. D'autres
canonicalisations dépendent du plan. Par exemple, avec les URI
http
, l'autorité est un nom de domaine et les
noms de domaine sont insensibles à la casse donc
http://www.demaziere.fr/eve/
est égal à
http://www.Demaziere.FR/eve/
(la section 6.2.2.1
détaille les comparaisons insensibles à la casse ; sauf indiqué
explicitement, les composants d'un URI sont sensibles à la casse). Le navigateur doit
donc normaliser les URI avant de les comparer.
Le RFC note qu'aucune normalisation ne sera parfaite. Après tout, deux URI différents peuvent parfaitement indiquer la même ressource, sans que le logiciel ne puisse le deviner.
Une section 7 détaille les questions de sécurité associées aux URI. Elle note que beaucoup de ces questions n'ont pas de solution technique et qu'elles dépendent d'une approche sociale. Par exemple, la persistence des URI, un sujet de recherche très actif, dépend plutôt de bonnes pratiques sociales (notamment d'organisations stables, et qui peuvent voir sur le long terme) que d'une technique particulière. Une autre question de sécurité est traitée dans la section 7.6, c'est celle du hameçonnage, pour les cas où l'auteur du site de hameçonnage tente de fabriquer des URI trompeurs (très peu d'utilisateurs vérifient les URI et la plupart des hameçonneurs ne se donnent même pas la peine d'en fabriquer de vraisemblables). La syntaxe des URI est suffisamment compliquée pour que certains URI soient difficiles à décoder par un humain.
Enfin, notons que l'appendice D expose toutes les différences entre ce RFC et son prédécesseur, le RFC 2396. La principale est la section sur la normalisation, qui a été complètement refaite, mais il y en a beaucoup d'autres, en général de faible importance.
Date de publication du RFC : Octobre 2006
Auteur(s) du RFC : S. Josefsson (SJD)
Chemin des normes
Première rédaction de cet article le 14 janvier 2008
Dernière mise à jour le 29 septembre 2012
Même les plus simples encodages peuvent réveler des surprises. Base64 en est désormais à son quatrième RFC, mais il est vrai que c'est un des formats les plus utilisés, qu'on le trouve partout dans les protocoles. Ce RFC normalise donc Base64, ainsi que Base32 et Base16.
Quel est le problème que tentent de résoudre ces encodages ? Le fait que certains environnements n'acceptent pas le jeu de caractères qu'on voudrait utiliser. C'est bien sûr le cas si ce jeu de caractères est Unicode mais même le simple ASCII peut être trop vaste pour certains usages. Par exemple, les URL ne peuvent pas comporter d'espace, et nécessitent donc un encodage de ces espaces, pour les protéger. Base64 et ses camarades sont des encodages généralistes pour tous ces cas où on doit réduire d'un jeu de caractères trop vaste à un jeu restreint : Base64 (sections 4 et 5) utilise 64 caractères (les majuscules et les minuscules d'ASCII, les chiffres, le signe plus et la barre oblique). Base32 (sections 6 et 7) utilise uniquement les majuscules et les chiffres et Base16 (section 8, mais il faut noter que ce nom de Base16 n'a jamais pris) utilise uniquement les caractères des chiffres hexadécimaux (il sert par exemple, sous un autre nom, à l'encodage des URL, cf. RFC 3986, section 2.1).
La section 3 du RFC est très détaillée car elle doit expliquer tous les problèmes d'interopérabilité qui peuvent se poser avec l'encodage, notamment si celui-ci est incomplètement spécifié (ce qui était le cas avec les RFC précédant celui-ci, comme le RFC 2045). Ainsi, la section 3.1 parle du difficile problème des sauts de ligne, ou bien 3.3 se demande ce que doit faire le récepteur si des caractères en dehors du jeu normalement utilisé apparaissent néanmoins dans les données. Le monde des encodages est vaste et peu organisé... Heureusement que ce RFC décrit bien l'état actuel du problème.
Historiquement, des tas de variantes plus ou moins importantes d'un de ces encodages ont été utilisées, ce qui contribue à la difficulté de la tâche de décodeur. La section 5 normalise une de ces variantes, un encodage de Base64 qui n'utilise pas le / et le +, qui ont souvent une signification particulière, mais le _ et le -. Comme il est surtout utilisé pour les URL, cet encodage est souvent nommé URL encoding.
La section 12, sur la sécurité, est également très complète car, historiquement, plusieurs problèmes de sécurité ont été liés à ces encodages. Par exemple, beaucoup de spams sont encodés en Base64, même lorsque cela n'est pas nécessaire, pour tenter d'échapper à des logiciels de filtrage naïfs. (C'est au point que SpamAssassin donne désormais une mauvaise note aux messages ainsi encodés.)
Du fait de l'étendue des usages de Base64, il existe des bibliothèques pour l'encoder et le décoder dans tous les langages de programmation (Base32 est moins bien traité). Le RFC cite également une implémentation de référence en C.
Voici un exemple d'encodeur en Perl :
#!/usr/bin/perl use MIME::Base64; foreach $word (@ARGV) { print("$word: " . encode_base64($word) . "\n"); }
Et un exemple de décodage en une seule ligne de Perl :
% echo Y2Fm6Q= | perl -MMIME::Base64 -e 'printf "%s\n", decode_base64(<>)'
Cet autre exemple est en D :
static import std.base64; import std.stdio; int main(char[][] argv) { int argc = argv.length; char[] word; if (argc <= 1) { writefln("Usage: %.*s word ...", argv[0]); return 1; } for (int i = 1; i < argc; i++) { // It would be cooler to use 'foreach (char[] word; argv)' but it // does not allow to skip 0th arg (and slices do not seem to work // in that context) word = argv[i]; writefln("%s: %s", word, std.base64.encode(word)); } return 0; }
Voici un exemple d'encodage Base64 en Go, montrant la différence entre l'encodage standard et l'« encodage URL » :
package main import ( "bufio" "encoding/base64" "flag" "fmt" "io" "os" ) const MAXSIZE int = 4096 func main() { result := make([]byte, MAXSIZE) value := make([]byte, MAXSIZE) rd := bufio.NewReader(os.Stdin) n, error := rd.Read(value) ... base64.StdEncoding.Encode(result, value[0:n]) fmt.Printf("Standard encoding of %s is %s\n", value[0:n], result) base64.URLEncoding.Encode(result, value[0:n]) fmt.Printf("URL encoding of %s is %s\n", value[0:n], result) }
Depuis le shell, on cite parfois le logiciel aish, mais je l'ai toujours trouvé inutilisable. Je préfère OpenSSL qui a une option d'encodage en Base64 (l'argument -n d'echo permet de voir la différence selon qu'il y a un saut de ligne ou pas) :
% echo -n café | openssl enc -base64 Y2Fm6Q== % echo café | openssl enc -base64 Y2Fm6Qo=
Et, pour décoder :
% echo Y2Fm6Qo= | openssl enc -d -base64
Notre RFC 4648 succède au RFC 3548 (qui lui même complétait le RFC 2045 sur ce point). La section 13 liste les changements (modérés), comme par exemple l'ajout d'exemples à des fins de tests des logiciels.
Première rédaction de cet article le 10 janvier 2008
Un terrible roman d'Elsa Osorio, sur la répression dans l'Argentine de la dictature militaire. L'héroïne a été enlevée, tout bébé, à sa mère, qui était prisonnière des militaires, et « donnée » à la famille de l'un d'eux. Devenue adulte et mère, elle part à la recherche de la vérité. C'est tendre, sensible, humain et pourtant très violent (et la première partie, qui se passe au plus fort de la répression, n'est pas forcément la plus dure).
Première rédaction de cet article le 10 janvier 2008
Dernière mise à jour le 14 janvier 2008
Beaucoup de sites Web affichent, dès qu'on dépasse la page d'accueil, et même parfois dès la page d'accueil, des URL incompréhensibles, très longs et bourrés de paramètres dont l'utilisateur ne connait pas la signification. C'est déplorable, à la fois pour des raisons esthétiques et pour des raisons pratiques. Pourquoi est-ce regrettable ? Comment éviter cela ?
Prenons quelques exemples affreux. L'UNESCO
proclame 2008 l'« Année Internationale des Langues » et la page Web de
présentation de l'activité est à l'URL http://portal.unesco.org/culture/en/ev.php-URL_ID=35559&URL_DO=DO_TOPIC&URL_SECTION=201.html
.
Pourquoi ne pas avoir utilisé le plus court et plus parlant
http://www.unesco.org/iyl
?. Autre exemple, si on
se promène sur le site de Dell à la recherche
d'informations sur le Latitude
430, on arrive en http://premierconfigure.euro.dell.com/dellstore/config.aspx?cs=RC1077983&customer_id=RC1077983&oc=LD4301&~tgt=global_cfg&c=FR&l=fr&s=PAD
.
Pourquoi ne pas avoir un URL comme
http://www.dell.com/computers/latitude-d430/
? Un
dernier exemple, alors que la loi est censée être facilement
accessible à tous, il n'existe pas de moyen de fabriquer facilement
l'URL pour, mettons le « Décret n°2006-1386 du 15 novembre 2006 fixant
les conditions d'application de l'interdiction de fumer dans les lieux
affectés à un usage collectif ». Sur
Légifrance, on arrive à un URL de http://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000000818309&dateTexte=20080124&fastPos=5&fastReqId=621185253&oldAction=rechTexte
.
Pourquoi pas http://www.legifrance.gouv.fr/decrets/2006/11/15/1386
?
Manifestement, le webmestre de Légifrance a lui-même des problèmes
avec de tels URL puisque, lorsqu'on regarde l'article R3512-1 du Code
de la Santé Publique, et qu'on voit un beau lien vers le décret, ce
lien ne fonctionne pas « Aucun document ne correspond à votre demande » !
C'est très laid. De tels URL heurtent mon sens esthétique. Pour se remonter le moral, voici quelques exemples de beaux URL :
http://fr.wikipedia.org/wiki/Valeria_Bruni-Tedeschi
. À part la
mention "wiki" qui semble tout à fait inutile, les URL de
Wikipédia sont courts et le sujet est connu à l'avance.http://embruns.net/carnet/actus-et-opinions/miss-france-2007.html
.
Comme souvent sur les blogs, un URL
parlant, qui résume le sujet.http://www.rueducommerce.fr/Ordinateurs/Ordinateur-Portable/Ordinateur-Portable-Grand-Public/LENOVO/419103-Ordinateur-Portable-Lenovo-3000-N200-Intel-Celeron-M-530-1-73-GHz-Ecran-15-4.htm
.
Les sites commerciaux peuvent avoir des URL corrects, eux aussi, même
si celui-ci est probablement trop détaillé, incluant même la vitesse
du processeur...http://www.humanite.fr/2007-06-14_Societe_En-Chine-Google-censure-a-tour-de-clic
.
L'URL est parlant : il inclut la date (ce qui est logique pour un
quotidien) et un résumé du titre (comme le font souvent les moteurs de
blog).http://del.icio.us/bortzmeyer/fran%C3%A7ais
. Les
URL de del.icio.us sont excellents (ici, le nom
de l'utilisateur et le tag choisi) mais un problème
technique a rendu celui-ci peu lisible. Originellement (RFC 1738), les URL devaient s'exprimer uniquement en
ASCII. Les IRI du RFC 3987 ont supprimé cette restriction mais ils ne sont pas
encore très répandus (par exemple, mon validateur RelaxNG ne me permet pas d'en mettre dans ce blog car, dit-il, Relax-NG validity error : Type anyURI doesn't allow value 'http://del.icio.us/bortzmeyer/français'). Essayez http://del.icio.us/bortzmeyer/français"
pour voir si votre
navigateur gère les IRI.http://www.figoblog.org/node/1903
. L'URL (pris sur
le site Figoblog) est court
et propre mais pas décodable (pourquoi 1903 ? Ce n'est qu'un
identificateur interne.) Mais c'est cohérent avec le discours de son
auteure, qui estime qu'un identifiant stable ne doit pas avoir de
sémantique (car un changement de sémantique pourrait changer
l'URL).Outre l'aspect esthétique, les URL laids posent aussi des problèmes pratiques (également bien détaillés dans un excellent article de Jakob Nielsen). Étant longs, ils sont difficiles à copier-coller, par exemple dans un courrier. Révélant le fonctionnement interne du site Web (noms des paramètres, type de langage utilisé comme PHP pour le site de l'UNESCO), ils ne sont pas stables. Si le site passe à un autre CMS, ces URL changeront probablement, en contradiction avec les principes posés dans l'article Cool URIs don't change.
Surtout, ces URL sont « indécodables ». Avec la meilleure volonté du monde, on ne peut pas les comprendre, on ne peut pas les mémoriser et on ne peut pas les bricoler de manière créative, par exemple en changeant la valeur d'un paramètre.
De tels URL sont parfois volontaires, par exemple pour décourager la création de « liens profonds » (liens hypertexte pointant vers une autre page que la page d'accueil). Pourquoi diable voudrait-on décourager les liens profonds ? Typiquement pour empêcher le lecteur d'accéder directement à l'information qui l'intéresse et pour l'obliger à suivre le parcours officiel, partant de la page d'accueil.
De tels URL très longs sont parfois volontaires parce qu'il y a
beaucoup d'informations à indiquer. C'est le cas des URL de
Google Maps où il y a beaucoup à encoder
(notamment longitude et latitude). Par exemple, dans http://www.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=san+cristobal+de+las+casas,+chiapas,+mexico&sll=16.75655,-93.129044&sspn=0.425394,0.579529&ie=UTF8&ll=16.738551,-92.633286&spn=0.053179,0.072441&t=h&z=14&iwloc=addr&om=1
, les chiffres dans le paramètre ll
indiquent la latitude et la longitude. Mais de
tels URL ne sont pas gratuitement compliqués, ils stockent de
l'information et ils sont décodables et modifiables. Notamment, je
peux générer un tel URL facilement, sans avoir besoin de Google
Maps, ce qui permet des applications géographiques intéressantes de
type mashup. Par exemple,
comme le service Vélib' donne accès à
la latitude et la longitude de chaque station (dans le fichier http://www.velib.paris.fr/service/carto
), on peut facilement faire un programme qui crée un URL
Google Maps pour chaque station, comme c'est le cas sur des sites
comme Roulib ou bien http://v.mat.cc/
. D'ailleurs, il existe même un langage pour décrire ces gabarits d'URL, normalisé dans le RFC 6570.
Mais, la plupart du temps, ces URL sont complexes car le webmestre a installé un logiciel de gestion du site Web (qu'il n'a pas toujours choisi) et que ce sont les URL par défaut du logiciel et que le webmestre ne peut pas ou ne sait pas les modifier (ou, pire, n'a pas compris à quoi servaient les URL).
A contrario, certains logiciels, comme la plupart des moteurs de blogs, fabriquent des URL clairs et simples, et faciles à décoder. Ils ne sont pas forcément stables sur le long terme (les professionnels de la stabilité suggèrent en général de ne pas mettre trop d'information dans l'URL car un changement de cette information changerait l'identificateur) mais ils sont bien agréables à manipuler.
Alors, que peut-on faire pour ne pas avoir de tels URL ? Si le
webmestre est impossible à faire évoluer sur ce sujet (souvent, il ne
lit même pas ses
messages), il existe des mécanismes de contournement comme
tinyurl. Ces systèmes créent une correspondance
entre un URL et un identificateur à eux, et fournissent un service de
redirection automatique. C'est ainsi que http://tinyurl.com/2u2ewd
va au même
endroit que l'affreux URL de l'UNESCO cité plus haut. Mais ces
mécanismes ont leurs propres inconvénients,
notamment le fait que l'URL soit encore moins décodable qu'avant (on
ne voit même pas le nom de domaine, donc on ne
peut pas savoir qui est responsable).
L'idéal est donc quand le webmestre fait bien son travail. Pour
l'aider, voyons quelques techniques utiles. Notons d'avord qu'il
n'existe aucune raison technique valable d'utiliser des URL
affreux. On voit parfois certains débutants croire que des URL
incluant un point d'interrogation sont nécessaires si la recherche de
l'information est dynamique (par exemple
http://www.maboutique.fr/catalogue?objet=642342
).
Mais c'est faux, l'URL est indépendant de la méthode utilisée pour
générer la page. On peut avoir un URL qui va faire une
recherche dynamique dans une base de données, sans point d'interrogation dedans. (On notera que, soucieux de
prouver chaque jour qu'on peut breveter n'importe quoi, l'office
états-unien des brevets a enregistré un brevet
n° 7,287,042 qui réserve cette technique à
Amazon, en dépit de nombreux précédents
d'utilisation, que l'incompétence ou la malhonnêteté de l'office des
brevets ne lui a pas permis de détecter.)
Notons d'abord que beaucoup de CMS ou de logiciels équivalents permettent de faire facilement des beaux URL. Si ce service n'est pas activé par défaut, il est souvent bien documenté. Par exemple, le CMS SPIP a une documentation détaillée « Utiliser des URLs personnalisées ».
Sinon, la solution générale, si on n'est pas l'auteur du CMS utilisé ou bien qu'on n'a pas envie de se plonger dans le code source est, si on utilise Apache, de se servir de l'excellent (mais complexe) module mod_rewrite
.
Première rédaction de cet article le 9 janvier 2008
Aujourd'hui, avec les mécanismes d'allocations d'adresses IP existants (cf. RFC 7020), il est relativement fréquent d'avoir à changer son adresse IP. Quelles sont les précautions particulières liées au DNS lors de ce changement ?
Supposons donc qu'un utilisateur aie une machine à lui chez Slicehost, Gandi, OVH ou un autre. L'adresse IP de cette machine est « fixe » au sens où elle ne change pas toutes les 24 heures, mais rien ne garantit qu'elle ne changera jamais. Une nouvelle configuration du réseau, un changement de fournisseur (pour les hébergeurs qui n'ont pas leurs propres adresses IP) et on doit changer. Il existe plusieurs précautions à prendre lors d'un tel changement mais on ne parle ici que de celles liées au DNS.
D'abord et avant tout, il faut penser que les informations distribuées par le DNS sont gardées dans des caches. La durée de vie maximale dans le cache est gouvernée par un paramètre nommé le TTL (RFC 1034, section 3.6), que l'administrateur de la zone fixe lui-même. Il est recommandé de réduire ce TTL avant le changement.
dig peut afficher le TTL, ce qui permet de vérifier la configuration serveur :
% dig @mon-serveur A www.venezvoirchezmoi.fr. ... www.venezvoirchezmoi.fr. 86400 IN A 192.0.2.249
Le TTL indiqué par le serveur faisant autorité est donc de 86400 secondes. Sur un serveur ne faisant pas autorité, le TTL diminue petit à petit et indique donc combien de temps il reste avant le renouvellement du cache :
% dig A www.venezvoirchezmoi.fr. www.venezvoirchezmoi.fr. 33982 IN A 192.0.2.249
Cette deuxième requête a interrogé le résolveur local, qui ne fait pas autorité, et a donné l'information à partir de son cache. L'enregistrement était déjà dans ce cache depuis 86400 - 33982 = 52418 secondes.
Cas le plus simple ; soit un bête enregistrement ordinaire qui stocke une adresse IP d'un serveur Web (ici, en IPv6) :
www IN AAAA 2001:DB8::DEAD:BABE
Son TTL va être donné (si on utilise BIND ou NSD) par la directive
$TTL
. Mais on peut la
changer pour chaque enregistrement :
www 300 IN AAAA 2001:DB8::DEAD:BABE ; Trois cents seconds, soit cinq minutes
Ainsi, lors du changement d'adresse, il n'y aura que cinq minutes de problème au maximum.
On peut descendre le TTL à 60 si on est pressé, mais il vaut mieux éviter de l'abaisser à zéro, pas mal de FAI l'ignorent (car il y a trop d'abus) et le forcent à une valeur plus élevée (ce qui, formellement, viole le RFC).
Évidemment, il faut faire ce changement de durée de vie à l'avance (si le TTL actuel est de 86 400 secondes, il faut faire le changement au moins une journée avant).
À l'heure H, on peut alors changer l'enregistrement (ici le AAAA, l'heure H est celle où on indique la nouvelle adresse IP). Il ne faut pas remonter le TTL tout de suite, il faut tester d'abord que tout marche bien.
Le TTL ne gouverne que la durée de vie dans les caches des
résolveurs ne faisant pas autorité. Pour les serveurs faisant autorité
sur la zone (le maître, autrefois nommé « primaire » et les esclaves,
autrefois nommés « secondaires »), il faut aussi surveiller leur
synchronisation. Si, par exemple, les NOTIFY (messages DNS normalisés
dans le RFC 1996 et permettant de prévenir immédiatement les esclaves) sont ignorés (il peut y avoir
des tas de raisons pour cela), le temps de synchronisation va
s'ajouter au TTL. Les esclaves ayant raté le NOTIFY ne seront
synchronisés qu'au prochain test. Les tests sont effectués toutes les
Refresh
secondes, avec rééssai toutes les
Retry
secondes en cas d'échec. Les paramètres
Refresh
et Retry
sont fixés
dans l'enregistrement SOA. On voit donc l'importance de tester la
synchronisation des serveurs de la zone avant
l'heure H.
Maintenant, cas compliqué, l'adresse IP peut se trouver à d'autres endroits que la zone :
Un coup de grep dans
/etc/**
est donc recommandé pour trouver toutes
les occurrences de l'ancienne adresse IP.
Pour le cas registre / registrar, ça dépend de leur réactivité combinée. Là encore, il vaut mieux étudier avant. Il est donc prudent de prévoir un recouvrement (ancien serveur qui marche toujours) si on change la colle (enregistrements d'adresses qui sont stockés dans la zone parente).
Cette question étant souvent celle qui pose le plus de problèmes, il faut donc faire doublement attention lorsqu'on change l'adresse IP d'une machine qui est serveur de noms, surtout lorsqu'elle a un nom dans la zone servie (obligeant ainsi le registre à garder la colle).
Prenons l'exemple de la machine 192.0.2.53
,
qui est connue sous le nom de ns1.example.com
et
qui est serveur de noms de la zone
example.com
. Le fait qu'elle soit nommée dans la
zone qu'elle sert oblige le registre de
.com
à distribuer la
colle, et donc à mémoriser l'adresse IP (certains registres gardent
l'adresse IP des serveurs même lorsqu'elle n'est pas nécessaire, ce
qui est mal vu, mais arrive). Son changement d'adresse va donc
nécessiter de vérifier l'information distribuée par le registre (et
mise à jour via le registrar puisque
.com
impose le passage par
un intermédiaire). Voyons avec dig comment vérifier l'adresse
distribuée par le registre, en interrogeant les serveurs de noms de
Verisign :
% dig @a.gtld-servers.net A ns1.example.com. ns1.example.com. 172800 IN A 192.0.2.3
(Notez que cette réponse ne fait pas autorité, le
flag aa
sera donc absent.)
Le DNS ne reflète pas toujours l'état actuel de la base de données du
registre. Selon les cas, il peut être prudent de vérifier avec
whois :
% whois -h whois.internic.net ns1.example.com Server Name: NS1.EXAMPLE.COM IP Address: 192.0.2.3
Ces deux commandes permettent de voir si les changements ont bien été transmis au registre, et exécutés.
Date de publication du RFC : Janvier 2008
Auteur(s) du RFC : J. Rosenberg, C. Jennings (Cisco)
Pour information
Réalisé dans le cadre du groupe de travail IETF sipping
Première rédaction de cet article le 5 janvier 2008
Le spam est la plaie du courrier électronique. Peut-il également affecter d'autres services comme la téléphonie sur IP ? C'est la crainte de l'IETF, d'où ce RFC qui étudie les moyens de faire face au spam via le protocole SIP, avant que ce phénomène se développe.
Rien n'indique que le spam restera limité au courrier électronique. Au contraire, l'expérience semble indiquer que, du moment qu'une technique permet de joindre beaucoup de personnes pour pas cher, et sans introduction préalable, elle est utilisée par les spammeurs. Les techniques soi-disant « sans spam » sont uniquement celles qui ne sont peu ou pas utilisées, ou qui sont chères et peu pratiques.
Le message principal du RFC est qu'il faut s'y prendre à l'avance. Le spam aurait été plus facile à combattre si on avait déployé certaines techniques dès le début. Pour le protocole SIP (RFC 3261), de loin le principal protocol ouvert pour faire du multimédia, notamment de la téléphonie, sur Internet, il est donc peut-être encore temps d'agir. (Je suis personnellement prudent par rapport à cette affirmation. Pour le courrier électronique, je n'ai pas encore vu de solution qui, si elle avait été déployée plus tôt, aurait empêché le spam de prendre une telle ampleur.)
La section 2 explique les formes que pourrait prendre le spam avec
SIP. Elle note qu'il n'est pas forcément nécessaire d'envoyer un
message pour spammer. Par exemple, SIP a une méthode INVITE qui peut
prendre un en-tête Subject:
(section 20.36 du
RFC 3261). Si ce sujet est affiché à
l'utilisateur avant même qu'il n'accepte l'appel (ce que font certains
soft phones), il peut servir de canal pour le
spam.
Cette particularité de SIP, et quelques autres, font que certaines des techniques couramment utilisées pour le filtrage du courrier ne sont pas forcément efficaces. Ainsi, le filtrage par contenu (section 3.1 de notre RFC), comme les filtres bayésiens, n'est pas tellement appliquable dans le cas d'un message audio, encore moins pour un message vidéo.
Le RFC insiste sur importance de l'identité. Beaucoup de techniques marchent si on peut être à peu près certain de l'identité de l'émetteur. Par exemple, les listes blanches sont facilement prises en défaut si le spammeur peut se faire passer pour une personne connue. Le problème est d'autant plus difficile qu'on voudrait authentifier la personne, pas uniquement son ordinateur car, comme le note la section 3.3, si l'ordinateur est compromis et est devenu un zombie, l'authentifier ne servira à rien.
Un autre problème classique des listes blanches est le fait qu'elles ne gèrent que le cas des personnes proches. Le RFC propose dans sa section 3.5, d'utiliser les mécanismes de réseau social (« mes copains ont aussi des copains ») pour augmenter automatiquement les listes blanches (la plupart des logiciels SIP, comme les logiciels d'IM, ont un système analogue, en général nommé buddy list, liste des copains).
En revanche, les techniques de dissimulation d'adresses, comme on
voit pour le courrier (stephane plus blog à bortzmeyer point
org
) ne fonctionnent pas bien si on reste aux traditionnels
numéros de téléphone. L'espace possible est en effet restreint et
relativement facile à parcourir de manière exhaustive
(ENUM facilitera probablement les choses pour les spammeurs).
Les approches du problème peuvent aussi être basées, non pas sur une technique mais sur une organisation. Une architecture possible est décrite en section 3.13, avoir un petit nombre de fournisseurs SIP qui se transmettent des coups de téléphone entre eux, et n'en acceptent pas des autres fournisseurs. Un tel cartel, qui ressemble aux propositions de mail peering qui sont proposées pour le courrier par des organismes comme le MAAWG ou comme le FAI AOL aurait, note notre RFC, tous les avantages et tous les inconvénients de l'actuel réseau téléphonique, que SIP visait à remplacer.
Finalement, la section 6 du RFC est consacrée aux quatre recommendations importantes :
Première rédaction de cet article le 4 janvier 2008
On le sait, les médias traditionnels n'aiment pas leur concurrent Internet. Mais l'édition 2006 du Larousse du Collège attaque particulièrement durement.
Cette édition du dictionnaire Larousse est destinée « aux 11-15 ans », un public sensible, qui rentre au collège. Outre des erreurs comme de faire remonter la naissance d'Arpanet à... 1957, on trouve dans cet article la conclusion suivante :
« Internet serait-il une machine qui s'emballe ? Devant le manque d'encadrement juridique, le système semble autoriser toutes les libertés. Internet consacre le piratage comme une sorte de sport international. S'introduisant dans le réseau, les crackers et les hackers [le second terme est absent de ce dictionnaire] inventent tous les moyens pour ruser. Ne parlons pas de la désorganisation des réseaux, vaste entreprise qui ressemble bien à une nouvelle forme de guerre. Par la force des images terrorisantes et des exécutions en direct, ce formidable outil peut à la fois servir de propagande et nous déstabiliser psychologiquement. C'est ce type d'infractions pénales que l'on désigne sous le terme de « cybercriminalité ». »
« Il est quasiment impossible de maîtriser le volume de données qu'Internet met à la disposition, de les classer ou de les hiérarchiser, d'en vérifier la fiabilité à cause de l'opacité des sources. Par ces lacunes, Internet ne risque t-il pas de devenir un moyen de manipulation planétaire ? »
Il n'y manque qu'une attaque contre Wikipédia pour que cet article soit la liste complète des préjugès anti-Internet :-)
Date de publication du RFC : Septembre 1981
Auteur(s) du RFC : J. Postel (University of Southern California (USC)/Information Sciences Institute)
Statut inconnu, probablement trop ancien
Première rédaction de cet article le 4 janvier 2008
Protocole auxiliaire d'IP depuis le début, ICMP est toujours un des protocoles essentiels de l'Internet. Sa version pour IPv4 est normalisé dans ce RFC.
Un très vieux RFC que notre RFC 792. À l'époque, on parlait encore du Catenet (le terme Internet n'était pas universellement adopté), les RFC étaient très courts, sans table des matières et sans sections numérotées, et la fameuse section Sécurité n'était pas obligatoire (alors qu'elle aurait été intéressante pour ICMP, protocole non connecté, sans aucune authentification, même faible).
ICMP est une partie intégrante d'IP (RFC 791). Même s'il est situé dans une couche au dessus (les paquets ICMP sont encapsulés dans l'IP), la mise en œuvre d'ICMP est obligatoire pour toute machine IP. IPv6 a d'ailleurs repris exactement le même modèle dans le RFC 4443.
À quoi sert ICMP ? À signaler les problèmes et à obtenir quelques informations sur les autres machines.
Un paquet ICMP comporte un champ de huit bits, le Message Type et notre RFC liste, par exemple, les types suivants :
D'autres types ont été depuis rajoutés dans le registre IANA.
Destination Unreachable nécessite de donner davantage d'informations (beaucoup de choses peuvent aller mal !) et les paquets de ce type ont donc un champ Code de huit bits dont voici certaines valeurs possibles :
traceroute affiche ces codes lorsque la réponse n'est pas Time exceeded, avec des lettres suivies d'un point d'exclamation (pour citer la documentation, !H, !N, or !P (host, network or protocol unreachable), !S (source route failed), !F (fragmentation needed), !X (communication administratively prohibited), [...] or !<num> (ICMP unreachable code <num>)
ICMP a évolué par la suite, notamment par la possibilité d'inclure des messages structurés dans les paquets (RFC 4884).
Un des plus gros problèmes que rencontre ICMP aujourd'hui, est que beaucoup de coupe-feux administrés par des ignorants bloquent la totalité des paquets ICMP. Cette erreur vient en général d'une mauvaise compréhension des problèmes de sécurité (comme le ping of death, mal nommé puisqu'il n'est pas spécifique à ping, ou à ICMP). Le résultat est que certains protocoles comme la découverte de la MTU du chemin fonctionnent mal (cf. RFC 4821).
Première rédaction de cet article le 3 janvier 2008
Dernière mise à jour le 30 mars 2008
L'alsacien est désormais enregistré dans le registre IETF/IANA des langues, après un processus qu'il est intéressant de décrire.
Le RFC 4646 spécifie un registre des langues, hébergé à l'IANA. Ce registre s'appuie largement sur des normes ISO comme ISO 639 (dont la version 3 est parue l'année dernière) ou ISO 15924. Mais, pour l'instant, aucune norme ISO n'enregistre les dialectes, les langues donnant déjà assez de travail à l'agence de maintenance, SIL. Le registre IETF/IANA est donc le seul à permettre l'enregistrement de dialectes (en attendant la future norme ISO 639-6), par son mécanisme de variant (le premier enregistré ayant été le valencien).
Rappelons que le mot « dialecte » n'a rien de péjoratif. Un dialecte est une variante d'une langue, qui ne forme pas une langue séparée (l'intercompréhension entre les différents dialectes demeure, alors qu'il n'y a pas intercompréhension entre les langues). Bien sûr, en pratique, la frontière est souvent floue (SIL a ainsi reclassifié le languedocien ou le provençal en dialectes de l'occitan alors qu'ils étaient d'abord considérés comme langues séparées) et c'est pour cela qu'un examen attentif par un expert, le Language Subtag Reviewer (actuellement Michael Everson) est nécessaire pour l'enregistrement d'une nouvelle étiquette.
La situation avec les dialectes est d'autant plus délicate que, si certaines langues, comme le français ou le japonais, sont assez normalisées par un État, une Académie, des médias nationaux, les dialectes, eux, ne sont pratiquement jamais spécifiés rigoureusement.
La procédure complète pour enregistrer une nouvelle
étiquette de langue est décrite dans le RFC 4646. Une version simplifiée figure en http://www.langtag.net/register-new-subtag.html
. C'est cette
procédure qui a été appliquée au début pour l'alsacien
dont voici la première demande (retirée par la suite).
L'alsacien désigne ici un dialecte
particulier de l'alémanique. L'alémanique (code
ISO gsw
) est
une langue germanique distincte de l'allemand (code ISO
de
), parlée en Allemagne,
en Suisse, en Autriche et en
France. Comme la plupart des langues non
étatiques, elle n'a pas une forme unique, ni même de forme officielle,
« de référence », elle est plutôt une
collection de dialectes. Celui qui nous intéresse est surtout parlé en
France, l'Alsace étant française depuis des
siècles. L'alsacien est surtout parlé mais on trouve aussi des livres
écrits dans le dialecte, comme un livre de la série Martine, que son dessinateur, Marcel Marlier est venu dédicacer à Strasbourg le 24 novembre 2007 :
. Microsoft avait
annoncé la disponibilité
de Office en alsacien.
On notera qu'il existe également des sous-dialectes selon les
régions d'Alsace et aussi des dialectes en Alsace qui ne sont pas
alémaniques mais franciques, voire
romans, comme le
welche. La demande d'enregistrement ne concerne
que le dialecte alémanique, d'où le préfixe gsw
qui indique que l'étiquette complète pour l'alsacien, si la demande
avait été acceptée, aurait été gsw-alsatian
.
La discussion a été très animée sur la liste ietf-languages,
où sont examinées les demandes d'enregistrement. Il faut dire que les
langues germaniques sont un sujet complexe, qui défie les
classifications, comme l'a montré une demande, faite un peu plus tard,
pour l'enregistrement de l'Erzgebirgisch. Beaucoup de personnes ayant
participé à la discussion suggéraient, plutôt que d'enregistrer la
nouvelle étiquette alsatian
, de se contenter des
étiquettes existantes et d'identifier l'alsacien avec
gsw-FR
(alémanique parlé en France). Le terme
« alsacien » n'est en effet utilisé qu'en France (même si les
frontières linguistiques et politiques ne coïncident pas). Reste la
question de savoir comment les utilisateurs de l'alsacien trouveront
cette étiquette, si le terme « alsacien » n'apparait pas dans le
registre. Fin janvier 2008, j'ai retiré la demande originelle, une
demande officielle ayant été faite
à l'agence de maintenance de ISO 639-2 (qui avait
enregistré le code gsw
) pour ajouter
explicitement l'alsacien dans la description de l'alémanique. Cette
demande a été
acceptée au bout de quelques semaines. « Alsacien » est
désormais listé comme nom pour le code gsw
. Il
restait à la transcrire dans le registre des langues, ce qui a fait
l'objet de la demande suivante, un
PRR (proposed revised record), normalement, juste
une formalité. En effet, cette demande a finie par être enregistrée
par l'IANA le 26 mars 2008, marquant la fin du processus. Désormais,
la description de l'alémanique, code gsw
, inclus
officiellement le fait que ce code s'applique à l'alsacien.
Merci à l'Office pour la Langue et la Culture d'Alsace pour son aide et sa documentation, mais la demande d'enregistrement est éditée par moi et ne représente pas forcément leur point de vue. Merci aussi à François Martin pour son aide érudite.
Date de publication du RFC : Décembre 2007
Auteur(s) du RFC : J. Abley (Afilias), P. Savola (CSC/Funet), G. Neville-Neil (Neville-Neil Consulting)
Chemin des normes
Première rédaction de cet article le 3 janvier 2008
Ce RFC supprime un type particulier d'en-tête IPv6, qui permettait de faire du routage IP contrôlé par la source mais qui ouvrait la voie à de graves attaques par déni de service.
Normalement, le routage dans IP se fait uniquement en fonction de
l'adresse
de destination. Une technique connue sous le nom de « routage par la
source » (source routing) permet de placer dans un
paquet IP des instructions pour les routeurs situés sur le trajet, forçant
l'usage d'un chemin particulier. En IPv4, ce
routage par la source se fait en indiquant la route (les routeurs par
lesquels le paquet doit passer) dans l'en-tête IP,
où la taille est limitée. Cela limitait donc sérieusement l'utilité de
ce routage par la source, mais aussi ses dangers, puisque un paquet ne
pouvait pas être forcé sur un chemin très long. Néanmoins, cette
option est tellement facile à utiliser pour contourner les politiques
de sécurité, qu'elle est désactivée sur la plupart des routeurs IP
(option sysctl
net.ipv4.conf.all.accept_source_route
sur
Linux, par exemple ou bien no ip
source-route
sur IOS).
Mais la menace en IPv6 était plus sérieuse. En effet, l'en-tête IPv6 est de taille fixe et les options sont placées dans des en-têtes auxiliaires, qui sont très variés (section 4 du RFC 2460). Cela permet de mettre des en-têtes de très grande taille. L'un d'eux, l'en-tête de routage (Routing Header, section 4.4 du RFC 2460) de type 0, permet de lister un plus grand nombre de routeurs intermédiaire qu'en IPv4 (et on peut indiquer plusieurs fois le même routeur, permettant ainsi des parties de ping-pong entre les routeurs). C'est celui, qui, suite à un article très médiatisé (souvent avec des exagérations ridicules) expliquant comment il pouvait être mal utilisé, et suite à l'analyse du RFC 4942, vient d'être déclaré abandonné. (La faille de sécurité avait été enregistrée sous le numéro CVE-2007-2242.)
Désormais, spécifie la section 3 de notre RFC 5095, une machine IPv6 doit ignorer les en-têtes de routage de type 0.
La section 4.2 couvre un problème intéressant, le risque que certains coupe-feux soient programmés de manière excessive pour rejeter tous les paquets ayant un en-tête de routage, même d'autres types (par exemple, le type 2 est utilisé par le RFC 3775). C'est une situation qui s'est déjà produite avec le soi-disant ping of death, où plusieurs administrateurs de coupe-feux ont bloqué complètement ICMP, alors que la vulnérabilité n'avait rien de spécifique à ICMP.
Notre RFC avertit donc qu'il ne faut pas surréagir : bloquer tous les paquets ayant un en-tête de routage empêcherait complètement le déploiement de beaucoup de protocoles.
Date de publication du RFC : Avril 2004
Auteur(s) du RFC : K. Konishi, K. Huang, H. Qian, Y. Ko
Pour information
Première rédaction de cet article le 3 janvier 2008
Une fois définie une norme pour les noms de domaines internationalisés, il reste à régler quelques problèmes liés à leur enregistrement. Par exemple, le chinois s'écrit couramment avec deux écritures, la traditionnelle et la simplifiée. Faut-il permettre l'enregistrement de deux noms de domaines identiques, ne se différenciant que par cette écriture ? Notre RFC propose un cadre pour spécifier de telles règles et crée la notion de lot (package), un ensemble de domaines qu'IDN considérerait différents mais que le registre préfère traiter comme équivalents, et ne pouvant donc faire l'objet que d'un seul enregistrement.
IDN, normalisé dans le RFC 3490 , permet d'exprimer des noms de domaine en Unicode. Une canonicalisation est effectuée par le mécanisme nameprep (RFC 3491) et certaines chaînes de caractères Unicode (commme Straße et strasse) sont donc identiques pour nameprep. Il ne peut donc y avoir qu'un seul nom de domaine pour ces deux chaînes.
Mais d'autres chaînes Unicode sont considérées comme distinctes par nameprep, et donc peuvent être enregistrées séparément, alors qu'un locuteur de telle ou telle langue pourrait les voir comme identiques. C'est le cas de deux mots en chinois en écriture traditionnelle ou simplifiée, par exemple. De même, en français, certains pourraient considérer que congres et congrès doivent être considérés comme identiques, car ne se différenciant que par un accent.
Notre RFC, qui n'a pas le statut de norme, n'essaie pas de décrire une telle politique pour toutes les langues du monde. Il fournit simplement un cadre permettant de décrire de telles politiques, en mettant l'accès sur les questions spécifiques des langues asiatiques, souvent désignées par le sigle CJC. Il a été co-écrit par les registres de noms de domaine de Chine, de Taïwan, de Corée et du Japon, regroupés dans une structure ad-hoc, le JET. Le RFC 4290 étendra ensuite cette méthode aux autres écritures du monde.
Avant de voir la technique, il est bon de se rappeler que
l'IETF n'a aucune légitimité pour décider des
politiques d'enregistrement suivies dans
.tw
ou
.kr
. Il ne peut s'agir ici
que de recommandations, telles qu'exprimées dans la note de
l'IESG qui précède le RFC, qui incite les
autres registres à suivre le même chemin, en rappelant (à regret ?)
que l'IESG ne peut pas les y obliger.
En quoi consiste le mécanisme de ce RFC ? Simplement en la définition d'une table des variantes de chaque caractère (sections 2.1.11 et 3.2.1). Toute chaîne peut donc être canonicalisée en étant réduite à la variante préférée (section 2.1.13). Les chaînes qui ont la même forme canonique font partie du même lot (package, section 2.1.18, nommé bundle dans le RFC 4290) et ne peuvent donc pas faire l'objet d'enregistrements distincts. Seule la variante préférée est enregistrée. Les autres sont réservées.
La section 3 du RFC détaille ce mécanisme et traite de certains cas particuliers, comme la suppression d'un nom de domaine (section 3.3).
Appliqué au français, avec une table de variantes telle que celle
proposée pour .fr, cette méthode ferait de
congres
et congrès
, mais
aussi de côngrës
et congrês
les membres d'un même lot.
Notre RFC ne répond pas à la question posée plus haut sur l'équivalence des écritures chinoises traditionnelles et simplifiées. Comme expliqué en section 4, cette tâche est laissé à des tables de variantes, dont certaines sont déposées sur le registre (non obligatoire) de l'IANA.
La section 5 du RFC décrit une proposition de syntaxe pour les tables de variantes, qui sera reprise dans le RFC 4290.
Articles des différentes années : 2024 2023 2022 2021 2020 2019 2018 Précédentes années
Syndication : Flux Atom avec seulement les résumés et Flux Atom avec tout le contenu.