3

Alice and Bob are both members of the docker group on the same host. Alice wants to run some long-running calculations in a docker container, then copy the results to her home folder. Bob is very nosy, and Alice doesn't want him to be able to read the data that her calculation is using.

Is there anything that the system administrator can do to keep Bob out of Alice's docker containers?

Here's how I think Alice should get data in and out of her container, based on named volumes and the docker cp command, as described in this question and this one.

$ pwd
/home/alice
$ date > input1.txt
$ docker volume create sandbox1
sandbox1
$ docker run --name run1 -v sandbox1:/data alpine echo OK
OK
$ docker cp input1.txt run1:/data/input1.txt
$ docker run --rm -v sandbox1:/data alpine sh -c "cp /data/input1.txt /data/output1.txt && date >> /data/output1.txt"
$ docker cp run1:/data/output1.txt output1.txt
$ cat output1.txt
Thu Oct  5 16:35:30 PDT 2017
Thu Oct  5 23:36:32 UTC 2017
$ docker container rm run1
run1
$ docker volume rm sandbox1
sandbox1
$ 

I create an input file, input1.txt and a named volume, sandbox1. Then I start a container named run1 just so I can copy files into the named volume. That container just prints an "OK" message and quits. I copy the input file, then run the main calculation. In this example, it copies the input to the output and adds a second timestamp to it.

After the calculation finishes, I copy the output file, then remove the container and the named volume.

Is there any way to stop Bob from loading his own container that mounts the named volume and shows him Alice's data? I've set up Docker to use a user namespace, so Alice and Bob don't have root access to the host, but I can't see how to make Alice and Bob use different user namespaces.

Don Kirkby
  • 53,582
  • 27
  • 205
  • 286

1 Answers1

3

Alice and Bob have been granted virtual root access to the host by being in the docker group.

The docker group grants them access to the Docker API via a socket file. There is no facility in Docker at the moment to differentiate between users of the Docker API. The Docker daemon runs as root and by virtue of what the Docker API allows, Alice and Bob will be able to work around any barriers that you did try to put in place.

User Namespaces

The use of the user namespace isolation stops users inside a container breaking out of a container as a privileged or different user, so in effect the container process is now running as an unprivileged user.

An example would be

  • Alice is given ssh access to container A running in namespace_a.
  • Bob is given ssh access to container B in namespace_b.

Because the users are now only inside the container, they won't be able to modify each others files on the host. Say if both containers mapped the same host volume, files without world read/write/execute will be safe from each others containers. As they have no control over the daemon, they can't do anything to break out.

Docker Daemon

The namespace doesn't secure the Docker daemon and API itself, which is still a privileged process. The first way around a user name space is setting the host namespace on the command line:

docker run --privileged --userns=host busybox fdisk -l

The docker exec, docker cp and docker export commands will give someone with access to the Docker API the contents of any created containers.

Restricting Docker Access

It is possible to restrict access to the API but you can't have users with shell access in the docker group.

Allowing a limited set of docker commands via sudo or providing sudo access to scripts that hard code the docker parameters:

#!/bin/sh
docker run --userns=whom image command

For automated systems, access can be provided via an additional shim API with appropriate access controls in front of the Docker API that then passes on the "controlled" request to Docker. dockerode or docker-py can be easily plugged into a REST service and interface with Docker.

Matt
  • 68,711
  • 7
  • 155
  • 158
  • Thanks for the details, @Matt. Can you clarify your comment on user namespace isolation? My understanding is that it lets you run an application as a root user inside the container without giving you root access to the host. For example, on mounted volumes. Doesn't that avoid giving members of the docker group root access to the host, or can they override the user namespace when they launch docker commands? – Don Kirkby Oct 06 '17 at 16:45
  • The user namespace works like that when the user is inside the container, but if the user you are trying to restrict has control of Docker itself, they can do anything. I've fleshed that out in the answer a bit more. – Matt Oct 07 '17 at 01:02
  • Thanks for the extra details. I wrote a [wrapper](https://github.com/cfe-lab/Kive/blob/518916d14ffee7a1d5c4113e2599ff1947618452/kive/fleet/docker_wrap.py) in Python that creates a volume, copies input files, runs the requested image, copies output files, and cleans up. Then I granted Alice and Bob sudo access to the wrapper with the image specified. That should keep them out of trouble. – Don Kirkby Oct 13 '17 at 00:08
  • Cool! The docker commands can be done directly to the API with [`docker-py`](https://github.com/docker/docker-py) as well, if you get tired of dealing with the shell-isms – Matt Oct 13 '17 at 00:20
  • Oh, I see I am repeating myself =) – Matt Oct 13 '17 at 00:23
  • I might look at `docker-py` eventually, but right now, I think a single-file install avoids hassling with virtual environments. – Don Kirkby Oct 13 '17 at 20:21