Personal tools
You are here: Home GNU / Linux Debian Sarge Création d'une prison chroot
Document Actions
  • Send this page to somebody
  • Print this page
  • Add Bookmarklet

Création d'une prison chroot

by admin last modified 2007-09-10 12:37

Il est courant aujourd'hui de trouver plusieurs serveurs sur une même machine. Ces serveurs sont autant de failles de sécurité potentielles pouvant être exploitées par des personnes mal intentionnées. Il est possible de limiter l'impact du piratage d'un serveur en le faisant fonctionner dans une prison. C'est ce qu'autorise la commande chroot. Attention toutefois, car ce n'est pas la solution miracle. Qui dit prison, dit aussi évasion !

Attention

Ce guide n'est plus à jour et utilise des solutions qui ne sont pas les plus élégantes. Préférez lui : Installer un chroot sur une Debian 4.0 Etch

Ubuntu

Ubunteros, exécutez la commande suivante avant de poursuivre ce howto :

sudo su -

Prérequis

La distribition GNU / Linux Debian dispose d'un outil permettant de créer très simplement des prisons chroot. Il s'agit de debootstrap. Notre première action sera d'installer cet outil :

apt-get install debootstrap

Après voir installé cet outil, vous pourrez entrer dans le vif du sujet.

Création de la prison

Afin de simplifier au maximum ce mode d'emploi, nous allons stocker le nom de notre prison dans une variable d'environnement :

CHROOT_JAIL_NAME=nom-de-la-prison

Evitez d'utiliser des espaces et autres caractères spéciaux dans ce nom, car il sera utilisé par la suite pour créer le dossier contenant votre prison chroot. Une fois cette variable créée, configurez le dossier où vous souhaitez créer votre prison :

CHROOT_JAIL_ROOT=/export/jails

Procédure de création

Créez le dossier de la future prison :

mkdir $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME

Une fois ce dossier créé, vous pouvez lancer l'initialisation de la prison. Pour cet exemple, nous allons utiliser la distribution Debian Sarge. Il est toutefois possible d'utiliser une version testing ou unstable si vous souhaitez disposer de paquets plus récents.

debootstrap sarge $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME

Remarque: Si vous êtes sous Ubuntu, vous pouvez installer une Debian Sarge dans un chroot en précisant le miroir à utiliser dans votre commande :

debootstrap sarge $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME ftp://ftp.fr.debian.org/debian

De même, pour installer une Ubuntu Dapper Drake dans un chroot:

debootstrap dapper $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME http://fr.archive.ubuntu.com/ubuntu/

La commande debootstrap va télécharger les paquets correspondants à la distribution choisie et va les installer dans le dossier de votre prison chroot. Cet étape peut prendre plusieurs minutes suivant la rapidité de votre connexion Internet. Enfin, nous créons le fichier debian_chroot qui nous permet de savoir quand nous travaillons dans le chroot :

echo $CHROOT_JAIL_NAME > $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/debian_chroot

Mise en place des points de montages nécessaires

Une fois que la commande debootstrap s'est terminée avec succès, il vous faut configurer le montages des systèmes de fichiers spéciaux :

echo "
# $CHROOT_JAIL_NAME jail environment.
proc-$CHROOT_JAIL_NAME $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/proc proc defaults 0 0
devpts-$CHROOT_JAIL_NAME $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/dev/pts devpts defaults 0 0
tmpfs-$CHROOT_JAIL_NAME $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/dev/shm tmpfs defaults 0 0" \
>> /etc/fstab

Nous créons de plus une partition loopback d'1 Go pour le dossier /tmp afin de le rendre non exécutable:

/bin/mkdir -p /var/lib/tmpfs
/bin/dd if=/dev/zero of=/var/lib/tmpfs/chrooted-$CHROOT_JAIL_NAME-tmp.fs bs=1024 count=1000000
/sbin/mkfs.ext3 -F /var/lib/tmpfs/chrooted-$CHROOT_JAIL_NAME-tmp.fs

Nous ajoutons la ligne adéquate au fichier fstab :

/bin/echo "/var/lib/tmpfs/chrooted-$CHROOT_JAIL_NAME-tmp.fs $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/tmp ext3 loop,noexec,nosuid,nodev,rw 0 0" \
>> /etc/fstab

Une fois cette configuration effectuée, il vous faut monter ces systèmes de fichier :

mount $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/proc
mount $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/dev/pts
mount $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/dev/shm
mount $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/tmp

Enfin, nous donnons les droits d'écriture à tout le monde sur le dossier temporaire de la prison :

chmod ugo+rwx $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/tmp

Configuration des hôtes

Copiez ensuite le fichier /etc/hosts de la machine hôde dans la prison :

cp /etc/hosts $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc

Configuration de syslog

Configurez le démon sysklogd de la machine hôte pour qu'il prenne en compte la prison :

echo $CHROOT_JAIL_ROOT | sed -e 's/\//\\\\\//g' | \
xargs -iCHROOT_JAIL_ROOT sed -i -e \
"s/^SYSLOGD[^=]*=[^\"]*\"\([^\"]*\)\"/SYSLOGD=\"\1 -a CHROOT_JAIL_ROOT\/$CHROOT_JAIL_NAME\/dev\/log\"/g" \
/etc/init.d/sysklogd

Il vous faut maintenant redémarrer le démon syslogd :

/etc/init.d/sysklogd restart

Configuration de apt-get

Vérifiez que le contenu du fichier sources.list de la prison correspond à vos besoins :

cat $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/apt/sources.list

Si il ne correspond pas à vos besoins, voici 2 commandes pour obtenir des configurations courantes :

Debian Sarge

echo "deb ftp://ftp2.fr.debian.org/debian/ stable main contrib non-free
deb-src ftp://ftp2.fr.debian.org/debian/ stable main contrib non-free
deb http://security.debian.org/ stable/updates main contrib non-free" \
> $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/apt/sources.list

Ubuntu Dapper Drake

echo "
deb http://fr.archive.ubuntu.com/ubuntu/ dapper main restricted universe multiverse
deb-src http://fr.archive.ubuntu.com/ubuntu/ dapper main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu dapper-security main restricted universe multiverse
deb-src http://security.ubuntu.com/ubuntu dapper-security main restricted universe multiverse" \
> $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/apt/sources.list

Configuration de la prison

La première action a effectuer dans votre prison est de mettre à jour la liste des paquets disponibles :

chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
apt-get update

Sélectionnez la zone horaire de votre prison :

chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
tzconfig

Il vous faut maintenant installer le support linguistique :

chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
apt-get install locales

Personnellement, je génère les locales suivantes :

  • en_US ISO-8859-1
  • en_US.ISO-8859-15 ISO-8859-15
  • en_US.UTF-8 UTF-8
  • fr_FR ISO-8859-1
  • fr_FR.UTF-8
  • fr_FR.UTF-8@euro
  • fr_FR@euro ISO-8859-15

Par défaut, j'utilise la locale "fr_FR.UTF-8".

Remarque: Dans le cas d'un chroot Ubuntu Dapper Drake, les commandes suivantes suffisent :

chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
locale-gen fr_FR.UTF-8
chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
sh -c 'echo LANG="fr_FR.UTF-8" >> /etc/environment'

Enfin, il nous faut remplacer le MTA (Mail Transport Agent : le serveur mail quoi :D) de la prison (par défaut exim) par nullmailer qui est un MTA qui se contente de transférer les emails du systèmes vers un autre serveur mail. Exim sera automatiquement supprimé par cette installation :

chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
apt-get install nullmailer

Ce qui nous interesse ici est de transférer les emails généré par l'environnement emprisonné vers le serveur mail de la machine hôte. Pour obtenir ce résultat, utilisez les options suivantes :

  • nom de courrier du système : localhost.localdomain
  • Machines relais : localhost.localdomain
  • Adresse ou sera envoyé les courriers locaux : root@localhost.localdomain

Il ne reste plus qu'a lier le script init.d de démarrage au système hôte :

for CHROOT_JAIL_INITD_SCRIPT in \
`find $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/var/cache/apt/archives/ \
-name *nullmailer*.deb | \
xargs -iFILE dpkg-deb --contents FILE | \
egrep "/etc/init.d/.+" | \
sed -e 's/^.*\/etc\/init\.d\/\(.*\)$/\1/'`; do

echo -E '#!/bin/sh' \
> /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;
echo "# Start/stops the chrooted $CHROOT_JAIL_INITD_SCRIPT daemon.
CHROOT_JAIL=$CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME
CHROOT_JAIL_INITD_SCRIPT=$CHROOT_JAIL_INITD_SCRIPT" \
>> /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;
echo '/usr/sbin/chroot $CHROOT_JAIL /etc/init.d/$CHROOT_JAIL_INITD_SCRIPT $1' \
>> /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;

chmod +x /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;

find $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/rc*.d -type l \
| egrep "rc.\.d/[SK]+[0-9]+$CHROOT_JAIL_INITD_SCRIPT$" \
| sed -e "s/^.*\(\/etc\/rc.\.d\/[SK]*[0-9]*\)$CHROOT_JAIL_INITD_SCRIPT$/ln -s \/etc\/init.d\/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT \1chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT/" \
| xargs -icommand sh -c "command";
done

Votre environnement prison est dès à présent fonctionnel. Vous pouvez si vous le souhaitez continuer avec la section suivante qui vous explique comment y installer un serveur.

Mise en place de la rotation des logs de la prison

Bien que la plupart des logiciels enregistrent leur actions par l'intermédiaire de sysklogd (ce que nous avons configuré plus haut), ceux pour qui ce n'est pas le cas stockent leur fichiers logs dans la prison même (c'est le cas par exemple pour apache). Nous allons donc faire en sorte que la rotation des fichiers logs s'applique aussi à ceux de la prison. Pour ce faire, nous  installons logrotate:
chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
apt-get install logrotate

et nous configurons le cron de la machine hôte pour qu'il exécute le logrotate de la prison à intervalles réguliers :

echo -E '#!/bin/sh' \
> /etc/cron.daily/chrooted-$CHROOT_JAIL_NAME-logrotate;
echo "# Cron file for chrooted logrotate.
CHROOT_JAIL=$CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME
CHROOT_JAIL_CRON_SCRIPT=logrotate
CHROOT_JAIL_CRON_FREQUENCY=daily" \
>> /etc/cron.daily/chrooted-$CHROOT_JAIL_NAME-logrotate;
echo '/usr/sbin/chroot $CHROOT_JAIL /etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/$CHROOT_JAIL_CRON_SCRIPT $1
exit $?' \
>> /etc/cron.daily/chrooted-$CHROOT_JAIL_NAME-logrotate
chmod +x /etc/cron.daily/chrooted-$CHROOT_JAIL_NAME-logrotate

Installation de cron-apt dans la prison

cron-apt est un logiciel très pratique qui surveille les mises à jour disponibles pour votre installation. Nous allons configurer ce logiciel pour l'adapter à notre prison. En premier lieu, nous installons le paquet :

chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
apt-get install cron-apt

Ensuite, nous configurons le paquet pour qu'il envoie des emails à l'utilisateur root lorsque des mises à jour sont disponibles :

sed -i -e 's/^#[ \t]*\(MAILTO="root"\)/\1/' \
-e '/^#[ \t]*\(MAILON="error"\)/a\
MAILON="upgrade"' \
$CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/cron-apt/config

Nous personnalisons les emails envoyés de façon à ce qu'il soit possible de mettre à jour la prison par un simple copier / coller :

echo "###### $(hostname) ######
## Prison : $CHROOT_JAIL_NAME

Pour mettre à jour la prison, executez la commande :

/usr/sbin/chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME apt-get upgrade

########################" \
> $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/cron-apt/mailmsg.d/0-update
cp $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/cron-apt/mailmsg.d/0-update \
$CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/cron-apt/mailmsg.d/3-download

Enfin, nous configurons le cron de la machine hôte pour qu'il exécute le cron-apt de la prison à intervalles réguliers.

cp $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/cron.d/cron-apt \
/etc/cron.d/chrooted-$CHROOT_JAIL_NAME-cron-apt
echo $CHROOT_JAIL_ROOT | sed -e 's/\//\\\\\//g' | \
xargs -iCHROOT_JAIL_ROOT sed -i -e \
"s/^\(.*\([\*0123456789\/]*[ \t]\)\{3\}[ \t]*[^ \t]*[ \t]*\)\(.*\)$/\1\/usr\/sbin\/chroot CHROOT_JAIL_ROOT\/$CHROOT_JAIL_NAME \/bin\/sh -c \"\3\"/g" \
/etc/cron.d/chrooted-$CHROOT_JAIL_NAME-cron-apt

Installation d'un serveur dans la prison

L'intérêt de la création des prisons chroot est la séparation des environnements des serveurs de l'environnement principal du serveur. Si votre serveur emprisonné est compromis, vous n'avez pas à craindre que le serveur hôte soit infecté. Il vous suffit donc de remplacer l'environnement chroot compromis par une sauvegarde propre. Nous allons pour l'exemple installer un serveur web Apache 2 dans notre prison nouvellement créée.

Commençons par mettre en place une variable globale contenant le nom du paquet installé :

CHROOT_JAIL_PACKAGE=apache2

Installation du logiciel

Puis nous installons le serveur dans sa prison :

chroot $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME \
apt-get install $CHROOT_JAIL_PACKAGE

Prise en charge des scripts init.d

Une fois le serveur installé, nous allons le lier à l'environnement hôte de façon à ce que son démarrage soit automatique. Le script suivant récupère les scripts init.d installés avec le serveur et les lie à l'environnement hôte :

for CHROOT_JAIL_INITD_SCRIPT in \
`find $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/var/cache/apt/archives/ \
-name *$CHROOT_JAIL_PACKAGE*.deb | \
xargs -iFILE dpkg-deb --contents FILE | \
egrep "/etc/init.d/.+" | \
sed -e 's/^.*\/etc\/init\.d\/\(.*\)$/\1/'`; do

echo -E '#!/bin/sh' \
> /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;
echo "# Start/stops the chrooted $CHROOT_JAIL_INITD_SCRIPT daemon.
CHROOT_JAIL=$CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME
CHROOT_JAIL_INITD_SCRIPT=$CHROOT_JAIL_INITD_SCRIPT" \
>> /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;
echo '/usr/sbin/chroot $CHROOT_JAIL /etc/init.d/$CHROOT_JAIL_INITD_SCRIPT $1' \
>> /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;

chmod +x /etc/init.d/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT;

find $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/rc*.d -type l \
| egrep "rc.\.d/[SK]+[0-9]+$CHROOT_JAIL_INITD_SCRIPT$" \
| sed -e "s/^.*\(\/etc\/rc.\.d\/[SK]*[0-9]*\)$CHROOT_JAIL_INITD_SCRIPT$/ln -s \/etc\/init.d\/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT \1chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_INITD_SCRIPT/" \
| xargs -icommand sh -c "command";
done

Attention : Ce script ne prend en compte que les scripts init.d créés par le paquet $CHROOT_JAIL_SERVER_PACKAGE. Si ce paquet installe des dépendances contenant des scripts init.d, il n'y a aucune garantie que ces scripts supplémentaires soient pris en compte. Dans le cas d'apache2, ce n'est pas vraiment un problème, mais ca peut l'être pour d'autres serveurs.

Prise en charge des scripts cron

Certain paquets tels que mysql-server utilisent des scripts cron pour leurs opérations de maintenance. Or le démon crond n'est pas lancé dans un environnement chroot. Comme nous souhaitons que seul les scripts cron concernant notre serveur soient éxecutés, il nous faut les faire appeler par le crond de la machine hôte. Il suffit pour cela d'éxecuter le script suivant :

for CHROOT_JAIL_CRON_FILE in \
`find $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/var/cache/apt/archives/ \
-name *$CHROOT_JAIL_PACKAGE*.deb | \
xargs -iFILE dpkg-deb --contents FILE | \
egrep "/etc/cron\..*/.+" | \
sed -e 's/^.*\/etc\/cron\.\(.*\/.*\)$/\1/'`; do

CHROOT_JAIL_CRON_SCRIPT=`echo $CHROOT_JAIL_CRON_FILE \
| sed -e 's/.*\/\(.*\)/\1/'`;
CHROOT_JAIL_CRON_FREQUENCY=`echo $CHROOT_JAIL_CRON_FILE \
| sed -e 's/\(.*\)\/.*/\1/'`;

if [ "$CHROOT_JAIL_CRON_FREQUENCY" = "d" ]; then

cp $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/$CHROOT_JAIL_CRON_SCRIPT \
/etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_CRON_SCRIPT;

echo $CHROOT_JAIL_ROOT | sed -e 's/\//\\\\\//g' | \
xargs -iCHROOT_JAIL_ROOT sed -i -e \
"s/^\(.*\([\*0123456789\/]*[ \t]\)\{3\}[ \t]*[^ \t]*[ \t]*\)\(.*\)$/\1\/usr\/sbin\/chroot CHROOT_JAIL_ROOT\/$CHROOT_JAIL_NAME \/bin\/sh -c \"\3\"/g" \
/etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_CRON_SCRIPT;

else

echo -E '#!/bin/sh' \
> /etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_CRON_SCRIPT;
echo "# Cron file for chrooted $CHROOT_JAIL_CRON_SCRIPT.
CHROOT_JAIL=$CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME
CHROOT_JAIL_CRON_SCRIPT=$CHROOT_JAIL_CRON_SCRIPT
CHROOT_JAIL_CRON_FREQUENCY=$CHROOT_JAIL_CRON_FREQUENCY" \
>> /etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_CRON_SCRIPT;
echo '/usr/sbin/chroot $CHROOT_JAIL /etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/$CHROOT_JAIL_CRON_SCRIPT $1
exit $?' \
>> /etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_CRON_SCRIPT;

chmod +x /etc/cron.$CHROOT_JAIL_CRON_FREQUENCY/chrooted-$CHROOT_JAIL_NAME-$CHROOT_JAIL_CRON_SCRIPT;

fi
done

Attention : cette manipulation ne s'occupe pas du fichier /etc/crontab. Il est rarement utilisé sous Debian, mais par prudence, vérifiez qu'il ne contient aucune référence à votre serveur.

cat $CHROOT_JAIL_ROOT/$CHROOT_JAIL_NAME/etc/crontab

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards:

Wikio