chroot pour Apache
L'utilitaire chroot est souvent utilisé pour emprisonner un démon
dans une arborescence restreint. Vous pouvez l'utiliser pour isoler des
services d'autres services, pour que les problèmes de sécurité d'un paquet
logiciel ne mettent pas en péril le serveur tout entier. Quand vous utiliser
le script makejail, mettre en place et mettre à jour
l'arborescence chrooté est beaucoup plus facile.
FIXME: Apache can also be chrooted using http://www.modsecurity.org which
is available in libapache-mod-security (for Apache 1.x) and
libapache2-mod-security (for Apache 2.x).
Ce document est copyright 2002 Alexandre Ratti. Il est publié sous une double
licence, la GPL version 2 (GNU General Public License) et la
GNU-FDL 1.2 (GNU Free Documentation Licence) et est inclus dans ce manuel
avec sa permission explicite (depuis le document
d'origine).
Cette procédure a été testée sur Debian GNU/Linux 3.0 (Woody) avec
makejail 0.0.4-1 (de Debian/testing).
root et créez le nouveau répertoire
prison :
$ mkdir -p /var/chroot/apache
chrapach.
$ adduser --home /var/chroot/apache --shell /bin/false \
--no-create-home --system --group chrapach
FIXME: est-ce qu'un nouvel utilisateur est nécessaire ? (Apache fonctionne déjà sous l'utilisateur apache)
/etc/apache/httpd.conf, positionnez les options
Group et User à chrapach. Redémarrez Apache et
assurez-vous que le serveur fonctionne correctement. Maintenant, stoppez le
démon Apache.
makejail (disponible dans Debian/testing actuellement).
Vous devriez également installer wget et lynx car ils
sont utilisés par makejail pour tester le serveur chrooté :
apt-get install makejail wget lynx
/etc/makejail :
# cp /usr/share/doc/makejail/examples/apache.py /etc/makejail/
/etc/makejail/apache.py. Vous devez changer les options
chroot, users et groups. Pour exécuter cette
version de makejail, vous pouvez également ajouter une option
packages. Voir la documentation
makejail. Un exemple est fourni ici :
chroot="/var/chroot/apache"
testCommandsInsideJail=["/usr/sbin/apachectl start"]
processNames=["apache"]
testCommandsOutsideJail=["wget -r --spider http://localhost/",
"lynx --source https://localhost/"]
preserve=["/var/www",
"/var/log/apache",
"/dev/log"]
users=["chrapach"]
groups=["chrapach"]
packages=["apache", "apache-common"]
userFiles=["/etc/password",
"/etc/shadow"]
groupFiles=["/etc/group",
"/etc/gshadow"]
forceCopy=["/etc/hosts",
"/etc/mime.types"]
FIXME: certaines options semblent ne pas fonctionner correctement.
Par exemple, /etc/shadow et /etc/gshadow ne sont pas
copiés, alors que /etc/password et /etc/group sont
intégralement copiés au lieu d'être filtrés.
/etc/password et /etc/group ont été
intégralement copiés, entrez :
$ grep chrapach /etc/passwd > /var/chroot/apache/etc/passwd
$ grep chrapach /etc/group > /var/chroot/apache/etc/group
pour les remplacer avec des copies filtrées.
makejail).
# cp -Rp /var/www /var/chroot/apache/var
# cp -Rp /var/log/apache/*.log /var/chroot/apache/var/log/apache
/var/chroot/apache/dev/log. Dans
/etc/init.d/sysklogd, remplacez :
SYSLOGD="" par SYSLOGD=" -a
/var/chroot/apache/dev/log" et redémarrez le démon
(/etc/init.d/sysklogd restart).
/etc/init.d/apache). Vous
pouvez avoir besoin d'effectuer certaines changements au script de démarrage
par défaut pour qu'il fonctionne correctement dans une arborescence chrooté.
Comme :
/proc dans la prison.
#! /bin/bash
#
# apache Start the apache HTTP server.
#
CHRDIR=/var/chroot/apache
NAME=apache
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/apache
SUEXEC=/usr/lib/apache/suexec
PIDFILE=/var/run/$NAME.pid
CONF=/etc/apache/httpd.conf
APACHECTL=/usr/sbin/apachectl
trap "" 1
export LANG=C
export PATH
test -f $DAEMON || exit 0
test -f $APACHECTL || exit 0
# ensure we don't leak environment vars into apachectl
APACHECTL="env -i LANG=${LANG} PATH=${PATH} chroot $CHRDIR $APACHECTL"
if egrep -q -i "^[[:space:]]*ServerType[[:space:]]+inet" $CONF
then
exit 0
fi
case "$1" in
start)
echo -n "Starting web server: $NAME"
mount -t proc proc /var/chroot/apache/proc
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON \
--chroot $CHRDIR
;;
stop)
echo -n "Stopping web server: $NAME"
start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo
umount /var/chroot/apache/proc
;;
reload)
echo -n "Reloading $NAME configuration"
start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" \
--signal USR1 --startas $DAEMON --chroot $CHRDIR
;;
reload-modules)
echo -n "Reloading $NAME modules"
start-stop-daemon --stop --pidfile "$CHRDIR/$PIDFILE" --oknodo \
--retry 30
start-stop-daemon --start --pidfile $PIDFILE \
--exec $DAEMON --chroot $CHRDIR
;;
restart)
$0 reload-modules
exit $?
;;
force-reload)
$0 reload-modules
exit $?
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|reload|reload-modules|force-reload|restart}"
exit 1
;;
esac
if [ $? == 0 ]; then
echo .
exit 0
else
echo failed
exit 1
fi
FIXME: est-ce que le premier processus Apache devrait être lancé avec un autre utilisateur que root (i.e. ajouter add --chuid chrapach:chrapach) ? Désavantage : chrapach devra avoir un accès en écriture aux journaux, ce qui est étrange.
/etc/logrotate.d/apache
/var/log/apache/*.log par
/var/chroot/apache/var/log/apache/*.log
/etc/init.d/apache start) et vérifiez ce qui est
indiqué dans les journaux de la prison
(/var/chroot/apache/var/log/apache/error.log). Si votre
configuration est plus complexe (e.g. si vous utilisez également PHP et
MySQL), des fichiers seront probablement manquants. Si certains fichiers ne
sont pas copiés automatiquement par makejail, vous pouvez les
lister dans les options forceCopy (pour copier les fichiers
directement) ou packages (pour copier les paquets en entier et leurs
dépendances) du fichier de configuration /etc/makejail/apache.py.
root 180 0.0 1.1 2936 1436 ? S 04:03 0:00 /usr/sbin/apache
chrapach 189 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
chrapach 190 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
chrapach 191 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
chrapach 192 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
chrapach 193 0.0 1.1 2960 1456 ? S 04:03 0:00 /usr/sbin/apache
/proc : ls -la
/proc/numero_processus/root/. où numero_processus est
l'un des numéros de PID listés ci-dessus (2e colonne ; 189 par exemple).
Les entrées pour une arborescence restreinte devraient être listées
ainsi :
drwxr-sr-x 10 root staff 240 Dec 2 16:06 .
drwxrwsr-x 4 root staff 72 Dec 2 08:07 ..
drwxr-xr-x 2 root root 144 Dec 2 16:05 bin
drwxr-xr-x 2 root root 120 Dec 3 04:03 dev
drwxr-xr-x 5 root root 408 Dec 3 04:03 etc
drwxr-xr-x 2 root root 800 Dec 2 16:06 lib
dr-xr-xr-x 43 root root 0 Dec 3 05:03 proc
drwxr-xr-x 2 root root 48 Dec 2 16:06 sbin
drwxr-xr-x 6 root root 144 Dec 2 16:04 usr
drwxr-xr-x 7 root root 168 Dec 2 16:06 var
Pour automatiser ce test, vous pouvez entrer :ls -la /proc/`cat /var/chroot/apache/var/run/apache.pid`/root/.
FIXME: ajouter d'autres tests qui peuvent être exécuter pour s'assurer que la prison est fermées ?
La raison pour laquelle j'aime ceci est que la mise en place d'une prison n'est pas très difficile et que le serveur peut être mis à jour avec seulement deux lignes :
apt-get update && apt-get install apache
makejail /etc/makejail/apache.py
Si vous recherchez plus d'informations, vous pouvez envisager ces sources d'informations dans lesquelles l'information présentée est basée :
page d'accueil de
makejail, ce programme a été écrit par Alain Tesio
Chrooting
daemons and system processes HOWTO par Jonathan, Network Dweebs,
21/10/2002
Manuel de sécurisation de Debian
Version: 3.2, Mon, 16 May 2005 21:28:01 +0200jfs@debian.orgdebian-l10n-french@lists.debian.org