Skip to content
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

Documentation does not describe non-root user requirement #138

Closed
nebhale opened this issue May 4, 2020 · 8 comments · Fixed by #186
Closed

Documentation does not describe non-root user requirement #138

nebhale opened this issue May 4, 2020 · 8 comments · Fixed by #186
Labels
good first issue A good first issue to get started with. help wanted Need some extra hands to the this done. status/ready Issue ready to be worked on.

Comments

@nebhale
Copy link
Contributor

nebhale commented May 4, 2020

Recently in the Spring Boot repo, an issue was opened and the difficulty ended up being that the user expected to be able to bind to port 80, but couldn't because the user that CNB applications run as, is not root.

This isn't broadly an issue (the security tradeoff is easy to defend), but it highlighted that we don't appear to have any user-facing documentation that describes that both builds and launches happen via a non-root user and what the implications of that choice are. There should be some sort of user-facing documentation about this.

When this documentation is complete, please comment on the previously linked issue to let the team know.

@jromero
Copy link
Member

jromero commented May 5, 2020

@nebhale If I'm understanding the root cause, it is occuring during runtime. A cursory look at the spec doesn't yield any remark to non-root user runtime execution as a requirement. Is this issue more intended for the spec?

@nebhale
Copy link
Contributor Author

nebhale commented May 14, 2020

This should also likely be documented in the spec (paging @sclevine), but end-users, who will be disproportionally affected by this limitation, should not be required to read the specification to understand the general environment that their application runs in.

@thephw
Copy link
Contributor

thephw commented May 15, 2020

I knew this and ran into again two days ago when writing a controller in golang that uses the kubernetes controller-runtime. It binds to 80/443 by default on the manager. I simply changed the port, but it may be interesting to see something around linux capabilities in the security context as a workaround as well CAP_NET_BIND_SERVICE and the like.

@jromero
Copy link
Member

jromero commented May 15, 2020

This should also likely be documented in the spec (paging @sclevine), but end-users, who will be disproportionally affected by this limitation, should not be required to read the specification to understand the general environment that their application runs in.

I completely agree with you but I want to make sure that it's in the spec before it's documented as a fact when there may be cases where that's not true (or may not want that to be true).

As an example, a very far stretch would be Windows where AFAIK this might not yet be possible when conflating Administrator as root. @micahyoung and @ameyer-pivotal might know a bit more in that context.

Nonetheless, I agree we should document something. I'm just not sure exactly what yet. A PR might help. :D

@jromero
Copy link
Member

jromero commented May 15, 2020

I knew this and ran into again two days ago when writing a controller in golang that uses the kubernetes controller-runtime. It binds to 80/443 by default on the manager. I simply changed the port, but it may be interesting to see something around linux capabilities in the security context as a workaround as well CAP_NET_BIND_SERVICE and the like.

I'm by no means a Linux expert but this sounds interesting. Might be worth looking more into for the purpose of an RFC.

@thephw
Copy link
Contributor

thephw commented May 15, 2020

I didn't get very far into that implementation before I sort of knocked myself upside the head and decided to change the port instead as the much easier thing to do instead. Doesn't look like I got as far as a commit (no history) in the linux capabilities implementation.

My basic understanding is linux capabilities are flags for a partial privilege escalation for a particular process. Looking through the headers they seem to enumerate some pretty common concerns.

Some additional reference material around the prior comment:
Linux Capabilities Headers
Kubernetes Security Context

@sclevine
Copy link
Member

sclevine commented May 19, 2020

Note that the non-root user requirement is in the Platform spec: https://github.com/buildpacks/spec/blob/master/platform.md#stacks
That said, the Platform spec definitely needs to provide more details around this (and other) requirements.

Applying CAP_NET_BIND_SERVICE to the runtime container doesn't actually apply it to the in-container process:

liberty:temp stephen$ docker run -u nobody --rm --cap-add net_bind_service gcr.io/paketo-buildpacks/run:full-cf nc -l 0.0.0.0 80
nc: Permission denied

There's a k8s proposal for user capabilities that would apply inside the container:
kubernetes/community#2285
But it doesn't seem to be going anywhere soon.

We could solve this without the above feature a few ways, but none are very clean. The cleanest might be to set the capability on the launcher binary and have the launcher upgrade it to a Linux 4.3+ ambient capability that's inherited through execve without +i on the target process (e.g., java) so that it persists to the processes that it launches. This would look like setcap 'cap_net_bind_service=+ep' /cnb/lifecycle/launcher + a bunch of a syscalls in the launcher.

@nebhale
Copy link
Contributor Author

nebhale commented May 19, 2020

@jromero it seems that @sclevine has identified the part of the spec, so the way should be clear to putting it into prose so that it's easier to find next time.

@nebhale nebhale added good first issue A good first issue to get started with. help wanted Need some extra hands to the this done. labels May 19, 2020
@dfreilich dfreilich added the status/ready Issue ready to be worked on. label May 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue A good first issue to get started with. help wanted Need some extra hands to the this done. status/ready Issue ready to be worked on.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants