From 435491d3118e8b1bf30e60862031052a1cf3d69c Mon Sep 17 00:00:00 2001 From: ConnorJC Date: Wed, 3 Aug 2022 15:21:16 -0400 Subject: [PATCH] Improve securityContext implementation Implement securityContext for containers Add securityContext for node pod Utilize more secure defaults for securityContext Improve `make generate-kustomize` to filter out namespace and tags --- Makefile | 10 ++--- charts/aws-ebs-csi-driver/CHANGELOG.md | 5 +++ charts/aws-ebs-csi-driver/Chart.yaml | 2 +- .../templates/controller.yaml | 26 +++++++++++- charts/aws-ebs-csi-driver/templates/node.yaml | 18 +++++++- charts/aws-ebs-csi-driver/values.yaml | 42 +++++++++++++++++-- deploy/kubernetes/base/controller.yaml | 31 +++++++++++++- deploy/kubernetes/base/node.yaml | 20 ++++++++- .../base/poddisruptionbudget-controller.yaml | 2 +- .../base/serviceaccount-csi-controller.yaml | 4 +- 10 files changed, 142 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index a09c715213..15a97c6aa5 100644 --- a/Makefile +++ b/Makefile @@ -229,9 +229,9 @@ generate-kustomize: bin/helm cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrolebinding-provisioner.yaml > ../../deploy/kubernetes/base/clusterrolebinding-provisioner.yaml cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrolebinding-resizer.yaml > ../../deploy/kubernetes/base/clusterrolebinding-resizer.yaml cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/clusterrolebinding-snapshotter.yaml > ../../deploy/kubernetes/base/clusterrolebinding-snapshotter.yaml - cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/controller.yaml --api-versions 'snapshot.storage.k8s.io/v1' > ../../deploy/kubernetes/base/controller.yaml + cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/controller.yaml --set "image.repository=k8s.gcr.io/provider-aws/aws-ebs-csi-driver" --api-versions 'snapshot.storage.k8s.io/v1' | sed -e "/namespace: /d" | sed -e "s/:v.*$$//g" > ../../deploy/kubernetes/base/controller.yaml cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/csidriver.yaml > ../../deploy/kubernetes/base/csidriver.yaml - cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/node.yaml > ../../deploy/kubernetes/base/node.yaml - cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/poddisruptionbudget-controller.yaml > ../../deploy/kubernetes/base/poddisruptionbudget-controller.yaml - cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/serviceaccount-csi-controller.yaml > ../../deploy/kubernetes/base/serviceaccount-csi-controller.yaml - cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/serviceaccount-csi-node.yaml > ../../deploy/kubernetes/base/serviceaccount-csi-node.yaml + cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/node.yaml --set "image.repository=k8s.gcr.io/provider-aws/aws-ebs-csi-driver" | sed -e "/namespace: /d" | sed -e "s/:v.*$$//g" > ../../deploy/kubernetes/base/node.yaml + cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/poddisruptionbudget-controller.yaml --api-versions 'policy/v1/PodDisruptionBudget' | sed -e "/namespace: /d" > ../../deploy/kubernetes/base/poddisruptionbudget-controller.yaml + cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/serviceaccount-csi-controller.yaml | sed -e "/namespace: /d" > ../../deploy/kubernetes/base/serviceaccount-csi-controller.yaml + cd charts/aws-ebs-csi-driver && ../../bin/helm template kustomize . -s templates/serviceaccount-csi-node.yaml | sed -e "/namespace: /d" > ../../deploy/kubernetes/base/serviceaccount-csi-node.yaml diff --git a/charts/aws-ebs-csi-driver/CHANGELOG.md b/charts/aws-ebs-csi-driver/CHANGELOG.md index ce484a9f6a..9818d2623f 100644 --- a/charts/aws-ebs-csi-driver/CHANGELOG.md +++ b/charts/aws-ebs-csi-driver/CHANGELOG.md @@ -1,5 +1,10 @@ # Helm chart +## 2.10.0 +* Implement securityContext for containers +* Add securityContext for node pod +* Utilize more secure defaults for securityContext + ## v2.9.0 * Bump app/driver to version `v1.10.0` * Feature: Reference `configMaps` across multiple resources using `envFrom` ([#1312](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/pull/1312), [@jebbens](https://github.com/jebbens)) diff --git a/charts/aws-ebs-csi-driver/Chart.yaml b/charts/aws-ebs-csi-driver/Chart.yaml index cdebb105fd..740e283582 100644 --- a/charts/aws-ebs-csi-driver/Chart.yaml +++ b/charts/aws-ebs-csi-driver/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 appVersion: 1.10.0 name: aws-ebs-csi-driver description: A Helm chart for AWS EBS CSI Driver -version: 2.9.0 +version: 2.10.0 kubeVersion: ">=1.17.0-0" home: https://github.com/kubernetes-sigs/aws-ebs-csi-driver sources: diff --git a/charts/aws-ebs-csi-driver/templates/controller.yaml b/charts/aws-ebs-csi-driver/templates/controller.yaml index 333190ea11..1beadd5ced 100644 --- a/charts/aws-ebs-csi-driver/templates/controller.yaml +++ b/charts/aws-ebs-csi-driver/templates/controller.yaml @@ -61,7 +61,7 @@ spec: {{- with .Values.controller.securityContext }} securityContext: {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} containers: - name: ebs-plugin image: {{ printf "%s:%s" .Values.image.repository (default (printf "v%s" .Chart.AppVersion) (.Values.image.tag | toString)) }} @@ -153,6 +153,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.controller.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} - name: csi-provisioner image: {{ printf "%s:%s" .Values.sidecars.provisioner.image.repository .Values.sidecars.provisioner.image.tag }} imagePullPolicy: {{ default .Values.image.pullPolicy .Values.sidecars.provisioner.image.pullPolicy }} @@ -185,6 +189,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.sidecars.provisioner.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} - name: csi-attacher image: {{ printf "%s:%s" .Values.sidecars.attacher.image.repository .Values.sidecars.attacher.image.tag }} imagePullPolicy: {{ default .Values.image.pullPolicy .Values.sidecars.attacher.image.pullPolicy }} @@ -212,6 +220,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.sidecars.attacher.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} {{- if or (.Capabilities.APIVersions.Has "snapshot.storage.k8s.io/v1beta1") (.Capabilities.APIVersions.Has "snapshot.storage.k8s.io/v1") }} - name: csi-snapshotter image: {{ printf "%s:%s" .Values.sidecars.snapshotter.image.repository .Values.sidecars.snapshotter.image.tag }} @@ -239,6 +251,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.sidecars.snapshotter.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} {{- end }} - name: csi-resizer image: {{ printf "%s:%s" .Values.sidecars.resizer.image.repository .Values.sidecars.resizer.image.tag }} @@ -267,6 +283,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.sidecars.resizer.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} - name: liveness-probe image: {{ printf "%s:%s" .Values.sidecars.livenessProbe.image.repository .Values.sidecars.livenessProbe.image.tag }} imagePullPolicy: {{ default .Values.image.pullPolicy .Values.sidecars.livenessProbe.image.pullPolicy }} @@ -283,6 +303,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.sidecars.livenessProbe.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} {{- if .Values.imagePullSecrets }} imagePullSecrets: {{- range .Values.imagePullSecrets }} diff --git a/charts/aws-ebs-csi-driver/templates/node.yaml b/charts/aws-ebs-csi-driver/templates/node.yaml index cec658dd94..f8d8569725 100644 --- a/charts/aws-ebs-csi-driver/templates/node.yaml +++ b/charts/aws-ebs-csi-driver/templates/node.yaml @@ -49,10 +49,12 @@ spec: {{- with .Values.node.tolerations }} {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.node.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - name: ebs-plugin - securityContext: - privileged: true image: {{ printf "%s:%s" .Values.image.repository (default (printf "v%s" .Chart.AppVersion) (toString .Values.image.tag)) }} imagePullPolicy: {{ .Values.image.pullPolicy }} args: @@ -104,6 +106,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.node.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} - name: node-driver-registrar image: {{ printf "%s:%s" .Values.sidecars.nodeDriverRegistrar.image.repository .Values.sidecars.nodeDriverRegistrar.image.tag }} imagePullPolicy: {{ default .Values.image.pullPolicy .Values.sidecars.nodeDriverRegistrar.image.pullPolicy }} @@ -135,6 +141,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.sidecars.nodeDriverRegistrar.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} - name: liveness-probe image: {{ printf "%s:%s" .Values.sidecars.livenessProbe.image.repository .Values.sidecars.livenessProbe.image.tag }} imagePullPolicy: {{ default .Values.image.pullPolicy .Values.sidecars.livenessProbe.image.pullPolicy }} @@ -151,6 +161,10 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} + {{- with .Values.sidecars.livenessProbe.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} {{- if .Values.imagePullSecrets }} imagePullSecrets: {{- range .Values.imagePullSecrets }} diff --git a/charts/aws-ebs-csi-driver/values.yaml b/charts/aws-ebs-csi-driver/values.yaml index c56f22942e..2d7076c11c 100644 --- a/charts/aws-ebs-csi-driver/values.yaml +++ b/charts/aws-ebs-csi-driver/values.yaml @@ -22,6 +22,9 @@ sidecars: tag: "v3.1.0" logLevel: 2 resources: {} + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false attacher: env: [] image: @@ -30,6 +33,9 @@ sidecars: tag: "v3.4.0" logLevel: 2 resources: {} + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false snapshotter: env: [] image: @@ -38,12 +44,18 @@ sidecars: tag: "v6.0.1" logLevel: 2 resources: {} + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false livenessProbe: image: pullPolicy: IfNotPresent repository: k8s.gcr.io/sig-storage/livenessprobe tag: "v2.6.0" resources: {} + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false resizer: env: [] image: @@ -52,6 +64,9 @@ sidecars: tag: "v1.4.0" logLevel: 2 resources: {} + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false nodeDriverRegistrar: env: [] image: @@ -60,6 +75,9 @@ sidecars: tag: "v2.5.1" logLevel: 2 resources: {} + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false proxy: http_proxy: @@ -136,9 +154,16 @@ controller: # topologyKey: kubernetes.io/hostname # whenUnsatisfiable: ScheduleAnyway topologySpreadConstraints: [] - securityContext: {} - # AWS EKS /var/run/secrets/eks.amazonaws.com/serviceaccount/token FS group is nogroup (65534) - required for Kubernetes 1.18.x and below - # fsGroup: 65534 + # securityContext on the controller pod + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + # securityContext on the controller container (see sidecars for securityContext on sidecar containers) + containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false node: env: [] @@ -172,6 +197,17 @@ node: type: RollingUpdate rollingUpdate: maxUnavailable: "10%" + # securityContext on the node pod + securityContext: + # The node pod must be run as root to bind to the registration/driver sockets + runAsNonRoot: false + runAsUser: 0 + runAsGroup: 0 + fsGroup: 0 + # securityContext on the node container (see sidecars for securityContext on sidecar containers) + containerSecurityContext: + readOnlyRootFilesystem: true + privileged: true storageClasses: [] # Add StorageClass resources like: diff --git a/deploy/kubernetes/base/controller.yaml b/deploy/kubernetes/base/controller.yaml index 0fdbe46778..397c8e696f 100644 --- a/deploy/kubernetes/base/controller.yaml +++ b/deploy/kubernetes/base/controller.yaml @@ -28,7 +28,12 @@ spec: operator: Exists - operator: Exists effect: NoExecute - tolerationSeconds: 300 + tolerationSeconds: 300 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 containers: - name: ebs-plugin image: k8s.gcr.io/provider-aws/aws-ebs-csi-driver @@ -63,6 +68,7 @@ spec: name: aws-meta key: endpoint optional: true + envFrom: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ @@ -86,6 +92,9 @@ spec: timeoutSeconds: 3 periodSeconds: 10 failureThreshold: 5 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true - name: csi-provisioner image: k8s.gcr.io/sig-storage/csi-provisioner imagePullPolicy: IfNotPresent @@ -99,9 +108,13 @@ spec: env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock + envFrom: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true - name: csi-attacher image: k8s.gcr.io/sig-storage/csi-attacher imagePullPolicy: IfNotPresent @@ -112,9 +125,13 @@ spec: env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock + envFrom: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true - name: csi-snapshotter image: k8s.gcr.io/sig-storage/csi-snapshotter imagePullPolicy: IfNotPresent @@ -124,9 +141,13 @@ spec: env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock + envFrom: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true - name: csi-resizer image: k8s.gcr.io/sig-storage/csi-resizer imagePullPolicy: IfNotPresent @@ -137,17 +158,25 @@ spec: env: - name: ADDRESS value: /var/lib/csi/sockets/pluginproxy/csi.sock + envFrom: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true - name: liveness-probe image: k8s.gcr.io/sig-storage/livenessprobe imagePullPolicy: IfNotPresent args: - --csi-address=/csi/csi.sock + envFrom: volumeMounts: - name: socket-dir mountPath: /csi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true volumes: - name: socket-dir emptyDir: {} diff --git a/deploy/kubernetes/base/node.yaml b/deploy/kubernetes/base/node.yaml index 908cc2fd0b..b7ea66c0f0 100644 --- a/deploy/kubernetes/base/node.yaml +++ b/deploy/kubernetes/base/node.yaml @@ -41,10 +41,13 @@ spec: - operator: Exists effect: NoExecute tolerationSeconds: 300 + securityContext: + fsGroup: 0 + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 containers: - name: ebs-plugin - securityContext: - privileged: true image: k8s.gcr.io/provider-aws/aws-ebs-csi-driver imagePullPolicy: IfNotPresent args: @@ -59,6 +62,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + envFrom: volumeMounts: - name: kubelet-dir mountPath: /var/lib/kubelet @@ -79,6 +83,10 @@ spec: timeoutSeconds: 3 periodSeconds: 10 failureThreshold: 5 + securityContext: + allowPrivilegeEscalation: false + privileged: true + readOnlyRootFilesystem: true - name: node-driver-registrar image: k8s.gcr.io/sig-storage/csi-node-driver-registrar imagePullPolicy: IfNotPresent @@ -91,19 +99,27 @@ spec: value: /csi/csi.sock - name: DRIVER_REG_SOCK_PATH value: /var/lib/kubelet/plugins/ebs.csi.aws.com/csi.sock + envFrom: volumeMounts: - name: plugin-dir mountPath: /csi - name: registration-dir mountPath: /registration + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true - name: liveness-probe image: k8s.gcr.io/sig-storage/livenessprobe imagePullPolicy: IfNotPresent args: - --csi-address=/csi/csi.sock + envFrom: volumeMounts: - name: plugin-dir mountPath: /csi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true volumes: - name: kubelet-dir hostPath: diff --git a/deploy/kubernetes/base/poddisruptionbudget-controller.yaml b/deploy/kubernetes/base/poddisruptionbudget-controller.yaml index 80c834f8ab..acf471300e 100644 --- a/deploy/kubernetes/base/poddisruptionbudget-controller.yaml +++ b/deploy/kubernetes/base/poddisruptionbudget-controller.yaml @@ -1,6 +1,6 @@ --- # Source: aws-ebs-csi-driver/templates/poddisruptionbudget-controller.yaml -apiVersion: policy/v1beta1 +apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: ebs-csi-controller diff --git a/deploy/kubernetes/base/serviceaccount-csi-controller.yaml b/deploy/kubernetes/base/serviceaccount-csi-controller.yaml index 208842cdf8..d0c6ff1922 100644 --- a/deploy/kubernetes/base/serviceaccount-csi-controller.yaml +++ b/deploy/kubernetes/base/serviceaccount-csi-controller.yaml @@ -6,6 +6,6 @@ metadata: name: ebs-csi-controller-sa labels: app.kubernetes.io/name: aws-ebs-csi-driver - #Enable if EKS IAM for SA is used + #Enable if EKS IAM roles for service accounts (IRSA) is used. See https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html for details. #annotations: - # eks.amazonaws.com/role-arn: arn:aws:iam::586565787010:role/ebs-csi-role + # eks.amazonaws.com/role-arn: arn::iam:::role/ebs-csi-role