Please for the love of all that is holy, do not ever do this! Giving access to the host's Docker socket is equivalent to giving a container unrestricted root access to your host. Mounting the socket read-only doesn't protect you in any way either, because you can still connect to and write to the socket! Seriously, try it:
% touch /tmp/docker.sock
% mount --bind -o ro /var/run/docker.sock /tmp/docker.sock # this is -v /var/run/docker.sock:/foo:ro
% docker -H unix:///tmp/docker.sock run --privileged -v /:/host -it ubuntu bash
# # I couldn't write to it, but I can connect and write to the connection...
# cat /host/etc/shadow # whoops!
To be fair, there are unix-like DAC controls that do restrict this somewhat but given that most people run containers as root or they don't use user namespaces this is still an issue.
Please stop doing this, please stop telling people to do this, and please stop making images that access docker.sock. I understand that this is something that a lot of people do, so it's obviously not exclusively the fault of the author for doing what the majority of people appear to be doing, but I think that this deserves to be said much stronger than it was in the past (people still expose Docker over the internet -- which is literally a free root-level RCE for anyone who figures out you're hosting it).
And yes, AuthZ plugins exist but nobody really uses them as far as I'm aware -- and personally (as someone who maintains container runtimes and other low-level container tools) I would not feel confident in depending on any AuthZ plugin's profile to protect against a container escape where you give unprivileged users access to /var/run/docker.sock. Even if I were to write one.
It seems like if the author(s) of docker-letsencrypt-nginx-proxy-companion had assumed something like docker compose or kubernetes that neatly handles sharing volumes between containers, they probably wouldn't have made the mistake of giving a docker container access to docker for such a trivial use.
I disagree that there's never a good reason to do this though. A docker control panel, or a CI or FaaS that spawns docker containers, can be a good reason to do this. https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-d...
BTW there's no escaping the container when you're doing this intentionally.
The number of cases where it is an acceptable idea to do this (compared to the number of cases where people do this because they read it on a random blog post) is so small that it is statistically insignificant. In my view, it is much better to tell people to never do something which is very rarely useful. People who know better would know when to ignore that warning (which I would hope would be the sort of people who would write a CI or FaaS), while those who don't know better likely wouldn't use it in a way that is "safe".
The blog post you link to is quite old (this was at a time when most users were well aware of what docker.sock did -- so much so that vulnerabilities I helped find in Docker from that time were not regarded vulnerabilities because they required docker.sock access!). I agree with Jerome's point which was to dissuade usage of Docker-in-Docker. His point was not that bind-mounting the docker.sock is generally an okay thing to do -- and as I said I think that we should be far more vocal about how dangerous this is (because people don't listen otherwise -- as has been shown by the fact that there are still plenty of users that have Docker listening on a TCP socket without client certificates).
> BTW there's no escaping the container when you're doing this intentionally.
I don't know what you mean by this -- if you bind-mount the docker.sock inside a container that container can trivially get root access on the host (AuthZ plugins can make it harder but as I said they are rarely used and cannot protect you from sufficiently clever attackers). My demo with 'mount --bind' was just to show how it worked, the same thing happens with '-v' (which is just a bind-mount under the hood).
Now, if you argue that the code in the container is always something you trust (which I think is a questionable assumption as it assumes that your code is not exploitable) then sure -- if all the code on your machine is safe you have no worries. But then the obvious question arises -- why do you need the isolation properties of containers in the first place? Why not just run in a chroot?
Docker containers are about more than isolation, they're also packaging. In my case, I already have a docker-compose.yaml with five services; adding another program as a chroot instead of a sixth service would significantly increase the installation complexity.
I do agree with you that mounting the Docker socket should never be recommended on a tutorial.
But I might be biased given that while I've worked on both runtimes and image tools, runtimes have a lot more interesting problems so I tend to focus more on them when discussing the benefits of containers. :P
On the second point, I mean that to call it escaping the container is incorrect. If they are given access to the docker socket intentionally, the expectation that it wouldn't be able to do anything with the server outside the container is gone.
We'll have to agree to disagree on this one. I originally wrote a longer explanation of how you need to distill an argument in order for non-domain-experts to get the gist, but if you think I'm manipulative there's not much to be said.
There is an argument to be made that any misconfiguration has a specific niche usecase (otherwise it wouldn't be configurable) -- so telling people to not do something is always "manipulative". But we have security best practices, and we tell people not to misconfigure things. There is a time when you should use 'curl --insecure' but we tell people not to use it because those who know when to use it also know when it is safe to use it.
> And your experience doesn't represent the whole of how Docker is used. [...] This is mixing different uses of Docker.
But running an node package as an unprivileged user on the host doesn't give it free root access on your machine. 'docker run -v /var/run/docker.sock:/var/run/docker.sock:ro' does, and so while you might argue that isolation is not a property everyone is interested in (which might very well be true[+]), the net result is a setup that is more insecure than the equivalent host-side setup (nobody runs node packages as root on the host in production I would hope).
> I mean that to call it escaping the container is incorrect.
It's not though. You are in a container and then you use a misconfiguration to break out of it. Just because it's trivial -- and it is very trivial -- doesn't make it not a container escape. You would use the exact same techniques to break out of a container that had a "real" container escape vulnerability -- namely `nsenter --mount=/host/proc/1/ns/mnt` or similar.
If someone misconfigured sudo on some ISO image to permit everyone to have root access, that would still be a privilege escalation vulnerability even though it caused by an intentional misconfiguration. It might not be as neat as other vulnerabilities, but it is still a vulnerability.
> If they are given access to the docker socket intentionally, the expectation that it wouldn't be able to do anything with the server outside the container is gone.
You say that from a position where you know that docker.sock access is equivalent to root host access. Many people are not aware of this, and are not told this when they are told to bind-mount docker.sock into containers that have potentially insecure software running in them. If everyone knew that this was the case, you might be right in arguing that you've already given up container (or even user) isolation at that point -- but it's not clear enough in my opinion.
[+]: Though I don't see why you should undermine it needlessly -- given that it is the most expensive and complicated parts of setting up a container. Images are effectively just tar archives.
Fortunately ducaale suggested https://hub.docker.com/r/steveltn/https-portal/.
I adapted the site and will publish a follow-up about using this image for nginx - let's encrypt configuration.
By default, docker-machine (which sets up internet-accessible docker instances) uses TLS client certificates, so no, this does not give a "free root-level RCE". This is just spreading FUD. (This does not detract from the parent's point that "access to docker.sock" == "root on the host". That part is true.)
I didn't mention TLS certificates with -H tcp:// because it wasn't really related to the main point I was making -- yes you can configure it to be secure but again security is not the default. I felt so strongly about this I pushed for having a required flag to allow insecure TCP access. I am more than aware this can be done safely, it just isn't done safely often enough that you see this type of misconfiguration in blog posts.