userchroot
is used heavily by the
buildbox
ecosystem to
provide a simple and lightweight build sandbox. Therefore, primary maintenance
of userchroot
now takes place over at
buildbox/userchroot. This
repo will soon be archived.
The chroot(2) system call can be used to
provide a restricted or new view onto an existing filesystem and thus has
applications in build sandboxing. Normally it can only be invoked by an
appropriately privileged user possessing the necessary capabilities or
privileges. userchroot
allows you to safely workaround that limitation,
provided it can be installed and configured by a user with the requisite
power. userchroot
allows you to create pre-defined chroot locations and allow
unprivileged users to safely run processes within those predefined
environments.
We use it at Bloomberg to allow non-privileged users to run builds on a chroot'd environment on Linux x86_64, Solaris sparc, and AIX powerpc. This provides sandboxing and consistent repeatability to builds across those platforms.
It is similar to schroot and bubblewrap.
There are some devices that so many processes expect to exist, that when provisioning ephemeral chroot locations as a non-privileged user you may need to make available. Those devices are:
- /dev/zero
- /dev/random
- /dev/urandom
- /dev/null
- /dev/poll (Solaris only)
- /dev/shm (Linux only)
The userchroot command offers a "--install-devices" and "--uninstall-devices" that will allow a non-privileged user to create and destroy those devices.
This allow us to run the entire build infrastructure as a non-privileged user.
There is very little build-time customization, so we provide a simple Makefile that will use the implicit rules in order to build the executable.
make
This variables (defaults to /usr/local
) controls the default base path to the
CONFIGFILE.
This variable (defaults to /etc/userchroot.conf
) will set the path for the
config file.
This tool will check for the config file in two places:
$(PREFIX)/etc/userchroot.conf
/etc/userchroot.conf
$(PREFIX)
defaults to bldroot
in the Makefile.
The tool will verify that the file as well as the entire path leading to the file is root owned, has limited permissions and is not a symbolic link.
This variable (defaults to an ident string created with git describe --tags
). This will be stored in a static string in the executable for
identifying the version with ident
.
We include a compat implementation of clearenv for architectures where that system call is not available. This is evaluated by the makefile by using the test-clearenv.sh script.
When running inside a Solaris zone, you will not be allowed to use mknod. As an alternative, the tool will allow you to use a lofs mount to the system location for the fundamental devices.
On Linux we also create /dev/shm and mount it as a tmpfs, since the GNU Libc will not only expect that location to exist, but it will also check that it is actually a tmpfs location. Without this, named pipes do not work on Linux.
On Solaris, we mount the kernel poll device at /dev/poll. This is a
Solaris-only replacement for select
and poll
.
The executable needs to be setuid root, but it must not be setgid root. In fact, it will validate that you haven't given too much permissions to it.
The config file must have the a path to a pre-approved chroot directory and the name of the user that owns that directory. In the format:
user:/path/to/userchroot/base
Then any user will be able to run
userchroot /path/to/userchroot/base/myimage some command
As well as:
userchroot /path/to/userchroot/base/myimage --install-devices
or
userchroot /path/to/userchroot/base/myimage --uninstall-devices
As long as:
- The entire path leading to /path/to/userchroot is owned by root and doesn't have open permissions.
- The directory /path/to/userchroot/base is owned by the configured user and doesn't have open permissions.
- The directory /path/to/userchroot/base/myimage is owned by the configured user and doesn't have open permissions.
This will result on some command
being invoked after performing
the chroot to the location and dropping the privileges back to the
calling user.
// ----------------------------------------------------------------------------
// Copyright 2015 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------