Quick Links

The chroot Linux utility can modify the working root directory for a process, limiting access to the rest of the file system. This is usually done for security, containerization, or testing, and is often called a "chroot jail."

What Does chroot Do?

Chroot does one thing---run a command with a different root directory. The command being run has no idea that anything outside of its jail exists, as it doesn't have any links to it, and as far as it's aware, is running on the root filesystem anyway. There's nothing above root, so the command can't access anything else.

Chroot doesn't make any modifications to your disk, but it can make it appear that way from the point of view of the processes running under it. Chrooting a process accomplishes the same thing as changing the mount namespace for a process, but does so at a higher level than namespace modification.

What is chroot Used For?

The main thing chroot is used for is locking away system daemons so that any security vulnerabilities in those daemons don't affect the rest of the system. For example, Postfix, a mail agent, can be configured to run inside a chrooted environment with limited access to the directories it uses to communicate with the system. This way, if a bug is found in Postfix, it affects Postfix, and not anything else.

This is pretty useful for a service like FTP. If you want to offer remote users access to parts of your system, chrooting the process is an easy way to lock down access.

It's also useful as a "budget container," to create a subset of your operating system and run apps in an isolated environment, be it for testing, security, or ease of development. But since chroot requires you to manually copy over application dependencies into the jail, it's not suitable for everything. A process that needs to access and interact with user-level resources would not work well inside a chroot jail, or would require extra configuration that may make the whole setup more insecure. But, even complicated apps like Apache and MySQL can be run inside a chrooted environment with all dependencies accounted for.

While a chroot jail is an added layer of security, chroot shouldn't be your only security tool. Breaking out of a jail can be relatively trivial if not configured properly, and a chroot jail only changes the mount location and doesn't affect the other namespaces. If you want better security, use namespaces, or a containerization engine like Docker.

Sending Processes to Jail

To open a shell inside a jailed directory, you can run:

sudo chroot /jail

However, this command will fail with a newly created /jail directory, since chroot will try to load bash from /jail/bin/bash. This file doesn't exist, which is the first problem with chroot---you have to build the jail yourself.

For some things, copying them over with cp is enough:

cp -a /bin/bash /jail/bin/bash

But this only copies over the bash executable, and not all of its dependencies, which don't exist in our jail yet. You can list the dependencies for bash with the ldd command:

ldd $(which bash)
    

linux-vdso.so.1 (0x00007ffd079a1000)

libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f339096f000)

libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f339076b000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f339037a000)

/lib64/ld-linux-x86-64.so.2 (0x00007f3390eb3000)

You can copy them over manually:

cp /lib/x86_64-linux-gnu/libtinfo.so.5 /jail/lib/x86_64-linux-gnu/
    

cp /lib/x86_64-linux-gnu/libdl.so.2 /jail/lib/x86_64-linux-gnu/

cp /lib/x86_64-linux-gnu/libc.so.6 /jail/lib/x86_64-linux-gnu/

cp /lib64/ld-linux-x86-64.so.2 /jail/lib64/

But this becomes a major hassle to do for every command you may want to run under chroot. If you don't care about your chroot accessing your actual lib and bin directories (without access to the rest of the system), then you can use mount --bind to provide a link in your jail:

mount --bind /bin /jail/bin
    

mount --bind /lib /jail/lib

mount --bind /lib64 /jail/lib64

You could also just copy over the entire /bin and /lib directories, which uses more space, but may be a bit better for security, especially if you're using chroot to run unsafe processes that you wouldn't want messing with your system's folders.

Now that everything is copied over, you should be able to once again run sudo chroot /jail to open bash. Alternatively, you can run any other command by running:

sudo chroot /jail command

If you're running processes through chroot bash, you can exit the shell with exit or Control+D, which will stop the running process. Processes running in jail run in their own environment, and don't have access to other processes on the system.

Can Process Escape The Jail?

Not easily, unless they're running as root. Chroot doesn't block access to low-level system resources (that would require root to access), and as such, a privileged process could easily escape a jail.

It is possible for non-privileged processes to break out entirely with the method chdir("..") and another call to chroot. If you're really focused on security, you should drop access to the chroot(2) system call, or use the fork jchroot, which automates this extra security feature.

chroot is not a bulletproof security tool, as it's not completely containerized, and shouldn't be thought of as a firewall that will save your system from attackers. However, unless a process is specifically trying to get out of a chroot jail, chroot achieves its job of sectioning off your file system for most processes, and can be configured with extra security measures to block the major escape methods.