From 310c48aba8f3a7ef2726dcb71d5b8b3723ba8666 Mon Sep 17 00:00:00 2001 From: Marco Ebert Date: Wed, 4 Oct 2023 15:03:49 +0200 Subject: [PATCH] Values: Tighten `controller.image`. Due to recent changes, the controller image can be run without privilege escalation: - https://github.com/kubernetes/ingress-nginx/issues/8499 - https://github.com/kubernetes/ingress-nginx/pull/7449 --- charts/ingress-nginx/README.md | 5 ++++- charts/ingress-nginx/templates/_helpers.tpl | 12 ++++++++++-- .../ingress-nginx/templates/controller-psp.yaml | 16 +++++++++++++--- charts/ingress-nginx/values.yaml | 6 +++++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/charts/ingress-nginx/README.md b/charts/ingress-nginx/README.md index de38cc20f..cf271b400 100644 --- a/charts/ingress-nginx/README.md +++ b/charts/ingress-nginx/README.md @@ -316,14 +316,17 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu | controller.hostPort.ports.http | int | `80` | 'hostPort' http port | | controller.hostPort.ports.https | int | `443` | 'hostPort' https port | | controller.hostname | object | `{}` | Optionally customize the pod hostname. | -| controller.image.allowPrivilegeEscalation | bool | `true` | | +| controller.image.allowPrivilegeEscalation | bool | `false` | | | controller.image.chroot | bool | `false` | | | controller.image.digest | string | `"sha256:5b161f051d017e55d358435f295f5e9a297e66158f136321d9b04520ec6c48a3"` | | | controller.image.digestChroot | string | `"sha256:5976b1067cfbca8a21d0ba53d71f83543a73316a61ea7f7e436d6cf84ddf9b26"` | | | controller.image.image | string | `"ingress-nginx/controller"` | | | controller.image.pullPolicy | string | `"IfNotPresent"` | | +| controller.image.readOnlyRootFilesystem | bool | `false` | | | controller.image.registry | string | `"registry.k8s.io"` | | +| controller.image.runAsNonRoot | bool | `true` | | | controller.image.runAsUser | int | `101` | | +| controller.image.seccompProfile.type | string | `"RuntimeDefault"` | | | controller.image.tag | string | `"v1.9.4"` | | | controller.ingressClass | string | `"nginx"` | For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation | | controller.ingressClassByName | bool | `false` | Process IngressClass per name (additionally as per spec.controller). | diff --git a/charts/ingress-nginx/templates/_helpers.tpl b/charts/ingress-nginx/templates/_helpers.tpl index 64d61ed1f..5f3296644 100644 --- a/charts/ingress-nginx/templates/_helpers.tpl +++ b/charts/ingress-nginx/templates/_helpers.tpl @@ -45,16 +45,24 @@ Controller container security context. {{- if .Values.controller.containerSecurityContext -}} {{- toYaml .Values.controller.containerSecurityContext -}} {{- else -}} +runAsNonRoot: {{ .Values.controller.image.runAsNonRoot }} +runAsUser: {{ .Values.controller.image.runAsUser }} +allowPrivilegeEscalation: {{ or .Values.controller.image.allowPrivilegeEscalation .Values.controller.image.chroot }} +{{- if .Values.controller.image.seccompProfile }} +seccompProfile: {{ toYaml .Values.controller.image.seccompProfile | nindent 2 }} +{{- end }} capabilities: drop: - ALL add: - NET_BIND_SERVICE {{- if .Values.controller.image.chroot }} + {{- if .Values.controller.image.seccompProfile }} + - SYS_ADMIN + {{- end }} - SYS_CHROOT {{- end }} -runAsUser: {{ .Values.controller.image.runAsUser }} -allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }} +readOnlyRootFilesystem: {{ .Values.controller.image.readOnlyRootFilesystem }} {{- end -}} {{- end -}} diff --git a/charts/ingress-nginx/templates/controller-psp.yaml b/charts/ingress-nginx/templates/controller-psp.yaml index 3c2065d86..aad1d2736 100644 --- a/charts/ingress-nginx/templates/controller-psp.yaml +++ b/charts/ingress-nginx/templates/controller-psp.yaml @@ -4,6 +4,8 @@ apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: {{ include "ingress-nginx.fullname" . }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: "*" labels: {{- include "ingress-nginx.labels" . | nindent 4 }} app.kubernetes.io/component: controller @@ -14,9 +16,7 @@ spec: privileged: false hostPID: false hostIPC: false -{{- if .Values.controller.hostNetwork }} hostNetwork: {{ .Values.controller.hostNetwork }} -{{- end }} {{- if or .Values.controller.hostNetwork .Values.controller.hostPort.enabled }} hostPorts: {{- if .Values.controller.hostNetwork }} @@ -67,15 +67,25 @@ spec: readOnlyRootFilesystem: false runAsUser: rule: MustRunAsNonRoot + runAsGroup: + rule: MustRunAs + ranges: + - min: 1 + max: 65535 supplementalGroups: rule: MustRunAs ranges: - min: 1 max: 65535 - allowPrivilegeEscalation: true + allowPrivilegeEscalation: {{ or .Values.controller.image.allowPrivilegeEscalation .Values.controller.image.chroot }} + requiredDropCapabilities: + - ALL allowedCapabilities: - NET_BIND_SERVICE {{- if .Values.controller.image.chroot }} + {{- if .Values.controller.image.seccompProfile }} + - SYS_ADMIN + {{- end }} - SYS_CHROOT {{- end }} seLinux: diff --git a/charts/ingress-nginx/values.yaml b/charts/ingress-nginx/values.yaml index 8adb565fd..a50383dee 100644 --- a/charts/ingress-nginx/values.yaml +++ b/charts/ingress-nginx/values.yaml @@ -31,9 +31,13 @@ controller: digest: sha256:5b161f051d017e55d358435f295f5e9a297e66158f136321d9b04520ec6c48a3 digestChroot: sha256:5976b1067cfbca8a21d0ba53d71f83543a73316a61ea7f7e436d6cf84ddf9b26 pullPolicy: IfNotPresent + runAsNonRoot: true # www-data -> uid 101 runAsUser: 101 - allowPrivilegeEscalation: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + readOnlyRootFilesystem: false # -- Use an existing PSP instead of creating one existingPsp: "" # -- Configures the controller container name