---------------------------
SECURISATION DU DEMON BIND
---------------------------

Cet article est destiné aux particuliers et administrateurs systèmes
qui souhaitent protéger leur serveur d'un point potentiellement vulnérables
: le démon BIND.

Ce démon est utilisé par plusieurs distributions Linux et fournit le
service des noms de domaines DNS. Etant donné sa complexité de structure
et de configuration, multiples failles y ont été découvertes. C'est pour
cela qu'il est courant aujourd'hui d'opérer dans un environnement chrooté
(le chroot est un peu comme une prison ou un pirate ne peut pas s'échapper).

Cet article vous serez sérieusement utile si vous deviez fournir un type
d'accès quelconque au port DNS sur une interface de réseau externe.

1. SECURITE DE BIND AVANT CHROOT()
-----------------------------------

Avant d'appliquer un chroot named, il faut surtout maintenir à jour vos
paquetages BIND. Parfois, les patchs s'enchaînent lors de découvertes de
failles successives. Soyez donc prudent si votre socket BIND est ouvert
aux hôtes sur une interface de réseau externe.

BIND communique via TCP (pour de grandes requêtes) et UDP (pour les moins
grandes requêtes). Il va falloir y penser lors du filtrage de paquets avec
ipchains ou iptables.
Voici une forme générale de ipchains :
Ipchains -A input -p tcp -s 100.100.100.100/24 \
-d int.ip.number.here domain -j ACCEPT
Ipchains -A input -p udp -s 100.100.100.100/24 \
-d int.ip.number.here domain -j ACCEPT
Ipchains -A input -p tcp -s trusted.ext.system.ip \
-d ext.ip.number.here domain -j ACCEPT
Ipchains -A input -p udp -s trusted.ext.system.ip \
-d ext.ip.number.here domain -j ACCEPT
ipchains -A input -I ! lo \
-d ext.ip.number.here domain -j DENY -l
Pour iptables, je ne refais pas le filtrage de port DNS, c'est presque
identique, juste pour la syntaxe, le premier filtrage donne :
iptables -t filter -A INPUT -p tcp -s 100.100.100.100/24 \
-d int.ip.number.here -desnation-port domain \
-j ACCEPT
et la dernière requête, spéciale, donne :
iptables -t filter -A INPUT -i ! lo \
-d ext.ip.number.here -j DROP
Notez que cette dernière commande élimine par filtrage tous les paquets
non exceptés précédemment. Elle doit toujours être unique et présente en
fin de filtrage.

Autre point important : le fichier named.conf. C'est un vrai El-Dorado
pour un cracker.
D'abord, il faut empêcher BIND de révéler l'information concernant sa version
quand un tiers l'interroge car cela représente 50 % du travail du pirate
(90 % si le système est Windows, car il est bourré de bugs ;). Donc, dans
la section option, il faut avoir :
Options {
Version "Désolé, le numéro de la version n'est pas disponible.";
};

Ensuite, ce fichier impose les contrôle d'accès. Voici les items dans cette
zone, à vous de choisir après :
- allow_query : détermine quels hôtes (ou réseaux) auront la permission
de recevoir des requêtes ordinaires auprès de ce serveur.
- allow_transfer : détermine quels hôtes (ou réseaux) auront la permission
de recevoir des transferts de zone à partir de ce serveur.
- allow_recursion : détermine quels hôtes (ou réseaux) auront la permission
de faire des requêtes répétitives auprès de ce serveur.
- allow_updates : détermine quels hôtes (ou réseaux) auront la permission
de soumettre des MaJ dynamiques de DNS à ce serveur.
- blackhole : détermine quels hôtes (ou réseaux) seront empêchés d'obtenir
une communication quelconque avec ce serveur.
Permettre allow_transfer est très délicat: un pirate pourrait mapper votre
réseau. d'une manière général, un type de réglages assez judicieux pourrait
être :
Options {
Version "Désolé, le numéro de la version n'est pas disponible.";
Allow_query {
Localhost;
};
allow_transfer {
none;
};
allow_recursion {
none;
};
};

Ainsi, les requêtes générales provenant du localhost seront permises. A
l'inverse, les requêtes répétitives ou transfert de zone sont tous refusés.
On peut aussi utiliser des spécificateurs de contrôles d'accès (dans les
accolades), au lieu d'utiliser les valeurs par défaut dans une zone de
donnée. Les plus usuels sont :
- any : aucun contrôle d'accès (accès de n'importe quel hôte depuis n'importe
où).
- None: tout accès interdit (accès a aucun hôte, peu importe où il est).
- Localhost: permet l'accès à l'hôte local.
- Localnet : permet l'accès aux hosts ayant une interface matérielle avec
le localhost.
- X.X.X.X:permet l'accès aux hosts ayant ce numéro d'IP
- X.X.X.X/X permet l'accès au réseau ayant le spécificateur réseau/masque
correspondant (100.100.100.0/24 permet l'accès aux hosts sur le localhost
100.100.100.


2. EXECUTION DE NAMED DANS UN ENVIRONNEMENT CHROOT()
-----------------------------------------------------

Un pirate cherchera obtenir un accès frauduleux via le démon BIND. Par
conséquent, nombreux sont les admins qui exécutent named dans un environnement
chroot. Qu'est-ce ? Un environnement chroot trompe BIND pour qu'il croie
qu'un sous-répertoire est le système de fichiers root. Ainsi, pour tous
les process, named peut être exécuter dans /usr/local/bind, mais pour le
process named et ses enfants, /usr/local/bind semblera être le root (/).
Si un cracker pirate named, à cause du chroot, il sera emprisonné (chrooté)
dans /usr/local/bind! Tout simple. La version 8 de BIND inclut sa propre
fonctionnalité chroot.
Autre conseil : il est plus sage d'opérer BIND sous un user (ou un groupe)
qui contiendra le process named, plutôt que de l'opérer comme root. Comme
chroot est inclut dans les versions récentes de BIND, il suffit d'ajouter
un user et un groupe pour named aux fichiers passwd et group de l'ensemble
du système se trouvant dans /etc :
#echo "named::29" >>/etc/group
#echo "named:x:29:29:named:/:" >>/etc/passwd
Il faut maintenant rajouter un nouvel user named au fichier /etc/ftpusers
(pas question que quelqu'un se loggue sous named en FTP) :
#echo named >>/etc/ftpusers

Après cette préparation, revenons à l'exécution de BIND depuis une prison
chroot. D'abord, commençons par créer la prison. Puis, il faudra ajouter
un user et un groupe spécifique pour named (et son appartenance, évidemment).
Vous pouvez placer votre cellule où bon vous semble, par exemple usr/local/named
:
# mkdir /usr/local/named
#cd usr/localnamed
# mkdir dev etc etc/named lib usr usr/bin
Le répertoire chrooté (/etc/named) contiendra les données DNS.
(parenthèse : pour copier les données de configuration d'une install named
existante, utilisez chown).
Créons maintenant les n?uds de périph nécessaire à l'exécution de BIND
:
# mknod dev/null c 1 3
# mknod dev/zero c 1 5
# mknod dev/random c 1 8
# mknod dev/urandom c 1 9
# mknod dev/tty c 5 0
# chmod 666 dev/null dev/zero dev/tty
Jusque là, aucun souci, ça coule de source. Je vous avez dit que c'était
facile. Il ne manque plus qu'à copier quelques fichiers de base (nécessaire
pour named) depuis /etc vers notre chroot :
# cp /etc/nsswitch.conf /etc/resolv.con etc
# cp /etc/ld.so.cache /etc/localtime etc
On copie maintenant seulement named & Cie :
# cp /usr/sbin/named /usr/sbin/named-xfer usr/sbin

Etant donné que named et named-xfer sont liée, il nous faut quelques libs.
Lesquelles ? Un petit coup de ldd :
# ldd usr/sbin/named
libc.so.6 => /lib/libc.so.6 (0x40020000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Donc, on les copie :
#cd lib
# cp /lib/libc-2.1.2.so
# cp /lib/ld-2.1.2.so
# ln -s libc-2.1.2.so libc.so.6
# ln -s ld-2.1.2.so ld-linux.so.2
Vous en aurez peut-être besoin d'autres. Les lib suivantes sont utiles,
mais il faut que vous y ajustiez votre propre numéro de version :
# cp /lib/libnss_comt-2.1.2.so .
# cp /lib/libnss_files-2.1.2.so .
# cp /lib/libnsl-2.1.2.so .
# ln -s libnss_compat-2.1.2.so libnss_compat.so.2
# ln -s libnss_files-2.1.2.so libnss_files.so.2
# ln -s libnsl-2.1.2.so libnsl.so.2
Ne pas oubliez de vérifier les permissions de fichiers de configuration,
de bibliothèques et des binaires, afin qu'aucun ne soit éditable par l'user
(ou le groupe) named, ou n'opère comme suid ou sgid au niveau du root.
Maintenant, vous êtes prêt!

On peut paramétrer syslogd pour le chroot named afin d'obtenir les entrées
de log de named pour les envoyer à l'enregistreur normal du système. Les
démons syslogd récents offrent une option (-a) à la ligne de commande pour
cela :
Syslogd -a /usr/local/named/dev/log
Ainsi, un socket d'écoute sera créé sur /usr/local/bind/dev/log (que le
chroot named verra comme étant /dev/log). Pour que ce changement soit permanent,
il faut éditer le script qui lance syslogd (communément /etc/rc.d/init.d/syslog)
et y ajouter les options nécessaires. Relançons ensuite le démon pour valider
les modifs :
# /etc/rd.d/init.d/syslogd restart

Maintenant, tout est nickel, on est prêt à lancer le chroot named. Testons
le nouveau named (après avoir arrêté un éventuel ancien ;)

Normalement, votre named devrait fonctionner comme avant. Cependant,
si dorénavant il est compromis par un cracker, l'intrusion ne pourra pas
aller plus loin. Néanmoins, n'oubliez pas de modifier /etc/rc.d/init.d/named
pour prendre en compte les modifications de manière permanente.


...::: PROGRAMMATION By Nocte :::...