Première rédaction de cet article le 24 novembre 2015
Un cas intéressant cité par Phil Mayers sur la liste des utilisateurs de BIND va me permettre, cher lecteur, de t'instruire sur la différence entre nom de domaine et nom de machine.
La question originale était de savoir pourquoi on pouvait faire
une résolution DNS (par exemple avec
dig) de
nexistesurementpas.um.outlook.com
alors que les
commandes comme ping ne pouvaient pas
utiliser ce nom :
% dig +short nexistesurementpas.um.outlook.com *.um.outlook.com.glbdns2.microsoft.com. wildcard-emeasouth.um.outlook.com. 157.55.9.252
On récupère bien une adresse IP (c'est pareil avec d'autres outils DNS comme host) mais :
% ping nexistesurementpas.um.outlook.com ping: unknown host nexistesurementpas.um.outlook.com
Mais, alors, pourquoi est-ce que ping prétend que ce nom n'existe pas ? (Le problème n'est pas spécifique à ping, d'autres commandes comme telnet font le même diagnostic.)
L'explication est qu'il existe une différence entre les
noms de domaine (domain
names) et les noms de machines (host
names). Les premiers permettent à peu près tous les
caractères possibles (cf. RFC 2181, section
11, et regardez le nom
&-funny-%-syntax-$.bortzmeyer.org
pour
s'en convaincre). Les seconds obéissent à une syntaxe bien plus
restrictive, documentée dans le RFC 1123,
section 2.1. En gros, un nom de machine est restreint à LDH
(Letters, Digits and Hyphen). C'est pour cela
que je peux résoudre le nom rigolo indiqué plus haut :
% dig +short +nodnssec '&-funny-%-syntax-$.bortzmeyer.org' www.bortzmeyer.org. 204.62.14.153
Mais que je ne peux pas l'utiliser :
% ping '&-funny-%-syntax-$.bortzmeyer.org' ping: unknown host &-funny-%-syntax-$.bortzmeyer.org
(Notez qu'il a fallu l'encadrer d'apostrophes car certains caractères sont spéciaux pour le shell Unix.)
Arrivé à ce stade, mes lecteurs et lectrices, qui sont très
malins, se grattent la tête « OK dans l'exemple avec
&-funny-%-syntax-$.bortzmeyer.org
mais le
nom au début,
nexistesurementpas.um.outlook.com
, est
parfaitement conforme au RFC 1123, lui ! »
Il faut examiner de plus près le processus de résolution DNS :
% dig nexistesurementpas.um.outlook.com ... ;; ANSWER SECTION: nexistesurementpas.um.outlook.com. 0 IN CNAME *.um.outlook.com.glbdns2.microsoft.com. *.um.outlook.com.glbdns2.microsoft.com. 0 IN CNAME wildcard-emeasouth.um.outlook.com. wildcard-emeasouth.um.outlook.com. 300 IN A 157.55.9.252
Le nom est en fait un pointeur (enregistrement DNS de type
CNAME
) vers un nom canonique,
*.um.outlook.com.glbdns2.microsoft.com
(qui,
à son tour, pointe vers un autre nom canonique,
wildcard-emeasouth.um.outlook.com
, mais ce
n'est pas important ici).
Or, le sous-programme
getaddrinfo()
, qu'appellent les
applications pour résoudre un nom en adresse IP, teste la validité
de ces noms. Sur les systèmes utilisant la GNU
libc (ce qui est le cas de
l'Ubuntu sur laquelle j'ai fait les tests),
getaddrinfo
est encore plus violent, il teste
tous les noms de la chaîne. Arrivant au
*.um.outlook.com.glbdns2.microsoft.com
, il le
rejette car contenant un caractère invalide,
l'astérisque. Ainsi, la résolution échoue
et le nom est considéré comme inconnu. (Les fanas du DNS noteront
que, dans un fichier de zone, l'astérisque a un sens spécial,
faisant du nom un joker. Mais ça n'a pas
d'importance ici : c'est un caractère illégal, point.)
À noter que le résultat dépend du système
d'exploitation utilisé car toutes les mises en œuvre
de getaddrinfo
ne sont pas aussi
sévères. Apparemment, FreeBSD refuse ces
noms, mais pas Mac OS ou
Windows. Ainsi,
sur Mac OS, même le nom le plus bizarre est accepté :
$ ping -c 1 '&-funny-%-syntax-$.bortzmeyer.org' PING www.bortzmeyer.org (204.62.14.153): 56 data bytes 64 bytes from 204.62.14.153: icmp_seq=0 ttl=51 time=73.471 ms --- www.bortzmeyer.org ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 73.471/73.471/73.471/0.000 ms
Windows, lui, accepte le premier nom (la machine ne répond pas aux requêtes ICMP mais peu importe) :
E:\Users\moi>ping -n 1 nexistesurementpas.um.outlook.com Envoi d'une requête 'ping' sur wildcard-emeacenter.um.outlook.com [157.55.9.252] avec 32 octets de données : Délai d'attente de la demande dépassé. Statistiques Ping pour 157.55.9.252: Paquets : envoyés = 1, reçus = 0, perdus = 1 (perte 100%),
Les programmeurs n'ont qu'à jeter un œil au code source de la
GNU libc, dans resolv/res_comp.c
:
#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ || ((c) >= 0x61 && (c) <= 0x7a)) #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) #define borderchar(c) (alphachar(c) || digitchar(c)) #define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c)) #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) int res_hnok(const char *dn) { int pch = PERIOD, ch = *dn++; while (ch != '\0') { int nch = *dn++; if (periodchar(ch)) { (void)NULL; } else if (periodchar(pch)) { if (!borderchar(ch)) return (0); } else if (periodchar(nch) || nch == '\0') { if (!borderchar(ch)) return (0); } else { if (!middlechar(ch)) return (0); } pch = ch, ch = nch; } return (1); }
Ce code teste que le nom de machine suit l'expression
rationnelle [a-z0-9\.\-]+
(pas
tout à fait : il autorise aussi le trait
bas à certains endroits, ce qui est une erreur). Le
code équivalent pour FreeBSD est gethostbydns.c
.
À noter qu'on a testé que le cas où le nom illégal est au milieu de la chaîne des pointeurs. Il serait intéressant de refaire le test avec tous ces systèmes d'exploitation pour les cas où le nom illégal est au début ou à la fin de cette chaîne.
Un post-scriptum pour mes lecteurs juristes : les définitions de domaine et de machine utilisées ici sont évidemment celles des RFC. Mais le gouvernement se moque bien de la terminologie existante et, dans sa hâte de contrôler l'Internet, il invente un vocabulaire bizarre. C'est ainsi que le décret français n° 2015-125 du 5 février 2015, qui institue la censure administrative en France a cette définition pittoresque « Les adresses électroniques figurant sur la liste comportent soit un nom de domaine (DNS), soit un nom d'hôte caractérisé par un nom de domaine précédé d'un nom de serveur. »
Merci à Kim-Minh Kaplan pour la discussion et à Vincent Archer et Pascal Courtois pour avoir prêté des machines à la science.
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)