Kernel of Truth

CHROOT in Linux: What It Is, Why You Would Use It, and How

chroot changes the apparent root directory / for a running process and its children. Inside a chroot, the process sees the specified directory as if it were the entire filesystem. This is often called a “chroot jail”.


Quick take

  • What it does: Runs a program with a different root directory.
  • Why use it: System recovery, building or testing packages in an isolated tree, running legacy software with specific libraries, or creating minimal sandboxes.
  • What it is not: A strong security boundary. Root inside a chroot can often break out if the environment is not carefully constrained.
  • Who can use it: Only root (or a process with CAP_SYS_CHROOT capability) can call chroot.

Common uses

1) System recovery from a live USB

Mount your broken system, chroot into it, then run tools like grub-install, apt, or dnf as if you had booted it normally.

2) Clean build environments

Create a minimal filesystem tree and chroot into it to compile software without polluting your host libraries and headers.

3) Legacy or pinned dependency stacks

Run an older userland and libraries for a specific application while keeping your host modern.

4) Lightweight sandboxes

Offer a restricted environment for specific tasks or scripts. For serious isolation see containers or VMs.


Security notes

  • Not a hard boundary: chroot limits the view of the filesystem but does not sandbox kernel calls. If a process gains root inside the jail, it may escape by various means if the environment is not locked down.
  • Mounts and devices: If you bind-mount host filesystems or device nodes into the jail, you can re-expose powerful host capabilities.
  • Use cases: Safe enough for building software or recovering systems. For multi-tenant or hostile workloads prefer containers (namespaces, cgroups), systemd-nspawn, LXD, or VMs.

How it works

The kernel changes the process’s root directory to a new path, affecting absolute path resolution. The process needs a minimal filesystem under that path, for example:

  • /bin, /sbin, /usr with the binaries you want to run
  • /lib, /lib64, /usr/lib for required shared libraries
  • /dev, /proc, /sys, /run if needed, usually via bind mounts

Quick start: a minimal chroot

Goal: Create a tiny root and run a shell in it. This example uses your host binaries by bind-mounting essentials. It is fine for learning, not for strong isolation.

# 1) Create the root
sudo mkdir -p /srv/jail/{bin,lib,lib64,usr,dev,proc,sys,run,etc}

# 2) Copy a static shell OR bind-mount host tools
# Option A: if you have busybox static
#   sudo cp /bin/busybox /srv/jail/bin/
#   sudo ln -s /bin/busybox /srv/jail/bin/sh
# Option B: bind-mount host directories (simpler demo)
sudo mount --bind /bin /srv/jail/bin
sudo mount --bind /usr /srv/jail/usr
sudo mount --bind /lib /srv/jail/lib
sudo mount --bind /lib64 /srv/jail/lib64

# 3) Provide minimally useful virtual filesystems
sudo mount --bind /dev  /srv/jail/dev
sudo mount -t proc proc /srv/jail/proc
sudo mount -t sysfs sys /srv/jail/sys
sudo mount --bind /run  /srv/jail/run

# 4) DNS inside the jail (optional, for network tools)
echo "nameserver 1.1.1.1" | sudo tee /srv/jail/etc/resolv.conf >/dev/null

# 5) Enter the jail with a shell
sudo chroot /srv/jail /bin/bash

# Inside the jail:
ls /
exit

# 6) Cleanup
sudo umount -l /srv/jail/{proc,sys,run,dev}
sudo umount -l /srv/jail/{bin,usr,lib,lib64}

Tip: If you see “chroot: failed to run command: No such file or directory” it usually means the binary or one of its shared libraries is missing inside the jail. Use ldd /bin/bash on the host to see which libraries you must provide.


Distro-native chroots that feel like a tiny OS

Debian/Ubuntu with debootstrap

Creates a self-contained Debian or Ubuntu filesystem tree.

sudo apt-get update
sudo apt-get install -y debootstrap

# Create a minimal Ubuntu Noble into /srv/ubjail
sudo debootstrap noble /srv/ubjail http://archive.ubuntu.com/ubuntu/

# Bind mounts for convenience
sudo mount --bind /dev  /srv/ubjail/dev
sudo mount -t proc proc /srv/ubjail/proc
sudo mount -t sysfs sys /srv/ubjail/sys
sudo cp /etc/resolv.conf /srv/ubjail/etc/resolv.conf

# Enter and finish configuring
sudo chroot /srv/ubjail /bin/bash
apt-get update
# ... install packages, set root password if you wish, etc.
exit

# Cleanup
sudo umount -l /srv/ubjail/{proc,sys,dev}

RHEL/CentOS/Fedora with dnf --installroot

# Fedora example
sudo dnf -y --releasever=40 --installroot=/srv/fedjail --nogpgcheck install bash coreutils
# Minimal mounts
sudo mount --bind /dev  /srv/fedjail/dev
sudo mount -t proc proc /srv/fedjail/proc
sudo mount -t sysfs sys /srv/fedjail/sys
sudo cp /etc/resolv.conf /srv/fedjail/etc/resolv.conf

sudo chroot /srv/fedjail /bin/bash
dnf update
exit

sudo umount -l /srv/fedjail/{proc,sys,dev}

Good practice and gotchas

  • Always: Provide the right libraries. Check with ldd.
  • Networking: Copy or create /etc/resolv.conf in the jail for DNS.
  • Locales and time: You may need locale packages and /etc/localtime for correct formatting.
  • Permissions: You usually need to be root to chroot. Use sudo or a root shell.
  • Unmount carefully: Use umount -l if a process keeps a mount busy and you understand the risk.
  • Automation: Wrap mount, chroot, and cleanup in a small script to avoid leaving mounts behind.

When chroot is not the right tool

Use chroot for simple isolation and recovery. For stronger guarantees consider:

  • Containers: Docker or Podman use namespaces and cgroups for process, network, and resource isolation, far stronger than chroot alone.
  • systemd-nspawn: A light container tool that runs a directory tree with additional isolation features.
  • Virtual machines: Full isolation with their own kernels.

Troubleshooting

“No such file or directory” when running a binary
Likely missing dynamic libraries, or binary built for a different architecture than the host kernel. Check with:

file /srv/jail/bin/bash
ldd  /srv/jail/bin/bash

Networking tools cannot resolve hosts
Populate /etc/resolv.conf in the jail, or bind-mount the host’s file.

Cannot see disks or processes
Mount the relevant virtual filesystems, for example proc and sysfs, or do not mount them if you want less visibility.

Build or package tools fail
Install compilers, headers, and build dependencies inside the jail, not on the host.


Reusable helper script

Handy for entering a chroot quickly and cleaning up mounts afterwards.

#!/usr/bin/env bash
# chroot-helper.sh - create mounts, enter chroot, then clean up

set -euo pipefail
ROOT="${1:-/srv/jail}"

for d in dev proc sys run; do
  sudo mkdir -p "$ROOT/$d"
done

sudo mount --bind /dev  "$ROOT/dev"
sudo mount -t proc proc "$ROOT/proc"
sudo mount -t sysfs sys "$ROOT/sys"
sudo mount --bind /run  "$ROOT/run"
sudo cp -f /etc/resolv.conf "$ROOT/etc/resolv.conf" || true

sudo chroot "$ROOT" /bin/bash

# Cleanup on exit
sudo umount -l "$ROOT/run" "$ROOT/sys" "$ROOT/proc" "$ROOT/dev"
echo "Unmounted and cleaned: $ROOT"

FAQ

Does chroot require a separate kernel? No. It uses the host kernel. It only changes the root directory for path resolution.

Can users escape a chroot? Non-root users are usually contained, but root inside the jail can often escape if given enough tools or mounts. Do not rely on chroot as your sole security boundary.

Is pivot_root the same? No. pivot_root switches the root of the calling process during boot or within namespaces. It is commonly used by initramfs and container runtimes. chroot is a simpler userland tool.


Summary

chroot is a simple, powerful way to run commands in an alternate filesystem tree. It shines for recovery and clean builds, and it is useful as a lightweight sandbox. It is not a full security solution. For strong isolation use containers or VMs. For the common admin tasks described above, a neat chroot will save you time and risk.


🛡️Latest Security Alerts 🛡️

NCSC Latest
(The National Cyber Security Centre UK)