Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

RFC 7901: CHAIN Query Requests in DNS

Date de publication du RFC : Juin 2016
Auteur(s) du RFC : P. Wouters (Red Hat)
Expérimental
Réalisé dans le cadre du groupe de travail IETF dnsop
Première rédaction de cet article le 24 juin 2016


Lorsqu'un client DNS parle à un résolveur, il pose une question et obtient une réponse. Avant DNSSEC, ce mode de fonctionnement simple était souvent satisfaisant. Mais, avec DNSSEC, il est beaucoup plus fréquent de devoir faire plusieurs requêtes pour obtenir toute l'information nécessaire pour valider les réponses. (Il faut les clés de toutes les zones situées entre la racine et la zone visée.) Cela coûtait cher en latence. Cette extension EDNS expérimentale permet au client DNS de demander au résolveur de chercher et de renvoyer toutes les réponses d'un coup.

Cette extension est particulièrement utile pour le cas de machines terminales hébergeant leur propre résolveur validant (ce qui est la meilleure configuration, question confiance et sécurité). Ce n'est donc pas un hasard si l'auteur du RFC travaille chez Red Hat, système qui est livré par défaut avec une telle configuration. Mais, lorsqu'un tel résolveur validant veut vérifier les informations obtenues sur foo.bar.example, il devra (en supposant qu'il y a une zone par composant du nom de domaine) obtenir la délégation sécurisée de example (dig @la-racine DS example), la clé de example (dig @ns-example DNSKEY example), la délégation sécurisée de bar.example, etc (la clé de la racine, elle, est en dur dans le résolveur, il faut bien partir de quelque part). À faire séquentiellement, cela serait beaucoup de requêtes, donc du temps passé à attendre les réponses. Sur des liens à latence élevée (ce qui arrive souvent aux machines terminales), cela peut être pénible, même si le cache DNS aidera, pour les requêtes suivantes.

L'idée de cette extension (sections 1 et 3 du RFC) est donc que le résolveur validant local ait un forwarder (attention, le RFC utilise un vocabulaire erroné, en donnant à forwarder un sens différent de celui qu'il a dans les RFC 2308 et RFC 8499 ; j'utilise, moi, la terminologie standard). Le résolveur validant local va demander à ce forwarder, grâce à la nouvelle extension EDNS CHAIN, d'envoyer tout d'un coup (tous les DS et DNSKEY nécessaires). Bien sûr, le forwarder, lui, devra faire toutes les requêtes mais, a priori, il a un plus gros cache et sera mieux connecté.

Cette nouvelle extension est donc conçue pour des résolveurs, et est ignorée par les serveurs faisant autorité. Notez que le résolveur validant local peut être un démon autonome (Unbound tournant sur mon portable Unix) ou bien une partie d'une application qui embarquerait ses propres fonctions de résolution de noms.

Le format de l'extension est décrit en section 4 du RFC. C'est une option EDNS (RFC 6891), encodée, comme les autres options EDNS, en TLV. Le type (le code) est 13. La valeur est composée d'un seul champ, l'ancêtre le plus proche (Closest Trust Point) dont on connaisse les informations nécessaires à la validation. Le résolveur validant local a en effet certaines informations (dans sa configuration ou dans son cache) qu'il n'est pas nécessaire de lui envoyer. Dans l'exemple plus haut, si le résolveur validant local connait déjà la clé DNSSEC de example, il mettra dans le champ Closest Trust Point ce nom de domaine, indiquant au forwarder qu'il peut se contenter des informations situées plus bas, dans l'arbre du DNS. Ce nom est encodé dans le format habituel du DNS (qui n'est pas le format texte avec les points).

La section 5 du RFC décrit comment utiliser cette extension au DNS. Si on veut tester les capacités du résolveur qu'on interroge, on peut utiliser une option CHAIN vide (longueur nulle). Si le serveur à qui on a envoyé cette option répond avec la même option nulle, c'est bon. Attention, les serveurs récursifs qui mettent en œuvre CHAIN n'accepteront des requêtes « réelles » (longueur non nulle) qu'au-dessus d'un transport où l'adresse IP source est vérifiée. Le but est d'éviter les attaques par réflexion avec amplification (voir aussi la section 7.2). Pour vérifier l'adresse IP source (ce qui ne se fait normalement pas en UDP), il y a plusieurs solutions, notamment TCP (RFC 7766) et les gâteaux (RFC 7873).

Une fois qu'on a un tel transport, et que le client DNS a testé que le serveur qu'il interroge gère bien CHAIN, on peut y aller. Le client met l'ancêtre le plus proche (dont il a les clés) du nom demandé dans le champ Closest Trust Point. Dans le cas le plus courant (résolveur validant configuré avec une seule clé, celle de la racine), le résolveur « froid », qui vient de démarrer et dont le cache est vide, il commencera par mettre la racine en Closest Trust Point puis, au fur et à mesure qu'il se « réchauffera » (que son cache se peuplera), il pourra mettre des noms plus proches du nom demandé (et donc plus éloignés de la racine). Par exemple, si le résolveur validant local est configuré avec la clé de la racine, et qu'il a appris par les réponses précédentes la clé de example, mais pas celle de bar.example, et qu'il veut des informations sur le nom foo.bar.example, son option CHAIN vaudra {type = 13, longueur = 9, valeur = 0x07 0x65 0x78 0x61 0x6d 0x70 0x6c 0x65 0x00} (la longueur est celle de la partie « valeur » uniquement, le nom example est encodé selon la norme DNS). S'il connaissait également la clé de bar.example, son option CHAIN vaudrait {type = 13, longueur = 13, valeur = 0x03 0x62 0x61 0x72 0x07 0x65 0x78 0x61 0x6d 0x70 0x6c 0x65 0x00}. D'autres exemples figurent en section 9 du RFC.

Faut-il envoyer l'option CHAIN à chaque requête ? On peut mais il est recommandé de se souvenir de quels serveurs la gèrent et de n'envoyer qu'à ceux-ci (autrement, non seulement on fait du travail inutile mais on renseigne des serveurs extérieurs sur l'état de son cache). Comme il existe des middleboxes boguées sur certains trajets, la stratégie de repli du RFC 6891, section 6.2.2 peut être utile.

Et le serveur interrogé, que fait-il ? S'il accepte de répondre à une requête contenant l'extension CHAIN, il doit :

  • Ajouter à la réponse, dans la section Autorité, les enregistrements DNSSEC nécessaires (DS, DNSKEY et NSEC),
  • Mettre une CHAIN dans la réponse, avec la valeur Closest Trust Point mise au nom le plus bas (le plus éloigné de la racine) pour lequel ces informations sont nécessaires. (C'est surtout utile lorsque le serveur n'envoie pas une chaîne complète, par exemple pour économiser le réseau.)

Évidemment, si la question avait une erreur de syntaxe (taille de la partie Valeur inférieure à la Longueur, par exemple), le serveur répond FORMERR (FORmat ERRor).

La section 7 sur la sécurité étudie quelques programmes que peut poser cette extension au DNS. D'abord, mettre en œuvre cette option fatigue davantage le serveur interrogé, en terme de travail et de capacité du réseau. Un serveur est donc toujours libre d'ignorer les options CHAIN et de s'en tenir au service minimum.

Ensuite, comme vu plus haut, les réponses suivant une question qui utilise CHAIN vont être évidemment plus grosses que les réponses DNS habituelles. Il y a donc un risque d'attaques par réflexion avec amplification, si un attaquant usurpe l'adresse IP de sa victime. C'est pour cela que notre RFC impose de ne répondre avec une chaîne complète que si l'adresse IP du client a été vérifiée (par exemple parce qu'il utilise TCP, ou bien les cookies du RFC 7873).

CHAIN a aussi quelques effets sur la vie privée. Le résolveur validant local va indiquer à son forwarder (et à tout espion qui surveille le trafic) comment il est configuré et ce qu'il y a dans son cache.

Il ne semble pas qu'il existe de mise en œuvre de cette option CHAIN pour l'instant, même si c'est en projet pour Go.

Si vous vous intéressez à la conception des protocoles réseaux, notez que cette extension a fait l'objet d'une discussion pour savoir s'il ne valait pas mieux, pour réduire la latence, envoyer toutes les requêtes possibles en parallèle (cette idée a finalement été rejetée).


Téléchargez le RFC 7901

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)