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
).
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 :
On doit également créer les deux fichiers spéciaux requis par BIND :
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 :
||
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) :
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 :
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
).
On resserre ensuite les permissions du répertoire principal du chroot, par sécurité et bonne pratique :
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 :
Il suffit ensuite de redémarrer rsyslog :
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 :
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 :
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
Cette opération peut être effectuée directement à l'aide de la commande suivante, avant de recharger la configuration de systemd :
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 :
Une fois que le bug sera corrigé, on pourra supprimer ce détournement à l'aide de cette commande :
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 :
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
!
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
:
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
# Création de l'environnement chroot sous /var/lib/bind
# Sauvegarde des fichiers de BIND (facultatif)
[ ||
# Copie des fichiers vers le chroot
# Modification des propriétaires et permissions
# Configuration de rsyslog
# Ajout de l'option -t à named pour désigner le chroot
# Avant de supprimer ces fichiers, assurez-vous bien que tout
# fonctionne dans le chroot, ou que les avez bien sauvegardés !
# Pour faciliter l'accès aux fichiers de BIND (facultatif)
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