New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't bind to privileged ports as non-root #8460
Comments
Maybe I've even just got the wrong CAP I'm trying to add. |
Essentially we'd love to drop the |
+1 (you got the right cap, but the cap also has to be granted to the process I believe) |
Do you have anything else like apparmor or selinux? |
Definitely not here - those things make life hard. 😄 |
I don't mind if only root is allowed to bind to privileged ports (to mimic containerless environments), but our deployment approach uses authbind to give the permission to other users. Unfortunately, authbind doesn't seem to work in Docker (I always get Permission denied when attempting to bind regardless). |
An even more simple example:
Further capsh indicates that cap_net_bind_service is included:
Running on boot2docker:
Versions:
What is the guidance? Is this supposed to work? |
This fails with --privileged as well, fyi. |
The issue here is that the process's effective capabilities don't have Example to get it working for nc:
|
@mrunalp don't we have Docker backends that don't properly support those cap bits though? |
@tianon There is really no other option here besides using user namespaces or setting caps on files :( |
so setting the executables as suid root (even worse) |
@mrunalp you've got me intrigued with mention of user namespaces -- do you just mean mapping the non-root user to be host root, or is there some other feature of user namespaces that makes privileged port mapping possible as non-root without setting caps on files? 😄 |
@tianon In case of user namespaces, the container process uid is 0 inside (and non-zero outside). When a process with uid 0 execs a binary (irrespective of which user namespace it belongs to), the rules for capabilities for root apply and it gains all the capabilities in its permitted and effective sets except those masked by the bounding set. So, from a capabilities perspective it will behave just like regular root and since we have CAP_NET_BIND_SERVICE in the default template, it will work :) |
Ah, but we'd still have the issue where Looks like it's time to document that setting capabilities on files is the solution going forward. |
@tianon Yep, this should be documented. |
@tianon @mrunalp apparently you both have a clear understanding what has to be documented. Would one of you be willing to create a PR for adding a description (and example) to the documentation? Also, is documentation the only actionable item here? Or should this stay open after that (in hope of a better solution)? |
I can add the documentation changes. I don't think there is any fix short of a kernel change if it ever happens. Sent from my iPhone
|
Is there any actual risk to set What I mean by this is that setting |
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 node in the Dockerfile because then the process would be unable to bind to port 80 internally (or anything below 1024). I didn't want to force it either and make it a breaking change, because many existing setups will be mapping 8080 externally to 80/443 internally, for example. The workaround is therefore on the user (sorry), they will need to set the environment variable to a higher number, or use the --sysctl net.ipv4.ip_unprivileged_port_start=0 flag Reference: moby/moby#8460 (comment) Issue #14
The simplest way to reproduce this is:
So, that led me to try this, but with the same result:
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.The text was updated successfully, but these errors were encountered: