DNSSEC par la pratique (tutoriel Bind9/FreeBSD)

De Ensiwiki
Aller à : navigation, rechercher
DNSSEC: Problèmes de performance et ponts vers d'autres protocoles
Projet Projet de spécialité 2A
Sous-projet Communication et Réseaux
Étudiants Quentin LUC, Cyril LUPO, Thê-Minh TRINH
Promo 2012
Tuteur Martin Heusse (LIG)
Accueil projet: DNSSEC: Problèmes de performances et ponts vers d’autres protocoles

Cet article présente un tutoriel expliquant comment mettre en place une architecture de résolution de nom (DNS puis DNSSEC) sur un réseau de machines virtuelles. En premier lieu, nous nous intéresserons aux configurations de base en configurant une architecture simplifiée avec un client et un serveur de nom, puis nous nous intéresserons à la configuration d'une architecture hiérarchique. Le système d'exploitation utilisé est ici FreeBSD 8.2. On utilisera Bind9 sur les serveurs DNS.

Mise en place des réseaux

Nous utiliserons ici des réseaux de machines virtuelles. Pour cela, il faut donc créer des interfaces virtuelles sur chaque machine virtuelle.

Relier une interface à Internet

Nous aurons principalement besoin de relier une interface à Internet lorsque nous aurons à exporter des fichiers (fichiers de source ou capture). Pour cela, il faut configurer une interface virtuelle en NAT puis autoriser la configuration automatique de l’accès à internet via DHCP sur Bind.

Je vous conseille personnellement d’avoir au minimum deux interfaces sur la machine sur laquelle vous souhaitez accéder à internet. La première en NAT, la seconde et éventuellement les suivantes sur le/les réseaux virtuels que vous souhaitez.

Le fichier /etc/rc.conf/ indique les opérations à réaliser au démarrage. C'est dans ce fichier que l'on doit configurer les interfaces. Pour que l'interface em0 soit reliée à Internet, ajoutez-y la ligne ifconfig_em0=”DHCP”. Pour redémarrer le réseau, entrez la commande /etc/netstart. A chaque démarrage du réseau, l’interface em0 sera automatiquement configurée pour accéder à internet. Cependant, il est possible que vous souhaitiez ne pas avoir accès à internet en permanence et l’activer seulement si nécessaire. Pour cela, il suffit simplement de désactiver l’interface de la machine au démarrage. Pour établir une connexion internet, il suffira simplement de l’activer puis de redémarrer le réseau.

Relier une interface à un réseau interne

Il faut relier l'interface voulue à un certain réseau interne dans l'onglet Reseaux de la configuration de la machine virtuelle et choisir le bon réseau. Il faut ensuite attribuer une adresse IP fixe dans /etc/rc.conf. En fait, il faut faire les mêmes manipulations qu'au paragraphe précédent mais en remplaçant "DHCP" par l'adresse IP de la machine sur le sous-reseau. Ajoutez par exemple pour l'interface emX: ifconfig_em<X>="inet 10.0.0.1. Redémarrez ensuite le réseau: /etc/netstart.


Configuration d'une architecture DNS pour Bind9

Architecture à une seule zone

Il s'agira de mettre en place la configuration suivante:

Architecure basique.png

Congifuration de pc1

Il suffit d'indiquer à pc1 qu'il doit contacter pc2 pour la résolution de noms. On doit donc remplacer le contenu du fichier /etc/resolv.conf par

nameserver 10.0.0.2

Configuration du serveur de nom pc2

Sur pc2, il faut maintenant configurer le serveur de nom. Le premier fichier à éditer est le fichier de configuration du daemon named. Pour cela remplacez dans /etc/namedb/named.conf la ligne listen-on {127.0.0.1;} par listen-on {any;}. Ainsi, le serveur de nom va aussi pouvoir écouter les requêtes de pc1.

Il faut maintenant configurer la zone. On veut par exemple un serveur ayant autorité sur la zone .projet., qui contient les enregistrements server.projet, quentin.projet, cyril.projet et theminh.projet.À la fin de /etc/namedb/named.conf, ajoutez donc:

zone “projet” {
		type master;
		file “/etc/namedb/master/db.projet”;
	};

Il faut maintenant créer le fichier db.projet et insérer les enregistrements voulus.


$TTL	2h
@	IN	SOA	server.projet. postmaster.projet. (
				20110601
				8H
				2H
				1W
				1D
	)

@		IN	NS	server.projet.

server		A	192.168.0.3
cyril		A	192.168.0.41
quentin		A	192.168.10.4
theminh		A	192.168.0.121

Après chaque modification de configuration, redémarrer le daemon named avec la commande /etc/rc.d/named onerestart

Il est à noter qu'on peut insérer la ligne named_enable="YES" dans /etc/rc.conf pour que named soit lancé au démarrage. Sinon, il faudra redémarrer manuellement le daemon {named} à chaque modification de la configuration.

Mise en place d'une architecture hiérarchique

Le but de cette partie sera de mettre en, œuvre une architecture DNS hiérarchique. Au niveau réseau, la configuration à mettre en place est la suivante:

Architecture hierarchique.png

pc1 est ici un client (le daemon named ne tourne pas sur pc1). pc2 est un serveur de nom récursif (il n'a autorité sur aucune zone). pc3 est un serveur de nom itératif qui a autorité sur la zone projet., qui joue ici le rôle de zone racine. pc4 est un serveur itératif qui a autorité sur la zone quentin.projet., qui est un sous-domaine de projet.. Il est à noter que pc1, pc3 et pc4 sont sur des sous-réseaux différents.

Congifuration de pc1

Il suffit d'indiquer à pc1 qu'il doit contacter pc2 pour la résolution de noms. On doit donc remplacer le contenu du fichier /etc/resolv.conf par

nameserver 10.0.0.2

Congifuration de pc2

PC2 va ici jouer le rôle de serveur récursif. Par défault, BIND se comporte de cette manière.

La première chose à faire est de vider le fichier /etc/resolv.conf afin que toutes les requêtes soient redirigées directement vers BIND.

Ensuite, BIND connaît par défaut l'adresse de tous les serveurs root de la planète. Il va donc falloir lui indiquer que le seul serveur root qu'il doit contacter est pc3. Pour cela, ouvrez le fichier /etc/namedb/named.root et supprimez toutes les lignes autres que les deux premières qu'il faut renseigner comme suit :

.              3600000   IN   NS   projet.
projet.        3600000        A    192.168.0.3

Enfin, je vous conseille de rassembler l'ensemble des include de named.conf dans ce fichier pour que les erreurs soient plus rapidement détectable (la séparation des fichiers est inutile ici, puisque la configuration n'est pas lourde). Vous pouvez tout de même garder la séparation, elle ne change rien à la configuration.

Le contenu du fichier named.conf doit ressembler à celui-ci :

options {
	directory "/etc/namedb/working";
        pid-file "var/run/named/pid";
        dump-file "/var/dump/named_dump.db";

	auth-nxdomain no;    # conform to RFC1035
	listen-on { any; };

	dnssec-must-be-secure projet yes;

};

zone "." {
	type hint;
	file "/etc/namedb/named.root";
};

trusted-keys {
	"projet." 257 3 5 "AwEAAc4hB/..."; #la KSK
};


logging {
	channel mon_fichier {
		file "/etc/namedb/resolveur.msgs";
		severity dynamic;
		print-category yes;
		print-severity yes;
	};

	category default { default_syslog; mon_fichier; };
	category queries { mon_fichier; };
	category dnssec { mon_fichier; };
};


Remarque : Pour éviter les effets non-désirés, je vous conseille fortement de supprimer (ou déplacer) les fichiers autres que db.root, named.conf (et ses dérivés) et rndc.key

Congifuration de pc3

PC3 va ici jouer le rôle de serveur autoritaire sur le domaine .projet.

Le premier fichier à éditer est le fichier de configuration du daemon named. Pour cela remplacez dans /etc/namedb/named.conf la ligne listen-on {127.0.0.1;} par listen-on {any;}. Ainsi, le serveur de nom va aussi pouvoir écouter les requêtes de pc1.

Il faut maintenant configurer la zone. À la fin de /etc/namedb/named.conf, ajoutez donc :

zone “projet” {
		type master;
		file “/etc/namedb/master/db.projet”;
	};

Il faut maintenant créer le fichier db.projet et insérer les enregistrements voulus. Dans ce cas-ci, le serveur pc4 est un serveur gérant le sous-domaine quentin.projet. Il faut donc lui indiquer un enregistrement NS pour que le serveur récursif demande au sous-domaine. Le fichier db.projet est donc :

$TTL 2h
@	IN	SOA	server.projet. postmaster.projet. (
	20110601
	8H
	2H
	1W
	1D
	)
@	IN	NS	server.projet.
server	A	192.168.0.3
cyril	A	192.168.0.41
theminh	A	192.168.0.121


$ORIGIN	quentin.projet.
@		IN	NS	server
server		A		192.168.10.4

Après chaque modification de configuration, redémarrer le daemon named avec la commande /etc/rc.d/named onerestart

Remarque : Pour éviter les effets non-désirés, je vous conseille fortement de supprimer (ou déplacer) les fichiers autres que db.projet, named.conf (et ses dérivés) et rndc.key

Congifuration de pc4

La configuration est quasiment identique à celle de pc3. Seulement le contenu des fichiers change.

Le premier fichier à éditer est le fichier de configuration du daemon named. Pour cela remplacez dans /etc/namedb/named.conf la ligne listen-on {127.0.0.1;} par listen-on {any;}. Ainsi, le serveur de nom va aussi pouvoir écouter les requêtes de pc1.

Il faut maintenant configurer la zone. À la fin de /etc/namedb/named.conf, ajoutez donc :

zone “quentin.projet” {
		type master;
		file “/etc/bind/db.quentin.projet”;
	};

Il faut maintenant créer le fichier db.quentin.projet et insérer les enregistrements voulus. Le fichier db.quentin.projet est donc :

$TTL 2h
@	IN	SOA	server.projet. postmaster.projet. (
	20110601
	8H
	2H
	1W
	1D
	)
@	IN	NS	server.quentin.projet.
server	A	192.168.10.4
ski	A	192.168.10.20
rando	A	192.168.10.51
bateau  A       192.168.10.121

Après chaque modification de configuration, redémarrer le daemon named avec la commande /etc/rc.d/named onerestart

Remarque : Pour éviter les effets non-désirés, je vous conseille fortement de supprimer (ou déplacer) les fichiers autres que db.quentin.projet, named.conf (et ses dérivés) et rndc.key

Captures et Débug(syslog)

Utilisation de Syslog

Bind9 dispose d’un bon système de log. Cependant, il faut lui indiquer quoi enregistrer et ou. Pour cela, éditez le fichier named.conf et insérez les lignes suivantes en début de fichier :

logging {
    channel mon_fichier {
   	 file "syslog.msgs";
   	 severity dynamic;
   	 print-category yes;
   	 print-severity yes;
    };

    category default { default_syslog; mon_fichier;};
    category queries { mon_fichier; };
    category dnssec { mon_fichier; };

};


Ainsi, tous les log seront insérés dans le fichier /etc/namedb/working/syslog.msgs.

Captures

Le fait que les machines soient toutes sous des sous-réseaux différents complique les captures et l'analyse des paquets échangés sur le réseau. Il est donc fortement recommandé de faire l'ensemble des captures sur pc2 qui est au centre de toutes les communications.

Pour capturer les paquets, on utilise notre très cher tcpdump. Ce logiciel permet seulement de capturer des paquets sur une interface à la fois. Il faut donc le lancer trois fois, pour avoir les paquets sur chacune des trois interfaces de pc2 (c'est la raison pour laquelle il faut le faire sur la même machine, car les horloges des différents systèmes ne sont pas synchronisées). Il est ensuite possible de les rassembler en un fichier par le biais de mergecap (nous n'avons pas réussi à l'installer) ou tout simplement en rapatriant vos fichiers sur votre machine et en le faisant avec Wireshark (File > Merge).

De plus, il est conseillé de vider le cache de chacune des machines sur lesquelles Bind est lancé et de le redémarrer afin d'appliquer l'ensemble des changements effectué. Pour éviter de taper un ensemble de commande assez répétitif, et de switcher trop régulièrement entre les machines virtuelles, nous vous conseillons d'utiliser un script shell qui fera tout automatiquement, pour vous.

Voici le script que nous avons utilisé :

#!/bin/sh

if [ $3 -eq 1 ] ; then

	echo "Redémarrage resolver + vidage du cache"
	rndc flush
	/etc/init.d/bind9 restart


	echo "Redémarrage serveur autoritaire + vidage cache"
	ssh root@192.168.0.3 /etc/init.d/bind9 restart
	ssh root@192.168.0.3 rndc flush


	echo "Redémarrage serveur sous-zone"
	ssh root@192.168.10.4 /etc/init.d/bind9 restart
	ssh root@192.168.10.4 rndc flush
fi

echo "Lancement des captures"
tcpdump -i eth1 -s0 -w sclient.log &
tcpdump -i eth2 -s0 -w serveur_auto.log &
tcpdump -i eth3 -s0 -w serveur_soumis.log &

echo "Requete ski.quentin.projet du client"
ssh root@10.0.0.1 dig $1 $2


killall tcpdump
scp sclient.log root@192.168.0.3:/home/
scp serveur_auto.log root@192.168.0.3:/home/
scp serveur_soumis.log root@192.168.0.3:/home/

echo "Envoi sur ensibm"
ssh root@192.168.0.3 scp /home/sclient.log lupoc@ensibm.imag.fr:.
ssh root@192.168.0.3 scp /home/serveur_auto.log lupoc@ensibm.imag.fr:.
ssh root@192.168.0.3 scp /home/serveur_soumis.log lupoc@ensibm.imag.fr:.

La commande fonctionne ainsi :

./captures [+dnssec] <adresse> [1]

Si le 1 est présent, tous les caches seront vidés et les serveurs redémarrés.

Remarques : Pour que ce script fonctionne, il faut avoir installé des clés ssh de telle sorte que la machine 2 puisse se connecter à la machine 3 sans avoir à redemander le mot de passe à chaque fois, mais aussi entre la machine 3 et votre compte distant (ici c'est ensibm). Pour cela, reportez-vous au tp réseau de première année :)

Implémentation de DNSSEC

L'implémentation de DNSSEC n'est vraiment intéressante que pour une architecture hiérarchique, car le cas basique (client-serveur unique) ne donne pas l'occasion de rencontrer les problématiques de chaîne de confiance et. Toutefois, il est intéressant de s'entrainer au préalable sur une architecture basique avant de se frotter à une architecture hiérarchique. Dans un souci de pédagogie, ce tutoriel suit cette démarche.

DNSSEC sur une seule zone

Il s'agira ici d'implémenter DNSSEC entre le client pc1 et le serveur de nom pc2. Il est à noter qu'ici pc1 est un petit peu plus qu'un client classique car il doit pouvoir vérifier la signature des réponses qu'il reçoit. Le daemon named doit donc aussi tourner sur pc1.

Configuration de pc2

Côté serveur, on commence par créer deux paires de clés :

cd /etc/namedb/master/
dnssec-keygen -a RSASHA1 -b 1024 -n ZONE projet
dnssec-keygen -f KSK -a RSASHA1 -b 1024 -n ZONE projet

Attention ! Notez bien les identifiant des clés pour pouvoir les distinguer par la suite.

Remarque 1 : Vous trouverez sûrement dans la littérature sur DNSSEC des remarques sur la taille des clés. La KSK est à renouveler moins souvent que la ZSK, elle peut donc être plus longue. Ici, on a fait le choix que les deux aient la même taille.

Remarque 2 : Vous remarquerez que cette commande créé deux fichier à chaque fois, un fichier .key et un fichier .private, qui correspondent respectivement à la clé publique et à la clé privée.


Le fichier .key contient l'enregistrement DNSKEY de la zone en question :

; This is a key-signing key, keyid 51781, for quentin.projet.
; Created: 20110607122604 (Tue Jun  7 14:26:04 2011)
; Publish: 20110607122604 (Tue Jun  7 14:26:04 2011)
; Activate: 20110607122604 (Tue Jun  7 14:26:04 2011)
quentin.projet. IN DNSKEY 257 3 5 AwEAAfE8ezIHSj+iMgyz1XdHky6OQAYIXzDi21IYgWdoHlYHNx8osgsz ZK2+CzFDaeHmxfM4ien8p3iKH+
NdgOWNZGNYsjKZZZH97RdY1NRMcUI9 CZr3xNIGvpiyaN8FG693/9OnYv0dLHatPq+Rev0MVXKzl4JKEh3UZV+v EDVzCOEB


Introduisons maintenant les clés dans notre fichier de zone (db.projet). Ecrivez à la fin de db.projet :

$include nom_du_fichier_KSK.key
$include nom_du_fichier_ZSK.key

Signons maintenant la zone :

cd /etc/namedb/master
dnssec-signzone -o projet. db.projet

Ceci crée le fichier db.projet.signed. La dernière étape est de modifier /etc/namedb/named.conf. Dans named.conf, effectuer la modification :

zone “projet” {
	type “master”;
	file “/etc/namedb/master/db.projet.signed”;
};

Dans named.conf, ajouter dans les options :

dnssec-enable yes;

N’oubliez pas de relancer bind :

/etc/rc.d/named onerestart

Configuration de pc1

Côté client, c'est un peu plus simple !

Dans une architecture à deux ordinateurs, si vous voulez faire de la vérification côté client, voici la démarche à suivre. Premièrement, il faut récupérer la KSK publique. Une fois cela fait, il faut la mettre dans le fichier /etc/namedb/named.conf :

tail -n 1 KSK.key >> /etc/namedb/named.conf 

Mainenant, vous pouvez effectuer le test en faisant :

dig +dnssec +sigchase papa.projet

DNSSEC sur une architecture hiérarchique

Nous reprenons la configuration des serveurs telle que nous l'avons laissée dans la section 2.2.

Configuration de pc4

Ce serveur la doit avoir deux paires de clés (une pour la ZSK, et une pour la KSK). Il faut donc effectuer les mêmes opérations que celles décrites ci-dessus, pour le pc2 de l'architecture à deux machines.

  • Génération des paires de clés
  • Insertion dans le fichier de zone
  • Signature de la zone
  • Modification de /etc/namedb/named.conf :
zone “quentin.projet” {
	type “master”;
	file “/etc/namedb/db.quentin.projet.signed”;
};
  • Ajout de l'option dnssec-enabled yes;


Maintenant que toutes ces étapes ont été effectuées, il faut envoyer au serveur autoritaire le fichier contenant l'enregistrement DS de la zone (voir Introduction à DNSSEC) de manière sécurisée et indépendante de DNSSEC (la sécurité importe peu dans le cas présent, mais c'était juste pour la forme).

Cet enregistrement a été créé dans un fichier à part : dsset-quentin.projet. qui contient :

quentin.projet.		IN DS 51781 5 1 3BFA45EC2BF40CC96308A3C3C4D2F55812E17015
quentin.projet.		IN DS 51781 5 2 754505D33985643182D3EF9AA0E47B4D3324A4818EA682BDA79E89DF 76377A74

Configuration de pc3

Ce serveur la doit aussi avoir deux paires de clés (une pour la ZSK, et une pour la KSK). Il faut donc effectuer les mêmes opérations que celles décrites ci-dessus, pour le pc2 de l'architecture à deux machines (avec quelques étapes supplémentaires) :

  • Génération des clés
  • Insertion des enregistrements DNSKEY dans le fichier de zone
  • Récupération du fichier dsset-quentin.projet et insertion de son contenu dans le fichier de zone (db.projet)
  • Signature de la zone
  • Ajout des infos dans named.conf

Voila, c'est tout. Pour les étapes qui ne sont pas détaillées, ce sont exactement les mêmes que celles détaillées ci-dessus.

Configuration de pc1

Le client n'a pas besoin de configuration particulière, il demande juste des réponses dnssec par l'intermédiaire d'un dig +dnssec <nom_domaine>

Configuration de pc2

Le serveur récursif doit simplement connaître la clé publique associée à la KSK du serveur autoritaire. Il faut lui transmettre cette clé par d'autre moyen que DNSSEC, car elle correspond dans notre cas à la trust anchor (voir section 1.4 de l'introduction à DNSSEC).

Une fois le fichier KSK.key récupéré, il faut indiquer dans named.conf qu'on fait confiance à cette clé. Pour cela, il faut rajouter les lignes suivantes :

trusted-keys {
     "projet." 257 3 5 "clé (chaine de caractère)"
};


Remarque : Pour vérifier que pc2 fait bien la vérification des clés et refuse bien les requêtes incorrectes, vous pouvez utiliser l'option dnssec-must-be-secure projet yes; (à rajouter dans accolade options donc), modifier la clé dans trusted-keys et vérifier que le client ne reçoit plus de réponse.

Observations

Les Captures suivantes (Fichier:Captures.tar.gz) retracent l'ensemble des trames que l'on peut observer entre les machines de l'architecture que nous venons de mettre lorsque nous effectuons un requête sur un nom appartenant au sous-domaine quentin.projet. Il est recommandé d'ouvrir ces fichiers avec wireshark.

Le fichier Recursion.pcap retrace les échanges pour une requête valide. Il est à rapproché du schéma suivant:


Requete dnssec.png


remarque: Il est à noter que ce schéma ne prend pas en compte le fait que pc2 commence par contacter pc3 avant. Il commence au moment où pc2 contacte pc4


Le fichier recursion_noexist.pcap retrace les échanges pour une requête invalide. On entend par requête invalide une requête concernant un nom qui n'est dans aucun enregistrement de la zone spécifiée.