Ces derniers temps, pas mal d'erreurs d'implémentation (tsig, infoleak,...) ont été découvertes dans BIND. Le détail de ces problèmes est disponible sur https://kb.isc.org/article/AA-00959/0. Ainsi à l'heure actuelle, il vous faut installer la version 8.2.3 ou la version 9.1. Bind 9 implémente DNSSEC pour les zones signés et TSIG pour signer les requêtes DNS, cela devrait permettre de résoudre à terme les différents problèmes liés au DNS spoofing. Une autre nouveauté de taille est le support d'IPV6 et de nouveaux protocoles (IXFR, DDNS, Notify, EDNSO). Le support TSIG est disponible à partir de Bind 8.2.
Si vous vous demandez si BIND est capable de supporter de lourde charge, le serveur F.root-servers.net utilisant bind 8.2.3 répond à plus de 272 millions de requêtes DNS par jour.
Vous pouvez aussi bien utiliser des packages pré-compilés que compiler bind vous-même à partir des sources. Celles-ci sont disponibles sur http://www.isc.org. Si vous utilisez des packages RedHat, il vous faut installer bind, bind-utils ainsi que bind-devel si vous programmez.
Le fichier de configuration de bind est généralement le fichier /etc/named.conf. Quelques mots rapides sur la configuration :
Prenons le parti d'être parano, interdisons tout par défaut.
options { also-notify { none; }; allow-transfer { none; }; allow-query { none; }; };
also-notify
doit contenir les DNS secondaires non officiels,
cela permet de les prévenir immédiatement si une mise à jour
d'une zone est effectuée. allow-transfer
indique quelles sont les machines
autorisées à effectuer un transfert de zone, c'est à dire à
récupérer toutes les informations d'une zone, les seuls DNS secondaires devraient être
autorisés. allow-query
indique qui peut interroger le serveur pour une zone donnée.
Les ACL (access control lists) permettent de définir des ensembles de machines et/ou de réseaux. Quatre ACL sont pré-définies : any, none, localhost et localnets. Elles correspondent respectivement à tout le monde, personne, le serveur seulement et l'ensemble des réseaux définis par les adresses IP et netmasks de la machine.
Une ACL se définit de la façon suivante :
acl name { address_match_list };
Par exemple, je peux définir l'acl dns_sec_non_officiel
comportant deux adresses IP de la manière suivante :
acl dns_sec_non_officiel { 192.168.1.2; 192.168.3.4; }
Pour obtenir la liste des DNS primaires, il suffit d'exécuter la commande
dig @ns.internic.net . ns > named.ca
. Ils résolvent
les adresses ip/noms pour lesquels le serveur DNS n'est ni primaire, ni
secondaire.
La zone pour les requêtes par défaut est la zone "." définie ci-dessous :
zone "." { type hint; file "named.ca"; allow-query { mon_parc_info; }; };
mon_parc_info
est une acl contenant les IPs des machines de mon réseau.
Dans certains cas d'architecture réseau ou pour des raisons de sécurité, on peut vouloir forcer un DNS interne à utiliser un serveur DNS bien spécifique pour répondre aux requêtes DNS. Dans ce cas-là, on va lui définir cette contrainte dans les options :
options { .... forward only; forwarders { mes_dns_en_sortie; }; };
Autre remarque, si votre machine utilise du "dial on demand" ou connexion à la demande (la connexion
par modem s'active s'il y a des requêtes vers Internet),
ajouter dans les options dialup yes;
pour éviter que votre
connexion ne soit démarrer de manière intempestive.
Une zone de résolution inverse, adresse IP vers nom de machine, pour l'adresse de loopback se définit ainsi
zone "0.0.127.in-addr.arpa" { type master; allow-query { mon_parc_info; }; file "named.local"; };
Un serveur primaire doit être interroger par tous mais n'autoriser que les dns secondaires à effectuer des transferts de zone. Le transfert de zone est comme son nom l'indique le moyen par lequel un DNS récupère la totalité des paramètres d'une 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; }; }
Les DNS indiqués dans le paramètre Also_notify
sont avertis
dès qu'une modification est intervenue dans une
zone. C'est utilisé concrètement pour avertir
les DNS secondaires non officiels, c'est
à dire ceux qui ne sont pas explicitement déclaré comme NS
dans le fichier de définissant la zone.
Certains services proposés par les ISP ne sont accessibles que par l'utilisation de leur DNS. Ainsi, pour accéder aux news ou lire son mail par l'interface webmail de Wanadoo, il faut utiliser le DNS spécifié sur la feuille indiquant le login/password ou donné par le serveur DHCP.
zone "wanadoo.fr" { type forward; forwarders { 193.252.19.3; }; };NB: Wanadoo filtre les IP accédant aux DNS, serveurs web,... réservés aux abonnés.
Le numéro 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 = "8.2.3-REL"
Une possibilité est de définir le texte à renvoyer. Dans la rubrique
options, il suffit de spécifier version "mon super texte". Mais cela a
l'inconvénient de le masquer pour tout le monde.
On peut ruser un peu plus en redéfinissant la zone "chaos
" :
zone "bind" chaos { type master; file "bind"; allow-query { localhost; }; };Dans le fichier
bind
, je définis la classe chaos
.
$TTL 1D $ORIGIN bind. @ 1D CHAOS SOA localhost. root.localhost. ( 1 3H 1H 1W 1D ) CHAOS NS localhost.Ainsi lorsqu'un petit malin cherche à obtenir la version de bind, sa tentative sera enregistrée :
Mar 12 17:51:12 vectra named[17035]: unapproved query from [10.0.0.169].4863 for "version.bind"Et on pourra continuer à récupérer le numéro de version en local sauf si on est encore plus parano et que l'on met
allow-query { none; };
.
Les ports inférieurs à 1024 sont des ports privilégiés, c'est-à-dire que seuls les programmes fonctionnant en tant que root peuvent les utiliser. Le port dédié aux serveurs DNS est le port TCP/UDP 53 (domains).
Un mécanisme de sécurité est incorporé dans les versions modernes de bind qui lui permettent une fois qu'il s'est attribué le port domains de prendre l'identité d'un utilisateur sans pouvoir, named généralement. Ainsi, en cas de faille de sécurité, le pirate prend l'identité named et non root.
Cependant, le pirate possède désormais un accès à la machine, où il
est en mesure d'exploiter des failles locales. L'idée
est de le confiner dans une partie de l'arborescence, par exemple, le
répertoire /var/chroot-named
où se trouvent également les
fichiers nécessaires à bind.
Pour créer la prison, il faut commencer par être 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
$ 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
Si syslogd
supporte l'option « -a », il faut qu'il soit
démarrer avec dans /etc/rc.d/init.d/syslog
:
daemon syslogd -m 0 -a /var/chroot-named/dev/logDans le cas contraire, il faut alors loguer directement :
$ mkdir /var/chroot-named/var/log $ ln -s /var/chroot-named/var/log /var/log/dnsDans
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 à root.
$ 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/namedAu passage, n'oubliez pas que bind doit pouvoir écrire dans les répertoires correspondant aux zones esclaves, n'oublier pas de créer ces répertoires et de changer le propriétaire en
named
. Sans quoi, il ne pourra
pas récupérer les zones dont il est secondaire.
Soit on compile named et named-xfer en statique, soit on utilise les binaires existants et on copie les librairies dynamiques nécessaires :
$ 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 dernière commande montre toutes les librairies dont bind a besoin pour fonctionner : chacune d'elle doit également être présente dans la prison.
Dans /etc/rc.d/init.d/named
(ici, supprimer le daemon
si
vous n'avez pas une RedHat), on signale que le démon tourne dans une
prison :
daemon named -u named -t /var/chroot-namedL'option "-u" désigne l'utilisateur sous lequel fonctionnera bind et l'option "-t" le répertoire dans lequel il s'exécute, sa prison.
La sécurité TSIG permet de réduire les conséquences de l'IP spoofing
entre les DNS primaires et secondaires. Ils partagent une clé secrète
dont le nom même est secret, grenier-supersecret
dans l'exemple.
La clé est encodée en base 64 et se
définit ainsi dans les fichiers de configuration des serveurs
concernés :
key grenier-supersecret. { algorithm hmac-md5; secret "mZiMNOUYQPMNwsDzrX2ENw=="; };Dans la configuration du DNS maître, on ajoute :
server ip_dns_secondaire { transfer-format many-answers; keys { grenier-supersecret.; }; };et pour les DNS secondaires, on met la même chose mais avec l'adresse IP du serveur DNS primaire.
Pour fonctionner, les horloges systèmes des deux serveurs doivent être synchronisées. Au besoin, on peut les synchroniser par xntp. La confidentialité des clés est liée à la sécurité du serveur le plus vulnérable.
Avec l'apport de la cryptographie, les protocoles DNS sont plus fiables et les mécanismes de sécurité système comme le chrootage sont toujours là pour contrer les problèmes d'implémentation =:-) (Bug TSIG).