Chroot
Chroot (Change root) è un'utilità dei sistemi Unix utilizzata per cambiare la root directory apparente, in modo da creare un nuovo ambiente logicamente separato dalla root del sistema principale. Questo nuovo ambiente è detto "gabbia chroot" (o "chroot jail"). Un utente che opera all'interno di una gabbia non può vedere o accedere a file al di fuori dell'ambiente in cui è stato rinchiuso.
Uno dei principali usi di chroot è quello di creare un sistema Linux separato sopra quello corrente a scopo di test o compatibilità software. Chroot è spesso visto come un'alternativa leggera alla virtualizzazione, perché è in grado di funzionare senza il sovraccarico di un hypervisor.
Prerequisiti
Impostare l'ambiente
Quando si crea una nuova impostazione di chroot, la prima cosa necessaria è una directory nella quale far risiedere il chroot. Ad esempio, un chroot potrebbe essere creato in /mnt/mychroot:
user $
mkdir /mnt/mychroot
user $
cd /mnt/mychroot
Per montare una installazione esistente da una partizione può essere eseguito il seguente comando. Assicurarsi di sostituire la stringa <DEVICE>
nell'esempio sotto con
l'unità e la partizione dell'installazione esistente:
user $
mkdir /mnt/mychroot
user $
mount /dev/<DEVICE> /mnt/mychroot
Se un'installazione è stata in precedenza creata in una sotto directory del filesystem di root attuale, i passaggi di cui sopra possono essere saltati.
Decomprimere i file di sistema e dell'albero Portage (nuove installazioni)
Quando si costruisce una nuova installazione, il passo successivo è quello di scaricare lo stage3 e Portage tarballs e metterli nella posizione in cui risiede chroot. Per ulteriori informazioni su questo processo si vedano le sezioni Scaricamento dello stage tarball e Estrazione dello stage tarball nel manuale di Gentoo.
root #
links http://distfiles.gentoo.org/releases/amd64/autobuilds/
root #
tar xvjpf stage3-*.tar.bz2 -C /mnt/mychroot
Configurazione
Prima di accedere all'ambiente chroot devono essere montate delle directory:
root #
mount --rbind /dev /mnt/mychroot/dev
root #
mount --make-rslave /mnt/mychroot/dev
root #
mount -t proc /proc /mnt/mychroot/proc
root #
mount --rbind /sys /mnt/mychroot/sys
root #
mount --make-rslave /mnt/mychroot/sys
root #
mount --rbind /tmp /mnt/mychroot/tmp
Qualche file di configurazione di base dovrà essere copiato dall'host, ma non si deve copiare make.conf quando si utilizza un'installazione esistente:
user $
cp /etc/portage/make.conf /mnt/mychroot/etc/portage # Quando si utilizza un'installazione preesistente, saltare questo comando.
user $
cp /etc/resolv.conf /mnt/mychroot/etc
Utilizzo
Una volta fatto entrare nell'ambiente chroot eseguendo i seguenti comandi:
root #
chroot /mnt/mychroot /bin/bash
root #
env-update && . /etc/profile
root #
export PS1="(chroot) $PS1"
Durante la creazione di una nuova installazione, è opportuno sincronizzare Portage per assicurarsi che tutto sia aggiornato.
(chroot) root #
emerge-webrsync
(chroot) root #
emerge --sync
Il sistema è ora pronto; sentitevi liberi di installare il software, modificare le impostazioni, testare pacchetti sperimentali e configurare senza avere alcun effetto sul sistema principale. Per lasciare il chroot è sufficiente digitare exit o premere Ctrl+d. In questo modo si tornerà nella console dell'ambiente normale. Non dimenticate di smontare (umount) le directory che sono state montate.
systemd-nspawn
If the system uses systemd, systemd-nspawn can be used, which can automatically handle much of the boilerplate required in administering chroots. For example, to enter a chroot via systemd-nspawn with the same configuration as specified in the Configuration section, simply run:
root #
cp /etc/portage/make.conf /mnt/mychroot/etc/portage
root #
systemd-nspawn -D /mnt/mychroot --bind=/tmp --resolv-conf=/etc/resolv.conf
Script di init
Se impostare chroot è un lavoro che è necessario eseguire spesso, è possibile accelerare il montaggio delle directory utilizzando uno script init. Lo script dovrebbe essere aggiunto al livello di esecuzione predefinito (default runlevel) e comunque impostato per l'esecuzione automatica all'avvio del sistema:
#!/sbin/openrc-run
depend() {
need localmount
need bootmisc
}
start() {
ebegin "Mounting chroot directories"
mount -o rbind /dev /mnt/mychroot/dev > /dev/null &
mount -t proc none /mnt/mychroot/proc > /dev/null &
mount -o bind /sys /mnt/mychroot/sys > /dev/null &
mount -o bind /tmp /mnt/mychroot/tmp > /dev/null &
eend $? "Si è verificato un errore durante il montaggio delle directory dell'ambiente chroot"
}
stop() {
ebegin "Unmounting chroot directories"
umount -f /mnt/mychroot/dev > /dev/null &
umount -f /mnt/mychroot/proc > /dev/null &
umount -f /mnt/mychroot/sys > /dev/null &
umount -f /mnt/mychroot/tmp > /dev/null &
eend $? "Si è verificato un errore durante lo smontaggio delle directory dell'ambiente chroot"
}
Quando si utilizza una directory od una partizione diverse, aggiungere i comandi di montaggio necessari nella funzione start()
e modificare /mnt/chroot con il nome appropriato.
Sound and graphics
The software running inside the chroot will by default not have access to the system sound- and display-server. Fixing this is done by either sharing a socket, or by running the communication with TCP over localhost.
Wayland
Wayland uses a socket to connect clients with the compositor. This socket needs to be shared with the chroot to make graphical applications work. The general procedure for finding this socket is:[1]
- If WAYLAND_SOCKET is set, interpret it as a file descriptor number on which the connection is already established, assuming that the parent process configured the connection for us.
- If WAYLAND_DISPLAY is set, concat with XDG_RUNTIME_DIR to form the path to the Unix socket.
- Assume the socket name is
wayland-0
and concat with XDG_RUNTIME_DIR to form the path to the Unix socket.
Using WAYLAND_DISPLAY and XDG_RUNTIME_DIR is fine in most cases and will be used here. By default XDG_RUNTIME_DIR is set to /run/user/$(uid). This directory will not be available in the chroot because the #Configuration instructions bind mounts /run non-recursively. Assuming the user's uid is 1000, this can be solved by either bind-mounting /run/user/1000 with:
root #
mkdir -p /mnt/mychroot/run/user/1000
root #
mount --bind /run/user/1000 /mnt/mychroot/run/user/1000
or by simply recursively bind mounting /run with:
root #
mount --rbind /run /mnt/mychroot/run
The Wayland library dev-libs/wayland uses the same procedure for finding out the socket as listed above. So to share the socket with the chroot, the only thing that's needed to do is defining XDG_RUNTIME_DIR and WAYLAND_DISPLAY. Here it is assumed that the Wayland socket name WAYLAND_DISPLAY is wayland-0
.
(chroot) root #
useradd -m user
(chroot) root #
su -l user
(chroot) user $
export XDG_RUNTIME_DIR=/run/user/1000
(chroot) user $
export WAYLAND_DISPLAY=wayland-0
(chroot) user $
MOZ_ENABLE_WAYLAND=1 firefox-bin
Permission errors will occur if the user in the chroot does not have permissions to access the Wayland socket. This can be solved by using user namespace remapping or ACLs. The easiest solution is to just make sure that the user ids match. The useradd -u, --uid UID option can be used when creating a user.
PipeWire
Like Wayland, PipeWire uses a socket to connect clients to the PipeWire daemon.
Applications assume that the PipeWire socket will be located in ${XDG_RUNTIME_DIR}/pipewire-0
,
so the only thing that's needed to get PipeWire clients to connect to the host's daemon is to expose
XDG_RUNTIME_DIR to the chroot. This process is identical to the one described in #Wayland.
To expose XDG_RUNTIME_DIR, often /run/user/$(uid), the following commands are used:
root #
mkdir -p /mnt/mychroot/run/user/1000
root #
mount --bind /run/user/1000 /mnt/mychroot/run/user/1000
XDG_RUNTIME_DIR will not be set when logging in inside the chroot, therefore XDG_RUNTIME_DIR needs to exported so the PipeWire client can find the socket:
(chroot) user $
export XDG_RUNTIME_DIR=/run/user/1000
(chroot) user $
pw-cli
Xorg
Xorg by default listens on a socket located in /tmp/.X11-unix/X${DISPLAY}
, as well as on localhost TCP port 6000 + ${DISPLAY}
[2]. The instructions in #Configuration bind mounts /tmp, and therefore no additional configuration is needed except setting the DISPLAY variable before running a graphical application:
(chroot) user $
DISPLAY=:0 firefox-bin
If the uid of the user inside the chroot does not match the uid outside the chroot, then setting permissions with xhost will be needed. To allow all local connections, run outside the chroot:
user $
xhost +local:
Vedere anche
- Project:X86/Chroot Guide — provides instructions on how to create a fresh Gentoo installation inside a chroot to assist in testing Gentoo packages for stabilization and for other sundry testing.
- Chrooting servizi proxy
- Chrooting e server virtuali
External resources
- chroot on Archlinux's wiki
References
- ↑ https://wayland-book.com/protocol-design/wire-protocol.html
- ↑ So if DISPLAY=:12, then Xorg will listen on localhost TCP port 6012