Chroot jail that can access the filesystem

chrootSecurity

chroot jails seem to be simply a different world, with no interaction with the actual filesystem. Thus, the entire environment has to be replicated inside the chroot, which would mean making a full installation of a system inside it.

However, is there some way to make the chroot jail have read access to the main filesystem? Additionally, I would also like to have the ability of the chroot preferring its own files. For example, if /usr/bin/wget exists within it, then that should be preferred over the system's /usr/bin/wget.

(I'm actually looking for something that behaves like Sandboxie.)

Is the above feasible?

Best Answer

You can bind-mount directories into your chroot root with:

mount -o bind /x/y /chroot/x/y

(see man mount, section "The bind mounts"). Any access to /chroot/x/y from now on acts exactly like an access to /x/y: same file listings, same contents, same inodes.

Note, however, that this puts the entire directory in as-is: a process inside the chroot that can write to the directory will be able to write to the "real" directory outside. If you want to make the mount inside the chroot read-only you need to remount explicitly read-only after the bind:

mount -o remount,ro /chroot/x/y

The original /x/y will remain read-write, but the copy will now be read-only.

To prefer internal copies of files, or to allow writing in some existing files or directories without affecting the originals, you can use a union file system. These let you overlay multiple directory trees on one another, specifying where writes go to and the order that reads are resolved. Common union filesystems for Linux include aufs, Unionfs, and unionfs-fuse. The first two of those are kernel modules, while the last uses FUSE to run a filesystem in user space. The kernel modules are generally faster, but the FUSE version may be easier to set up, although you may want to avoid using external user-space tools from your chroot anyway. You can prepare the union filesystems you want and then chroot into them.

In each case the basic approach is the same, something like:

unionfs-fuse -o cow /jail/bin:/other/bin:/bin /chroot/bin

This creates a union mount in /chroot/bin which gives the files from /jail/bin priority if they exist, then try /other/bin/, and otherwise shows the files from /bin. -o cow makes it copy-on-write: attempts to write to, say, /chroot/bin/foo will copy /bin/foo to /jail/bin/foo and save the modifications there. If you don't want that behaviour, leave the option out. The other filesystems have slightly different configurations, but the principle is the same.

Whichever way you set it up, you could then:

chroot /chroot

and have everything work the way you wanted.

Related Question