-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Add page Block Services with ExternalIPs #52631
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,100 @@ | ||||||||||||||
--- | ||||||||||||||
reviewers: | ||||||||||||||
- thockin | ||||||||||||||
- danwinship | ||||||||||||||
- aojea | ||||||||||||||
min-kubernetes-server-version: v1.30 | ||||||||||||||
title: Block Services with ExternalIPs | ||||||||||||||
content_type: task | ||||||||||||||
--- | ||||||||||||||
|
||||||||||||||
<!-- overview --> | ||||||||||||||
|
||||||||||||||
This document shares how to control how Services with ExternalIPs are managed within your cluster. | ||||||||||||||
|
||||||||||||||
An ExternalIP is a powerful tool that could be used for [malicious intent](https://www.cvedetails.com/cve/CVE-2020-8554/). | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
? nit: also update https://k8s.io/docs/concepts/services-networking/service/#external-ips to link to this new task page. Aside: if we fix #46623 (which will create a page for each known Kubernetes vulnerability), we can link to that page instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is that it's not supposed to be a powerful tool. The power was accidental, and that's the problem. Some background to incorporate:
|
||||||||||||||
|
||||||||||||||
Any user who can create a Service with ExternalIPs could: | ||||||||||||||
|
||||||||||||||
- intercept other users' outbound traffic to arbitrary IPs. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
- could (non-deterministically) steal other users' inbound traffic to their own ExternalIPs. | ||||||||||||||
Comment on lines
+13
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: avoid using UpperCamelCase for externalIPs; in our style guide, we use otherwise unstyled UpperCamelCase for API kinds (eg StatefulSet, Service). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need some (style-guide-approved) way of being explicit that we are referring to the externalIPs feature and not just the vague concept of "external IPs", which can easily be misinterpreted. (eg if this point was rewritten as "to their own external IPs", it would be easy to assume it meant cluster-external IPs as in the previous bullet point). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the field capitalization: For example:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
(You already have a "could" introducing the list.) |
||||||||||||||
|
||||||||||||||
## {{% heading "prerequisites" %}} | ||||||||||||||
|
||||||||||||||
{{< include "task-tutorial-prereqs.md" >}} | ||||||||||||||
|
||||||||||||||
{{< version-check >}} | ||||||||||||||
|
||||||||||||||
<!-- steps --> | ||||||||||||||
|
||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. somewhere in this doc you should also meantion that you can disable the feature entirely by enabling the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tabs might work well here. |
||||||||||||||
## Kubernetes Service ExternalIP Policies | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
||||||||||||||
Cluster administrators can implement policies to control the creation and modification of Services with ExternalIPs within the cluster. This allows for centralized management of the allowed ExternalIPs used for Services and helps prevent unintended or conflicting configurations. Kubernetes provides mechanisms like Validating Admission Policies to enforce these rules. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
nit: I would also move this paragraph to the introduction, since the page is specifically about solving this with ValidatingAdmissionPolicy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(If you add a section mentioning the admission controller (which I'm pretty sure we don't document anywhere else other than the list-of-all-admission-controllers) then that wouldn't apply.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In that case, reword it and move the reworded thing. |
||||||||||||||
|
||||||||||||||
### Allowing only specific ExternalIPs within a certain IP range to be created | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
||||||||||||||
The following example allows an administrator to restrict the allowed IP address range(s) of any new or updated Service: | ||||||||||||||
|
||||||||||||||
```yaml | ||||||||||||||
--- | ||||||||||||||
apiVersion: admissionregistration.k8s.io/v1 | ||||||||||||||
kind: ValidatingAdmissionPolicy | ||||||||||||||
metadata: | ||||||||||||||
name: "allow-specific-externalips" | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding a |
||||||||||||||
spec: | ||||||||||||||
failurePolicy: Fail | ||||||||||||||
matchConstraints: | ||||||||||||||
resourceRules: | ||||||||||||||
- apiGroups: [""] | ||||||||||||||
apiVersions: ["v1"] | ||||||||||||||
operations: ["CREATE", "UPDATE"] | ||||||||||||||
resources: ["services"] | ||||||||||||||
variables: | ||||||||||||||
- name: allowed | ||||||||||||||
expression: "['192.0.2.0/24', '2001:db8::/64']" | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs a comment: change this to your actual allowed IP address range. |
||||||||||||||
validations: | ||||||||||||||
- expression: | | ||||||||||||||
!has(object.spec.externalIPs) || | ||||||||||||||
object.spec.externalIPs.all(ip, variables.allowed.exists(cidr, cidr(cidr).containsIP(ip))) | ||||||||||||||
message: "All externalIPs must be within the allowed CIDR ranges." | ||||||||||||||
--- | ||||||||||||||
apiVersion: admissionregistration.k8s.io/v1 | ||||||||||||||
kind: ValidatingAdmissionPolicyBinding | ||||||||||||||
metadata: | ||||||||||||||
name: "allow-specific-externalips-binding" | ||||||||||||||
spec: | ||||||||||||||
policyName: "allow-specific-externalips" | ||||||||||||||
validationActions: [Deny, Audit] | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
### Restricting which users/groups may create/update Services with ExternalIPs | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
||||||||||||||
```yaml | ||||||||||||||
--- | ||||||||||||||
apiVersion: admissionregistration.k8s.io/v1 | ||||||||||||||
kind: ValidatingAdmissionPolicy | ||||||||||||||
metadata: | ||||||||||||||
name: "allow-specific-users-to-manage-externalips" | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding a |
||||||||||||||
spec: | ||||||||||||||
failurePolicy: Fail | ||||||||||||||
matchConstraints: | ||||||||||||||
resourceRules: | ||||||||||||||
- apiGroups: [""] | ||||||||||||||
apiVersions: ["v1"] | ||||||||||||||
operations: ["CREATE", "UPDATE"] | ||||||||||||||
resources: ["services"] | ||||||||||||||
validations: | ||||||||||||||
- expression: | | ||||||||||||||
!has(object.spec.externalIPs) || | ||||||||||||||
request.userInfo.username == "myuser" || | ||||||||||||||
request.userInfo.groups.exists(g, g in ["system:masters", "net-admins"]) | ||||||||||||||
message: "Only user 'myuser' or members of groups 'system:masters' and 'net-admins' can assign externalIPs." | ||||||||||||||
--- | ||||||||||||||
apiVersion: admissionregistration.k8s.io/v1 | ||||||||||||||
kind: ValidatingAdmissionPolicyBinding | ||||||||||||||
metadata: | ||||||||||||||
name: "allow-specific-users-binding" | ||||||||||||||
spec: | ||||||||||||||
policyName: "allow-specific-users-to-manage-externalips" | ||||||||||||||
validationActions: [Deny, Audit] | ||||||||||||||
``` | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should get someone in sig-auth to review your VAPs and make sure they're correct too There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SIG Security are also fine folks to ask. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to be clear about what these policies do and don't protect against. The first policy protects against "users can intercept traffic to arbitrary cluster-external IPs", but it doesn't prevent "users can intercept each others' ExternalIPs". The second policy doesn't protect against either problem; it just assumes that you're restricting the feature to users who you trust to not (intentionally or accidentally) exploit the CVE. Does CEL let you use maps in variables? It would be cool to have a policy that says "service account X is allowed to use these specific externalIPs, and service account Y is allowed to use these specific externalIPs (which are different from X's)". That would block both problems. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use parameters in bindings, which gives you a way to do mappings I think (not tried it). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.