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?

up vote 6 down vote accepted

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.

  • remount will fail if any file is open for writing. – sevo Feb 15 at 19:39

mount -o bind should do it for full directories.

mount -o bind /bin /chroot/bin
chroot /chroot

Would end up with a copy of your systems /bin inside the chroot.

To have your copy of bash supersede /chroot/bin/bash handle it the same way we do today, put it in /chroot/usr/local/bin and set PATH accordingly.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.