From 7266367ddbcb543cb44b9dae59766669d3ff8dff Mon Sep 17 00:00:00 2001 From: juliankatz Date: Wed, 28 Aug 2024 16:00:00 -0700 Subject: [PATCH] fix(k8spsphostnetworkingports): CEL fixes for hostNetwork variable and message My updates to the suite.yaml file yielded an expected failure due to an incorrect CEL expression: ``` unexpected number of violations: got 1 violations but want none: got messages [failed expression: (has(request.operation) && request.operation == "UPDATE") || (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && !variables.anyObject.spec.hostNetwork) : true)] ``` By contrast, a run of `gator verify -v . --enable-k8s-native-validation=false` yielded a fully passing suite.yaml. This expression was actually failing due to its `messageExpression`, as non-primitive types cannot be combined with strings as in some interpreted languages (like rego). Unfortunately the compiler does not indicate that the messageExpression is the source of the problem. Once the message was fixed, I resolved the incorrect violation expression to fix the bug in the handling of params.hostNetwork. Signed-off-by: juliankatz --- .../1.1.3/artifacthub-pkg.yml | 22 +++ .../1.1.3/kustomization.yaml | 2 + .../block_host_network/constraint.yaml | 2 - .../constraint.yaml | 13 ++ ...llowed_out_of_range_host_network_true.yaml | 0 .../psp-host-network-ports/constraint.yaml | 13 ++ .../disallowed_ephemeral.yaml | 14 ++ .../example_allowed_in_range.yaml | 1 - .../example_allowed_no_ports.yaml | 11 ++ ...e_allowed_no_ports_host_network_false.yaml | 9 + ...le_allowed_no_ports_host_network_true.yaml | 9 + .../psp-host-network-ports/update.yaml | 19 ++ .../host-network-ports/1.1.3/suite.yaml | 62 +++++++ .../host-network-ports/1.1.3/template.yaml | 165 ++++++++++++++++++ .../block_host_network/constraint.yaml | 11 ++ .../constraint.yaml | 13 ++ ...llowed_out_of_range_host_network_true.yaml | 14 ++ .../example_allowed_in_range.yaml | 13 ++ ...e_allowed_no_ports_host_network_false.yaml | 9 + ...le_allowed_no_ports_host_network_true.yaml | 9 + .../host-network-ports/suite.yaml | 34 ++-- .../host-network-ports/template.yaml | 20 ++- .../host-network-ports/constraint.tmpl | 2 +- .../host-network-ports/src.cel | 18 +- website/docs/validation/host-network-ports.md | 126 ++++++++++--- 25 files changed, 561 insertions(+), 50 deletions(-) create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/artifacthub-pkg.yml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/kustomization.yaml rename library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml => artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/block_host_network/constraint.yaml (87%) create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/port_range_block_host_network/constraint.yaml rename library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_disallowed.yaml => artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml (100%) create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/constraint.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/disallowed_ephemeral.yaml rename library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed.yaml => artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_in_range.yaml (91%) create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/update.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/suite.yaml create mode 100644 artifacthub/library/pod-security-policy/host-network-ports/1.1.3/template.yaml create mode 100644 library/pod-security-policy/host-network-ports/samples/block_host_network/constraint.yaml create mode 100644 library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/constraint.yaml create mode 100644 library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml create mode 100644 library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml create mode 100644 library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml create mode 100644 library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/artifacthub-pkg.yml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/artifacthub-pkg.yml new file mode 100644 index 0000000000..878f809ba9 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/artifacthub-pkg.yml @@ -0,0 +1,22 @@ +version: 1.1.3 +name: k8spsphostnetworkingports +displayName: Host Networking Ports +createdAt: "2024-08-29T21:28:18Z" +description: Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific ports must be specified. Corresponds to the `hostNetwork` and `hostPorts` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces +digest: 751752950daeb4002a10cad6cbeba6a4afe03b98605f32885ae3fe0179eaff67 +license: Apache-2.0 +homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/host-network-ports +keywords: + - gatekeeper + - open-policy-agent + - policies +readme: |- + # Host Networking Ports + Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific ports must be specified. Corresponds to the `hostNetwork` and `hostPorts` fields in a PodSecurityPolicy. For more information, see https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces +install: |- + ### Usage + ```shell + kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/template.yaml + ``` +provider: + name: Gatekeeper Library diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/kustomization.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/kustomization.yaml new file mode 100644 index 0000000000..7d70d11b71 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/kustomization.yaml @@ -0,0 +1,2 @@ +resources: + - template.yaml diff --git a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/block_host_network/constraint.yaml similarity index 87% rename from library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml rename to artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/block_host_network/constraint.yaml index 7ef87dbb39..b5f2e9f44a 100644 --- a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/block_host_network/constraint.yaml @@ -9,5 +9,3 @@ spec: kinds: ["Pod"] parameters: hostNetwork: false - exemptImages: - - "nginx" \ No newline at end of file diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/port_range_block_host_network/constraint.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/port_range_block_host_network/constraint.yaml new file mode 100644 index 0000000000..46e16454c7 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/port_range_block_host_network/constraint.yaml @@ -0,0 +1,13 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network-ports +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: false + min: 80 + max: 9000 diff --git a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_disallowed.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml similarity index 100% rename from library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_disallowed.yaml rename to artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/constraint.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/constraint.yaml new file mode 100644 index 0000000000..aba7c24e76 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/constraint.yaml @@ -0,0 +1,13 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network-ports +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: true + min: 80 + max: 9000 \ No newline at end of file diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/disallowed_ephemeral.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/disallowed_ephemeral.yaml new file mode 100644 index 0000000000..7a4fa31144 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/disallowed_ephemeral.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: true + ephemeralContainers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 diff --git a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_in_range.yaml similarity index 91% rename from library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed.yaml rename to artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_in_range.yaml index 08b321fe58..2b4f7c9266 100644 --- a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed.yaml +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_in_range.yaml @@ -5,7 +5,6 @@ metadata: labels: app: nginx-host-networking-ports spec: - hostNetwork: false containers: - name: nginx image: nginx diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports.yaml new file mode 100644 index 0000000000..e009decf90 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: true + containers: + - name: nginx + image: nginx diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml new file mode 100644 index 0000000000..8c0b0ef577 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-network-false +spec: + hostNetwork: false + containers: + - name: nginx + image: nginx diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml new file mode 100644 index 0000000000..91cd7f4cd7 --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-network-true +spec: + hostNetwork: true + containers: + - name: nginx + image: nginx diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/update.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/update.yaml new file mode 100644 index 0000000000..231096430e --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/samples/psp-host-network-ports/update.yaml @@ -0,0 +1,19 @@ +kind: AdmissionReview +apiVersion: admission.k8s.io/v1beta1 +request: + operation: "UPDATE" + object: + apiVersion: v1 + kind: Pod + metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports + spec: + hostNetwork: true + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/suite.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/suite.yaml new file mode 100644 index 0000000000..44bbab1bea --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/suite.yaml @@ -0,0 +1,62 @@ +kind: Suite +apiVersion: test.gatekeeper.sh/v1alpha1 +metadata: + name: host-network-ports +tests: +- name: port-range-with-host-network-allowed + template: template.yaml + constraint: samples/psp-host-network-ports/constraint.yaml + cases: + - name: out-of-range + object: samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml + assertions: + - violations: yes + - name: example-allowed + object: samples/psp-host-network-ports/example_allowed_in_range.yaml + assertions: + - violations: no + - name: out-of-range-ephemeral + object: samples/psp-host-network-ports/disallowed_ephemeral.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-host-network-ports/update.yaml + assertions: + - violations: no + - name: no-ports-specified + object: samples/psp-host-network-ports/example_allowed_no_ports.yaml + assertions: + - violations: no +- name: host-network-forbidden + template: template.yaml + constraint: samples/block_host_network/constraint.yaml + cases: + - name: hostnetwork-true + object: samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml + assertions: + - violations: yes + - name: hostnetwork-false + object: samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml + assertions: + - violations: no +- name: port-range-with-host-network-forbidden + template: template.yaml + constraint: samples/port_range_block_host_network/constraint.yaml + cases: + - name: out-of-range-and-host-network-true + object: samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml + assertions: + - violations: yes + - name: in-range-host-network-false + object: samples/psp-host-network-ports/example_allowed_in_range.yaml + assertions: + - violations: no + - name: disallowed-ephemeral + object: samples/psp-host-network-ports/disallowed_ephemeral.yaml + assertions: + - violations: yes + - name: update + object: samples/psp-host-network-ports/update.yaml + assertions: + - violations: no + diff --git a/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/template.yaml b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/template.yaml new file mode 100644 index 0000000000..036a3e045a --- /dev/null +++ b/artifacthub/library/pod-security-policy/host-network-ports/1.1.3/template.yaml @@ -0,0 +1,165 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8spsphostnetworkingports + annotations: + metadata.gatekeeper.sh/title: "Host Networking Ports" + metadata.gatekeeper.sh/version: 1.1.3 + description: >- + Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific + ports must be specified. Corresponds to the `hostNetwork` and + `hostPorts` fields in a PodSecurityPolicy. For more information, see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces +spec: + crd: + spec: + names: + kind: K8sPSPHostNetworkingPorts + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + description: >- + Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific + ports must be specified. Corresponds to the `hostNetwork` and + `hostPorts` fields in a PodSecurityPolicy. For more information, see + https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces + properties: + exemptImages: + description: >- + Any container that uses an image that matches an entry in this list will be excluded + from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`. + + It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name) + in order to avoid unexpectedly exempting images from an untrusted repository. + type: array + items: + type: string + hostNetwork: + description: "Determines if the policy allows the use of HostNetwork in the pod spec." + type: boolean + min: + description: "The start of the allowed port range, inclusive." + type: integer + max: + description: "The end of the allowed port range, inclusive." + type: integer + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + variables: + - name: containers + expression: 'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []' + - name: initContainers + expression: 'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []' + - name: ephemeralContainers + expression: 'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []' + - name: exemptImagePrefixes + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", "")) + - name: exemptImageExplicit + expression: | + !has(variables.params.exemptImages) ? [] : + variables.params.exemptImages.filter(image, !image.endsWith("*")) + - name: exemptImages + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + container.image in variables.exemptImageExplicit || + variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))) + - name: badContainers + expression: | + (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container, + !(container.image in variables.exemptImages) && has(container.ports) && + ( + (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) || + (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) + ) + ) + - name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" + - name: hostNetworkAllowed + expression: has(variables.params.hostNetwork) && variables.params.hostNetwork + - name: hostNetworkEnabled + expression: has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork + - name: hostNetworkViolation + expression: variables.hostNetworkEnabled && !variables.hostNetworkAllowed + validations: + - expression: 'variables.isUpdate || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' + - expression: variables.isUpdate || !variables.hostNetworkViolation + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' + - engine: Rego + source: + rego: | + package k8spsphostnetworkingports + + import data.lib.exclude_update.is_update + import data.lib.exempt_container.is_exempt + + violation[{"msg": msg, "details": {}}] { + # spec.hostNetwork field is immutable. + not is_update(input.review) + + input_share_hostnetwork(input.review.object) + msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters]) + } + + input_share_hostnetwork(o) { + not input.parameters.hostNetwork + o.spec.hostNetwork + } + + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort < input.parameters.min + } + + input_share_hostnetwork(_) { + hostPort := input_containers[_].ports[_].hostPort + hostPort > input.parameters.max + } + + input_containers[c] { + c := input.review.object.spec.containers[_] + not is_exempt(c) + } + + input_containers[c] { + c := input.review.object.spec.initContainers[_] + not is_exempt(c) + } + + input_containers[c] { + c := input.review.object.spec.ephemeralContainers[_] + not is_exempt(c) + } + libs: + - | + package lib.exclude_update + + is_update(review) { + review.operation == "UPDATE" + } + - | + package lib.exempt_container + + is_exempt(container) { + exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", []) + img := container.image + exemption := exempt_images[_] + _matches_exemption(img, exemption) + } + + _matches_exemption(img, exemption) { + not endswith(exemption, "*") + exemption == img + } + + _matches_exemption(img, exemption) { + endswith(exemption, "*") + prefix := trim_suffix(exemption, "*") + startswith(img, prefix) + } diff --git a/library/pod-security-policy/host-network-ports/samples/block_host_network/constraint.yaml b/library/pod-security-policy/host-network-ports/samples/block_host_network/constraint.yaml new file mode 100644 index 0000000000..b5f2e9f44a --- /dev/null +++ b/library/pod-security-policy/host-network-ports/samples/block_host_network/constraint.yaml @@ -0,0 +1,11 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: false diff --git a/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/constraint.yaml b/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/constraint.yaml new file mode 100644 index 0000000000..46e16454c7 --- /dev/null +++ b/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/constraint.yaml @@ -0,0 +1,13 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network-ports +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: false + min: 80 + max: 9000 diff --git a/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml b/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml new file mode 100644 index 0000000000..9a496cd606 --- /dev/null +++ b/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-disallowed + labels: + app: nginx-host-networking-ports +spec: + hostNetwork: true + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9001 + hostPort: 9001 diff --git a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml new file mode 100644 index 0000000000..2b4f7c9266 --- /dev/null +++ b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-networking-ports-allowed + labels: + app: nginx-host-networking-ports +spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 9000 + hostPort: 80 diff --git a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml new file mode 100644 index 0000000000..8c0b0ef577 --- /dev/null +++ b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-network-false +spec: + hostNetwork: false + containers: + - name: nginx + image: nginx diff --git a/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml new file mode 100644 index 0000000000..91cd7f4cd7 --- /dev/null +++ b/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-network-true +spec: + hostNetwork: true + containers: + - name: nginx + image: nginx diff --git a/library/pod-security-policy/host-network-ports/suite.yaml b/library/pod-security-policy/host-network-ports/suite.yaml index b0c7f7816c..44bbab1bea 100644 --- a/library/pod-security-policy/host-network-ports/suite.yaml +++ b/library/pod-security-policy/host-network-ports/suite.yaml @@ -3,19 +3,19 @@ apiVersion: test.gatekeeper.sh/v1alpha1 metadata: name: host-network-ports tests: -- name: use-of-host-networking-ports-blocked +- name: port-range-with-host-network-allowed template: template.yaml constraint: samples/psp-host-network-ports/constraint.yaml cases: - - name: example-disallowed - object: samples/psp-host-network-ports/example_disallowed.yaml + - name: out-of-range + object: samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml assertions: - violations: yes - name: example-allowed - object: samples/psp-host-network-ports/example_allowed.yaml + object: samples/psp-host-network-ports/example_allowed_in_range.yaml assertions: - violations: no - - name: disallowed-ephemeral + - name: out-of-range-ephemeral object: samples/psp-host-network-ports/disallowed_ephemeral.yaml assertions: - violations: yes @@ -27,16 +27,28 @@ tests: object: samples/psp-host-network-ports/example_allowed_no_ports.yaml assertions: - violations: no -- name: use-of-host-network-blocked +- name: host-network-forbidden template: template.yaml - constraint: samples/psp-host-network-ports/constraint_block_host_network.yaml + constraint: samples/block_host_network/constraint.yaml cases: - - name: example-disallowed - object: samples/psp-host-network-ports/example_disallowed.yaml + - name: hostnetwork-true + object: samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml assertions: - violations: yes - - name: example-allowed - object: samples/psp-host-network-ports/example_allowed.yaml + - name: hostnetwork-false + object: samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml + assertions: + - violations: no +- name: port-range-with-host-network-forbidden + template: template.yaml + constraint: samples/port_range_block_host_network/constraint.yaml + cases: + - name: out-of-range-and-host-network-true + object: samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml + assertions: + - violations: yes + - name: in-range-host-network-false + object: samples/psp-host-network-ports/example_allowed_in_range.yaml assertions: - violations: no - name: disallowed-ephemeral diff --git a/library/pod-security-policy/host-network-ports/template.yaml b/library/pod-security-policy/host-network-ports/template.yaml index 218cb36e7d..036a3e045a 100644 --- a/library/pod-security-policy/host-network-ports/template.yaml +++ b/library/pod-security-policy/host-network-ports/template.yaml @@ -4,7 +4,7 @@ metadata: name: k8spsphostnetworkingports annotations: metadata.gatekeeper.sh/title: "Host Networking Ports" - metadata.gatekeeper.sh/version: 1.1.2 + metadata.gatekeeper.sh/version: 1.1.3 description: >- Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific ports must be specified. Corresponds to the `hostNetwork` and @@ -78,13 +78,19 @@ spec: (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) ) + - name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" + - name: hostNetworkAllowed + expression: has(variables.params.hostNetwork) && variables.params.hostNetwork + - name: hostNetworkEnabled + expression: has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork + - name: hostNetworkViolation + expression: variables.hostNetworkEnabled && !variables.hostNetworkAllowed validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' - messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' - - expression: | - (has(request.operation) && request.operation == "UPDATE") || - (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && !variables.anyObject.spec.hostNetwork) : true) - messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' + - expression: 'variables.isUpdate || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' + - expression: variables.isUpdate || !variables.hostNetworkViolation + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' - engine: Rego source: rego: | diff --git a/src/pod-security-policy/host-network-ports/constraint.tmpl b/src/pod-security-policy/host-network-ports/constraint.tmpl index 9f6e90d281..d5f7146821 100644 --- a/src/pod-security-policy/host-network-ports/constraint.tmpl +++ b/src/pod-security-policy/host-network-ports/constraint.tmpl @@ -4,7 +4,7 @@ metadata: name: k8spsphostnetworkingports annotations: metadata.gatekeeper.sh/title: "Host Networking Ports" - metadata.gatekeeper.sh/version: 1.1.2 + metadata.gatekeeper.sh/version: 1.1.3 description: >- Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific ports must be specified. Corresponds to the `hostNetwork` and diff --git a/src/pod-security-policy/host-network-ports/src.cel b/src/pod-security-policy/host-network-ports/src.cel index 1bd9b333c1..8d0fe507ec 100644 --- a/src/pod-security-policy/host-network-ports/src.cel +++ b/src/pod-security-policy/host-network-ports/src.cel @@ -27,10 +27,16 @@ variables: (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) ) +- name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" +- name: hostNetworkAllowed + expression: has(variables.params.hostNetwork) && variables.params.hostNetwork +- name: hostNetworkEnabled + expression: has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork +- name: hostNetworkViolation + expression: variables.hostNetworkEnabled && !variables.hostNetworkAllowed validations: -- expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' - messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' -- expression: | - (has(request.operation) && request.operation == "UPDATE") || - (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && !variables.anyObject.spec.hostNetwork) : true) - messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' +- expression: 'variables.isUpdate || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' +- expression: variables.isUpdate || !variables.hostNetworkViolation + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' diff --git a/website/docs/validation/host-network-ports.md b/website/docs/validation/host-network-ports.md index 17c2b6b6ba..549b373803 100644 --- a/website/docs/validation/host-network-ports.md +++ b/website/docs/validation/host-network-ports.md @@ -16,7 +16,7 @@ metadata: name: k8spsphostnetworkingports annotations: metadata.gatekeeper.sh/title: "Host Networking Ports" - metadata.gatekeeper.sh/version: 1.1.2 + metadata.gatekeeper.sh/version: 1.1.3 description: >- Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific ports must be specified. Corresponds to the `hostNetwork` and @@ -90,13 +90,19 @@ spec: (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max)) ) ) + - name: isUpdate + expression: has(request.operation) && request.operation == "UPDATE" + - name: hostNetworkAllowed + expression: has(variables.params.hostNetwork) && variables.params.hostNetwork + - name: hostNetworkEnabled + expression: has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork + - name: hostNetworkViolation + expression: variables.hostNetworkEnabled && !variables.hostNetworkAllowed validations: - - expression: '(has(request.operation) && request.operation == "UPDATE") || size(variables.badContainers) == 0' - messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' - - expression: | - (has(request.operation) && request.operation == "UPDATE") || - (!has(variables.params.hostNetwork) || !variables.params.hostNetwork ? (has(variables.anyObject.spec.hostNetwork) && !variables.anyObject.spec.hostNetwork) : true) - messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name + ". Allowed values: " + variables.params' + - expression: 'variables.isUpdate || size(variables.badContainers) == 0' + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' + - expression: variables.isUpdate || !variables.hostNetworkViolation + messageExpression: '"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name' - engine: Rego source: rego: | @@ -178,7 +184,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper- ``` ## Examples
-use-of-host-networking-ports-blocked +port-range-with-host-network-allowed
constraint @@ -208,7 +214,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-
-example-disallowed +out-of-range ```yaml apiVersion: v1 @@ -231,7 +237,7 @@ spec: Usage ```shell -kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_disallowed.yaml +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml ```
@@ -246,7 +252,6 @@ metadata: labels: app: nginx-host-networking-ports spec: - hostNetwork: false containers: - name: nginx image: nginx @@ -259,12 +264,12 @@ spec: Usage ```shell -kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed.yaml +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml ```
-disallowed-ephemeral +out-of-range-ephemeral ```yaml apiVersion: v1 @@ -319,7 +324,7 @@ kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-
-use-of-host-network-blocked +host-network-forbidden
constraint @@ -336,20 +341,98 @@ spec: kinds: ["Pod"] parameters: hostNetwork: false - exemptImages: - - "nginx" + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/block_host_network/constraint.yaml +``` + +
+ +
+hostnetwork-true + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-network-true +spec: + hostNetwork: true + containers: + - name: nginx + image: nginx + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml +``` + +
+
+hostnetwork-false + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx-host-network-false +spec: + hostNetwork: false + containers: + - name: nginx + image: nginx + +``` + +Usage + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml +``` + +
+ + +
+port-range-with-host-network-forbidden + +
+constraint + +```yaml +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sPSPHostNetworkingPorts +metadata: + name: psp-host-network-ports +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Pod"] + parameters: + hostNetwork: false + min: 80 + max: 9000 + ``` Usage ```shell -kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint_block_host_network.yaml +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/constraint.yaml ```
-example-disallowed +out-of-range-and-host-network-true ```yaml apiVersion: v1 @@ -372,12 +455,12 @@ spec: Usage ```shell -kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_disallowed.yaml +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml ```
-example-allowed +in-range-host-network-false ```yaml apiVersion: v1 @@ -387,7 +470,6 @@ metadata: labels: app: nginx-host-networking-ports spec: - hostNetwork: false containers: - name: nginx image: nginx @@ -400,7 +482,7 @@ spec: Usage ```shell -kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed.yaml +kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml ```