diff --git a/deploy/charts/cert-manager/values.yaml b/deploy/charts/cert-manager/values.yaml index a2f06f6a6..b24c6371f 100644 --- a/deploy/charts/cert-manager/values.yaml +++ b/deploy/charts/cert-manager/values.yaml @@ -104,7 +104,8 @@ resources: {} # Pod Security Context # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ -securityContext: {} +securityContext: + runAsNonRoot: true # legacy securityContext parameter format: if enabled is set to true, only fsGroup and runAsUser are supported # securityContext: # enabled: false @@ -208,7 +209,10 @@ webhook: # maxSurge: 0 # maxUnavailable: 1 - securityContext: {} + # Pod Security Context to be set on the webhook component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true # Container Security Context to be set on the webhook component container # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ @@ -329,7 +333,10 @@ cainjector: # maxSurge: 0 # maxUnavailable: 1 - securityContext: {} + # Pod Security Context to be set on the cainjector component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true # Container Security Context to be set on the cainjector component container # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ diff --git a/devel/BUILD.bazel b/devel/BUILD.bazel index 543e7253d..0ad434022 100644 --- a/devel/BUILD.bazel +++ b/devel/BUILD.bazel @@ -12,6 +12,7 @@ filegroup( "//devel/addon/bind:all-srcs", "//devel/addon/certmanager:all-srcs", "//devel/addon/ingressnginx:all-srcs", + "//devel/addon/kyverno:all-srcs", "//devel/addon/pebble:all-srcs", "//devel/addon/sample-external-issuer:all-srcs", "//devel/addon/samplewebhook:all-srcs", diff --git a/devel/addon/bind/manifests/deployment.yaml b/devel/addon/bind/manifests/deployment.yaml index 44d6138c2..429fb9fe7 100644 --- a/devel/addon/bind/manifests/deployment.yaml +++ b/devel/addon/bind/manifests/deployment.yaml @@ -18,6 +18,10 @@ spec: - name: bind image: sameersbn/bind:bazel imagePullPolicy: Never + # TODO(wallrj): I couldn't figure out how to run Bind as a non-root user, using this Docker image. + # I think bind expects to start as root and then chown to a non-root BIND user. + # securityContext: + # runAsNonRoot: true command: - /bin/bash - -c diff --git a/devel/addon/kyverno/BUILD.bazel b/devel/addon/kyverno/BUILD.bazel new file mode 100644 index 000000000..6df04e38c --- /dev/null +++ b/devel/addon/kyverno/BUILD.bazel @@ -0,0 +1,13 @@ +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/devel/addon/kyverno/install.sh b/devel/addon/kyverno/install.sh new file mode 100755 index 000000000..a991695d3 --- /dev/null +++ b/devel/addon/kyverno/install.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# Copyright 2020 The cert-manager Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Installs an instance of Kyverno with its restrictive Pod security policies enabled. +# * https://kyverno.io/policies/pod-security/ +# +# We create custom Kyverno policies using a kustomization of the upstream +# policies, as follows: +# kustomize build . > policy.yaml + +set -o nounset +set -o errexit +set -o pipefail + +SCRIPT_ROOT=$(dirname "${BASH_SOURCE}") +source "${SCRIPT_ROOT}/../../lib/lib.sh" + +KYVERNO_VERSION="v1.3.6" + +check_tool kubectl +check_tool helm + +# Install latest version of Kyverno +helm repo add kyverno https://kyverno.github.io/kyverno/ +helm repo update +helm upgrade --install --wait kyverno kyverno/kyverno --namespace kyverno --create-namespace --version "${KYVERNO_VERSION}" +# Install cert-manager specific Pod security policy +kubectl create ns cert-manager || true +kubectl apply -f ${SCRIPT_ROOT}/policy.yaml diff --git a/devel/addon/kyverno/kustomization.yaml b/devel/addon/kyverno/kustomization.yaml new file mode 100644 index 000000000..4ea57fe28 --- /dev/null +++ b/devel/addon/kyverno/kustomization.yaml @@ -0,0 +1,17 @@ +# This Kustomization is used to adapt the upstream Pod security policy for use +# specifically in the cert-manager namespace. +# Changes ClusterPolicy resources to namespaced Policy. +# Use as follows: +# kustomize build . > policy.yaml +bases: + - https://github.com/kyverno/policies/pod-security +patches: + - patch: |- + - op: replace + path: /kind + value: Policy + - op: add + path: /metadata/namespace + value: cert-manager + target: + kind: ClusterPolicy diff --git a/devel/addon/kyverno/policy.yaml b/devel/addon/kyverno/policy.yaml new file mode 100644 index 000000000..34dcef43c --- /dev/null +++ b/devel/addon/kyverno/policy.yaml @@ -0,0 +1,725 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/description: Privilege escalation, such as via set-user-ID + or set-group-ID file mode, should not be allowed. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: deny-privilege-escalation + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: deny-privilege-escalation + validate: + message: Privilege escalation is disallowed. The fields spec.containers[*].securityContext.allowPrivilegeEscalation, + and spec.initContainers[*].securityContext.allowPrivilegeEscalation must be + undefined or set to `false`. + pattern: + spec: + =(initContainers): + - =(securityContext): + =(allowPrivilegeEscalation): "false" + containers: + - =(securityContext): + =(allowPrivilegeEscalation): "false" + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: Capabilities permit privileged actions without + giving full root access. Adding capabilities beyond the default set must not + be allowed. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: disallow-add-capabilities + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: capabilities + validate: + message: Adding of additional capabilities beyond the default set is not allowed. + The fields spec.containers[*].securityContext.capabilities.add and spec.initContainers[*].securityContext.capabilities.add + must be empty. + pattern: + spec: + =(initContainers): + - =(securityContext): + =(capabilities): + X(add): null + containers: + - =(securityContext): + =(capabilities): + X(add): null + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: Host namespaces (Process ID namespace, Inter-Process + Communication namespace, and network namespace) allow access to shared information + and can be used to elevate privileges. Pods should not be allowed access to + host namespaces. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: disallow-host-namespaces + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: host-namespaces + validate: + message: Sharing the host namespaces is disallowed. The fields spec.hostNetwork, + spec.hostIPC, and spec.hostPID must not be set to true. + pattern: + spec: + =(hostIPC): "false" + =(hostNetwork): "false" + =(hostPID): "false" + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: HostPath volumes let pods use host directories + and volumes in containers. Using host resources can be used to access shared + data or escalate privileges and should not be allowed. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: disallow-host-path + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: host-path + validate: + message: HostPath volumes are forbidden. The fields spec.volumes[*].hostPath + must not be set. + pattern: + spec: + =(volumes): + - X(hostPath): "null" + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: Access to host ports allows potential snooping + of network traffic and should not be allowed, or at minimum restricted to a + known list. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: disallow-host-ports + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: host-ports + validate: + message: Use of host ports is disallowed. The fields spec.containers[*].ports[*].hostPort + and spec.initContainers[*].ports[*].hostPort must be empty. + pattern: + spec: + =(initContainers): + - =(ports): + - X(hostPort): 0 + containers: + - =(ports): + - X(hostPort): 0 + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: Privileged mode disables most security mechanisms + and must not be allowed. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: disallow-privileged-containers + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: priviledged-containers + validate: + message: Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged + and spec.initContainers[*].securityContext.privileged must not be set to true. + pattern: + spec: + =(initContainers): + - =(securityContext): + =(privileged): "false" + containers: + - =(securityContext): + =(privileged): "false" + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: SELinux options can be used to escalate privileges + and should not be allowed. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/title: Disallow SELinux + name: disallow-selinux + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: seLinux + validate: + message: Setting custom SELinux options is disallowed. The fields spec.securityContext.seLinuxOptions, + spec.containers[*].securityContext.seLinuxOptions, and spec.initContainers[*].securityContext.seLinuxOptions + must be empty. + pattern: + spec: + =(initContainers): + - =(securityContext): + X(seLinuxOptions): "null" + =(securityContext): + X(seLinuxOptions): "null" + containers: + - =(securityContext): + X(seLinuxOptions): "null" + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: The default /proc masks are set up to reduce + attack surface and should be required. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: require-default-proc-mount + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: check-proc-mount + validate: + message: Changing the proc mount from the default is not allowed. The fields + spec.containers[*].securityContext.procMount and spec.initContainers[*].securityContext.procMount + must not be changed from `Default`. + pattern: + spec: + =(initContainers): + - =(securityContext): + =(procMount): Default + containers: + - =(securityContext): + =(procMount): Default + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/description: Containers should be forbidden from running with + a root primary or supplementary GID. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: require-non-root-groups + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: check-runasgroup + validate: + message: "Running with root group IDs is disallowed. The fields\t spec.securityContext.runAsGroup, + spec.containers[*].securityContext.runAsGroup,\t and spec.initContainers[*].securityContext.runAsGroup + must be empty\t or greater than zero." + pattern: + spec: + =(initContainers): + - =(securityContext): + =(runAsGroup): '>0' + =(securityContext): + =(runAsGroup): '>0' + containers: + - =(securityContext): + =(runAsGroup): '>0' + - match: + resources: + kinds: + - Pod + name: check-supplementalGroups + validate: + message: "Adding of supplemental group IDs is not allowed. The field\t spec.securityContext.supplementalGroups + must not be defined." + pattern: + spec: + =(securityContext): + =(supplementalGroups): + - "null" + - match: + resources: + kinds: + - Pod + name: check-fsGroup + validate: + message: Changing to root group ID is disallowed. The field spec.securityContext.fsGroup + must be empty or greater than zero. + pattern: + spec: + =(securityContext): + =(fsGroup): '>0' + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/description: Containers must be required to run as non-root + users. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: require-run-as-non-root + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: check-containers + validate: + anyPattern: + - spec: + =(initContainers): + - =(securityContext): + =(runAsNonRoot): true + containers: + - =(securityContext): + =(runAsNonRoot): true + securityContext: + runAsNonRoot: true + - spec: + =(initContainers): + - securityContext: + runAsNonRoot: true + containers: + - securityContext: + runAsNonRoot: true + message: Running as root is not allowed. The fields spec.securityContext.runAsNonRoot, + spec.containers[*].securityContext.runAsNonRoot, and spec.initContainers[*].securityContext.runAsNonRoot + must be `true`. + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: On supported hosts, the 'runtime/default' AppArmor + profile is applied by default. The default policy should prevent overriding + or disabling the policy, or restrict overrides to an allowed set of profiles. + policies.kyverno.io/minversion: 1.3.0 + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod, Annotation + policies.kyverno.io/title: Restrict AppArmor + name: restrict-apparmor-profiles + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: app-armor + validate: + message: Specifying other AppArmor profiles is disallowed. The annotation container.apparmor.security.beta.kubernetes.io + must not be defined, or must not be set to anything other than `runtime/default`. + pattern: + metadata: + =(annotations): + =(container.apparmor.security.beta.kubernetes.io/*): runtime/default + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/description: The runtime default seccomp profile must be required, + or only specific additional profiles should be allowed. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/title: Restrict Seccomp + name: restrict-seccomp + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: seccomp + validate: + message: Use of custom Seccomp profiles is disallowed. The fields spec.securityContext.seccompProfile.type, + spec.containers[*].securityContext.seccompProfile.type, and spec.initContainers[*].securityContext.seccompProfile.type + must be unset or set to `runtime/default`. + pattern: + spec: + =(initContainers): + - =(securityContext): + =(seccompProfile): + =(type): runtime/default + =(securityContext): + =(seccompProfile): + =(type): runtime/default + containers: + - =(securityContext): + =(seccompProfile): + =(type): runtime/default + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/description: Sysctls can disable security mechanisms or affect + all containers on a host, and should be disallowed except for an allowed "safe" + subset. A sysctl is considered safe if it is namespaced in the container or + the Pod, and it is isolated from other Pods or processes on the same Node. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: restrict-sysctls + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: sysctls + validate: + message: Setting additional sysctls above the allowed type is disallowed. The + field spec.securityContext.sysctls must not use any other names than 'kernel.shm_rmid_forced', + 'net.ipv4.ip_local_port_range', 'net.ipv4.tcp_syncookies' and 'net.ipv4.ping_group_range'. + pattern: + spec: + =(securityContext): + =(sysctls): + - name: kernel.shm_rmid_forced | net.ipv4.ip_local_port_range | net.ipv4.tcp_syncookies + | net.ipv4.ping_group_range + value: ?* + validationFailureAction: enforce +--- +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + annotations: + policies.kyverno.io/category: Pod Security Standards (Restricted) + policies.kyverno.io/description: In addition to restricting HostPath volumes, + the restricted pod security profile limits usage of non-core volume types to + those defined through PersistentVolumes. + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + name: restrict-volume-types + namespace: cert-manager +spec: + background: true + rules: + - match: + resources: + kinds: + - Pod + name: restricted-vol-gcePersistentDisk + validate: + message: Use of the gcePersistentDisk type volume is disallowed. The fields + spec.volumes[*].gcePersistentDisk must not be set. + pattern: + spec: + =(volumes): + - X(gcePersistentDisk): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-awsElasticBlockStore + validate: + message: Use of the awsElasticBlockStore type volume is disallowed. The fields + spec.volumes[*].awsElasticBlockStore must not be set. + pattern: + spec: + =(volumes): + - X(awsElasticBlockStore): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-gitRepo + validate: + message: Use of the gitRepo type volume is disallowed. The fields spec.volumes[*].gitRepo + must not be set. + pattern: + spec: + =(volumes): + - X(gitRepo): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-nfs + validate: + message: Use of the nfs type volume is disallowed. The fields spec.volumes[*].nfs + must not be set. + pattern: + spec: + =(volumes): + - X(nfs): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-iscsi + validate: + message: Use of the iscsi type volume is disallowed. The fields spec.volumes[*].iscsi + must not be set. + pattern: + spec: + =(volumes): + - X(iscsi): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-glusterfs + validate: + message: Use of the glusterfs type volume is disallowed. The fields spec.volumes[*].glusterfs + must not be set. + pattern: + spec: + =(volumes): + - X(glusterfs): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-rbd + validate: + message: Use of the rbd type volume is disallowed. The fields spec.volumes[*].rbd + must not be set. + pattern: + spec: + =(volumes): + - X(rbd): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-flexVolume + validate: + message: Use of the flexVolume type volume is disallowed. The fields spec.volumes[*].flexVolume + must not be set. + pattern: + spec: + =(volumes): + - X(flexVolume): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-cinder + validate: + message: Use of the cinder type volume is disallowed. The fields spec.volumes[*].cinder + must not be set. + pattern: + spec: + =(volumes): + - X(cinder): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-cephfs + validate: + message: Use of the cephfs type volume is disallowed. The fields spec.volumes[*].cephfs + must not be set. + pattern: + spec: + =(volumes): + - X(cephfs): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-flocker + validate: + message: Use of the flocker type volume is disallowed. The fields spec.volumes[*].flocker + must not be set. + pattern: + spec: + =(volumes): + - X(flocker): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-fc + validate: + message: Use of the fc type volume is disallowed. The fields spec.volumes[*].fc + must not be set. + pattern: + spec: + =(volumes): + - X(fc): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-azureFile + validate: + message: Use of the azureFile type volume is disallowed. The fields spec.volumes[*].azureFile + must not be set. + pattern: + spec: + =(volumes): + - X(azureFile): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-vsphereVolume + validate: + message: Use of the vsphereVolume type volume is disallowed. The fields spec.volumes[*].vsphereVolume + must not be set. + pattern: + spec: + =(volumes): + - X(vsphereVolume): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-quobyte + validate: + message: Use of the quobyte type volume is disallowed. The fields spec.volumes[*].quobyte + must not be set. + pattern: + spec: + =(volumes): + - X(quobyte): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-azureDisk + validate: + message: Use of the azureDisk type volume is disallowed. The fields spec.volumes[*].azureDisk + must not be set. + pattern: + spec: + =(volumes): + - X(azureDisk): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-portworxVolume + validate: + message: Use of the portworxVolume type volume is disallowed. The fields spec.volumes[*].portworxVolume + must not be set. + pattern: + spec: + =(volumes): + - X(portworxVolume): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-scaleIO + validate: + message: Use of the scaleIO type volume is disallowed. The fields spec.volumes[*].scaleIO + must not be set. + pattern: + spec: + =(volumes): + - X(scaleIO): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-storageos + validate: + message: Use of the storageos type volume is disallowed. The fields spec.volumes[*].storageos + must not be set. + pattern: + spec: + =(volumes): + - X(storageos): "null" + - match: + resources: + kinds: + - Pod + name: restricted-vol-csi + validate: + message: Use of the csi type volume is disallowed. The fields spec.volumes[*].csi + must not be set. + pattern: + spec: + =(volumes): + - X(csi): "null" + validationFailureAction: enforce diff --git a/devel/addon/pebble/BUILD.bazel b/devel/addon/pebble/BUILD.bazel index a1337a6fe..9f60fef78 100644 --- a/devel/addon/pebble/BUILD.bazel +++ b/devel/addon/pebble/BUILD.bazel @@ -1,6 +1,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary") load("@io_bazel_rules_docker//go:image.bzl", "go_image") load("@io_bazel_rules_docker//container:bundle.bzl", "container_bundle") +load("@io_bazel_rules_docker//container:container.bzl", "container_image") # gazelle:ignore @@ -12,9 +13,16 @@ container_bundle( tags = ["manual"], ) +container_image( + name = "nonroot_go_image_static", + base = "@go_image_static//image", + # See https://github.com/GoogleContainerTools/distroless/blob/2cac07c7c62b2dc52c4274a1810939fb06039ab9/base/base.bzl#L9 + user = "65532", +) + go_image( name = "image", - base = "@static_base//image", + base = ":nonroot_go_image_static", binary = ":app", tags = ["manual"], visibility = ["//visibility:public"], diff --git a/devel/addon/pebble/chart/templates/deployment.yaml b/devel/addon/pebble/chart/templates/deployment.yaml index ea47e533a..73f97831f 100644 --- a/devel/addon/pebble/chart/templates/deployment.yaml +++ b/devel/addon/pebble/chart/templates/deployment.yaml @@ -23,6 +23,8 @@ spec: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + runAsNonRoot: true args: - -config=/config/config.json - -strict={{ .Values.strict }} diff --git a/devel/addon/samplewebhook/chart/templates/deployment.yaml b/devel/addon/samplewebhook/chart/templates/deployment.yaml index 1d506aeee..60f18403e 100644 --- a/devel/addon/samplewebhook/chart/templates/deployment.yaml +++ b/devel/addon/samplewebhook/chart/templates/deployment.yaml @@ -25,19 +25,17 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} args: + - --secure-port=8443 - --tls-cert-file=/tls/tls.crt - --tls-private-key-file=/tls/tls.key - # These are explicitly set as they are not granted by default in OpenShift securityContext: - capabilities: - add: - - NET_BIND_SERVICE + runAsNonRoot: true env: - name: GROUP_NAME value: {{ .Values.groupName | quote }} ports: - name: https - containerPort: 443 + containerPort: 8443 protocol: TCP livenessProbe: httpGet: diff --git a/devel/addon/samplewebhook/sample/BUILD.bazel b/devel/addon/samplewebhook/sample/BUILD.bazel index 44049ddcf..380ff102f 100644 --- a/devel/addon/samplewebhook/sample/BUILD.bazel +++ b/devel/addon/samplewebhook/sample/BUILD.bazel @@ -1,9 +1,17 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") load("@io_bazel_rules_docker//go:image.bzl", "go_image") +load("@io_bazel_rules_docker//container:container.bzl", "container_image") + +container_image( + name = "nonroot_go_image_static", + base = "@go_image_static//image", + # See https://github.com/GoogleContainerTools/distroless/blob/2cac07c7c62b2dc52c4274a1810939fb06039ab9/base/base.bzl#L9 + user = "65532", +) go_image( name = "image", - base = "@static_base//image", + base = ":nonroot_go_image_static", binary = ":sample", tags = ["manual"], visibility = ["//visibility:public"], diff --git a/devel/setup-e2e-deps.sh b/devel/setup-e2e-deps.sh index 5508235f7..9095c8bf9 100755 --- a/devel/setup-e2e-deps.sh +++ b/devel/setup-e2e-deps.sh @@ -31,6 +31,9 @@ source "${SCRIPT_ROOT}/lib/lib.sh" # Configure PATH to use bazel provided e2e tools setup_tools +echo "Installing kyverno into cluster..." +"${SCRIPT_ROOT}/addon/kyverno/install.sh" + echo "Installing cert-manager into the cluster..." "${SCRIPT_ROOT}/addon/certmanager/install.sh" @@ -38,20 +41,19 @@ check_bazel bazel build --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 //devel/addon/... echo "Installing sample-webhook into the cluster..." -"${SCRIPT_ROOT}/addon/samplewebhook/install.sh" +"${SCRIPT_ROOT}/addon/samplewebhook/install.sh" echo "Installing bind into the cluster..." -"${SCRIPT_ROOT}/addon/bind/install.sh" +"${SCRIPT_ROOT}/addon/bind/install.sh" echo "Installing pebble into the cluster..." -"${SCRIPT_ROOT}/addon/pebble/install.sh" +"${SCRIPT_ROOT}/addon/pebble/install.sh" echo "Installing ingress-nginx into the cluster..." -"${SCRIPT_ROOT}/addon/ingressnginx/install.sh" +"${SCRIPT_ROOT}/addon/ingressnginx/install.sh" echo "Loading vault into the cluster..." -"${SCRIPT_ROOT}/addon/vault/install.sh" +"${SCRIPT_ROOT}/addon/vault/install.sh" echo "Installing sample-external-issuer into the cluster..." -"${SCRIPT_ROOT}/addon/sample-external-issuer/install.sh" - +"${SCRIPT_ROOT}/addon/sample-external-issuer/install.sh" diff --git a/pkg/issuer/acme/http/BUILD.bazel b/pkg/issuer/acme/http/BUILD.bazel index 515ce5f4d..eba282845 100644 --- a/pkg/issuer/acme/http/BUILD.bazel +++ b/pkg/issuer/acme/http/BUILD.bazel @@ -28,6 +28,7 @@ go_library( "@io_k8s_client_go//listers/core/v1:go_default_library", "@io_k8s_client_go//listers/networking/v1beta1:go_default_library", "@io_k8s_utils//net:go_default_library", + "@io_k8s_utils//pointer:go_default_library", ], ) diff --git a/pkg/issuer/acme/http/pod.go b/pkg/issuer/acme/http/pod.go index 8aafd7bd7..49805729b 100644 --- a/pkg/issuer/acme/http/pod.go +++ b/pkg/issuer/acme/http/pod.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/utils/pointer" cmacme "github.com/jetstack/cert-manager/pkg/apis/acme/v1" logf "github.com/jetstack/cert-manager/pkg/logs" @@ -168,6 +169,9 @@ func (s *Solver) buildDefaultPod(ch *cmacme.Challenge) *corev1.Pod { }, Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyOnFailure, + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: pointer.BoolPtr(true), + }, Containers: []corev1.Container{ { Name: "acmesolver",