undocker - Running Docker containers from unprivileged users
There are many tools for running containers (e.g. LXC, Singularity, udocker, etc.) but docker is probably the most popular of them.
But some sysadmins do not want to let their users to run Docker containers because of security concerns.
The objective of
undocker is to enable sysadmins to let the users run Docker containers using their user credentials (i.e. the containers will be processes owned by the user and not by root).
undocker inspects the parameters to docker, removes the dangerous parameters and adds some parameters that should be included depending on the user. It also enables to limit the docker images that each user may use.
In this case you need to install the runtime
bashc, that can be obtained from here.
In this case you will need to install the dependencies of
$ git clone https://github.com/dealfonso/undocker $ cd undocker $ make $ DESTDIR=/ make install
Get the appropriate package from the releases page and follow the instructions.
$ yum install ./undocker.rpm
$ dpkg -i ./undocker.deb $ apt update $ apt install -f
$ apt-add-repository ppa:grycap/apps $ apt update $ apt install undocker
Once undocker is installed, any user can call undocker to try to call docker. How the users can interact with undocker is configured in the file
/etc/undocker.conf (that must be readonly for any user).
The configuration file describes the commandlines that the users are allowed to run. It is possible to specify specific permissions depending on linux groups or users.
Description of fine tune features
Let's use this configuration (taken from the distributed
.conf file) as an example:
[command:run] WHITELIST=--help,-i|--interactive,-t|--tty,-d|--detach,--rm,-e|--env list,-v|--volume list,-w|--workdir string,--name string FORCED=-u $U_UID:$U_GID -v '$PWD:$PWD' -w '$PWD' ALLOWEDIMAGES=alpine:.* ubuntu:.* [command:run group:users] RESTRICTEDIMAGES=ubuntu:14.04 [command:exec] WHITELIST=--help,-i|--interactive,-t|--tty,-v|--volume list FORCED=-u $U_UID:$U_GID -v '$PWD:$PWD' -w '$PWD' UIDMUSTMATCH=true
If a section
[command:<command name>] appears, then the command is allowed to be run by the users, with the restrictions that are defined in that sections.
i.e. if a section (e.g)
[command:exec]does not appear in the configuration file, the users won't be able to issue
undocker exec ...commands.
Then the allowed flags must be defined in the
WHITELIST variable. The flags may use a pipe separation to explain that the flags are equivalent (e.g.
-t|--tty). If the flag has parameters, they must be included in the definition (e.g.
The list of parameters can be obtained from the
In the case of
[command:run], we are allowing to use a set of parameters (e.g.
-d), but not other that we consider dangerous (e.g.
FORCE is also enabled, that forces a set of parameters to appear in the final call. In our case,
-u $U_UID:$U_GID -v '$PWD:$PWD' -w '$PWD'. That means that the docker call will include the credentials of the user that is calling undocker (and not root), and the container will have the current folder mapped into the container (and it will be the working folder in the container).
The parameters in variable
FORCE appear just after those parameters used by the user. So they have more priority (that means that (e.g.) if the user included other
-w option, the one valid is the forced one).
It is possible to limit the images that the users are able to use, by using variables
RESTRICTEDIMAGES. These variables may include a list of space separated names of docker images (it is possible to use regular expressions).
In the case of
[command:run] we are allowing any alpine standard image, along with any ubuntu standard image.
specific permissions for groups and users
It is possible to specify options for a group of users or a individual user, by including sections with the form
[command:<command name> group:<group name>] or
[command:<command name> user:<user name>].
Each section that begins with
[command:<command name>] is accumulated to create the final permission set. The order of preference is
[command:<command name> group:<group name>] and
[command:<command name> user:<username>]. That means that the specific setting for an individual user have more preference.
WHITELIST is the accumulation of
WHITELIST. The same applies for
In our example, if a user belongs to group
users, he will be able to use any
alpine image and any
ubuntu image, except from
preventing the usage from other's containers
Each command that accepts a container name as a parameter can be forced to be used only if the referred container was started by the user.
That is made by setting the variable
true. In our example, a user can make a
docker exec call to a container (e.g.
docker exec -it <conainername> bash) if he started the container (i.e. the container has his credentials).
How undocker works
undocker is based in the existence of the application
/usr/bin/undocker-rt. This application creates the safely constructed commandline and calls
In order to make the final call to
docker, needs to raise permissions to be able to make a final call to docker. It can be made in two ways: using
sudo or a setuid application.
In any case, the application
/usr/bin/undocker-rt must be readonly for any user except from root, to prevent users from unauthorized modifications.
SUDO mode (preferred).
A sudo configuration is needed. The distribution of undocker includes the proper configuration, that enables any user to
sudo the application
The content of
/etc/sudoers.d/undocker is the next:
An application with u+s permissions and owned by root has to be installed in
/usr/bin/undocker-rts. That application simply calls
/usr/bin/undocker-rt, but having "root" permissions. In this way, it is avoided the usage of sudo.
The permissions for file
/usr/bin/undocker-rts look like this:
$ ls -l /usr/bin/undocker-rts -rwsr-xr-x 1 root root 8880 jun 6 17:46 /usr/bin/undocker-rts
On container runtimes security
While most of other container runtimes are limited to run containers using the user's credentials by default (e.g. Singularity has that way of working, or LXC that uses user-namespace remapping, using
subgid), Docker does not work like that.
While Docker can also remap users to make it more secure. Its default working mode is to run a daemon under root credentials and thus run the containers using that credentials.
root credentials are needed for running most of containers (otherwise they will probably be a simple
chroot). And the other runtimes also use them:
- LXC: runs the daemon as root, but starts give the containers other uid.
- Singularity: uses a setuid application that gives root privileges to the singularity runtime (* singularity can work without that setuid mode, but they recognise that most of the functionality won't work).
- udocker: the containers are not full featured containers, as it aims at being (more or less) a simple chroot on a Docker container filesystem to take profit from the installed applications.
How to secure Docker containers
One of my premises on Docker security is...
The best way to let the users run Docker containers is not to let the users run Docker containers
But I can rewrite the prase to
The best way to let the users run Docker containers is not to let the users run arbitrary Docker containers
And this is the key work: arbitraty.
A security aware sysadmin should not let arbitraty users to run arbitrary Docker containers under root credentials.
$ docker run --privileged -it alpine ash
$ docker run -it alpine ash
$ docker run -u $(id -u):$(id -g) -it alpine ash
And that is how undocker works. It analyzes the commands issued by the user and removes the prohibited ones (e.g.
--dev) and forces some other (e.g.
-u $(id -u):$id -g)).