Unionfs Chroot · 8 min read · Feb 03, 2026

Entrer dans un miroir sécurisé lors de la connexion avec Unionfs et Chroot

Entrer dans un miroir sécurisé lors de la connexion avec Unionfs et Chroot

1. Introduction

En lisant un ‘indice’ sur le site de LinuxFromScratch, j’ai découvert les capacités spéciales de unionfs, en particulier en combinaison avec chroot. Plus tard, j’ai lu un HowTo sur un site wiki de Gentoo, concernant l’entrée dans un répertoire personnel chrooté en utilisant un script spécial comme shell. La combinaison de ces deux éléments m’amène à utiliser un environnement chrooté, que vous entrez lorsque vous vous connectez en tant qu’utilisateur spécial. Cet environnement est une copie exacte (miroir) du système sur lequel vous travaillez. Comme vous êtes dans une copie sécurisée du véritable système, vous pouvez faire ce que vous voulez, cela ne changera jamais le système, tout reste à l’intérieur du cache (la branche en lecture-écriture).

Liens :
TRIP, un TRIvial Packager pour LFS (et d’autres systèmes linux) - Indice original sur le site de LFS
Home_directory_jail - Guide pour configurer une prison chroot à Gentoo

2. Technique de base

Faites ce que vous voulez, installez, modifiez et supprimez des fichiers du système, et aucun dommage. Votre véritable système reste intact. Cela peut sembler magique, mais c’est en réalité possible en combinant certaines techniques parmi toutes celles disponibles pour Linux.
En utilisant le système de fichiers Unionfs, un chroot et quelques répertoires bien choisis remontés, vous pouvez configurer ce système virtuel.

2.1 Unionfs

La partie la plus importante est l’utilisation de unionfs. Unionfs vous donne la possibilité de créer un système de fichiers, qui est l’union d’au moins deux autres. Voir www.unionfs.org pour plus d’infos. Maintenant, en laissant le nouveau système de fichiers être l’union de notre système de fichiers original (la racine) en mode lecture seule, et d’un système de fichiers temporaire (le cache) en mode lecture-écriture, vous aurez un système de fichiers qui ressemble exactement à votre système de fichiers original, mais dans lequel vous pouvez modifier, supprimer et/ou ajouter des fichiers sans rien faire à votre système original. Cela n’est pas possible, car la racine est montée en lecture seule. Chaque modification est stockée par le unionfs dans le cache.
La seule différence entre le système original et le système nouvellement créé est le chemin : dans le nouveau système, il commence toujours par le chemin du point de montage de l’union. C’est pourquoi l’étape suivante est nécessaire.

Une note spéciale : aujourd’hui [juin 2007], il semble que unionfs sera inclus dans le noyau. Unionfs subit un développement intensif en ce moment. Consultez le site pour plus d’infos.

Sur le site, vous trouverez des informations sur la façon d’activer unionfs. Pour les derniers noyaux (postérieurs à 2.6.19), il existe un patch pour la source du noyau, pour les noyaux moins récents, il existe un module externe.

2.2 (Re)Montage

Une chose supplémentaire que vous devrez faire est de (re)monter plusieurs répertoires cruciaux comme /dev, /proc et /sys. Cela est dû au fait que le système de fichiers union ne préserve pas les points de montage existants.
Il est également recommandé de remonter certains répertoires spéciaux comme /tmp et le répertoire dans lequel vous construisez le logiciel.

2.3 Chroot

En chrootant à ce point de montage, vous entrez dans un environnement qui est absolument une copie de votre système. Vous pouvez faire ce que vous voulez, même supprimer des répertoires et fichiers cruciaux. Testez-le ! Regardez jusqu’où vous pouvez aller avant que votre système ne se bloque.

2.4 Connexion à cet environnement

Comme le concept expliqué dans Home_directory_jail, il est possible de créer un shell de connexion spécial pour entrer dans l’environnement créé avec unionfs et chroot.
L’idée expliquée ici est de créer un utilisateur spécial, avec un shell spécial. Ce shell fera, avant d’entrer dans un shell interactif, d’abord les étapes nécessaires comme le montage du système de fichiers union, le remontage de certains répertoires importants et le chroot.

3. Préparation

3.1 La partition cache

Pour commencer, une partition avec suffisamment d’espace pour fonctionner comme cache. Cela n’a pas besoin d’être une partition physique, cela peut être un disque virtuel.

Créez ce disque avec :

dd if=/dev/zero of=/mnt/cache.img bs=1M count=500  
mkfs.ext2 /mnt/cache.img  
mkdir /mnt/cache  
mount /mnt/cache.img /mnt/cache -o loop
chmod 777 /mnt/cache
mkdir /mnt/union

Cela crée une partition (ou un disque) virtuel de 500M.

(Note : le périphérique de boucle doit être pris en charge dans votre noyau. Les noyaux de la plupart des distributions le font.)

3.2 Shell de connexion spécial

Créez un script shell chroot-union qui effectuera toutes les étapes nécessaires :

Le script chroot-union dans /bin :

#!/bin/bash
function mount_unionfs {
# monter des systèmes de fichiers temporaires
if [ -z "$(mount -t unionfs | grep -w /mnt/union )" ]; then
    sudo /bin/mount -t unionfs -o dirs=/mnt/cache:/=ro unionfs /mnt/union
    
fi
if [ -n "$(mount -t unionfs | grep -w /mnt/union )" ]; then
    # montages de base du système
    if [ -z "$(mount | grep -w /mnt/union/dev)" ]; then
    sudo /bin/mount --bind /dev /mnt/union/dev 2> /dev/null
    fi
    
    if [ -z "$(mount -t devpts | grep -w /mnt/union/dev/pts)" ]; then
    sudo /bin/mount -t devpts devpts /mnt/union/dev/pts 2> /dev/null
    fi
    if [ -z "$(mount -t tmpfs | grep -w /mnt/union/dev/shm)" ]; then
    sudo /bin/mount -t tmpfs shm /mnt/union/dev/shm 2> /dev/null
    fi
    
    if [ -z "$(mount -t sysfs | grep -w /mnt/union/sys)" ]; then
    sudo /bin/mount -t sysfs sysfs /mnt/union/sys 2> /dev/null
    fi
    
    if [ -z "$(mount -t proc | grep -w /mnt/union/proc)" ]; then
    sudo /bin/mount -t proc proc /mnt/union/proc 2> /dev/null
    fi
    if [ -z "$(mount | grep -w /mnt/union/tmp)" ]; then
    sudo /bin/mount --bind /tmp /mnt/union/tmp 2> /dev/null
    fi
    
    
else
    echo "Le montage de /mnt/union a échoué."
    
    exit 2
fi
    
}
function umount_unionfs {
#
# démonter /tmp
#
if [ -n "$(mount | grep -w /mnt/union/tmp)" ]; then
    sudo /bin/umount /mnt/union/tmp 2> /dev/null
fi
#
# démonter /proc
#
if [ -n "$(mount -t proc | grep -w /mnt/union/proc)" ]; then
    sudo /bin/umount /mnt/union/proc 2> /dev/null
fi
#
# démonter /sys
#
if [ -n "$(mount -t sysfs | grep -w /mnt/union/sys)" ]; then
    sudo /bin/umount /mnt/union/sys 2> /dev/null
fi
#
# démonter /dev/shm
#
if [ -n "$(mount -t tmpfs | grep -w /mnt/union/dev/shm)" ]; then
    sudo /bin/umount /mnt/union/dev/shm 2> /dev/null
fi
#
# démonter /dev/pts
#
if [ -n "$(mount -t devpts | grep -w /mnt/union/dev/pts)" ]; then
    sudo /bin/umount /mnt/union/dev/pts 2> /dev/null
fi
#
# démonter /dev
#
if [ -n "$(mount | grep -w /mnt/union/dev)" ]; then    
sudo /bin/umount /mnt/union/dev 2> /dev/null
fi
if [ -n "$(mount | grep -w /mnt/union )" ]; then  
sudo /bin/umount /mnt/union 2> /dev/null
fi
}
mount_unionfs
# entrer dans le chroot
sudo /usr/sbin/chroot /mnt/union /bin/su --shell /bin/bash --login $USER
# démonter les systèmes de fichiers temporaires
umount_unionfs
EOF

Ajoutez le nouveau shell de connexion au fichier /etc/shells. Vous devrez le faire lorsque PAM vérifiera le shell.

3.3 Créer un utilisateur et un groupe.

Créez un nouveau groupe et un utilisateur avec ce script comme shell :

groupadd -g 27 uniongroup  
useradd -c "Utilisateur de test pour chrooted union." -d /home/unionuser \  
-m -s /bin/chroot-union -g uniongroup -u 27 unionuser  
passwd unionuser

3.4 Donner à l’utilisateur suffisamment de droits

Donnez au nouvel utilisateur plus de droits avec sudo. Ajoutez la ligne suivante au fichier de configuration de sudo, /etc/sudoers :


unionuser ALL=(ALL) ALL

Note : il existe d’autres moyens de donner à cet utilisateur les permissions. Je les examine en ce moment.

Note : donner ces permissions complètes est trop pour un utilisateur normal. Mais pour un utilisateur qui installera des logiciels et modifiera votre système, c’est nécessaire.

Qu’est-ce qui est possible

Environnement sûr et sécurisé pour les utilisateurs normaux

Cette construction est très adaptée aux utilisateurs invités, que vous ne pouvez pas faire confiance. La première chose que j’ai essayée est de démarrer une session graphique. Je n’ai eu aucun problème.

Installer des logiciels en tant que cet utilisateur

Une autre utilisation possible est l’installation de logiciels en tant que cet utilisateur. Cela peut être fait comme suit :

  • en tant que cet utilisateur, installez votre logiciel. En raison de la construction spéciale, tous les changements vont dans le cache.
  • après vous être déconnecté, comparez le contenu du cache avec le véritable système.
  • l’utilisateur contrôlant (root) a le choix de faire la véritable installation en déplaçant simplement le contenu du cache vers la racine.

Par exemple, la compilation et l’installation d’un petit paquet, audiofile-0.2.6. Supposons que la source soit dans /tmp. Première connexion :

[root@hostname ]# login  
hostname login: unionuser  
Password:  
Last login: Wed Jun 20 19:58:32 CEST 2007 on pts/0  
[unionuser@hostname ]$

Maintenant, compilez et installez le paquet :

[unionuser@hostname ]$ cd /tmp/audiofile-0.2.6
[unionuser@hostname ]$ ./configure –prefix=/usr
[unionuser@hostname ]$ make
[unionuser@hostname ]$ sudo make install

Maintenant, quittez la session et vérifiez le contenu du cache :

[unionuser@hostname ]$exit
[root@hostname ]# cd /mnt/cache
[root@hostname ]# ls -Al
drwxr-xr-x 3 root root 1024 2007-06-05 17:32 home
drwxr-xr-x 6 root root 1024 2007-06-05 17:37 usr
drwxr-xr-x 3 root root 1024 2007-06-05 17:32 var
[root@hostname ]#

Le répertoire personnel apparaît ici parce que le shell Bash modifie le fichier .bash_history ; le répertoire var apparaît en raison des modifications dans le fichier /var/run/utmp et le répertoire /var/run/sudo. Cela prouve que cela fonctionne comme il se doit.

Maintenant, en regardant les changements dans le répertoire /usr où j’ai installé le logiciel donne :

[root@hostname ]# find usr -type f
usr/lib/pkgconfig/audiofile.pc
usr/lib/libaudiofile.la
usr/lib/libaudiofile.a
usr/lib/libaudiofile.so.0.0.2
usr/include/audiofile.h
usr/include/aupvlist.h
usr/include/af_vfs.h
usr/bin/audiofile-config
usr/bin/sfconvert
usr/bin/sfinfo
usr/share/aclocal/audiofile.m4
[root@hostname ]# find usr -type d
usr
usr/lib
usr/lib/pkgconfig
usr/include
usr/bin
usr/share
usr/share/aclocal

Comme vous pouvez le voir, tout est dans le répertoire /mnt/cache/usr.

Vous pouvez faire une sauvegarde de cela :

[root@hostname ]# find usr | sort -u > /tmp/filelist-audiofile-0.2.6  
  
[root@hostname ]# tar --create --files-from=/tmp/filelist-audiofile-0.2.6 \  
                  --file=/tmp/install-audiofile-0.2.6.tar --directory=/mnt/cache \  
                  --no-recursion --absolute-names --preserve-permissions

Il est également très possible de faire une sauvegarde de tous les fichiers qui seront écrasés :

[root@hostname ]# for installfile in $(cat /tmp/filelist-audiofile-0.2.6); do \  
                    if [ -e "/$installfile ]; then \  
                      echo "/$installfile" >> /tmp/backup-audiofile-0.2.6 \  
                    fi \  
                  done  
[root@hostname ]# tar --create --files-from=/tmp/backup-audiofile-0.2.6 \  
                  --file=/tmp/backup-audiofile-0.2.6.tar --directory=/mnt/cache \  
                  --no-recursion --absolute-names --preserve-permissions

Maintenant, faites la véritable installation en copiant tous les fichiers vers la racine :

[root@hostname ]# for installfile in $(cat /tmp/filelist-audiofile-0.2.6); do \  
                    cp --verbose --force --recursive --parents --no-dereference \  
                      --preserve --target-directory=/ $installfile \  
                  done

Note : les commandes ci-dessus sont pour illustrer l’idée. J’ai créé des scripts pour effectuer les sauvegardes, les vérifications et les installations, et cela fonctionne très bien.

Share: X/Twitter LinkedIn

Recevez de nouveaux articles dans votre boîte de réception.

Aucun spam. Désabonnez-vous à tout moment.