-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Rework port binding logic without privileges #3573
Conversation
I have left the NET_BIND_SERVICE capability in the Permitted set on the binary file. But I'm thinking now that there is no scenario where Kubernetes ends up using it. Is there some strange Docker native scenario where it's helpful? My understanding is: having the capability as Permitted for file allows the capability to be added to the thread, if the bounding set includes NET_BIND_SERVICE. |
As mentioned in description, to test the chart, you would need to build the image similar to: make debian-image PREFIX=myregistry.example.com/nginx-ingress TARGET=container If using Minikube, you can pull the image into local cluster: minikube image load myregistry.example.com/nginx-ingress:untagged-EXAMPLE When installing the chart:
|
39191b8
to
4f0a6e1
Compare
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more @@ Coverage Diff @@
## main #3573 +/- ##
==========================================
+ Coverage 52.24% 52.29% +0.05%
==========================================
Files 59 59
Lines 16873 16849 -24
==========================================
- Hits 8816 8812 -4
+ Misses 7762 7740 -22
- Partials 295 297 +2
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
Smoke Tests (debian-plus-nap, dos, 1.26.0) failure leads to this The 7th argument is checking
|
@sigv thanks for the PR! I've re-run the DoS test and it passed 🎉 I've been doing some testing and I think we can remove EDIT: running natively in Docker is not a use case for use, so no need to worry about that. |
4f0a6e1
to
84325d9
Compare
|
Taking a look at K8s Patch Releases, K8s v1.21 went EOL |
Alternative approach I mentioned in the linked issue could be that IC process (entrypoint) is modified, so that it gets NET_BIND_SERVICE initially and executes Nginx (which could inherit the capability) and then IC drops that capability. In theory we don't need lowered unprivileged port range then - only change in IC to remove privilege escalation. If that's preferred I can propose the change instead. It's kind of a risk assessment question of how to get rid of escalation. Either the current scope which enables the whole Pod to easily bind, or simply better handling of the NET_BIND_SERVICE capability. |
84325d9
to
466caed
Compare
I like the approach of enabling the pod to easily bind. Do you see any drawbacks with this that I'm not seeing? |
Capability being dropped would be more restrictive. In theory, an RCE attack against nginx could result in a different process replacing nginx silently. In current setup, the same risk already exists. At least when taking a quick look, it seemed the nginx process does not drop |
466caed
to
3bb01d2
Compare
67092b4
to
b08a149
Compare
b08a149
to
54bc86b
Compare
yeah we don't drop it |
75c670c
to
05fb370
Compare
Build Docker Plus (ubi-plus, linux/arm64, linux/amd64, linux/s390x, goreleaser) failed to resolve the Nginx Plus package repository:
I presume this could be an intermittent issue, as nothing should have changed for this step. Or my pipeline is not allowed to use the secret material:
|
05fb370
to
02b0469
Compare
b2c3a07
to
da15524
Compare
This is a breaking change! To start Nginx Ingress Controller with this commit applied, you must use an updated image. Historically, the Ingress Controller entrypoint launched with restricted capabilities. Then Nginx process escalated privileges (NET_BIND_SERVICE) to bind ports 80 and 443 as non-root user. Allowing privilege escalation is generally frowned upon in various policies. The Nginx binary in old images was adding NET_BIND_SERVICE to its Permitted capability set and also setting the Effective bit, to enforce the Permitted capability during launch. (That's the escalation there.) With this change, privilege escalation is no longer allowed and the NET_BIND_SERVICE capability is removed. To allow the binary to start, the capabilities are no longer being adjusted on the binary file. This works because Kubernetes v1.22+ allows Pods to independently lower unprivileged port range to start with zero without affecting other ports (namespaced/"safe" sysctls). OBS! An old image may be used if the binary's Effective bit is removed: FROM nginx/nginx-ingress:3.0.2 USER root RUN setcap 'cap_net_bind_service=-e' /usr/sbin/nginx 'cap_net_bind_service=-e' /usr/sbin/nginx-debug \ && setcap -v 'cap_net_bind_service=-e' /usr/sbin/nginx 'cap_net_bind_service=-e' /usr/sbin/nginx-debug # 101 is nginx USER 101
da15524
to
528ff50
Compare
This is a breaking change! To start Nginx Ingress Controller with this commit applied, you must use an updated image. Historically, the Ingress Controller entrypoint launched with restricted capabilities. Then Nginx process escalated privileges (NET_BIND_SERVICE) to bind ports 80 and 443 as non-root user. Allowing privilege escalation is generally frowned upon in various policies. The Nginx binary in old images was adding NET_BIND_SERVICE to its Permitted capability set and also setting the Effective bit, to enforce the Permitted capability during launch. (That's the escalation there.) With this change, privilege escalation is no longer allowed and the NET_BIND_SERVICE capability is removed. To allow the binary to start, the capabilities are no longer being adjusted on the binary file. This works because Kubernetes v1.22+ allows Pods to independently lower unprivileged port range to start with zero without affecting other ports (namespaced/"safe" sysctls). OBS! An old image may be used if the binary's Effective bit is removed: FROM nginx/nginx-ingress:3.0.2 USER root RUN setcap 'cap_net_bind_service=-e' /usr/sbin/nginx 'cap_net_bind_service=-e' /usr/sbin/nginx-debug \ && setcap -v 'cap_net_bind_service=-e' /usr/sbin/nginx 'cap_net_bind_service=-e' /usr/sbin/nginx-debug # 101 is nginx USER 101
Proposed changes
This is a breaking change! To start Nginx Ingress Controller with this commit applied, you must use an updated image.
Historically, the Ingress Controller entrypoint launched with restricted capabilities. Then Nginx process escalated privileges (NET_BIND_SERVICE) to bind ports 80 and 443 as non-root user. Allowing privilege escalation is generally frowned upon in various policies.
The Nginx binary in old images was adding NET_BIND_SERVICE to its Permitted capability set and also setting the Effective bit, to enforce the Permitted capability during launch. (That's the escalation there.)
With this change, privilege escalation is no longer allowed and the NET_BIND_SERVICE capability is removed. To allow the binary to start, the capabilities are no longer being adjusted on the binary file.
This works because Kubernetes v1.22+ allows Pods to independently lower unprivileged port range to start with zero without affecting other pods (namespaced/"safe" sysctls).
OBS! An old image may be used if the binary's Effective bit is removed:
Improves #3544. Privilege Escalation is the initial scope of the linked issue. However, as indicated by the issue creator, there may be follow-up tasks to fully close it.
Checklist
Before creating a PR, run through this checklist and mark each as complete.