Une compilation de documentations   { en , fr }

Configurer bind9 en chroot sous debian

Étiquettes:
Créé en:
Dernière modification:
Auteur:
Xavier Béguin

De nos jours, des logiciels de sécurité comme AppArmor permettant de restreinte les accès d'un programme au système d'exploitation sont distribués et intégrés par défaut dans la plupart des systèmes GNU/Linux.

Lors qu'ils sont bien configurés, leur utilisation rend inutile la mise en place d'un chroot telle que décrite sur cette page. Cette solution reste toutefois intéressante dans le cas où vous ne souhaitez pas mettre en place un logiciel comme AppArmor.

Installation du paquet

Si vous n'utilisez pas encore BIND, sous Debian il vous suffira d'installer le paquet bind9 (qui entraîne notamment l'installation automatique du paquet bind9utils).

apt-get install bind9

Sa configuration n'entre pas dans le cadre de ce document, mais notez qu'après installation, la configuration par défaut du paquet fait fonctionner le daemon named sous l'utilisateur bind, qui fait partie du groupe bind.

Toutes les commandes données dans ce document doivent être exécutées par le superutilisateur du système (habituellement root). Cela signifie généralement que vous devrez préfixer toutes ces commandes par la commande sudo ou les exécuter dans un shell root créé, par exemple, par la commande sudo -i.

Préparation de l'environnement du chroot

Création des répertoires du chroot

Le choix du répertoire où sera installé le chroot (et auquel sera donc limité le daemon) est libre, mais on choisira ici le répertoire /var/lib/bind qui est déjà créé pour cet usage par le paquet Debian.

On va recréer l'arborescence et les fichiers nécessaires à BIND dans ce répertoire grâce aux commandes suivantes :

mkdir -p /var/lib/bind/dev
mkdir -p /var/lib/bind/etc
mkdir -p /var/lib/bind/var
mkdir -p /var/lib/bind/var/run/named
mkdir -p /var/lib/bind/var/cache/bind

On doit également créer les deux fichiers spéciaux requis par BIND :

mknod /var/lib/bind/dev/null c 1 3
chmod 666 /var/lib/bind/dev/null
mknod /var/lib/bind/dev/random c 1 8
chmod 666 /var/lib/bind/dev/random

Copie des fichiers de configuration

Avant de déplacer les fichiers, il peut être intéressant d'en conserver une copie de sauvegarde. J'ai l'habitude de conserver ces copies de sécurité dans le répertoire /var/local/backups que je crée s'il n'existe pas encore :

test -d /var/local/backups || mkdir /var/local/backups
cp -a /etc/bind /var/local/backups/etc_bind.orig

Note : si votre serveur BIND gère des zones DNS dynamiques, il est préférable de l'arrêter maintenant (avec la commande service bind9 stop), sinon vous pourriez perdre les mises à jour qui auraient lieu entre la copie des fichiers et le redémarrage de BIND dans son nouvel environnement chroot. Si le serveur ne gère pas de zone dynamique, vous pouvez laisser fonctionner le serveur pendant que vous préparez le chroot, pour ne le redémarrer qu'une fois qu'il est prêt.

On peut maintenant copier les fichiers de configuration vers le chroot (on fait une copie et non un déplacement pour ne pas empêcher le fonctionnement normal de BIND pendant la préparation du chroot ; on supprimera les fichiers en fin de procédure) :

cp -a /etc/bind /var/lib/bind/etc/

Copie du cache

Cette opération est utile si le serveur est configuré comme esclave dans au moins une zone DNS, puisque ça lui évitera de retélécharger les zones depuis le serveur maître :

cp -a /var/cache/bind/* /var/lib/bind/var/cache/bind/

Changement du propriétaire et des permissions des répertoires

Le daemon named doit pouvoir écrire dans le répertoire de cache (où il conserve les zones pour lesquelles il est esclave, notamment), et dans le répertoire où il écrit son PID (fichier named.pid).

chgrp bind /var/lib/bind/var/cache/bind
chmod g+w /var/lib/bind/var/cache/bind
chgrp bind /var/lib/bind/var/run/named
chmod g+w /var/lib/bind/var/run/named

On resserre ensuite les permissions du répertoire principal du chroot, par sécurité et bonne pratique :

chgrp bind /var/lib/bind
chmod 750 /var/lib/bind

Modification de la configuration de syslog

Sous GNU/Linux, BIND communique par défaut avec le daemon syslog à l'aide du fichier socket Unix /dev/log. Puisque, par définition, BIND ne pourra accéder qu'aux fichiers présents dans l'environnement du chroot, on doit donc configurer le daemon syslog pour qu'il y crée un autre fichier socket et y lise ce que bind écrira. Dans notre exemple, on utilisera donc le socket /var/lib/bind/dev/log.

Cette configuration dépend du daemon syslog qu'on utilise. Avec rsyslog (utilisé par défaut sous Debian), on peut modifier la configuration du daemon en créant un fichier dans /etc/rsyslog.d, par exemple avec la commande suivante :

cat <<'_EOD_' > /etc/rsyslog.d/bind-chroot.conf
$AddUnixListenSocket /var/lib/bind/dev/log
_EOD_

Il suffit ensuite de redémarrer rsyslog :

service rsyslog restart

Note : si vous utilisez le syslog classique sysklogd (qui était notamment utilisé par défaut sous debian etch), éditer /etc/default/syslogd et y changer SYSLOGD="" en SYSLOGD="-a /var/lib/bind/dev/log", par exemple avec la commande suivante :

sed -i -e 's|SYSLOGD=""|SYSLOGD="-a /var/lib/bind/dev/log"|' /etc/default/syslogd
service sysklogd restart

Modifier la configurer du démarrage

On doit ensuite adapter la configuration du démarrage de BIND pour que le daemon named de BIND soit lancé avec avec l'option -t lui demandant de fonctionner en chroot dans le répertoire indiqué.

Pour ça, on édite le fichier de configuration du lancement de bind, /etc/default/bind9, pour y changer OPTIONS="-u bind" en OPTIONS="-u bind -t /var/lib/bind". Ça peut être fait avec cette commande :

sed -i -e 's|OPTIONS="-u bind"|OPTIONS="-u bind -t /var/lib/bind"|' /etc/default/bind9

Attention : sous Debian 8 (Jessie), un bug du paquet bind9 empêche le daemon named de prendre en compte les options fournies via le fichier /etc/default/bind9 si vous utilisez systemd (ce qui est le cas par défaut). Pour contourner ce problème, il faut modifier la configuration systemd de bind9 en éditant le fichier /lib/systemd/system/bind9.service. Remplacez-y la ligne commençant par ExecStart= par ces deux lignes-ci :

EnvironmentFile=-/etc/default/bind9
ExecStart=/usr/sbin/named -f $OPTIONS

Cette opération peut être effectuée directement à l'aide de la commande suivante, avant de recharger la configuration de systemd :

sed -i 's|^ExecStart=.*$|EnvironmentFile=-/etc/default/bind9\nExecStart=/usr/sbin/named -f $OPTIONS|' /lib/systemd/system/bind9.service
systemctl daemon-reload

Attention, car chaque mise à jour du paquet bind9 réinstallera le fichier d'origine en écrasant vos modifications, et named serait alors relancé sans chroot. Pour demander au paquet de ne plus modifier ce fichier, vous pouvez mettre en place un détournement avec cette commande :

dpkg-divert --divert /lib/systemd/system/bind9.service.orig --rename /lib/systemd/system/bind9.service

Une fois que le bug sera corrigé, on pourra supprimer ce détournement à l'aide de cette commande :

dpkg-divert --rename --remove /lib/systemd/system/bind9.service

Pour plus d'information sur ces dernières opérations, voir l'astuce: « Détournement de fichier sous Debian »

Redémarrer BIND

Notre configuration de BIND en chroot est terminée. On redémarre le service bind, ce qui relancera le daemon named dans le chroot :

service bind9 restart

Nettoyage des répertoires (facultatif)

Après s'être assuré que tout fonctionne correctement après le redémarrage, on peut supprimer les fichiers d'origine dans /etc/bind (puisque BIND utilise maintenant les fichiers du chroot, /var/lib/bind/etc/bind dans notre exemple), et les fichiers de cache dans /var/cache/bind.

Attention: avant suppression, bien s'assurer que les fichiers du répertoire /etc/bind ont bien été copiés dans /var/lib/bind/etc/bind !

rm -rf /etc/bind/* /var/cache/bind/*

Si on veut rendre la configuration du chroot transparente pour les administrateurs du système, on peut remplacer /etc/bind par un lien vers /var/lib/bind/etc/bind :

rmdir /etc/bind
ln -s /var/lib/bind/etc/bind /etc/bind

Récapitulatif

Résumé des commandes

Voici le récapitulatif de toutes les commandes données et expliquées ci-dessus, et qu'il suffit d'effectuer pour configurer le chroot (on suppose ici qu'on utilise le daemon rsyslog).

Attention, certains points de configuration ont certainement changé dans les nouvelles versions de BIND sous Debian depuis l'écriture de cette documentation. Je vous recommande donc de n'exécuter ces instructions que pas-à-pas pour vérifier et corriger les éventuelles erreurs au fur et à mesure :

# Arrêt de BIND
service bind9 stop

# Création de l'environnement chroot sous /var/lib/bind
mkdir -p /var/lib/bind/{dev,etc,var,var/run/named,var/cache/bind}
mknod /var/lib/bind/dev/null c 1 3
mknod /var/lib/bind/dev/random c 1 8
chmod 666 /var/lib/bind/dev/{null,random}

# Sauvegarde des fichiers de BIND (facultatif)
[ -d /var/local/backups ] || mkdir /var/local/backups
cp -a /etc/bind /var/local/backups/etc_bind.orig

# Copie des fichiers vers le chroot
cp /etc/localtime /var/lib/bind/etc/
cp -a /etc/bind /var/lib/bind/etc/
cp -a /var/cache/bind/* /var/lib/bind/var/cache/bind/

# Modification des propriétaires et permissions
chgrp bind /var/lib/bind/{var/cache/bind,var/run/named}
chmod g+w /var/lib/bind/{var/cache/bind,var/run/named}
chgrp bind /var/lib/bind
chmod 750 /var/lib/bind

# Configuration de rsyslog
cat <<'_EOD_' > /etc/rsyslog.d/bind-chroot.conf
$AddUnixListenSocket /var/lib/bind/dev/log
_EOD_
service rsyslog restart

# Ajout de l'option -t à named pour désigner le chroot
sed -i \
  -e 's|OPTIONS="-u bind"|OPTIONS="-u bind -t /var/lib/bind"|' \
  /etc/default/bind9
service bind9 restart

# Avant de supprimer ces fichiers, assurez-vous bien que tout
# fonctionne dans le chroot, ou que les avez bien sauvegardés !
rm -rf /etc/bind/* /var/cache/bind/*

# Pour faciliter l'accès aux fichiers de BIND (facultatif)
rmdir /etc/bind
ln -s /var/lib/bind/etc/bind /etc/bind

Exemple d'arborescence d'une configuration neuve

Pour référence, voici les fichiers et répertoires que vous devez retrouver dans le chroot (dans notre exemple, c'est donc le contenu du répertoire /var/lib/bind) après mise en chroot d'une installation neuve du paquet bind9 sous Debian 8 (Jessie) (cette liste a été obtenue à l'aide de la commande tree /var/lib/bind) :

/var/lib/bind
├── bind9-default.md5sum
├── dev
│   ├── log
│   ├── null
│   └── random
├── etc
│   ├── bind
│   │   ├── bind.keys
│   │   ├── db.0
│   │   ├── db.127
│   │   ├── db.255
│   │   ├── db.empty
│   │   ├── db.local
│   │   ├── db.root
│   │   ├── named.conf
│   │   ├── named.conf.default-zones
│   │   ├── named.conf.local
│   │   ├── named.conf.options
│   │   ├── rndc.key
│   │   └── zones.rfc1918
│   └── localtime
└── var
    ├── cache
    │   └── bind
    │       ├── managed-keys.bind
    │       └── managed-keys.bind.jnl
    └── run
        └── named