How to run a command in a chroot jail not as root and without sudo?

Viewed 48366

I'm setting up a minimal chroot and want to avoid having sudo or su in it but still run my processes as non-root. This is a bit of a trick as running chroot requiers root. I could write a program that does this that would look something like:

uid = LookupUser(args[username])  // no /etc/passwd in jail
chroot(args[newroot])
cd("/")
setuids(uid)
execve(args[exe:])

Is that my best bet or is there a standard tool that does that for me?


I rolled my own here:

6 Answers

These days chrooting without root-permissions is possible with unshare command provided by mount namespaces.

Plain Unshare

Suppose you want to chroot into ~/Projects/my-backup directory, and run inside it the ~/Projects/my-backup/bin/bash binary . So you run:

$ unshare -mr chroot ~/Projects/my-backup/ /bin/bash

Here:

  • -m means you can use mount --bind inside the new chroot (note that mounts will not be visible to the outside world, only to your chroot)
  • -r makes it look as if you are root inside the chroot
  • chroot … is the usual chroot command.

Possible pitfalls:

  1. Make sure you have environment variables set correctly. For example, upon chrooting into an Ubuntu from Archlinux I was getting errors like bash: ls: command not found. Turned out, my $PATH did not contain /bin/ (on Archlinux it's a symlink to /usr/bin/), so I had to run:

    PATH=$PATH:/bin/ unshare -mr chroot ~/Projects/my-backup/ /bin/bash
    
  2. Note that /proc or /dev filesystems won't get populated, so running a binary that requires them will fail. There is a --mount-proc option, but it doesn't seem to be accessible to a non-root user.

  3. chown won't work unless you do some complicated setup with newuidmap and newgidmap commands.

Buildah Unshare

This has advantage compared to plain unshare in that it takes care of the needed setup for chown command to start working. You only need to make sure you have defined the ranges in /etc/subuid and /etc/subgid for your user.

You run it as:

$ buildah unshare chroot ~/Projects/my-backup/ /bin/bash
Related