Comment utiliser la commande chroot sous Linux



La commande `chroot` est un outil puissant qui permet d’isoler des environnements de développement, de test ou de renforcer la sécurité de votre système. Explorons ensemble la méthode la plus simple pour l’utiliser.

Comprendre le concept de chroot

Pour évaluer l’utilité d’une commande, il faut tenir compte de ses capacités et de sa simplicité d’utilisation. Si une commande est trop complexe ou demande une configuration trop laborieuse, elle risque de ne pas être employée. Or, une commande inutilisée est une fonctionnalité perdue. La commande `chroot` est souvent considérée comme difficile à maîtriser ou trop compliquée à configurer, ce qui explique pourquoi cet outil, pourtant formidable, n’est pas aussi utilisé qu’il le pourrait.

En utilisant `chroot`, vous pouvez établir et exécuter des programmes ou des shells interactifs comme Bash dans un système de fichiers isolé, incapable d’interagir avec votre système de fichiers principal. Tout ce qui se passe dans cet environnement `chroot` est contenu et isolé. Aucun élément de cet environnement ne peut accéder à l’extérieur de son propre répertoire racine spécifique sans posséder les privilèges root. C’est pourquoi on parle souvent de « prison chroot ». Il ne faut toutefois pas confondre ce terme avec la commande « jail » de FreeBSD, qui offre un environnement `chroot` plus sécurisé.

Heureusement, il existe une approche simple pour utiliser `chroot`, que nous allons détailler. Nous emploierons des commandes Linux standard, compatibles avec toutes les distributions. Bien que certaines distributions, comme Ubuntu avec debootstrap, proposent des outils dédiés, nous privilégions ici une méthode universelle.

Quand utiliser un environnement chroot ?

Un environnement `chroot` offre des fonctionnalités similaires à une machine virtuelle, tout en étant plus léger. Contrairement à une machine virtuelle qui nécessite un hyperviseur comme VirtualBox ou Gestionnaire de machine virtuelle, l’environnement `chroot` n’en a pas besoin. De plus, il n’est pas nécessaire d’installer un noyau spécifique, car il partage votre noyau existant.

Les environnements `chroot` se rapprochent davantage des conteneurs comme LXC que des machines virtuelles. Ils sont rapides à mettre en œuvre, légers et peuvent être automatisés. Comme pour les conteneurs, on peut installer un minimum de système d’exploitation pour accomplir une tâche précise. Cette « tâche précise » détermine la configuration de votre environnement `chroot`.

Voici quelques cas d’utilisation courants :

  • Développement et tests de logiciels : Les développeurs écrivent du code, tandis que l’équipe de vérification produit (PV) le teste. Il arrive que des problèmes rencontrés par l’équipe PV ne puissent être reproduits sur la machine du développeur. Ceci est dû au fait que les développeurs disposent d’outils et de bibliothèques spécifiques non présents dans un environnement standard, tel que celui de l’équipe PV. Le problème peut provenir d’une ressource du PC du développeur qui n’a pas été incluse dans la version de test du logiciel. `chroot` permet aux développeurs de tester leur logiciel dans un environnement propre et minimaliste, avant de le soumettre à l’équipe PV, avec les dépendances minimales requises.
  • Réduction des risques lors du développement : Un développeur peut créer un environnement de développement isolé pour éviter toute interférence avec son système principal.
  • Exécution de logiciels obsolètes : Si vous avez besoin d’utiliser une ancienne version d’un logiciel, dont les exigences sont incompatibles avec votre version de Linux, vous pouvez créer un environnement `chroot` dédié.
  • Récupération et mise à niveau du système de fichiers : Si une installation Linux devient inopérante, `chroot` permet de monter le système de fichiers endommagé à partir d’un Live CD. Vous pouvez ainsi travailler sur le système endommagé comme s’il était monté normalement à la racine (/). Cela garantit que les chemins des fichiers sont correctement référencés. Cette technique a été employée dans un article décrivant la migration du système de fichiers Linux d’ext2 ou ext3 vers ext4.
  • Sécurisation des applications : Exécuter un serveur FTP ou un autre service connecté à Internet dans un environnement `chroot` réduit les dommages qu’une attaque externe pourrait causer, améliorant ainsi la sécurité du système.

Création d’un environnement chroot

Nous allons maintenant créer un répertoire qui servira de répertoire racine pour notre environnement `chroot`. Pour y accéder plus facilement, nous allons créer une variable et y stocker le chemin de ce répertoire. Dans cet exemple, nous créons une variable pour stocker le chemin vers un répertoire nommé « testroot ». Si ce répertoire n’existe pas encore, il sera créé prochainement. S’il existe déjà, il doit être vide.

chr=/home/dave/testroot

Si le répertoire n’existe pas, nous devons le créer. La commande suivante avec l’option `-p` permet de créer tous les répertoires parents manquants en même temps :

mkdir -p $chr

Nous devons créer des répertoires pour héberger les éléments du système d’exploitation dont notre environnement `chroot` aura besoin. Nous allons mettre en place un environnement Linux minimaliste, utilisant Bash comme shell interactif, ainsi que les commandes `touch`, `rm` et `ls`. Cela nous permettra d’utiliser toutes les commandes intégrées de Bash, et les commandes `touch`, `rm` et `ls` pour créer, lister et supprimer des fichiers.

Nous allons utiliser l’ expansion des accolades pour énumérer les répertoires à créer :

mkdir -p $chr/{bin,lib,lib64}

Maintenant, nous allons nous déplacer dans notre nouveau répertoire racine :

cd $chr

Nous allons copier les binaires nécessaires à notre environnement Linux minimaliste. Nous allons les copier depuis votre répertoire normal « /bin » vers notre répertoire « /bin » de `chroot`. L’option -v (verbeux) indique à la commande `cp` ce qu’elle fait durant chaque action de copie :

cp -v /bin/{bash,touch,ls,rm} $chr

Voici les fichiers copiés :

Ces binaires ont des dépendances. Nous devons les identifier et les copier également dans notre environnement. Sinon, `bash`, `touch`, `rm` et `ls` ne pourront pas fonctionner. Nous allons procéder à l’identification et la copie des dépendances pour chaque commande, en commençant par Bash. La commande `ldd` liste les dépendances pour nous :

ldd /bin/bash

Les dépendances sont identifiées et listées dans la fenêtre du terminal :

Nous devons copier ces fichiers dans notre nouvel environnement. La récupération et la copie manuelle de chaque fichier prendrait du temps et serait source d’erreurs.

Heureusement, nous pouvons automatiser ce processus. Nous allons lister à nouveau les dépendances et former une liste. Ensuite, nous allons parcourir cette liste pour copier les fichiers.

Nous utilisons `ldd` pour lister les dépendances et envoyons le résultat via un tube vers `egrep`. Utiliser `egrep` est l’équivalent de `grep` avec l’option `-E` (expressions régulières étendues). L’option `-o` (correspondance uniquement) limite la sortie aux parties des lignes qui correspondent. Nous recherchons des fichiers de bibliothèque qui se terminent par un numéro [0-9].

list="$(ldd /bin/bash | egrep -o '/lib.*.[0-9]')"

Nous pouvons vérifier le contenu de la liste en utilisant `echo` :

echo $list

Maintenant que nous avons la liste, nous pouvons la parcourir avec la boucle suivante, en copiant les fichiers un par un. Nous utilisons la variable `i` pour parcourir la liste. Pour chaque élément de la liste, nous copions le fichier dans le répertoire racine `chroot`, dont le chemin est contenu dans la variable `$chr`.

L’option `-v` (verbeux) oblige `cp` à indiquer chaque copie effectuée. L’option `–parents` assure la création des répertoires parents manquants dans l’environnement `chroot`.

for i in $list; do cp -v --parents "$i" "${chr}"; done

Voici le résultat :

Nous allons utiliser cette technique pour obtenir les dépendances de chacune des autres commandes, ainsi que pour la copie. La bonne nouvelle est que nous n’aurons qu’une petite modification à apporter à la commande qui regroupe les dépendances.

Nous pouvons récupérer la commande depuis l’historique en utilisant la touche « Flèche vers le haut », puis la modifier. La commande de copie en boucle ne change pas.

Ici, nous avons utilisé la touche « Flèche vers le haut » pour retrouver la commande, et nous l’avons modifiée pour « touch » au lieu de « bash ».

list="$(ldd /bin/touch | egrep -o '/lib.*.[0-9]')"

Nous pouvons réutiliser la même commande de boucle qu’avant :

for i in $list; do cp -v --parents "$i" "${chr}"; done

Et les fichiers sont copiés :

Nous allons maintenant modifier la ligne de commande pour « ls » :

list="$(ldd /bin/ls | egrep -o '/lib.*.[0-9]')"

Nous allons encore une fois utiliser la même commande de boucle. Les fichiers contenus dans la liste n’ont pas d’importance, elle est parcourue pour la copie :

for i in $list; do cp -v --parents "$i" "${chr}"; done

Et les dépendances de « ls » sont copiées :

Nous modifions une dernière fois la ligne de commande de la liste pour qu’elle fonctionne avec `rm` :

list="$(ldd /bin/ls | egrep -o '/lib.*.[0-9]')"

Nous utilisons la commande de copie en boucle une dernière fois :

for i in $list; do cp -v --parents "$i" "${chr}"; done

La dernière de nos dépendances est copiée dans notre environnement `chroot`. Nous sommes enfin prêts à utiliser la commande `chroot`. Cette commande définit le répertoire racine de l’environnement `chroot` et spécifie l’application à exécuter en tant que shell.

sudo chroot $chr /bin/bash

Notre environnement `chroot` est maintenant actif. L’invite de la fenêtre du terminal a changé, et le shell interactif est géré par le shell bash de notre environnement `chroot`.

Nous pouvons essayer les commandes que nous avons introduites dans l’environnement.

ls
ls /home/dave/Documents

La commande `ls` fonctionne comme prévu à l’intérieur de l’environnement. Par contre, lorsque nous tentons d’accéder à un répertoire extérieur, la commande échoue.

Nous pouvons utiliser `touch` pour créer un fichier, `ls` pour le lister et `rm` pour le supprimer.

touch sample_file.txt
ls
rm sample_file.txt
ls

Bien sûr, nous pouvons aussi utiliser les commandes intégrées fournies par le shell Bash. Pour les lister, tapez `help` dans la ligne de commande :

help

Utilisez la commande `exit` pour quitter l’environnement `chroot`:

exit

Si vous souhaitez supprimer l’environnement `chroot`, vous pouvez simplement le supprimer :

rm -r testroot/

Cela supprimera tous les fichiers et répertoires de l’environnement `chroot`.

Automatisation pour plus de confort

Si vous pensez que les environnements `chroot` peuvent être utiles, mais que leur mise en place vous paraît laborieuse, n’oubliez pas que vous pouvez toujours automatiser et simplifier les tâches répétitives en utilisant des alias, des fonctions ou des scripts.