Passer son domaine DNS à DNSSEC sous BIND

DNSSEC est un protocole visant à sécuriser les transactions DNS, contrairement à SSL, il ne protège pas que le canal de communication, mais aussi les enregistrements, voyons comment le mettre en place.
Ce guide est plus centré sur Debian Wheezy ou Ubuntu 12.10 et supérieur, mais peut en grande partie être réutilisé pour d'autres distributions.

Préliminaires

Nous utiliseront dans ce tutorial la zone test.net, considérerons que celle-ci est actuellement en place sur un serveur primaire et un secondaire de façon standard et qu'elle fonctionne correctement. Ces deux serveurs utilisent le logiciel BIND.

  • ns1.test.net : Serveur primaire, adresse IPv4 10.0.0.1, IPv6 fd00:a::1
  • ns2.test.net : Serveur secondaire, adresse IPv4 10.0.0.2, IPv6 fd00:a::2
  • db.test.net : Fichier de la zone test.net

Sur le serveur primaire

Activation de DNSSEC

La première chose à faire est d'activer DNSSEC, pour cela, éditez le fichier /etc/bind/named.conf.options, et vérifiez que les options suivantes soient présentent et configurées comme ci-dessous. Si elles n'y sont pas, les ajouter

options {
        [...]
        dnssec-enable yes;
        dnssec-validation auto;
        dnssec-lookaside auto;
        [...]
};

Création des clefs

Une fois ceci fait, nous pouvons générer les clefs de chiffrement utilisées par DNSSEC, pour ce faire, nous utiliserons la commande zonesigner, fournis par le paquet dnssec-tools.

# zonesigner -genkeys -usensec3 -zone test.net db.test.net
Après quelques secondes, vous vous retrouvez avec de nouveaux fichiers, parmi lesquels :
  • Ktest.*.private : Clef privée de la zone test.net
  • Ktest.*.key : Clef de publique de la zone test.net
  • dsset-test.net. : Contient les enregistrements de type DS de la zone, et peuvent être utilisés fournis à votre bureau d'enregistrement DNS (registar).
  • db.test.net.signed : Fichier de zone signé.
  • test.net.krf : Fichier référençant les clefs de la zone test.net.

DNSSEC utilise deux types de pairs de clefs différent, les pairs de signement de clefs, ou KSK pour Key-Signing Key, et ceux de signature de zone, ou ZSK pour Zone-Signing Key, zonesigner ayant crée deux pairs de clefs ZSK, nous nous retrouvons avec six fichiers Ktest, dont, trois .private et trois .key.
Pour savoir quelle paire de clefs est un KSK d'une KSK, il suffit de consulter le fichier test.net.krf.

zone	"test.net"
	keyrec_type	"zone"
	zonefile	"db.test.net"
	keyrec_signsecs	"1378929175"
	keyrec_signdate	"Wed Sep 11 19:52:55 2013"
	lastset		"test.net-signset-00003"
	signedzone	"db.test.net.signed"
	zskdirectory	"/etc/bind/etc/bind"
	kskdirectory	"/etc/bind/etc/bind"
	archivedir	"/var/lib/dnssec-tools/archive"
	endtime		"2592000"
	kskcount	"1"
	zskcount	"1"
	zskcur		"test.net-signset-00001"
	zskpub		"test.net-signset-00002"
	kskcur		"test.net-signset-00003"
	serial		"4"
	rollmgr		"rollerd"
	lastcmd		"-krfile test.net.krf -zone test.net db.test.net"

set	"test.net-signset-00001"
	keyrec_setsecs	"1378929170"
	keyrec_setdate	"Wed Sep 11 19:52:50 2013"
	zonename	"test.net"
	set_type	"zskcur"
	keys		"Ktest.net.+008+44505"

set	"test.net-signset-00002"
	keyrec_setsecs	"1378929170"
	keyrec_setdate	"Wed Sep 11 19:52:50 2013"
	zonename	"test.net"
	set_type	"zskpub"
	keys		"Ktest.net.+008+19995"

key	"Ktest.net.+008+44505"
	keyrec_type	"zskcur"
	algorithm	"rsasha256"
	random		"/dev/urandom"
	keypath		"/etc/bind/etc/bind/Ktest.net.+008+44505.key"
	zsklength	"1024"
	zsklife		"604800"
	keyrec_gensecs	"1378929171"
	keyrec_gendate	"Wed Sep 11 19:52:51 2013"
	zonename	"test.net"

key	"Ktest.net.+008+19995"
	keyrec_type	"zskpub"
	algorithm	"rsasha256"
	random		"/dev/urandom"
	keypath		"/etc/bind/etc/bind/Ktest.net.+008+19995.key"
	zsklength	"1024"
	zsklife		"604800"
	keyrec_gensecs	"1378929171"
	keyrec_gendate	"Wed Sep 11 19:52:51 2013"
	zonename	"test.net"

set	"test.net-signset-00003"
	keyrec_setsecs	"1378929171"
	keyrec_setdate	"Wed Sep 11 19:52:51 2013"
	zonename	"test.net"
	set_type	"kskcur"
	keys		"Ktest.net.+008+56077"

key	"Ktest.net.+008+56077"
	keyrec_type	"kskcur"
	algorithm	"rsasha256"
	random		"/dev/urandom"
	keypath		"/etc/bind/etc/bind/Ktest.net.+008+56077.key"
	ksklength	"2048"
	ksklife		"15768000"
	revperiod	"3888000"
	keyrec_gensecs	"1378929173"
	keyrec_gendate	"Wed Sep 11 19:52:53 2013"
	zonename	"test.net"

Les clefs de type ZSK devant régulièrement être changé, zonesigner en a généré deux, qu'il suffira d'alterner. Dans le fichier test.net.zrf, l'une est référencée comme étant celle actuellement utilisé via le keyrec_type zskcur, et l'autre, celle de réserve avec le keyrec_type zskpub. La clef KSK est référencée par keyrec_type kskcur.

Le fichier de zone signé peu être véréfié avec la commande donuts

# donuts --level 8 -v db.test.net.signed test.net

Par défaut, le fichier de zone signé est généré dans le dossier où zonesigner est utilisé, mais il est possible de la déplacer, sans oublier de modifier le fichier .krf en conséquence.

Chargement de la zone signée

Pour indiquer à BIND d'utiliser la zone signée, il suffit de modifier le fichier contenant la déclaration de la zone test.net et de lui dire d'utiliser le fichier db.test.net.signed.

zone "test.net" {
        type master;
        allow-transfer {
                10.0.0.2;
                fd00:a::2;
        };
        also-notify {
                10.0.0.2;
                fd00:a::2;
        };
        file "/var/cache//bind/db.test.net.signed";
};

Redémarrage de BIND

Enfin, redémarrez le service BIND.
# service bind9 restart

Serveur secondaire

Activation de DNSSEC

Comme pour le serveur primaire, modifiez le fichier /etc/bind/named.conf.options et vérifiez que les options suivantes soient présentent et configurées comme ci-dessous. Si elles n'y sont pas, les ajouter

options {
        [...]
        dnssec-enable yes;
        dnssec-validation auto;
        dnssec-lookaside auto;
        [...]
};

Chargement de la zone signée

Idem ici, modifiez le fichier contenant la déclaration de la zone test.net et de lui dire d'utiliser le fichier db.test.net.signed.

zone "test.net" {
        type slave;
        masters {
                10.0.0.1;
                fd00:a::1;
        };
        allow-notify {
                10.0.0.1;
                fd00:a::1;
        };
        file "/var/cache/bind/db.test.net.signed";
};

Redémarrage de BIND et nettoyage

Redémarrez le service BIND et supprimez l'ancien fichier de zone de serveur secondaire, celui n'en ayant plus besoin.
# service bind9 restart
# rm /var/cache/bind/db.test.net

Roulement automatique des clefs avec rollerd

Comme dit précédemment, nous disposons de deux paires de clefs ZSK, celle ci devant être changé régulièrement, nous n'aurons pas à en générer d'autres, reste cependant à encro automatiser leur roulement afin de nous éviter cet effort. Pour ce faire, nous utiliserons le service rollerd
Rollerd demande un fichier de configuration contenant les informations des différentes zones et clefs DNSSEC pour effectuer le roulement, ce fichier de configuration peut être généré avec la commande rollinit.

# rollinit -zonefile /var/cache/bind/db.test.net.signed -keyrec /etc/bind/test.net.krf -admin admin@test.net test.net >> /etc/dnssec-tools/dnssec-tools.rollrec
Puis, démarrez le service rollerd
# service rollerd restart

Vérification automatique des zones avec donutsd

La commande donuts utilisée précédemment existe en version service via donutsd afin de régulièrement vérifier les zones DNS, cependant, donutsd viens sans aucun fichier d'Init et demande à être lancé manuellement. Pour l'utiliser plus agréablement, nous créerons quelques fichiers supplémentaires.

Fichier de configuration

Créez un fichier /etc/dnssec-tools/dnssec-tools.donuts contenant la syntaxe suivante :

/le/fichier/de/zone.signed       zone.tld      admin@zone.tld
Soit, dans notre cas :
/var/cache/bind/db.test.net.signed       test.net      admin@test.net

Fichier d'Init

Créez un fichier /etc/default/donutsd avec le contenu suivant, il indiquera au script d'init le fichier de configuration à charger.

# Defaults for dnssec-tools donutsd initscript
# sourced by /etc/init.d/donutsd
# installed at /etc/default/donutsd by the maintainer scripts

# Additional options that are passed to the Daemon.
DAEMON_OPTS="-i /etc/dnssec-tools/dnssec-tools.donuts"

Enfin le fichier /etc/init.d/donutsd, le script d'Init proprement dit :

#!/bin/sh
### BEGIN INIT INFO
# Provides:          donutsd
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: DNSSEC-Tools daemon to check DNS zone.
# Description: The donutsd daemon will regulary check DNS zones.
### END INIT INFO

# Author: Ondřej Surý 

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="DNSSEC-Tools donutsd"
NAME=donutsd
DAEMON=/usr/sbin/donutsd
DAEMON_OPTS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x $DAEMON ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
	echo -n "Starting $DESC"
	$DAEMON	$DAEMON_OPTS &
	if [ $? -eq 0 ]; then
		if [ -r "$PIDFILE" ]; then
			rm -f "$PIDFILE";
		fi
		echo $(ps -ef | grep $NAME | grep -v grep | awk '{ print $2 }' | awk 'NR == 2 { print; }') > "$PIDFILE";
		echo -e " [ \\033[00;32mok\\033[00m ]";
	else
		echo -e " [ \\033[00;31mfail\\033[00m ]";
	fi
}

#
# Function that stops the daemon/service
#
do_stop()
{
	echo -n "Stoping $DESC"
	kill $(cat "$PIDFILE");
	if [ $? -eq 0 ]; then
		rm -f "$PIDFILE";
		echo -e " [ \\033[00;32mok\\033[00m ]";
	else
		echo -e " [ \\033[00;31mfail\\033[00m ]";
	fi
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
	do_stop;
	sleep 1;
	do_start;
}

case "$1" in
  start)
	do_start;
  ;;
  stop)
	do_stop;
	;;
  restart|force-reload)
	do_reload;
	;;
  *)
	echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
	exit 3
	;;
esac

Pour terminer, rendez ce script exécutable, ajoutez le aux scripts de démarrage et démarrez-le :

# chmod 755 /etc/init.d/donutsd
# insserv donutsd
# service donutsd restart

Tester

Pour test, il suffit d'utiliser la commande dig avec l'option +dnssec, si DNSSEC est convenablement configuré, des information DNSSEC concernant la zone interrogée vous seront retournées.

$ dig +dnssec test.net

Indiquer à son registrar qu'une zone utilise DNSSEC

Pour indiquer à votre bureau d'enregistrement DNS (registrar) que votre zone utilise DNSSEC, il faut, selon, selon le registrar, soit lui fournir le contenu du fichier .dsset (ici dsset-test.net.) ou la clefs KSK publique de votre zone.

Danse ce dernier cas, affichez le contenu du fichier contenant la clef KSK publique de votre zone et copiez le longs groupe de chiffres, jusqu'au signe =.

; This is a key-signing key, keyid 56077, for zergy.net.
; Created: 20130911195251 (Wed Sep 11 21:52:51 2013)
; Publish: 20130911195251 (Wed Sep 11 21:52:51 2013)
; Activate: 20130911195251 (Wed Sep 11 21:52:51 2013)
test.net. IN DNSKEY 257 3 8 AwEAAbLM5XW6ECxbCmUXJDI4GW04TrkpDAIP+4nj7GGA4T0CsNYiRWrr la8Ro2RCUV14Ce4bCSZja+PpfMqffcytMf+Fqd548duROV2Dc05WINfJ /VAklbYLsMfs1XM6x54WXGDEL1kRz7C0s8wqu1jFeX5pSjrOooGdG3BQ 8mo0dRA1/35JT8EOZboSg4kLqmjqU3OtlEkLO5W9rfzN5z+jbj5Io+T9 B+/DET0ATfE7/N929DtDlRdvsE+entGFZUiLOrMj6Dfy76ESXMxjjb/6 bRf1Gmo6eu66XwGt+7QZ6+UFOjY7MMJUzslvEUgTXYkVWYsm12LHovD0 oJ8F3zMtrik=
Ici, le registrar à besoin de la suite de chiffres suivante :
AwEAAbLM5XW6ECxbCmUXJDI4GW04TrkpDAIP+4nj7GGA4T0CsNYiRWrr la8Ro2RCUV14Ce4bCSZja+PpfMqffcytMf+Fqd548duROV2Dc05WINfJ /VAklbYLsMfs1XM6x54WXGDEL1kRz7C0s8wqu1jFeX5pSjrOooGdG3BQ 8mo0dRA1/35JT8EOZboSg4kLqmjqU3OtlEkLO5W9rfzN5z+jbj5Io+T9 B+/DET0ATfE7/N929DtDlRdvsE+entGFZUiLOrMj6Dfy76ESXMxjjb/6 bRf1Gmo6eu66XwGt+7QZ6+UFOjY7MMJUzslvEUgTXYkVWYsm12LHovD0 oJ8F3zMtrik=

Modifier une zone

Les modifications de zone DNSSEC doivent s'effectuer sur le fichier de zone non signé, veillez donc à toujours en garder un original. Une fois la modification effectuée, il vous sera demandé de resigner la zone pour générer en fichier de zone signé prenant en compte les modifications. La nouvelle signature ne demande pas la génération d nouvelle clefs et peu être effectuée avec zonesigner de la fonçon suivante :

# zonesigner -gends -zone test.net db.test.net db.test.net.signed
Si vous utilisez le service rollerd, arrêtez-le le temps de signer votre nouvelle version de zone :
# service rollerd stop
# zonesigner -gends -zone test.net db.test.net db.test.net.signed
# service rollerd start
Vus : 822
Publié par Zergy : 41