Michel Boucey

DNSSEC dans la zone .nl

Cet article est la traduction (mise en ligne le 14 avril 2003) de l’article "Secure DNS, Het beveiligingen van DNS in de praktijk" paru dans c’t magazine le 14 mars 2003, à partir de sa version anglo-saxonne. Cet article est en passe de devenir pour une part d'un simple intérêt historique puisque 2010 fut l'année du début du déploiement effectif de DNSSEC. Il garde et gardera cependant tout son intérêt pédagogique quant au pourquoi et au comment de la transition du DNS vers DNSSEC.
Le NIC hollandais (SIDN [1]), l’office Internet pour la région européenne (RIPE [2]), et NLnetLabs [3] ont créé le premier DNS de niveau maximal (NdT : i.e. un Top Level Domain, ou TLD) qui soit sécurisé. Cette expérimentation fonctionne avec son propre jeu de serveurs de nom afin de garantir qu’elle n’interfère pas avec les serveurs de nom qui sont en production. Le projet a débuté en novembre 2002 en vue d’acquérir de l’expérience dans la pratique de DNSSEC pour un service de TLD. Depuis des années, l’IETF (re)pense le successeur du système actuel de noms de domaine (DNS). Le nouveau protocole a été modifié si fréquemment que tout le monde commençait à se demander si jamais il arriverait ; et pourtant on aurait plutôt pensé que le DNS eût été l’un des tout premiers protocoles à être intégralement sécurisé. Car, après tout, toute la communication sur Internet repose sur la confiance dans le DNS. Un utilisateur malveillant a seulement besoin de manipuler le DNS pour obtenir le contrôle de la communication.
Le fichier standard de zone DNS du domaine "ct.nl", avec les enregistrements de ressource (Resource Record, ou RR) standards de "début d’autorité" (SOA), serveur de nom (NS), courrier électronique (MX), adresse de machine (A) et alias (CNAME).

La signature numérique

Les requêtes et les réponses DNS standards sont aisées à falsifier. Si une tierce partie peut observer le trafic DNS à partir de n’importe quelle machine entre l’utilisateur final et le serveur DNS que la personne interroge, les données peuvent être facilement manipulées. DNSSEC résout ce problème en utilisant la signature numérique de tous les enregistrements. Une paire de clés est générée : la clé publique est mise dans le DNS lui-même, sous la forme d’un enregistrement KEY. La clé privée est alors employée pour signer numériquement tous les enregistrements, et ce en incluant l’enregistrement de la clé publique. Ces signatures sont placées dans les enregistrements SIG. Un utilisateur malveillant peut toujours manipuler les données DNS, mais sans la clé privée, les enregistrements SIG correspondants ne peuvent pas être reproduits afin de valider les faux enregistrements. L’altération sera notifiée, et les réponses DNS piratées ne seront pas crédibles. La beauté de ce dispositif est que la zone entière peut être signée sur une machine très sûre, et seulement alors copiée dans le serveur DNS. Quand bien même quelqu’un aurait le contrôle intégral du serveur de nom, celui-ci ne pourrait changer aucun enregistrement DNS sans casser l’enregistrement SIG. Un attaquant peut certes toujours détruire le serveur de nom, du moins personne n’aura été dupée en étant connecté au réseau malfaisant de l’assaillant, même après que le serveur de nom ait été compromis.  
Le fichier de zone ct.nl, sécurisé grâce aux enregistrements DNSSEC. (La longueur de la KEY a été réduite pour une meilleure lisibilité) DNSSEC possède un autre nouveau type d’enregistrement, l’enregistrement NXT. Cet enregistrement nous offre l’opportunité de dénier l’existence d’un RR donné. Il est insuffisant de seulement ne pas avoir un enregistrement donné pour affirmer clairement que le RR réclamé est inexistant. Nous avons à le prouver de quelque façon. L’enregistrement NXT pour ct.nl montre l’existence des types d’enregistrement NS, SOA, MX, SIG, KEY et NXT. Il nous dit aussi que le prochain RR, dans l’ordre alphabétique, va être www.ct.nl. L’enregistrement NXT pour www.ct.nl montre lui qu’il n’y a que les enregistrements CNAME, SIG et NXT. Et lorsque l’on sait que son enregistrement NXT pointe en retour sur ct.nl, nous savons qu’il s’agit du dernier nom de la chaîne. Il n’y a pas de zzz.ct.nl. Et toute cette information est numériquement signée. C’est l’essence même de DNSSEC. Mais tout n’est pas réglé pour autant. Le DNS consiste en un système hiérarchique. La zone au-dessus de la nôtre, la zone mère, détient des informations au sujet de notre zone. Le serveur de nom de la zone mère contient les enregistrements des serveurs de nom (NS) pointant sur les serveurs de nom responsables de ses zones fille. Et si les serveurs de nom de la zone fille eux-mêmes ont ces noms à l’intérieur de leurs propres zones (par exemple lorsque ns.ct.nl est un enregistrement NS pour ct.nl), il est alors aussi nécessaire de transmettre cette information afin d’assurer la transition ; ces enregistrements étant dits enregistrements de liaison (glue records). Si quelqu’un projette de manipuler ces enregistrements dans notre zone parent, le degré de sécurisation de notre propre serveur est alors sans importante. Personne n’atteindra jamais notre serveur de nom super sécurisé. Par conséquent cette information a également à être signée. Cependant notre parent ne possède pas notre clé privée, il ne peut ainsi signer ses enregistrements en notre nom. Quoiqu’il en soit, nous aurons à donner à notre parent des informations concernant notre clé, sans pour autant la lui remettre.  

La solution

Ce problème n’est bien sûr pas nouveau dans le DNS. Le serveur de nom .nl (ns.nic.nl) détenait déjà nos enregistrements NS pour la zone ct.nl. Dans notre cas il s’agit de ns.xtdnet.nl. Toutefois, cette réponse est donnée sans que le drapeau dit "réponse de l’autorité" soit positionné. L’information est fournie "telle quelle". Si nous questionnions ns.xtdnet.nl, il retournerait la même réponse, mais cette fois-ci le drapeau "réponse de l’autorité" serait positionné. Si ns.xtdnet.nl donnait une réponse différente, nous appellerions ça un "serveur boiteux" (lame server). Cependant, pour DNSSEC, cet indice est insuffisant. Après tout, n’importe qui peut monter un serveur autoritaire. C’est pourquoi DNSSEC offre une solution cryptographique, l’enregistrement de Délégation du Signataire (Delegation Signer, ou DS). L’enregistrement DS contient l’id et l’empreinte (le hash) de l’enregistrement KEY de la zone fille. L’enregistrement DS lui-même est signé par la zone mère avec un enregistrement SIG. Afin de trouver la zone ct.nl, nous questionnons le serveur de nom .nl à la fois pour les enregistrements NS et DS. Nous recevons l’information (NS) d’utiliser ns.xtdnet.nl en tant que serveur de nom et une empreinte de la clé (DS) que .nl pour l’heure en sa possession, et qui a dû servir à signer la totalité de la zone ct.nl. Nous nous tournons alors vers ns.xtdnet.nl afin de lui réclamer l’enregistrement KEY pour ct.nl. Nous recevons l’enregistrement KEY, et la signature allant de paire. Nous réalisons une empreinte de KEY et la comparons avec celle de l’enregistrement DS que nous avons reçu du serveur de nom .nl. S’ils correspondent, c’est que, en toute sécurité, nous sommes arrivés au serveur de nom ayant autorité sur ct.nl et que nous pouvons poursuivre en l’interrogeant au sujet du domaine ct.nl. Toutes les réponses de ns.xtdnet.nl seront numériquement signées, et ne pourrons être falsifiées.
Résolution sécurisée de www.ct.nl, en usant de l’outil réalisé par Miek Gieben [4]  

Le remplacement des KEY

Quoi qu’il en soit, avec assez de temps et de puissance cpu, tout cryptage peut finalement être cassé. C’est pourquoi il est important de changer régulièrement vos enregistrements KEY. Cependant nous ne pouvons nous contenter de changer la clé, parce qu’alors l’enregistrement DS parent deviendra faux. Conséquemment, comment renouveler nos KEY sans constamment mettre en porte-à-faux le parent lors de la mise à jour de l’enregistrement DS ? L’astuce est d’utiliser deux enregistrements KEY dans notre zone, une clé de signature de zone (zone-signing key, ou ZSK) et une clé de signature de clé (key-signing key, ou KSK). Nous signons tous les enregistrements KEY avec la KSK, puis signons la zone entière avec la ZSK. La KSK est la clé pour laquelle nos parents publient l’enregistrement DS. La clé de signature de zone (ZSK) peut être d’une petite taille (par exemple 768 bits) si nous la recyclons tous les mois. Nous pouvons garder la KSK une année si nous la faisons plus forte, 2048 bits par exemple. Nous obtenons ainsi la chaîne de confiance suivant : nous avons confiance dans la KEY de .nl , et ainsi avons également confiance dans les enregistements NS et DS que nous fournit ns.nic.nl, lesquels finalement nous servent à atteindre ns.xtdnet.nl. Nous vérifions sa KSK avec le DS que nous avons, nous avons confiance dans la KSK ayant signée la ZSK, cette dernière ayant servi à signer toutes les données (les RR) parmi lesquelles nous voulons connaître l’enregistrement signé A pour www.ct.nl. Et maintenant nous pouvons recycler la ZSK sans le notifier au parent. Bien sûr nous n’avons fait qu’ajourner notre problème. Il nous reste encore à recycler la KSK après un an d’utilisation, et nous avons besoin d’informer en toute sécurité notre parent de la présence d’une nouvelle KSK. Pour effectuer un remplacement de la KSK nous créons premièrement une autre KSK (appelons-là KSK2) et ajoutons cette troisième clé à la zone. Nous pouvons alors informer le parent (bien que cela soit de façon non sûre !) de l’existence d’une nouvelle clé. Le parent vérifie si sa KSK existante (pour laquelle il a une DS à vérifier) a signé la nouvelle KSK2. Si tel est le cas, il mettra à jour son enregistrement afin de pointer sur KSK2. Une fois que nous sommes sûrs qu’aucune copie mise en cache de KSK n’est disséminée à travers le monde, nous pouvons retirer la KSK de notre zone. Pour .nl, NLnetlabs a mis en place une telle procédure, SECREG [5].

Du DNS à DNSSEC

Notre dernier problème est que le monde ne va pas passer en un instant du DNS à DNSSEC. Ainsi pendant que certaines sous-arborescences, telle que .nl, auront basculé, d’autres, et tout particulièrement la zone racine (".") elle-même, seront encore non sécurisées. La solution à ce problème est qu’il est possible de définir des "îlots de sécurité" au sein d’une arborescence non sécurisée. Vous pouvez définir une "clé de confiance" pour une portion d’arborescence donnée. C’est exactement ce qu’a fait SIDN pour .nl. Nous allons maintenant décrire comment sécuriser un domaine de .nl en utilisant DNSSEC et SECREG. Évidemment, SECREG ne s’applique qu’au domaine .nl, mais vous pouvez tout à fait lire les procédures impliquées en vue de sécuriser n’importe quelle zone. DNSSEC est encore une cible mouvante, très mouvante. Pour l’heure, le seul logiciel qui peut être utilisé pour créer des zones signées est la dernière archive de développement de bind9 [6]. Dans cette archive, le multi-threading ne fonctionne pas, vous aurait donc à le désactiver avec --disable-threads. Les zones signées avec cette archive peuvent de toute façon être servies par un paquetage récent d’un logiciel de serveur de nom, tels que les versions stables de bind8 et bind9, ou encore nsd [7]. Le seul problème provient de l’usage de bind8. Si vous installez une zone sécurisée, avec ses signatures valides pour un mois, et que, oubliant votre expérimentation, vous laissez expirer ces signatures, bind8 retirera l’enregistrement de la zone. Bind9 continuera lui à servir l’enregistrement expiré, et laissera aux résolveurs qui l’interrogent le soin de déterminer s’il faut oui ou non transmettre l’enregistrement expiré à l’application. Afin de ne pas compromettre le fonctionnement normal de la zone .nl, deux copies conformes aux serveurs de nom de ce TLD, mais sous DNSSEC, "bakbeest.sidnl.nl" et "alpha.nlnetlabs.nl", sont employées. Si vous voulez tester la résolution sécurisée, prenez soin de bien utiliser ces deux serveurs au lieu des serveurs officiels de .nl. Vous pouvez bien sûr également utiliser manuellement des outils tels que dig ou resolv.pl [4] Si vous souhaitez créer votre propre serveur de nom récursif, vous aurez besoin de la dernière archive de développement bind9, mais également d’ajouter l’instruction trusted-key pour la clé .nl [8] dans named.conf :
trusted-keys {
	"nl." 256 3 1
	"AQOtBQXOH5L/wmOt01PuxXAfSk1bw/dneWPoCyl4yi8tLCjz+DkAs0mzAAvd9XUNpYDaf5KT
	ciSs9254oeiE0s0FuYbxS4nm7veZSPCgWoHULFNJtKPNeb4EEblNkAsEGagwQJoIrjlAYKx4C
	En3hPwElUlVko23I5tSSPPssxrVnQ==" ;
} ;
(Ce qui précède doit tenir sur une seule et même ligne) Soyez averti qu’utiliser des archives de développement bind9 détruira fréquemment certaines fonctionnalités de votre serveur de nom. Ne les faites pas fonctionner sur des serveurs de nom en production, à moins de savoir exactement ce que vous faites et d’avoir un suivi détaillé de l’activité. Quand bien même le développement se concentre sur dnssec, certaines archives de développement ont aussi la résolution courante hors service ; par conséquent, gare. La prochaine étape est d’installer Net ::DNS ::SEC de CPAN. Certains des scripts perl que nous utiliserons plus tard en dépendent. Olaf Kolkman de RIPE NCC a écrit un outil d’administration[9] qui utilise ce module de façon intensive. Un tel outil est vital à partir du moment où vous sécurisez de nombreuses zones. Après avoir installé tous ces programmes, nous sommes prêts à sécuriser notre domaine, fln.nl. Idéalement, ce serait le moment opportun de retirer du réseau la machine qui va servir à la production des signatures, et seulement la connecter au serveur primaire de nom afin de télécharger les zones signées. D’autres méthodes pourraient même être meilleures, comme le transfert des zones grâce à une cartouche de mémoire USB. L’installation sécurisée de la machine signataire est laissée en exercice au lecteur. Nous allons commencer en créant la KSK et la ZSK :
$ dnssec-keygen -a RSASHA1 -b 2048 -n ZONE fnl.nl
Kfnl.nl.+005+16217
$ dnssec-keygen -a RSASHA1 -b 768 -n ZONE fnl.nl
Kfnl.nl.+005+25541
Les clés privées sont dans les fichiers dont l’extension est .private. Les clés publiques sont elles dans les fichiers dont l’extension est .key. Si vous créez une grande quantité de clés, vous pourriez avoir besoin d’utiliser "-r /dev/urandom". Cette source d’entropie est un peu moins sûr, cependant elle ne bloquera pas lorsque vous attendrait qu’apparaisse plus d’entropie. Il semble, du moins avec Linux, que le moyen le plus rapide pour que le résultat soit encore plus aléatoire est de bouger la souris. Une fois que nous en avons fini avec la création des paires de clés, nous ajoutons les enregistrements KEY au fichier de zone :
$ cat *key >> /var/named/fnl.nl
Et, après que nous ayons augmenté le numéro de série de la zone, nous sommes prêts à signer la zone :
$ dnssec-signzone -o fnl.nl -k Kfnl.nl.+005+16217.key
/var/named/fnl.nl Kfnl.nl.+005+25541.key
Nous pouvons alors copier le fichier de zone dans notre serveur primaire et recharger la zone :
# rndc reload fnl.nl
(Si vous utilisez RedHat, vous pouvez aussi frapper ’service named restart’) Après quelques minutes, votre serveur de nom secondaire devrait avoir chargé la nouvelle zone. Pour vérifier cela, nous utiliserons la commande dig. Nous recommandons aux gens qui ont coutume d’employer nslookup ou la command host de véritablement abandonner cette habitude dès maintenant. Si vous préférez la sortie de host ou de nslookup bien plus que celle de dig, vous pouvez maintenant utiliser avec dig l’option +multiline (que vous pouvez même mettre dans un fichier .digrc) pour obtenir une sortie très similaire à celles de nslookup ou de host. Pour vérifier si notre serveur secondaire a reçu la nouvelle zone, nous questionnons l’enregistrement de clé :
$ dig +dnssec +multiline -t key fnl.nl @ns.xtdnet.nl
Nous devrions recevoir une réponse contenant à la fois les enregistrements KEY et SIG. Jetez aussi un coup d’œil à la section "drapeaux" de la sortie de dig. Le drapeau "réponse de l’autorité" (Authoritative Answer, ou aa) nous dit si oui ou non le serveur de nom est lui-même responsable de la zone. Le drapeau "données authentifiées" (Authenticated Data, ou ad) nous dit lui si la véracité de la réponse a été assurée par l’usage des extensions dnssec. La requête ci-dessus, contrairement à ce que vous pourriez penser, ne positionne pas le drapeau "ad". La raison en est que la vérification des données est réalisée par le résolveur, et non pas par le serveur ayant autorité lui-même. Il n’y aurait pas plus de sens à vérifier la zone sur votre propre disque.  

Création de l’enregistrement DS

Nous avons notre zone sécurisée et chargée dans nos serveurs de nom, nous pouvons maintenant interroger SECREG afin qu’il atteste de la vérité de notre nom de domaine et lui demander qu’il ajoute un enregistrement DS signé à la zone .nl. Nous pouvons faire cette demande par mél (pour des enregistrements en masse) ou utiliser l’interface web[6] :
Sélectionner la KEY correcte pour SECREG. Pour le moment il n’y a aucun moyen pour que SECREG puisse déterminer quelle clé est votre ZSK, quelle autre est votre KSK, bien qu’un brouillon au sujet de cette distinction soit en cours. Si vous employez des tailles de clé différentes lors de la génération des clés vous pouvez les distinguer par leurs tailles. Si vous utilisez une taille identique, vous aurez à vérifier l’id de votre clé, qui apparaît dans son propre nom de fichier. Une fois que vous annoncez à SECREG quelle clé est la KSK, la zone apparaîtra "en cours de traitement".
Le Registrant et le Registrar ont deux jours pour abandonner la requête SECREG. SECREG a décidé d’ajouter un délai d’attente de deux jours afin que toutes les parties impliquées (Registrant ouRegistrar) aient une chance de décliner la requête. Il s’agit d’une politique expérimentale pouvant déboucher sur une meilleure pratique courante (Best Current Practice, ou BCP). Si personne ne décline la requête, votre zone sera ajoutée à SECREG. La zone .nl est rafraîchie tous les jours ouvrables, entre 7h et 11h du matin. Ce fichier de 40 Mo est alors signé par la machine signataire, actuellement un Pentium-III 1Ghz. Ce processus prend environ deux heures, et lorsqu’il est achevé, la taille du fichier a atteint les 300 Mo. SECREG enverra des méls aux parties impliquées en cas de succès dans l’ajout de la zone, ce qui signifie ajout et signature de l’enregistrement DS pour la zone.
Le drapeau "ad" est fixé. Dig a trouvé avec succès l’adresse de notre site web en employant DNSSEC.  

Le remplacement de la KSK

Les clés KSK et ZSK n’ont pas de date d’expiration - seuls les enregistrements SIG expirent. Le remplacement de ZSK peut être réalisé quand vous le souhaitez, tant que la KSK signera une quelconque KSK que vous aurez mise en place. C’est ainsi que ce remplacement consiste juste dans la destruction de l’ancienne clé, la génération d’une nouvelle, et la mise à jour de l’enregistrement KEY dans la zone. Le remplacement de KSK a besoin d’être réalisé d’une manière coordonnée avec le parent, de telle façon que l’enregistrement DS puisse être mis à jour. Premièrement, nous avons à créer une nouvelle KSK :
$ dnssec-keygen -a RSASHA1 -b 2048 -n ZONE fnl.nl
Kfnl.nl.+005+16310
L’enregistrement public KEY a besoin d’être ajouté à la zone. Sachant que le fichier de zone se tient dans /var/named/fnl.nl :
$ cat Kfnl.nl.+005+16310.key >> /var/named/fnl.nl
Et, après avoir augmenté le numéro de série, les KSK (NdT : l’ancienne et la nouvelle) doivent signer les enregistrements KEY, et la ZSK doit signer la zone entière :
$ dnssec-signzone -o fnl.nl -k Kfnl.nl.+005+16217 -k Kfnl.nl.+005+16310
/var/named/fnl.nl Kfnl.nl.+005+25541
Nous avons alors à propager la nouvelle zone aux serveurs de nom primaire et secondaire. Nous retournons au site web SECREG et choisissons "remplacement" ("rollover"). Un challenge nous est alors présenté consistant en un enregistrement TXT contenant une chaîne aléatoire de caractères. Il faut signer cette chaîne grâce à l’outil sign.pl, dont le lien se trouve sur la page même, en utilisant notre ANCIENNE KSK.
$ sign.pl
What is the full path to your private key ? []
Kfnl.nl.+005+16217.private
What is your domain ? []
fnl.nl
Record to sign : []
3600 IN TXT "random txt m80fN0LtmpXz2aQ"
Key path : Kfnl.nl.+005+35861.private
Domain name : fnl.nl
Record to sign : 3600 IN TXT "random txt m80fN0LtmpXz2aQ"

Is this correct (y/n) ? y

fnl.nl. 3600 IN SIG TXT 5 2 3600 20030315125047 (
	20030213125047 35861 fnl.nl
	KHR718ehTtidLkTUbnf+NPPJymSo2jwrWTkPOvjKySFTe
	v6tRoCPkvQ2pZxnn7aR3hOCrMAWmwa7WCUJ4GzdPJD2fx
	M0zYkH722ewhVmayyZTTgGQ81cpVmbag/95/OR
)
En utilisant l’outil sign.pl et notre ancienne KSK, nous avons signé l’enregistrement TXT aléatoire comme preuve de notre droit à effectuer le remplacement de KSK. Si la signature est correcte, SECREG sait que nous sommes les détenteurs de l’ancienne clé KSK, et que nous sommes autorisés à réaliser un remplacement de clé. SECREG mettra à jour l’enregistrement DS, qui sera publié lorsque la zone .nl sera rechargée. Le remplacement est achevé. L’ancienne KSK peut encore se trouver dans certains caches sur le réseau, il vous faut donc au moins la garder aussi longtemps que sa TTL dure. Et c’est seulement lorsque ce temps sera passé que pourra être ôtée de la zone l’ancienne KSK.  

Conclusion

La hollande est le premier tld avec un service dnssec fonctionnel. On ne peut donc trouver de nombreux programmes [10] mettant déjà en oeuvre les fonctionnalités supplémentaires offertes par DNSSEC. A cause de nombreux changements, et même très récents, du protocole DNSSEC, cela n’était véritablement pas possible du tout. Les extensions DNSSEC sont aussi manquantes des bibliothèques POSIX, telle que la bibliothèque C ; ce qui signifie que tous les programmes souhaitant intégrer DNSSEC ont besoin d’écrire leurs propres fonctions dns. Les premières applications à adopter DNSSEC seront probablement FreeS/WAN, l’implémentation Linux d’IPsec la plus déployée, et OpenSSH. Chacun de ces outils utilise la cryptographie à clé publique, et doit aller chercher et vérifier ses propres clés d’application. Ces clés peuvent être mises dans le DNS, mais on ne pourra avoir confiance en elles qu’à partir du moment où le DNS lui-même sera sécurisé. Et l’intégralité du problème peut devenir assez complexe dès que DNSSEC se combine avec les mises à jour DHCP, les mises à jour de dns dynamique, ou bien encore l’encryptage opportuniste d’IPsec. Les navigateurs vont bientôt comprendre DNSSEC, ainsi les banques en ligne pourront implémenter une véritable sécurité DNS, au lieu d’avertir l’usager de "seulement continuer tant que le nom de la banque apparaît dans la barre d’adresse". Nous attendions DNSSEC depuis des années. Espérons que l’expérimentation hollandaise SECREG donnera le courage à chacun de poursuivre dans la bonne direction.

 


Liens :

Michel • Boucey @ gmail • com 06 • 18 • 62 • 50 • 73