Unionfs e Chroot · 8 min read · Feb 03, 2026
Entrare in uno Specchio Sicuro Durante il Login con Unionfs e Chroot
Entrare in uno Specchio Sicuro Durante il Login con Unionfs e Chroot
1. Introduzione
Quando leggevo un ‘suggerimento’ sul sito di LinuxFromScratch, ho scoperto le capacità speciali di unionfs, specialmente in combinazione con chroot. Più tardi ho letto un HowTo su un wiki di Gentoo, riguardo all’ingresso in una home directory chrooted quando si utilizza uno script speciale come shell. Combinando queste due cose, arrivo a utilizzare un ambiente chrooted, che si entra quando si effettua il login come un utente speciale. Questo ambiente è una copia esatta (specchio) del sistema su cui stai lavorando. Poiché sei in una copia sicura del sistema reale, puoi fare ciò che vuoi, non cambierà mai il sistema, tutto rimane all’interno della cache (il ramo readwrite).
Link:
TRIP, un TRIvial Packager per LFS (e altri sistemi linux) - Suggerimento originale sul sito di LFS
Home_directory_jail - Guida per impostare una chroot jail su Gentoo
2. Tecnica di base
Fai ciò che vuoi, installa, modifica e rimuovi file dal sistema, e nessun danno. Il tuo sistema reale rimane intatto. Questo può sembrare magia, ma in realtà è possibile solo combinando alcune tecniche di tutte quelle disponibili per Linux.
Utilizzando il filesystem Unionfs, un chroot e alcune directory rimontate scelte con cura, puoi impostare questo sistema virtuale.
2.1 Unionfs
La parte più importante è l’uso di unionfs. Unionfs ti dà la possibilità di creare un filesystem, che è l’unione di almeno altri due. Vedi www.unionfs.org per ulteriori informazioni. Ora, facendo sì che il nuovo filesystem sia l’unione del nostro filesystem originale (la radice) in sola modalità lettura, e di un filesystem temporaneo (la cache) in modalità lettura-scrittura, avrai un filesystem che appare esattamente come il tuo filesystem originale, ma in cui puoi modificare, eliminare e/o aggiungere file senza fare nulla al tuo sistema originale. Questo non è possibile, perché la radice è montata in sola lettura. Ogni modifica è memorizzata da unionfs nella cache.
L’unica differenza tra il sistema originale e quello appena creato è il percorso: nel nuovo sistema inizia sempre con il percorso del punto di mount dell’unione. Questo è il motivo per cui il passo successivo è necessario.
Una nota speciale: oggi [giugno 2007] sembra che unionfs sarà incluso nel kernel. Unionfs è attualmente in fase di sviluppo intenso. Controlla il sito web per ulteriori informazioni.
Sul sito troverai informazioni su come abilitare unionfs. Per i kernel più recenti (dopo il 2.6.19) c’è una patch per il kernel sorgente, per i kernel non così recenti c’è un modulo esterno.
2.2 (Re)Montaggio
Una cosa extra che dovrai fare è (re)montare diverse directory cruciali come /dev, /proc e /sys. Questo perché il filesystem union non preserva i punti di mount esistenti.
È anche consigliato rimontare alcune directory speciali come /tmp e la directory in cui stai costruendo il software.
2.3 Chroot
Chrootando a questo punto di mount, entri in un ambiente che è assolutamente una copia del tuo sistema. Puoi fare ciò che vuoi, anche rimuovere directory e file cruciali. Provalo! Guarda fino a che punto puoi arrivare prima che il tuo sistema si blocchi.
2.4 Effettuare il login in questo ambiente
Come il concetto spiegato in Home_directory_jail, è possibile creare una shell di login speciale per entrare nell’ambiente creato con unionfs e chroot.
L’idea spiegata qui è di creare un utente speciale, con una shell speciale. Questa shell, prima di entrare in una shell interattiva, eseguirà prima i passaggi necessari come montare il filesystem union, rimontare alcune directory importanti e fare il chroot.
3. Preparazione
3.1 La partizione cache
Per iniziare, una partizione con spazio sufficiente per funzionare come cache. Questa non deve essere una partizione fisica, può essere un’unità virtuale.
Crea questa unità con:
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 loopchmod 777 /mnt/cachemkdir /mnt/unionQuesto crea una partizione virtuale (o unità) di 500M.
(Nota: il dispositivo loopback deve essere supportato nel tuo kernel. I kernel della maggior parte delle distribuzioni lo fanno.)
3.2 Shell di login speciale
Crea uno script shell chroot-union che eseguirà tutti i passaggi necessari:
Lo script chroot-union in /bin:
#!/bin/bash
function mount_unionfs {
# monta filesystem temporanei
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
# montaggi di sistema di base
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 "Il montaggio di /mnt/union è fallito."
exit 2
fi
}
function umount_unionfs {
#
# smonta /tmp
#
if [ -n "$(mount | grep -w /mnt/union/tmp)" ]; then
sudo /bin/umount /mnt/union/tmp 2> /dev/null
fi
#
# smonta /proc
#
if [ -n "$(mount -t proc | grep -w /mnt/union/proc)" ]; then
sudo /bin/umount /mnt/union/proc 2> /dev/null
fi
#
# smonta /sys
#
if [ -n "$(mount -t sysfs | grep -w /mnt/union/sys)" ]; then
sudo /bin/umount /mnt/union/sys 2> /dev/null
fi
#
# smonta /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
#
# smonta /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
#
# smonta /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
# entra nel chroot
sudo /usr/sbin/chroot /mnt/union /bin/su --shell /bin/bash --login $USER
# smonta filesystem temporanei
umount_unionfs
EOF
Aggiungi la nuova shell di login al file /etc/shells. Dovrai farlo quando PAM controllerà la shell.
3.3 Creare utente e gruppo.
Crea un nuovo gruppo e utente con questo script come shell:
groupadd -g 27 uniongroup
useradd -c "Utente di test per chrooted union." -d /home/unionuser \
-m -s /bin/chroot-union -g uniongroup -u 27 unionuser
passwd unionuser3.4 Dare all’utente abbastanza diritti
Dai al nuovo utente più diritti con sudo. Aggiungi la seguente riga al file di configurazione di sudo, /etc/sudoers:
unionuser ALL=(ALL) ALL
Nota: ci sono altri modi per dare a questo utente i permessi. Li sto esaminando in questo momento.
Nota: dare questi permessi completi è troppo per un utente normale. Ma per un utente che installerà software e modificherà il tuo sistema è necessario.
Cosa è possibile
Ambiente sicuro e protetto per utenti normali
Questa costruzione è molto adatta per utenti ospiti, di cui non ti puoi fidare. La prima cosa che ho provato è stata avviare una sessione grafica. Non ho avuto alcun problema.
Installare software come questo utente
Un altro possibile utilizzo è l’installazione di software come questo utente. Questo può essere fatto come segue:
- come questo utente installa il tuo software. A causa della costruzione speciale, tutte le modifiche vanno nella cache.
- dopo aver effettuato il logout, confronta il contenuto della cache con il sistema reale.
- l’utente controllante (root) ha la possibilità di eseguire l’installazione reale semplicemente spostando il contenuto dalla cache alla radice.
Ad esempio, la compilazione e l’installazione di un piccolo pacchetto, audiofile-0.2.6. Supponiamo che la sorgente sia in /tmp. Prima login:
[root@hostname ]# login
hostname login: unionuser
Password:
Last login: Wed Jun 20 19:58:32 CEST 2007 on pts/0
[unionuser@hostname ]$Ora compila e installa il pacchetto:
[unionuser@hostname ]$ cd /tmp/audiofile-0.2.6
[unionuser@hostname ]$ ./configure –prefix=/usr
[unionuser@hostname ]$ make
[unionuser@hostname ]$ sudo make install
Ora esci dalla sessione e controlla il contenuto della 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 ]#
La directory home appare qui perché la shell Bash modifica il file .bash_history; la directory var appare a causa delle modifiche nel file /var/run/utmp e nella directory /var/run/sudo. Questo dimostra che funziona come dovrebbe.
Ora, guardando le modifiche nella directory /usr dove ho installato il software dà:
[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
Come puoi vedere, tutto è nella directory /mnt/cache/usr.
Puoi fare un backup di questo:
[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È anche molto possibile fare un backup di tutti i file che verranno sovrascritti:
[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-permissionsOra fai l’installazione reale copiando tutti i file nella radice:
[root@hostname ]# for installfile in $(cat /tmp/filelist-audiofile-0.2.6); do \
cp --verbose --force --recursive --parents --no-dereference \
--preserve --target-directory=/ $installfile \
doneNota: i comandi sopra sono per illustrare l’idea. Ho creato script che eseguono il backup, il controllo e l’installazione, e funziona molto bene.
Ricevi i nuovi post nella tua casella di posta.
Nessuno spam. Disiscriviti in qualsiasi momento.