How can we deny Docker developers root privileges from their containers?

We are setting up a Ubuntu machine for developers as a “playground” for learning Docker, and for testing out new images before they are put into production. (Most of our desktop PCs run Windows, so this is to provide a native *nix Docker environment.)

By default, a container runs with root privileges within the container. Inside the container, abusing those privileges that doesn’t hurt anyone but the user starting it - the next user of the same image will run a virgin container, unaffected by any other run. The user may at container startup mount a volume containing his input files, and ready to receive his output files. (This is our standard working mode.) A malicious user could destroy or otherwise affect the files in the volume that the user has provided himself. Why would he?

But… The user may mount / - the root directory. The container code may access the entire file system with root privileges. If a shell is provided (e.g. in the Ubuntu base image), you can start the container with the -it options and broswe the entire file system manually, unrestruicted by access limitations. Sure, the root privileges outside the container is restricted to what you can do by file system operations - but in *nix, that is quite a lot!

Those running Linux on their desktops have sudo access to that machine, so whatever malice they can do from a Docker container, they can do by sudo - but it affects only their own, private desktop. It is different on a shared, central Playground machine - they could create havoc for other users, and they could gain access to e.g. NDA-protected code of other projects that are doing tests in the same sandbox.

Fortunately, we do not have many developer with malicious intentions :slight_smile: Yet, I suspect that a security audit may be critical to this, considering that the playground is a resource shared by all sorts of projects.

Is there any way to keep developers from creating containers running with root privileges? Or any way to prevent users from mounting volumes with files they do not have access to (or rather: filter the container’s access to the volume by the rights of the running user), in a way that cannot be circumvented by the users?

Production images create no problems: They always define a non-root user. But as long as we let developers build their own images, we see a certain security risk. We more or less “must” allow our developers create new test versions of images!

What you need can not be done with docker alone.
Though, it seems like a perfect fit for “rootless docker” (https://de.slideshare.net/AkihiroSuda/dockercon-2019-hardening-docker-daemon-with-rootless-mode)

Even with a normal docker installation, at least two methods can help to enforce what you need:
– prevent access to Dockerhub on network level. Host “safe” (non-root user) images on your own docker image repository and only allow the users to use those
– You could provide your normal users access to docker using a wrapper script. Inside your wrapper script you could whitelist/blacklits whatever you want. In a couple of our productive environments, our ops team encapsulated the docker-cli this way.

Look for ‘user namespaces’. It’s the prescription for what ails here. It maps the user ID in the container to non privileged users on the host. So, root in the container is actually some non root user in host.

1 Like

Rootless mode is officialy part of todays Docker 19.03 release:
Running dockerd as a non-root user (Rootless mode) is now allowed. moby/moby#380050

Haven’t tried it myself but you may want to check out Singularity

Look at Sysbox; it’s a new open-source container runtime (aka runc) that enables Docker to create rootless containers that act like VMs, inside of which you can run systemd, Docker, and even Kubernetes easily and full isolation from the underlying host.

That is, you deploy the container with docker run --runtime=sysbox-runc -it ubuntu, and inside of it you can install and run Docker (CLI + daemon) in total isolation from the host. It essentially voids the need for privileged containers. This dockerhub repo has several images that come preinstalled with Docker already (and even systemd if you need it).

It’s different from rootless Docker, because rootless Docker hardens the Docker daemon on the host via a user-namespace; Sysbox does not harden the Docker daemon on the host, it hardens the containers generated by it and additionally enables them to run system software such as Docker inside.