---------------------------
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
:::...