It's a Linux command that allows you to set the root directory of a new process. In our container use case, we just set the root directory to be where-ever the new container's new root directory should be. And now the new container group of processes can't see anything outside of it, eliminating our security problem because the new process has no visibility outside of its new root.
Let's try it. Start up a Ubuntu VM however you feel most comfortable
docker run -it --name docker-host --rm --privileged ubuntu:bionic
To see what version of Ubuntu you're using
cat /etc/issue
Ubuntu 18.04.6 LTS \n \l
Okay, so let's attempt to use chroot
right now.
1. Make a new folder in your home: mkdir new-root
2. Insider that new folder run echo "my super secret thing" >> /new-root/secret.txt
3. Now try to run chroot /new-root bash
and see the error it gives you
chroot: failed to run command 'bash': No such file or directory
You should see something about failing to run a shell or not being able to find bash. That's because bash is a program and your new root wouldn't have bash to run (because it can't reach outside of its new root.) So let's fix that! Run:
1. mkdir /new-root/bin
2. cp /bin/bash /bin/ls /bin/cat /new-root/bin/
3. chroot /new-root bash
chroot: failed to run command 'bash': No such file or directory
Still not working! The problem is that these commands rely on libraries to power them and we didn't bring those with us.
So let's do that too. Run ldd /bin/bash
root@d93ae2aee53d:/# ldd /bin/bash
linux-vdso.so.1 (0x00007ffec7767000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f3e95023000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3e94e1f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3e94a2e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3e95567000)
These are the libraries we need for bash. Let's go ahead and copy those into our new environment.
1. mkdir /new-root/lib{,64}
2. Then we need to copy all those paths (ignore the lines that don't have paths) into our directory. Make sure you get the right files in the right directory. In my case above (yours likely will be different) it'd be two commands:
cp /lib/x86_64-linux-gnu/libtinfo.so.5 /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libc.so.6 /new-root/lib
cp /lib64/ld-linux-x86-64.so.2 /new-root/lib64
3. Do it again for ls
. Run ldd /bin/ls
root@d93ae2aee53d:/# ldd /bin/ls
linux-vdso.so.1 (0x00007ffd4939c000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f817b198000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f817ada7000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f817ab36000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f817a932000)
/lib64/ld-linux-x86-64.so.2 (0x00007f817b5e2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f817a713000)
4. Follow the same process to copy the libraries for ls
to new-root
cp /lib/x86_64-linux-gnu/libselinux.so.1 /lib/x86_64-linux-gnu/libpcre.so.3 /lib/x86_64-linux-gnu/libpthread.so.0 /new-root/lib
Now finally, run chroot /new-root bash
and then ls
root@d93ae2aee53d:/# chroot /new-root bash
bash-4.4# ls
bin lib lib64 secret.txt
bash-4.4# cat secret.txt
my super secret thing
You should successfully see everything in the directory. Now try pwd
to see your working directory. You should see /
. You can't get out of here! This, before being called containers, was called a jail for this reason. At any time, hit CTRL+D or run exit
to get out of your chrooted environment.