One of the things about Docker is that whilst it provides you with a sane set of defaults from a security persective, it’s still pretty easy to quickly reduce the level of security/isolation provided if you deviate from those defaults without understanding the consequences.
At the moment the Docker Engine authorization model is pretty basic (although there’s now a plugin API available, so hopefully this will improve soon). Essentially a process which can access the docker socket (usually at /var/run/docker.sock) or who can connect to the HTTPS API, can execute any command that the docker service can run, which generally provides access to the whole host system as the docker service runs as root.
Where this can trip you up is where you might want to provide access to the Docker socket to a container to allow a process running in that container to extract information about other containers running on the service. This is typically done by mounting the Docker socket into the container with a switch like
There are a couple of projects that I’ve noticed so far which do this, one of the more popular is nginx-proxy which uses access to the Docker socket to allow it to automatically create reverse proxy entries for other containers.
The only real access control that’s possible with this kind of set-up is that you can set the access to be read only (e.g.
-v /var/run/docker.sock:/var/run/docker.sock:ro), however this could still be risky, depending on your configuration as commands like
docker inspect can leak secret information about running containers. (Also see the update below)
For example the official Docker postgres image provides a startup command of
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres which uses an environment variable to set the postgres password. So if another container gets access to the docker socket, they can extract that password from docker inspect and then likely make a connection straight to your database (unless you’ve disabled Inter-container commmunication ).
So in general I’d recommend thinking very carefully before making use of a Docker image that requires access to the Docker socket, even with read-only permissions as it could open your environment up to some additional risks. Hopefully with future developments on the Docker authorization model it’ll get easier to allow a container introspection in a less risky manner…
Update - After tweeting this article out @benhall pointed out that actually the
ro setting on the volume mount doesn’t have a lot of effect in terms of security. An attacker with ro access to the socket can still create another container and do something like mount /etc/ into it from the host, essentially giving them root access to the host. So bottom line is don’t mount docker.sock into a container unless you trust its provenance and security…