Chroot

De Lea Linux
Aller à la navigation Aller à la recherche

Utiliser chroot

Utiliser chroot
par Jop, Prae & Anne

Emprisonnez un utilisateur, ou un progamme dans une geôle!


Préambule

On ne juge la solidité d'une chaîne que par la résistance de son maillon le plus faible. C'est ainsi que dans l'univers informatique, le maillon est représenté par l'utilisateur. Bien sûr, on peut établir plusieurs classements, mais il est plus simple de considérer que toute personne introduite sur un système peut provoquer des dommages irréparables. Depuis quelques années maintenant, des recherches sont effectuées afin de séparer l'utilisateur du système qu'il utilise. Différentes méthodes ont été testées et employées, limitation des droits des usagers, mise en place d'access lists, limitation d'utilisation, emprisonnement dans un répertoire, déplacement de la racine, emprisonnement d'un espace et de ses processus et pour finir, mise en place d'un système totalement dédié. Il est important de noter que les systèmes tels que les *BSD ont une nette avance dans cette matière. Je ne saurais donc que vous conseiller d'utiliser ces systèmes si vous souhaitez fournir des comptes systèmes à vos utilisateurs.

Note : une extension de l'outil est implémentée dans le noyau Linux par l'intermédiaire des outils GRsec ou WOLK.

Installation

Chroot est installé par défaut dans les distributions courantes. Si jamais ce n'était pas le cas, vous pouvez le trouver normalement dans le paquet coreutils (au moins pour les distributions Debian et Mandrake).

# whereis chroot
chroot: /usr/sbin/chroot

Notre utilitaire se trouve dans le répertoire /usr/sbin. Cela signifie qu'il appartient aux outils de l'administrateur du système et que l'exécutable n'est pas indispensable au démarrage du système.

Vérifions les droits assignés par défaut :

# ls -l /usr/sbin/chroot
 -rwxr-xr-x    1 root     root        10136 Jul 12 15:54 /usr/sbin/chroot

Nous pouvons constater que le fichier appartient à l'administrateur root et au groupe de même nom (root:root).

En termes plus simples, cela signifie qu'il peut être lu par n'importe qui (r) et exécuté par n'importe qui (x).

Dans ce cas de figure, la seule chose que nous pourrons obtenir est le changement de racine pour un utilisateur, de par son propre chef.

Préparation du système

Pour l'exercice qui nous intéresse, à savoir emprisonner un utilisateur dans un espace restreint, nous nécessitons des droits supplémentaires. Pendant un court laps de temps, il est indispensable que le programme usurpe l'identité de l'administrateur (root) pour effectuer les opérations nécessaires. Ce mécanisme est rendu possible grâce au suid.

Note : l'emploi du suid implique des failles de sécurité potentielles. Il faut le manier avec précaution et bien être conscient des risques encourrus. Dans les cas extrêmes, cette situation permet à un utilisateur distant mal intentionné de prendre le contrôle du système en tant qu'administrateur.

Pour suid notre programme, exécutons l'opération suivante :

# chmod u+s /usr/sbin/chroot
 # ls -l /usr/sbin/chroot
 -rwsr-xr-x    1 root     root        10136 2003-07-12 15:54 /usr/sbin/chroot

/!\ /!\ /!\ /!\ Mettre en place le bit setuid en exec sur chroot revient à donner à tout utilisateur les droits de "root"... En effet chroot étant par défaut propriété de "root", un simple "chroot / /bin/bash" suffit à obtenir un shell en temps que "root"... Je déconseille donc une telle pratique. /!\ /!\ /!\ /!\

Le droit d'exécution x a été remplacé par le droit s, signifiant que le suid est désormais appliqué au programme.

Le système est maintenant en mesure d'utiliser correctement le programme.

Nous désirons que l'utilisateur qui se connectera soit dès son arrivée enfermé dans l'environement que nous construisons à cet effet. En ce sens, nous allons créer un script shell qui permettra d'adapter l'entrée de l'utilisateur à notre environement.

Préparation du compte

Si vous ne l'avez pas déjà créée, il faut établir les paramêtres du dit compte.

Petit rappel des options de l'outil useradd :

useradd [-u uid [-o]] [-g groupe] [-G groupe,...]
[-d home] [-s shell] [-c commentaire] [-m [-k template]]
[-f inactif] [-e expire ] [-p mot-de-passe] nom

Voici un exemple :

$ useradd -u 1001 -g 1001 -d /home/chroot/toto -s /bin/chroot -c exemple toto

Notre utilisateur toto se voit attribuer les numéros 1001 d'utilisateur et 1001 de groupe et sera logé dans le répertoire /home/chroot/toto. Le shell qui lui permettra de se connecter est un petit script qui autorise l'emprisonnement de l'utilisateur à son arrivée.

De manière simple, ce script peut ainsi être écrit :

#!/bin/bash
exec -c /usr/sbin/chroot /home/chroot/$USER /bin/bash

Si nous utilisons la ligne de commande qui constitue ce script, dans une phase de test, une erreur va nous être retournée :

$/usr/sbin/chroot /home/chroot/toto /bin/bash
/usr/sbin/chroot: /bin/bash: No such file or directory

Que se passe t'il donc ? La réponse est simple. L'invocation du shell, ici /bin/bash, se fait après le déplacement de la racine. Il cherche donc au pied de cette nouvelle racine un répertoire bin contenant l'utilitaire bash. Cependant, puisque nous n'avons jusqu'à lors inséré aucun outil, le système refuse la commande.

Que faire dans ce cas ? La réponse est assez simple, nous allons construire l'environnement nécessaire à l'utilisation de la prison. Cela signifie que chaque commande que vous désirerez utiliser dans cet espace restreint doit y être copié, dans le répertoire aproprié.

Avant de chercher à automatiser la tâche, commençons par le bash de tout à l'heure :

$ cd /home/chroot/toto
$ mkdir bin
$ cp /bin/bash bin/bash

L'utilitaire est à présent copié.

Il faut également fournir les librairies nécessaires à son utilisation. Nous utiliserons l'outil ldd pour déterminer les fichiers nécessaires.

$ ldd /bin/bash
libncurses.so.5 => /lib/libncurses.so.5 (0x4001e000)
libdl.so.2 => /lib/libdl.so.2 (0x4005a000)
libc.so.6 => /lib/libc.so.6 (0x4005d000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Comme dit, copions les librairies indispensable au fonctionnement :

$ mkdir lib
$ cp /lib/libncurses.so.5 lib
$ cp /lib/libdl.so.2 lib
$ cp /lib/ld-linux.so.2 lib

Voilà, il ne reste plus qu'à tester en s'identifiant sous l'utilisateur toto :

toto@127.0.0.1's password:
****************************************************************
* Bienvenue dans l'environnement restreint qui vous est imparti *
****************************************************************
bash-2.05b$ pwd
/
bash-2.05b$

Notre premier travail, créer un espace restreint pour un utilisateur, est achevé.
La tâche ne s'arrête pas là. Tout comme nous avons copié le shell bash, il faut de même insérer tous les utilitaires nécessaires ou vitaux tels que ls, chmod, rm, etc...

Pour ne pas effectuer une tâche répétitive, il est plus intelligent de créer un script qui travaillera pour nous et qui aura le mérite d'être réutilisable :

#!/bin/bash

# On vérifie que le nom de l'utilisateur souhaité est bien passé en paramêtre
if [ "$#" != 1 ];
then
echo "Usage : $0 <login>"
exit 255;
fi

# Nom d'utilisateur
LOGIN=$1
# Groupe attribué à l'utilisateur
GROUP=chroot
# Répertoire par défaut des shell chrootés
REP=/home/chroot

# Utilitaires présents dans /bin
OUTILB="bash cat chmod chown cp grep gunzip gzip ls mkdir more mv rm tar"

echo "-- Création du groupe \"${GROUP}\""
groupadd "${GROUP}" > /dev/null 2>&1

echo "-- Création de l'utilisateur \"${LOGIN}\""
useradd \
-c "Utilisateur en espace restreint" \
-d "/home/${LOGIN}/" \
-g "${GROUP}" \
-s "/bin/chroot" \
"${LOGIN}"

echo "-- Son mot de passe : "
passwd "${LOGIN}" > /dev/null

echo "-- Création de l'arborescence de son Répertoire personnel --"
mkdir -p $REP/${LOGIN}/bin/ $REP/${LOGIN}/lib/ $REP/${LOGIN}/dev/

# Mise en place des droits sur les répertoires
cd $REP
chmod -R 700 ${LOGIN}

# Copie des programmes et de leurs librairies
for I in $OUTILB;
do
cp /bin/$I $REP/${LOGIN}/bin/
# Pour chaque programme, on recherche les librairies correspondantes.
# On termine en demandant l'exécution par bash des lignes renvoyées par awk
ldd /bin/$I | awk -v "LOGIN=$LOGIN" '{ print "cp "$3 $REP"/"LOGIN"/lib/" }' | bash
done

# Création de l'espace /dev
mknod $REP/${LOGIN}/dev/null c 1 3 -m 666
chown -R "${LOGIN}:${GROUP}" $REP/${LOGIN}

# Fin de la création du compte utilisateur.
echo ">> Utilisateur \"${LOGIN}\" créée et emprisonné"

if [ ! -e /bin/chroot ]; then
echo "-- Création du programme /bin/chroot"
cat < /bin/chroot
#!/bin/bash
exec -c /usr/sbin/chroot /home/chroot\$USER /bin/bash
EOF
chmod 555 /bin/chroot
fi

Liens utiles - Bibliographie

Très bientôt la suite de cet article abordera comment "chrooter" les services afin d'en optimiser la sécurité

Cette page est issue de la documentation 'pré-wiki' de Léa a été convertie avec HTML::WikiConverter. Elle fut créée par Jop, Prae & Anne le 25/08/2003.

Copyright

Copyright © 25/08/2003, Jop, Prae & Anne

Creative Commons License
Creative Commons Attribution iconCreative Commons Share Alike iconCreative Commons Noncommercial
Ce document est publié sous licence Creative Commons
Attribution, Partage à l'identique, Contexte non commercial 2.0 :
http://creativecommons.org/licenses/by-nc-sa/2.0/fr/