[an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive]

Chrooting for mortals

I recently set up a simple way for people to run their own chrooted services without being root. Non-geeks/sysadmins should probably stop reading now. Oh, and if you do count yourself as one of the above and don't know what a chroot is or when to use one, well... google for it (just now, this paper seems to be a good introduction).

So we want our users, not running as root, to be able to run chrooted services. It seems like a simple problem, doesn't it? But the chroot call is only available to the root user, so we need a simple way of allowing users to run the chroot call as root, and then depositing them safely back at their own uid so they can't break out of the chroot as root. There's no magic in this, but I'd not seen any examples of people doing anything equivalent, so I thought it was worth documenting.

Someone pointed out after reading this article that dchroot, a Debian developer tool, may be able to do the same thing, but I've not looked at it, so I can't comment on how suitable it is for what I'm doing.

The nice thing about this approach is that it achieves privilege separation for the user, without having to worry about SE Linux policies or separate per-user daemon accounts.

We need:


  1. Create an empty directory that will be your chroot, and have it owned by your mortal. Note that this configuration (the user-owned chroot) is only secure because we aren't running anything inside the chroot as the root user, because we change user with the chrootuid program (which is stored outside the chroot). The more obvious way, to use su inside the chroot, exposes your root user to running trojanned commands supplied by your mortal (and the root user inside a chroot can break out of the chroot). Having a SUID-root binary inside the chroot also introduces another attack vector, of course.
  2. As your test user, populate the chroot with the files needed to run your daemon. For the statically linked network daemon I tested with, literally all I needed was /etc/resolv.conf, /etc/hosts, and the daemon and its configuration file.
  3. Configure sudo, userv or similar to run one of these two commands if asked to do so by just your test user:
    • chrootuid /some/chroot testuser daemon daemon-args. This will allow the user to just run the daemon inside the chroot. In this instance, you can use suppress-args in userv for absolute paranoia.
    • chrootuid /some/chroot testuser. This way, the user can execute anything he likes inside the chroot, as his user. Which is best will be context-dependent. Note however that userv won't report errors in running chrootuid back to the user in its default configuration, but syslogs them, so if they just try to run that bare command nothing will happen, but an error will be reported in syslog that they should specify a program to run.

So with userv, the user would run a command like: userv root chroot-test in the first instance, and userv root chroot-test /bin/bash in the second (however the user should be made aware that leaving shells lying around in the chroot is a bad plan). Remember that the user can manipulate files in the chroot from outside the chroot, so in general there shouldn't be any need for this second version.

That's it, but for some final points:

[an error occurred while processing this directive] This page last updated: Wednesday, 05-Jan-2005 01:04:46 GMT
You are connected with [an error occurred while processing this directive] IPv6 from

My email address

This site © 1997-2009 Dominic Hargreaves. This web site is a minimum of four years out of date, and some parts much more so.