2. Préparation de l'environnement restreint

2.1. Création d'un utilisateur

Comme cela est mentionné dans l'introduction, il n'est pas conseillé de faire fonctionner BIND sous le compte root. Ainsi, avant de commencer, créons un utilisateur spécifique pour BIND. Notez que vous ne devez jamais employer un utilisateur générique comme nobody pour cela. Ainsi, quelques distributions, comme SuSE et Mandrake Linux ont commencé à fournir un utilisateur spécifique (généralement appelé named) ; si vous le souhaitez, vous pouvez tout simplement adapter cet utilisateur à nos desseins. Ceci exige l'ajout d'une ligne comme celle qui suit dans /etc/passwd :

named:x:200:200:Serveur de noms:/chroot/named:/bin/false

Et d'une ligne de ce type dans /etc/group :

named:x:200:

Ceci crée pour BIND un utilisateur et un groupe appelés named. Assurez-vous que l'UID et le GID (tous deux valant 200 dans cet exemple) sont uniques sur votre système. L'interpréteur de commande est mis à /bin/false car cet utilisateur n'aura jamais besoin de se connecter.

2.2. Arborescence de répertoires

Nous devons maintenant mettre en place l'arborescence de répertoires que nous allons utiliser pour l'environnement restreint d'exécution de BIND. Elle peut se situer n'importe où dans votre système de fichiers ; si vous êtes vraiment paranoïaque, vous pourrez même la placer dans un volume séparé. Je supposerai que vous allez employer /chroot/named. Commençons en créant l'arborescence de répertoires suivante :

/chroot
  +-- named
       +-- dev
       +-- etc
       |    +-- namedb
       |         +-- slave
       +-- var
            +-- run

Si vous utilisez la commande GNU mkdir (tel que présente sur les systèmes Linux), vous pourrez créer l'arborescence de répertoires ainsi :

# mkdir -p /chroot/named
# cd /chroot/named
# mkdir -p dev etc/namedb/slave var/run

2.3. Mise en place des données de BIND

Si vous avez déjà fait une installation conventionnelle de BIND et si vous l'utilisez, votre fichier named.conf et vos fichiers de zones existent déjà. Ces fichiers doivent être déplacés (ou copiés pour plus de sûreté) dans l'environnement restreint, de sorte que BIND puisse les atteindre. named.conf ira dans /chroot/named/etc, et les fichiers de zone pourront aller dans /chroot/named/etc/namedb. Par exemple :

# cp -p /etc/named.conf /chroot/named/etc/
# cp -a /var/named/* /chroot/named/etc/namedb/

BIND a normalement besoin d'écrire dans le répertoire namedb, mais pour renforcer la sécurité, nous ne l'autoriserons pas à le faire. Si votre serveur de nom est esclave pour une zone quelconque, il aura besoin de mettre à jour ces fichiers de zones, ce qui veut dire nous devrons les enregistrer dans un répertoire séparé, auquel BIND aura accès.

# chown -R named:named /chroot/named/etc/namedb/slave

Gardez à l'esprit que vous devrez déplacer toutes vos zones esclaves dans ce répertoire et que vous devez mettre à jour votre named.conf en conséquence.

BIND aura aussi besoin d'écrire dans le répertoire /var/run, pour y mettre ses fichiers pid et ses fichiers de statistiques, donc permettons-lui de le faire :

# chown named:named /chroot/named/var/run

2.4. Fichiers de support système

Lorsque BIND s'exécute dans l'environnement restreint, il ne peut plus du tout accéder aux fichiers situés hors de celui-ci. Cependant, il a besoin d'accéder à quelques fichiers clefs, bien que leur nombre soit bien moindre que ce dont BIND 8 avait besoin.

Un fichier dont BIND aura besoin à l'intérieur de sa prison est le bon vieux /dev/null. Notez que la commande exacte nécessaire pour créer ce fichier spécial peut varier de système à système ; vérifiez le script /dev/MAKEDEV pour vous en assurer. Quelques systèmes peuvent également exiger /dev/zero, que nous pourrons créer de la même façon. Il a été mentionné que les version préliminaires de BIND 9.2.0 ont maintenant également besoin de /dev/random. Pour la plupart des systèmes Linux, nous pourrons employer les commandes suivantes :

# mknod /chroot/named/dev/null c 1 3
# mknod /chroot/named/dev/random c 1 8
# chmod 666 /chroot/named/dev/{null,random}

Pour FreeBSD 4.3, ce sera :

# mknod /chroot/named/dev/null c 2 2
# mknod /chroot/named/dev/random c 2 3
# chmod 666 /chroot/named/dev/{null,random}

Vous aurez besoin de disposer d'un autre fichier dans le répertoire /etc de l'environnement restreint. Vous devrez copier /etc/localtime (nommé /usr/lib/zoneinfo/localtime sur certains systèmes), afin que BIND puisse enregistrer les évènements avec un horodatage correct. La commande suivante s'en chargera :

# cp /etc/localtime /chroot/named/etc/

2.5. Journalisation des évènements

BIND a beau être prisonnier de son environnement restreint, contrairement à un prisonnier ordinaire, il ne peut écrire son journal sur les murs de sa cellule :-) Normalement, BIND enregistre un journal des évènements grâce à syslogd, le démon de journalisation système. Cependant, ce type de journalisation est effectué en envoyant les enregistrements d'évènements vers le connecteur (socket) spécial /dev/log. Puisqu'elle se trouve désormais à l'extérieur de l'environnement restreint, BIND ne peut plus l'employer. Heureusement, il existe quelques solutions pour contourner le problème.

2.5.1. La solution idéale

La solution idéale de ce dilemme exige une version raisonnablement récente de syslogd qui prenne en charge le paramètre -a introduit par OpenBSD. Reportez-vous à la page de manuel de votre syslogd(8) pour vérifier si elle offre cette option. Si c'est la cas, la seule chose que vous ayez à faire est d'ajouter le paramètre « -a /chroot/named/dev/log » à la ligne de commande utilisée pour lancer syslogd. Sur les systèmes qui utilisent un init SysV complet (ce qui inclut la plupart des distributions Linux), vous pouvez faire cela en modifiant le fichier /etc/rc.d/init.d/syslog. Par exemple, sur mon système Linux Red Hat, j'ai changé la ligne

daemon syslogd -m 0

en

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

Il est intéressant de noter qu'à partir de la Red Hat 7.2, Red Hat a apparemment rendu ce processus plus facile. Il y a maintenant un fichier appelé /etc/sysconfig/syslog dans lequel on peut définit des paramètres supplémentaires pour syslogd. Les systèmes OpenLinux de Caldera utilisent un démon de lancement appelé ssd, qui lit la configuration depuis /etc/sysconfig/daemons/syslog. Il vous suffit de modifier la ligne d'options pour qu'elle ressemble à ceci :

OPTIONS_SYSLOGD="-m 0 -a /chroot/named/dev/log"

De la même façon sur les systèmes SuSE, il m'a été indiqué que le meilleur endroit pour ajouter ce paramètre est le fichier /etc/rc.config. Changez la ligne

SYSLOGD_paraMS=""

en

SYSLOGD_paraMS="-a /chroot/named/dev/log"

devrait faire l'affaire. Enfin, le dernier mais non le moindre, pour FreeBSD 4.3, il suffit apparemment de modifier le fichier rc.conf et d'y ajouter :

syslogd_flags="-s -l /chroot/named/dev/log"

Le -s est là pour des raisons de sécurité, et fait partie des paramètres par défaut. Le -l doit être suivi d'un chemin local, dans lequel on souhaite placer une autre interface de journalisation. Une fois que vous avez compris comment faire cette modification sur votre système, il vous suffira de redémarrer syslogd, que cela soit en le tuant (avec un kill) et en le relançant (avec les paramètres supplémentaires) ou en employant le script d'init SysV qui le fera pour vous :

# /etc/rc.d/init.d/syslog stop
# /etc/rc.d/init.d/syslog start

Une fois redémarré, vous devriez voir dans /chroot/named/dev une entrée appelée log qui ressemble à ceci :

srw-rw-rw-   1 root     root            0 Mar 13 20:58 log

2.5.2. L'autre solution

Si vous avez un ancien syslogd, vous devrez trouver une autre façon d'écrire dans le journal des évènements. Il existe quelques programmes pour cela, comme holelogd, qui est conçu pour agir comme un serveur mandataire en acceptant les entrées d'évènements du BIND en environnement restreint pour les passer au véritable connecteur /dev/log. Vous pouvez aussi tout simplement configurer BIND pour journaliser les évènements dans un fichier au lieu de les passer à syslog. Reportez-vous à la documentation de BIND pour plus d'informations si vous choisissez d'utiliser cette méthode.

2.6. Resserrer les permissions

Tout d'abord, n'hésitez à restreindre à l'utilisateur root l'accès à la totalité du répertoire /chroot. Bien sur, tout le monde ne voudra pas faire cela, particulièrement si cela indisposait d'autres logiciels installés dans la même arborescence.

# chown root /chroot
# chmod 700 /chroot

Vous pouvez aussi sans danger restreindre l'accès de /chroot/named à l'utilisateur named.

# chown named:named /chroot/named
# chmod 700 /chroot/named

Pour renforcer un peu plus la sécurité, sur les systèmes Linux utilisant le système de fichier ext2, nous pouvons rendre certains fichiers et répertoires immuables, en utilisant l'utilitaire chattr.

# cd /chroot/named
# chattr +i etc etc/localtime var

De même, sur FreeBSD 4.3, chflags est l'outil à examiner pour rendre certains fichiers immuables. À titre d'exemple, ce qui suit devrait rendre immuable le contenu du répertoire /chroot/named/etc :

# chflags schg /chroot/named/etc/*(*).

Il serait pratique de pouvoir faire la même chose sur le répertoire dev, mais malheureusement cela empêcherait syslogd de créer son connecteur dev/log. Vous pourrez aussi choisir de positionner le bit immuable sur d'autres fichiers de votre prison, comme par exemple vos fichiers de zone primaire, à condition qu'ils ne soient pas supposés changer.