Introduction
Not overly recently, I was asked to configure a chroot jail by setting up bind mounts instead of copying over the correct binaries. The incident caused a really interesting system failure, a wake-up call to myself, and an ambitious project to create an autochroot command (more later).
The Back Story
When setting up a chroot jail it’s well known that all the binaries and references that will be used in that jail need to be inside that jail. This creates quite a complicated configuration for something even as simple as creating a chroot jail that only has bash and bash internals in it. Not only do we need to create a clean directory structure and duplicate our file system hierarchy but we also need to create all the dependencies (and for bash this quickly grows):
ldd /bin/bash
linux-vdso.so.1 => (0x00007fff189ff000)
libncurses.so.5 => /lib/libncurses.so.5 (0x00007f6ca8604000)
libdl.so.2 => /lib/libdl.so.2 (0x00007f6ca8400000)
libc.so.6 => /lib/libc.so.6 (0x00007f6ca809a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6ca8854000)
Once all the dependencies are in place, the proper items to do work in this minimal shell environment also need to be installed. This may include device nodes or system environment files (e.g. /etc/passwd, /etc/shadow). Which make some commands a real pain to install in a chroot by hand (e.g. /usr/bin/ssh, /usr/bin/scp, etc).
The Problem
So, it’s hard; that’s not a big deal. There are ways to make this easier. Things like bind mounts:
mount -o bind
These handy features allow you to take any directory in the system and mount it somewhere else. These become extremely useful when setting up a chroot environment for system recovery via a livecd but can be a ticking time bomb if used incorrectly.
Alright, let’s solve our chroot problem with bind mounts, but I bet you can guess by this point how it’s going to be accomplished. We’re simply going to mount all of the necessary areas of the external filesystem inside the chroot:
mount -o bind /dev /chroot/dev
mount -o bind /lib /chroot/lib
mount -o bind /usr/lib /chroot/usr/lib
Now, that chroot was much easier to set up and work with, but what happens if an unsuspecting party does the unthinkable: `rm -fr /chroot`. They’re simply cleaning up a chroot environment that doesn’t need to be used anymore, right? Unfortunately, that’s not the case. This will remove all files in /chroot including /dev, /lib, /usr/lib, etc.
The Lesson
Don’t ever use bind mounts in chroot environments unless you know exactly what you are doing! Even then, it may be best practice to simply not use bind mounts. You may be thinking, why can’t we simply mount these points readonly? Unfortunately, bind mounts aren’t that smart. This is what happens when you attempt a bind mount readonly:
mount -o bind,or /proc /mnt
mount: warning: /mnt seems to be mounted read-write.
mount
/proc on /mnt type none (rw,bind)
Not quite what we were looking for and unfortunate for our quick solution.
Conclusion
Never use bind mounts for a chroot environment (except maybe livecd chroot environments). It may take more time but copying the necessary binaries to the chroot is much safer and will keep your system from any inadvertent harm.
Now, I mentioned that I came up with a much more ambitious solution to this problem, autoroot. This small utility (when finished) will be able to take a directory and list of binaries and automatically create an appropriate chroot environment. The system should be smart enough to take into consideration different distributions and installation points (a current limitation of existing solutions).
Sorry, the comment form is closed at this time.