SECURISATION DU SERVEUR DNS BIND


I. VERSION DE BIND

Suite a la decouverte ces derniers temps, de nombreuses erreurs d'implementation dans BIND. On optera pour version 8.2.3 minimum. De plus la version 9 de Bind implemente DNSSEC pour les zones signees et TSIG pour signer les requetes DNS, ce qui devrait resoudre a terme les differents problemes lies au DNS spoofing. Donc nous decidons d installer la version 9.2.1. Nous savons que BIND est capable de supporter de lourdes charges, le serveur F.root-servers.net utilisant bind 8.2.3 repond a plus de 272 millions de requetes DNS par jour.

II. CACHER LE NUMERO DE VERSION

Le numero de version s'obtient facilement :


$ nslookup - 127.0.0.1
Default Server: localhost
Address: 127.0.0.1

> set class=chaos
> set q=txt
> version.bind
Server: localhost
Address: 127.0.0.1

VERSION.BIND text = "9.2.1"

Une possibilite est de definir le texte a renvoyer. Dans la rubrique options, il nous suffit de specifier


version "7.2.2";

Mais cela a l'inconvenient de le masquer pour tout le monde. On peut ruser un peu plus en redefinissant la zone "chaos" :


zone "bind" chaos {
type master;
file "bind";
allow-query { localhost; };
};

Cette zone recouvre un ensemble d'information sur le serveur comme sa version VERSION.BIND ou ses auteurs authors.bind. Dans le fichier bind, on definit la classe chaos.


$TTL 1D
$ORIGIN bind.
@ 1D CHAOS SOA localhost. root.localhost. (
1
3H
1H
1W
1D )
CHAOS NS localhost.

Ainsi lorsqu'un potentiel pirate cherche a obtenir la version de bind, sa tentative sera enregistree :


Sun 04 07:02:12 vectra named[17035]: unapproved query from [10.0.0.169].4863 for "version.bind"

Et on pourra continuer a recuperer le numero de version en local.


III. STRATEGIE "PARANOIAQUE PAR DEFAUT"

Prenons le parti d'etre paranoiaque, interdisons tout par defaut.


options {
also-notify { none; };
allow-query { none; };
};

"also-notify" doit contenir les DNS secondaires non officiels, cela permet de les prevenir immediatement si une mise a jour d'une zone est effectuee.


"allow-query" indique qui peut interroger le serveur pour une zone donnee.


IV. DEFINITION DES ZONES ET UTILISATION DES ACLs

Pour obtenir la liste des DNS primaires, il suffit d'executer la commande


$ dig @ns.internic.net .ns > named.ca.

Ils resolvent les adresses ip/noms pour lesquels le serveur DNS n'est ni primaire, ni secondaire.


La zone pour les requetes par defaut est la zone "." definie ci-dessous :


zone "." {
type hint;
file "named.ca";
allow-query { mon_parc_info; };
};

Dans certains cas d'architecture reseau ou pour des raisons de securite, on peut vouloir forcer un DNS interne a utiliser un serveur DNS bien specifique pour repondre aux requetes DNS. Dans ce cas-la, on impose cette contrainte dans les options :


options {
....
forward only;
forwarders { mes_dns_en_sortie; };
};

Une zone de resolution inverse, adresse IP vers nom de machine, pour l'adresse de loopback se definit ainsi


zone "0.0.127.in-addr.arpa" {
type master;
allow-query { mon_parc_info; };
file "named.local";
};

Le serveur primaire doit etre interroger par tous mais n'autoriser que les dns secondaires a effectuer des transferts de zone.


zone "domaine1.org" {
type master;
file "domain1/domaine1.org";
also_notify { dns_sec_non_officiel; };
allow-transfer { dns_sec_officiel; dns_sec_non_officiel; };
allow-query { any; };
}

V. SECURISATION


Les ports inferieurs a 1024 sont des ports privilegies, c'est-a-dire que seuls les programmes fonctionnant en tant que root peuvent les utiliser. Le port dedie aux serveurs DNS est le port TCP/UDP 53 (domains).

Un mecanisme de securite est incorpore dans les versions modernes de bind qui lui permet, une fois qu'il s'est attribue le port domains (53), de prendre l'identite d'un utilisateur sans pouvoir, named generalement. Ainsi, en cas de faille de securite, le pirate prend l'identite named et non root.

Cependant, le pirate possede desormais un acces a la machine, ou il est en mesure d'exploiter des failles locales. L'idee est de le confiner dans une partie de l'arborescence, par exemple, le repertoire /var/chroot-named ou se trouvent egalement les fichiers necessaires a bind.

1. Creation de la prison


Pour creer la prison, il faut commencer par etre root.


$ mkdir /var/chroot-named
$ mkdir /var/chroot-named/dev
$ mkdir /var/chroot-named/etc
$ mkdir /var/chroot-named/var
$ mkdir /var/chroot-named/var/run
$ mkdir /var/chroot-named/usr
$ mkdir /var/chroot-named/usr/sbin
$ mknod /var/chroot-named/dev/null c 1 3

2. Creation du compte


$ adduser named -s /bin/false
$ egrep "(^root:|^named:)" /etc/passwd > /var/chroot-named/etc/passwd
$ egrep "(^root:|^named:)" /etc/group > /var/chroot-named/etc/group

3. Configuration du systeme de log


Syslogd supporte l'option "-a", donc il faut qu'il soit demarrer avec dans


/etc/rc.d/init.d/syslog :


daemon syslogd -m 0 -a /var/chroot-named/dev/log

Dans named.conf :


logging {
channel replace_syslog{
file "/var/log/dns" versions 3 size 100k;
severity info;
print-category yes;
print-severity yes;
print-time yes;
};
category default { replace_syslog; default_debug; };
};

Les fichiers de log appartiennent a root.


Recuperation de la configuration


$ mv /etc/named.conf /var/chroot-named/etc
$ mv /var/named /var/chroot-named/var
$ ln -s /var/chroot-named/etc/named.conf /etc/named.conf
$ ln -s /var/chroot-named/var/named /var/named
$ chown -R named:named /var/chroot-named/var/named

N'oublions pas que bind doit pouvoir ecrire dans les repertoires correspondant aux zones esclaves. Il faut donc les creer et les attribuer a l'utilisateur named, sans quoi il ne pourra pas recuperer les zones dont il est secondaire.


3. Installation des binaires


Soit on compile named et named-xfer en statique, soit on utilise les binaires existants et on copie les librairies dynamiques necessaires :


$ cp /usr/sbin/named /var/chroot-named/usr/sbin
$ cp /usr/sbin/named-xfer /var/chroot-named/usr/sbin
$ mkdir /var/chroot-named/lib
$ mkdir /var/chroot-named/usr/lib
$ ldd /usr/sbin/named-xfer
libc.so.6 => /lib/libc.so.6 (0x40022000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Cette derniere commande montre toutes les librairies dont bind a besoin pour fonctionner : chacune d'elle doit egalement etre presente dans la prison.


4. Utilisation


Dans /etc/rc.d/init.d/named, on signale que le demon tourne dans une prison :


daemon named -u named -t /var/chroot-named

L'option "-u" designe l'utilisateur sous lequel fonctionnera bind et l'option "-t" le repertoire dans lequel il s'execute, sa prison.


5. Pour aller plus loin


La securite TSIG permet de reduire les consequences de l'IP spoofing entre les DNS primaires et secondaires. Ils partagent une cle secrete dont le nom meme est secret, grenier-supersecret dans l'exemple. La cle est encodee en base 64 head -c 16 /dev/urandom | uuencode -m - et se definit ainsi dans les fichiers de configuration des serveurs concernes :


key grenier-supersecret. {
algorithm hmac-md5;
secret "mZiMNOUYQPMNwsDzrX2ENw==";
};

Dans la configuration du DNS maitre, on ajoute :


server ip_dns_secondaire {
transfer-format many-answers;
keys { grenier-supersecret.; };
};

et pour les DNS secondaires, on met la meme chose mais avec l'adresse IP du serveur DNS primaire.

Pour fonctionner, les horloges systemes des deux serveurs doivent etre synchronisees. Au besoin, on peut les synchroniser par ntp. La confidentialite des cles est liee a la securite du serveur le plus vulnerable.