1 22/05/2026 11 min

Un chroot su Debian non è una sandbox completa, ma resta uno strumento utile quando serve confinare un servizio, preparare un ambiente di test o eseguire manutenzione su un sistema non avviabile. Il punto chiave è semplice: il processo vede una radice diversa da /, quindi molti percorsi assoluti vengono reinterpretati dentro la directory scelta. Se lo imposti bene, ottieni un ambiente coerente e ripetibile; se lo imposti male, ottieni un contenitore fragile che sembra funzionare finché non incontra librerie mancanti, device non montati o permessi sbagliati.

Su Debian la procedura è abbastanza lineare, ma conviene ragionare per obiettivo: vuoi un chroot per manutenzione manuale, per un servizio avviato da systemd, per build e test, oppure per isolare un demone legacy? La risposta cambia soprattutto nella parte di bootstrap, nei bind mount e nella gestione di rete, DNS e device. Qui parto da un caso pratico e solido: creare un chroot Debian minimale, entrarci in shell, renderlo utilizzabile e poi chiuderlo in modo pulito, con note su errori tipici e limiti reali della tecnica.

Quando il chroot ha senso e quando no

Ha senso quando vuoi separare filesystem e runtime senza introdurre una VM o un container completo. Esempi tipici: recupero di un sistema, compilazione in ambiente pulito, esecuzione di tool che devono vedere un set limitato di file, gestione di vecchi software che si aspetta una gerarchia standard. Non è la scelta giusta se il tuo obiettivo è isolamento forte: un processo con privilegi adeguati può ancora fare danni fuori dal perimetro atteso, soprattutto se gli concedi device, mount o capability troppo ampie.

In pratica, il chroot è uno strumento di confinamento parziale, non una barriera di sicurezza completa. Se il requisito è security hardening serio, va affiancato ad altri controlli: namespace, seccomp, AppArmor, systemd sandboxing, container runtime o VM. Se invece ti serve un ambiente riproducibile e semplice, Debian con chroot resta una soluzione ancora molto concreta.

Prerequisiti minimi sul sistema host

Servono privilegi amministrativi, spazio disco sufficiente e una directory dedicata. Su Debian la coppia di pacchetti più utile è debootstrap per creare il filesystem base e schroot se vuoi gestire l’accesso in modo più comodo rispetto al comando chroot puro. Per un primo setup manuale basta debootstrap, mentre schroot diventa comodo quando vuoi più profili, utenti non root o sessioni multiple.

Verifica prima la versione della release Debian che vuoi installare nel chroot. Non dare per scontato che la stessa versione dell’host sia quella giusta: spesso conviene usare una stable specifica per avere librerie e repository coerenti. Un controllo rapido dell’host aiuta anche a evitare sorprese su architettura e spazio disponibile.

Comandi utili:

cat /etc/debian_version
uname -m
df -h /srv /var /home

Se la directory destinata al chroot sta su una partizione piccola, meglio scoprirlo subito. Un chroot minimale parte con poco, ma appena aggiungi pacchetti, log o cache APT può crescere rapidamente.

Creazione del filesystem base con debootstrap

La strada più pulita è creare una directory dedicata, poi inizializzare un sistema Debian minimale con debootstrap. Per esempio, se vuoi una stable a 64 bit in /srv/chroot/debian12, puoi partire così:

sudo mkdir -p /srv/chroot/debian12
sudo debootstrap --variant=minbase bookworm /srv/chroot/debian12 http://deb.debian.org/debian

--variant=minbase crea un sistema essenziale, abbastanza piccolo da essere gestibile e abbastanza completo da non dover rincorrere dipendenze banali. Se ti serve un ambiente più ricco, puoi installare i pacchetti dopo l’accesso nel chroot. Se il mirror è locale o aziendale, sostituiscilo con quello corretto: il vantaggio è velocità e prevedibilità, soprattutto in ambienti con connettività intermittente.

Se il comando fallisce, le cause più comuni sono tre: mirror non raggiungibile, mismatch di architettura, oppure repository non coerente con la release scelta. Il check più veloce è riprovare con un mirror noto e verificare la reachability con curl -I o ping se la policy lo consente. Se usi una release non più supportata, il problema potrebbe essere il repository archivio, non il chroot in sé.

Bind mount necessari per rendere il chroot usabile

Un chroot appena creato non è molto utile se non gli dai accesso a pseudo-filesystem e punti di montaggio essenziali. In genere servono almeno /proc, /sys, /dev e, a seconda del caso, /dev/pts. Senza questi mount, molti strumenti si comportano male: apt può funzionare, ma utility di rete, shell interattive e programmi che leggono informazioni dal kernel possono rompersi in modi poco intuitivi.

Una configurazione manuale tipica è questa:

sudo mount --bind /dev /srv/chroot/debian12/dev
sudo mount --bind /dev/pts /srv/chroot/debian12/dev/pts
sudo mount -t proc proc /srv/chroot/debian12/proc
sudo mount -t sysfs sys /srv/chroot/debian12/sys

Se ti serve risoluzione DNS dentro il chroot, copia o monta anche /etc/resolv.conf. La soluzione più semplice è un bind mount del file, ma in ambienti con systemd-resolved o con resolv.conf gestito dinamicamente conviene capire bene chi lo scrive sull’host, altrimenti rischi di portare dentro un file stantio.

sudo mount --bind /etc/resolv.conf /srv/chroot/debian12/etc/resolv.conf

Se prevedi di usare il chroot spesso, automatizza questi mount con /etc/fstab o con una configurazione schroot. Farli a mano va bene per il primo test; come procedura operativa regolare, invece, diventa troppo facile dimenticare un pezzo.

Entrare nel chroot e verificare la coerenza del sistema

Una volta preparato il filesystem, puoi entrare con il comando classico:

sudo chroot /srv/chroot/debian12 /bin/bash

Dentro il chroot, verifica subito tre cose: hostname, mount visibili e repository APT. Un controllo semplice è questo:

cat /etc/debian_version
mount | head
apt update

Se apt update fallisce con errori di rete, il problema è quasi sempre DNS o routing sul chroot, non il pacchetto in sé. Se invece fallisce con chiavi o repository, il problema è nella configurazione di /etc/apt/sources.list o nella release scelta. Per un ambiente minimo, basta un file essenziale come questo:

deb http://deb.debian.org/debian bookworm main deb http://deb.debian.org/debian bookworm-updates main deb http://security.debian.org/debian-security bookworm-security main

Ricorda che il chroot eredita il kernel dell’host. Se ti aspetti un ambiente “diverso” anche lato kernel, stai chiedendo a uno strumento sbagliato. Il filesystem cambia, il kernel no.

Rendere il chroot pratico con schroot

Se devi usarlo con regolarità, schroot semplifica molto la vita. Ti evita di ricordare ogni volta i mount e ti permette di definire profili riutilizzabili. È anche più comodo se vuoi far accedere utenti non root a un ambiente limitato. Su Debian installi i pacchetti necessari così:

sudo apt update
sudo apt install schroot debootstrap

Poi puoi definire una voce dedicata, ad esempio in /etc/schroot/chroot.d/debian12.conf:

[debian12]
type=directory
description=Debian 12 chroot
directory=/srv/chroot/debian12
users=tuoutente
root-users=root
preserve-environment=true

Con questa configurazione, l’accesso diventa più pulito:

schroot -c debian12

Il vantaggio operativo è evidente: meno errori manuali, meno mount dimenticati, meno dipendenza dalla memoria dell’operatore. Il rovescio della medaglia è che devi curare bene il file di configurazione e i permessi sulla directory del chroot, altrimenti il comportamento diventa poco chiaro.

Installare pacchetti e preparare un ambiente utile

A questo punto puoi installare ciò che serve davvero. Per un ambiente base di amministrazione, spesso bastano pochi pacchetti: vim o nano, curl, iproute2, procps, ca-certificates. Se il chroot deve ospitare build o test, aggiungi toolchain e librerie specifiche del progetto.

apt install vim curl iproute2 procps ca-certificates

Se usi il chroot per recupero di un sistema, installa solo il minimo necessario. Più pacchetti inserisci, più aumentano tempo di bootstrap, superficie di manutenzione e probabilità di mismatch tra ambiente host e chroot. In un contesto operativo, il minimalismo è una scelta tecnica, non estetica.

Un dettaglio che viene spesso trascurato è il fuso orario. Se il chroot deve generare log leggibili, conviene allineare /etc/localtime e, se necessario, /etc/timezone. Anche qui un bind mount è spesso sufficiente, ma dipende da quanto vuoi che il chroot sia autonomo rispetto all’host.

Avviare servizi dentro il chroot senza creare confusione

Far partire un servizio dentro il chroot è possibile, ma richiede disciplina. Non tutti i demoni sono felici di girare in questo contesto, soprattutto se si aspettano accesso a device, socket di sistema o feature di init non presenti. Se il servizio è semplice, puoi avviarlo manualmente dal chroot; se è più complesso, valuta se non sia più sensato usare un container o un’unità systemd dedicata con namespace e limiti appropriati.

Per un demone che non richiede init completo, il pattern è questo: prepara config, verifica dipendenze, avvia in foreground se possibile e controlla i log. Se il processo deve scrivere in /var/log, assicurati che la directory esista e che i permessi siano coerenti con l’UID del servizio. Molti “non parte” dipendono da questo, non dal chroot in sé.

Se vuoi testare la presenza dei device base, un controllo rapido è:

ls -l /dev/null /dev/urandom /dev/pts

Se questi elementi mancano o sono errati, diversi programmi si comportano in modo anomalo. La correzione non è “riavviare il chroot”, ma sistemare i mount o i bind nel punto giusto.

Errori tipici e come leggerli in fretta

Il primo errore classico è il chroot che entra ma non riesce a eseguire la shell. In quel caso la causa più probabile è una root filesystem incompleta o un binario mancante, spesso /bin/bash o le sue librerie dinamiche. Un controllo utile è verificare con ldd sul binario usato dal chroot, oppure installare una shell alternativa se il bootstrap è stato fatto in modo troppo minimale.

Il secondo errore comune riguarda APT: repository non raggiungibili, chiavi mancanti, DNS rotto. Qui la diagnosi passa da /etc/resolv.conf, /etc/apt/sources.list e connettività dell’host. Se l’host risolve e il chroot no, il problema è quasi sempre nel bind mount del resolver o nella presenza di un file vecchio nel filesystem del chroot.

Il terzo errore è più subdolo: il servizio dentro il chroot sembra partire, ma si blocca appena deve accedere a socket, pseudo-terminali o mount secondari. In questo caso il problema è spesso la mancanza di /dev/pts, /proc o del contesto di esecuzione atteso. Il fix è aggiungere ciò che serve in modo mirato, non aprire tutto “per sicurezza” o “per farlo andare”.

Chiusura corretta e pulizia dei mount

Quando hai finito, esci dal chroot e smonta tutto in ordine inverso rispetto alla preparazione. È un passaggio banale ma importante: lasciare mount appesi crea confusione al reboot e rende più difficile capire se il sistema è davvero pulito. La sequenza tipica è questa:

exit
sudo umount /srv/chroot/debian12/dev/pts
sudo umount /srv/chroot/debian12/dev
sudo umount /srv/chroot/debian12/proc
sudo umount /srv/chroot/debian12/sys

Se un mount non si smonta perché è occupato, non forzare subito. Prima verifica quale processo lo sta tenendo aperto con lsof o fuser. Solo dopo, e con cognizione di causa, valuta l’intervento. In un ambiente condiviso, forzare lo smontaggio senza capire chi lo usa è un modo rapido per creare un problema nuovo.

Per capire se il chroot è stato preparato bene, il controllo finale non è “entra”, ma “entra, risolve, installa, esegue e si chiude senza residui”. Se questi quattro punti passano, l’ambiente è utilizzabile davvero. Se ne fallisce uno, il difetto è quasi sempre nella preparazione iniziale: mount incompleti, repository, permessi o aspettative sbagliate sul livello di isolamento.

Una configurazione robusta da riusare nel tempo

Se devi standardizzare la procedura, tieni separati tre livelli: bootstrap del filesystem, configurazione dei bind mount e profilo di accesso. In questo modo puoi rifare solo il pezzo che cambia senza toccare tutto il resto. Anche un semplice script di provisioning può bastare, purché sia leggibile e mantenga traccia delle directory coinvolte.

Un approccio pratico è documentare almeno questi elementi: release Debian, mirror usato, directory target, mount richiesti, account autorizzati e pacchetti minimi. Non serve un framework, serve coerenza. Il chroot funziona bene quando è trattato come un componente ripetibile, non come un trucco da ricordare a memoria ogni volta.

Se vuoi fare un passo ulteriore, puoi aggiungere logging delle operazioni di bootstrap e una checklist di verifica: spazio disco, reachability del mirror, DNS, mount, shell, APT. Sono controlli semplici, ma abbattono parecchio il tempo perso in diagnosi quando qualcosa non parte al primo colpo.

In sintesi, su Debian un chroot ben costruito è utile quando hai bisogno di un ambiente leggero, controllabile e vicino al sistema reale. Non sostituisce un container o una VM, ma in molte attività operative resta più rapido, più trasparente e più facile da debuggare. La differenza la fa quasi sempre la disciplina con cui prepari filesystem, mount e rete: il chroot non perdona l’approssimazione, ma ripaga bene quando è configurato con metodo.