moby: Can't bind to privileged ports as non-root
The simplest way to reproduce this is:
$ docker run --rm -u 1000 php:apache
...
(13)Permission denied: AH00072: make_sock: could not bind to address [::]:80
(13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80
...
So, that led me to try this, but with the same result:
$ docker run --rm -u 1000 --cap-add NET_BIND_SERVICE php:apache
...
(13)Permission denied: AH00072: make_sock: could not bind to address [::]:80
(13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80
...
IMO, it seems reasonable to allow non-root to bind to privileged ports inside the container, especially since they have a private net namespace, so I was actually surprised this wasn’t already taken care of. I’m also confused as to why the --cap-add
didn’t work, but maybe that’s because it adds the cap to the whitelist of things to not remove, not necessarily adds it if it isn’t there? I’m grasping at straws here.
About this issue
- Original URL
- State: closed
- Created 10 years ago
- Reactions: 3
- Comments: 44 (39 by maintainers)
Commits related to this issue
- Add support for ambient capabilities Linux kernel 4.3 and later supports "ambient capabilities" which are the only way to pass capabilities to containers running as a non root uid. Previously there ... — committed to justincormack/docker by justincormack 8 years ago
- Add support for ambient capabilities Linux kernel 4.3 and later supports "ambient capabilities" which are the only way to pass capabilities to containers running as a non root uid. Previously there ... — committed to moby/moby by justincormack 8 years ago
- Add ambient capabilities gated by no new privileges This is a rework of support for ambient capabilities, to avoid the issues in the previous version, where there was a conflict between two use cases... — committed to justincormack/docker by justincormack 7 years ago
- Allow running the process as a non root user. I've chowned the /app directory in the container to node user. This allows the process to access the private key. However! I've not set the USER to nod... — committed to mendhak/docker-http-https-echo by mendhak 4 years ago
Just an fyi, for people that don’t want to deal with CAP_NET_BIND_SERVICE but would like to bind low ports; as of kernel 4.11, there is a sysctl that you can set in the network namesace will allow you to bind low ports[1]. If you are using a user namespace and you don’t have privileges in the network namespace, you will have to set it on the network namespace before hand, but for everyone else you can actually set it as part of docker run:
[1] http://elixir.free-electrons.com/linux/v4.11.8/source/Documentation/networking/ip-sysctl.txt#L832
Is there any actual risk to set
--sysctl net.ipv4.ip_unprivileged_port_start=0
on a container when that container is attached only to bridge networks (or actually, any network excepthost
)? After all, even if a process opens an extra low port from inside the container, it wont be accessible unless the port is actually exposed and mapped to an external port, from the host. And the possibility that a port that is expected to be legitimately opened be hijacked by an illegitimate process, is not greater with this config (relative to what it is now), since the illegitimate process would have to start before the legitimate process opens its port, so very early in the container launch sequence, at which time, the process would be running as root anyway in the current approach…What I mean by this is that setting
net.ipv4.ip_unprivileged_port_start
to 0 by default (that is, unless the container is attached directly to a network of type host) would appears to be a possible and reasonable solution, and most likely more secure than the status quo. Of course, this is arguably a patch, and yes this could be simply be highlighted in documentation. However, from the large number of outside tickets pointing to this one, it seems to be a very common issue, and it appears that many people, if not most, ends up lowering their security (by running their container as root) because they failed to find documentation on how to fix the issue by themselves.Seems like this can be closed 👼
Definitely not here - those things make life hard. 😄
Ok, opened a new PR for
runc
https://github.com/opencontainers/runc/pull/1286 and will open an updated one here soon.