Chroot: Intro
Chroot(8) refers to changing the root. When a process runs inside a chroot, you change what a process thinks is its root directory.
Normally, a process can access any file within the root filesystem it has permissions for. By changing what the process thinks is its root directory, however, the process is now stuck in a chroot "jail".
This provides enhanced security: if a program gets compromised, it can only access and modify files within the new root.
Uses
Many OpenBSD daemons are chrooted by default, and some third-party applications can also be chrooted:
Chrooted OpenBSD services | |
---|---|
Application | Chroot path |
openhttpd | /var/www/ |
nsd | /var/nsd/ |
unbound | /var/unbound/ |
Chrooted third party applications | |
---|---|
Application | Chroot path |
ngircd | /var/ngircd/ |
znc | /home/znc/ |
perl | /var/www |
Creating a Chroot
Suppose for a moment we want to chroot an imaginary program. We first call whereis(1) on the binary to find its absolute path:
$ whereis program /usr/bin/program
Next, we call ldd(1) on the absolute path to find its dependencies:
$ ldd /usr/bin/program /usr/bin/program Start End Type Open Ref GrpRef Name 0000022622dc8000 0000022622dcd000 exe 1 0 0 /usr/bin/program 000002285bdc7000 000002285c133000 rlib 0 1 0 /usr/lib/libprogram.so.20.0 00000228c7de6000 00000228c7e16000 rlib 0 2 0 /usr/lib/libm.so.10.1 000002282f00d000 000002282f101000 rlib 0 2 0 /usr/lib/libc.so.100.3 0000022914fb2000 0000022914fb2000 ld.so 0 1 0 /usr/libexec/ld.so
In order to chroot this program, we must re-create the filesystem in our target chroot directory, /home/program, and copy all necessary dependencies:
$ doas mkdir -p /home/program/usr/bin/ $ doas mkdir -p /home/program/usr/lib/ $ doas mkdir -p /home/program/usr/libexec/ $ doas cp /usr/bin/program /home/program/usr/bin/ $ doas cp /usr/lib/libprogram.so.20.0 /home/program/usr/lib/ $ doas cp /usr/lib/libm.so.10.1 /home/program/usr/lib/ $ doas cp /usr/lib/libc.so.100.3 /home/program/usr/lib/ $ doas cp /usr/libexec/ld.so /home/program/usr/libexec/
Then, to run the chroot:
$ doas chroot -u daemon -g daemon /home/program program
Sometimes, these dependencies have their own dependencies, so you may need to run ldd and copy files multiple times. Some of these dependencies do not become apparent until you attempt to run the program.
Drawbacks
There are many drawbacks to using a chroot:
- It requires you replicate each dependency inside the chroot every time you install or update the program
- It cannot limit the type of syscalls that the process can make
- chroot(8) requires root, so normal users cannot run them
- Chrooted processes still have access to the network
Because of these limitations of a chroot, OpenBSD developed pledge and unveil to tighten the security of a process.