diff --git a/charts/agent/Chart.yaml b/charts/agent/Chart.yaml index 5c0039e5a..4094fb5a5 100644 --- a/charts/agent/Chart.yaml +++ b/charts/agent/Chart.yaml @@ -30,4 +30,4 @@ sources: - https://app.sysdigcloud.com/#/settings/user - https://github.com/draios/sysdig type: application -version: 1.26.0 +version: 1.27.0 diff --git a/charts/agent/README.md b/charts/agent/README.md index 61fb4a42c..31e11b675 100644 --- a/charts/agent/README.md +++ b/charts/agent/README.md @@ -148,6 +148,7 @@ The following table lists the configurable parameters of the Sysdig chart and th | `slim.resources.limits.memory` | Specifies the memory limit for building the kernel module. | `512Mi` | | `ebpf.enabled` | Enables eBPF support for Sysdig instead of `sysdig-probe` kernel module. | `false` | | `ebpf.kind` | Define which eBPF driver to use, can be `legacy_ebpf` or `universal_ebpf` | `legacy_ebpf` | +| `privileged` | Run the Sysdig Agent container as privileged. When set to false, eBPF must be enabled | `true` | | `clusterName` | Sets a unique cluster name which is used to identify events with the `kubernetes.cluster.name` tag. Overrides `global.clusterConfig.name`. | ` ` | | `sysdig.accessKey` | Your Sysdig Agent Access Key. Overrides `global.sysdig.accessKey` | Either `accessKey` or `existingAccessKeySecret` is required | | `sysdig.existingAccessKeySecret` | Specifies the name of a Kubernetes secret containing an `access-key ` entry. Overrides `global.sysdig.existingAccessKeySecret` | Either `accessKey` or `existingAccessKeySecret` is required | diff --git a/charts/agent/templates/_helpers.tpl b/charts/agent/templates/_helpers.tpl index ddc4e7174..4409f4bb4 100644 --- a/charts/agent/templates/_helpers.tpl +++ b/charts/agent/templates/_helpers.tpl @@ -585,6 +585,13 @@ true {{- end }} {{- end }} +{{/* Check if semver. The regex is from the code of the library Helm uses for semver. */}} +{{- define "agent.isSemVer" -}} + {{- if regexMatch "^v?([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?$" . }} + true + {{- end -}} +{{- end -}} + {{/* Return the name of the local forwarder configmap */}} {{- define "agent.localForwarderConfigMapName" }} {{- include "agent.configmapName" . | trunc 46 | trimSuffix "-" | printf "%s-local-forwarder" }} @@ -592,18 +599,77 @@ true {{- define "agent.enableHttpProbes" }} {{- if not (include "agent.gke.autopilot" .) }} -{{- if regexMatch "^v?([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?$" .Values.image.tag }} -{{- if semverCompare ">= 12.18.0-0" .Values.image.tag }} +{{- if and (include "agent.isSemVer" .Values.image.tag) (semverCompare ">= 12.18.0-0" .Values.image.tag) }} {{- printf "true" -}} {{- end }} {{- end }} {{- end }} -{{- end }} {{- define "agent.enableFalcoBaselineSecureLight" }} -{{- if regexMatch "^v?([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?$" .Values.image.tag }} -{{- if semverCompare ">= 12.19.0-0" .Values.image.tag }} +{{- if and (include "agent.isSemVer" .Values.image.tag) (semverCompare ">= 12.19.0-0" .Values.image.tag) }} {{- printf "true" -}} {{- end }} {{- end }} + +{{- define "agent.annotationsSection" }} + {{- if (include "agent.gke.autopilot" .) }} +annotations: + autopilot.gke.io/no-connect: "true" + {{- else if or (.Values.daemonset.annotations) (eq "false" (include "agent.privileged" .)) }} +annotations: + {{- if (eq "false" (include "agent.privileged" .)) }} + container.apparmor.security.beta.kubernetes.io/sysdig: unconfined + {{- end }} + {{- if .Values.daemonset.annotations }} +{{- toYaml .Values.daemonset.annotations | nindent 2 }} + {{- end }} + {{- end }} +{{- end }} + +{{/* + - .Values.privileged is true: no problem + - .Values.privileged is false: + - eBPF disabled: fail + - eBPF enabled: + - image tag >= 13.3.0: no problem + - image tag not semver: go on at user's risk +*/}} +{{- define "agent.privileged" }} + {{- if or .Values.privileged (include "agent.gke.autopilot" .) }} + {{- /* OK */ -}} + {{- print "true" }} + {{- else }} + {{- $errMsg := "Disabling 'privileged' flag requires eBPF and Sysdig Agent 13.3.0 or newer" }} + {{- /* eBPF is mandatory */ -}} + {{- if not (eq "true" (include "agent.ebpfEnabled" .)) }} + {{- /* FAIL */ -}} + {{- fail $errMsg }} + {{- end }} + {{- /* Version check */ -}} + {{- if (include "agent.isSemVer" .Values.image.tag) }} + {{- /* Check for release version */ -}} + {{- if (semverCompare ">= 13.3.0-0" .Values.image.tag) }} + {{- /* OK */ -}} + {{- print "false" }} + {{- else }} + {{- /* FAIL */ -}} + {{- fail $errMsg }} + {{- end }} + {{- /* Check for dev version */ -}} + {{- else }} + {{- /* Let it go through */ -}} + {{- print "false" }} + {{- end }} + {{- end }} {{- end }} + +{{- define "agent.capabilities" -}} +- SYS_ADMIN +- SYS_RESOURCE +- SYS_PTRACE +- SYS_CHROOT +- DAC_READ_SEARCH +- KILL +- SETUID +- SETGID +{{- end -}} diff --git a/charts/agent/templates/daemonset.yaml b/charts/agent/templates/daemonset.yaml index fa23912b1..3dcf92ce9 100644 --- a/charts/agent/templates/daemonset.yaml +++ b/charts/agent/templates/daemonset.yaml @@ -18,15 +18,7 @@ spec: labels: {{ include "agent.labels" . | nindent 8 }} {{ include "agent.daemonsetLabels" . | nindent 8 }} - {{- if (include "agent.gke.autopilot" .) }} - annotations: - autopilot.gke.io/no-connect: "true" - {{- else }} - {{- if .Values.daemonset.annotations }} - annotations: - {{ toYaml .Values.daemonset.annotations | nindent 8 }} - {{- end }} - {{- end }} + {{ include "agent.annotationsSection" . | nindent 6 }} spec: serviceAccountName: {{ template "agent.serviceAccountName" .}} {{- if or .Values.priorityClassName (include "agent.gke.autopilot" .) }} @@ -178,11 +170,22 @@ spec: resources: {{- include "agent.resources" . | nindent 12 }} securityContext: + {{- if eq "true" (include "agent.privileged" .) }} privileged: true runAsNonRoot: false runAsUser: 0 readOnlyRootFilesystem: false allowPrivilegeEscalation: true + {{- else }} + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + capabilities: + drop: + - ALL + add: + {{- include "agent.capabilities" . | nindent 14 }} + {{- end }} env: - name: K8S_NODE valueFrom: diff --git a/charts/agent/templates/securitycontextconstraint.yaml b/charts/agent/templates/securitycontextconstraint.yaml index b59ca0ba8..d92568681 100644 --- a/charts/agent/templates/securitycontextconstraint.yaml +++ b/charts/agent/templates/securitycontextconstraint.yaml @@ -15,7 +15,12 @@ allowHostPID: true allowHostPorts: false allowPrivilegeEscalation: true allowPrivilegedContainer: true +{{- if eq "true" (include "agent.privileged" .) }} allowedCapabilities: [] +{{- else }} +allowedCapabilities: +{{ include "agent.capabilities" . }} +{{- end }} allowedUnsafeSysctls: [] defaultAddCapabilities: [] fsGroup: diff --git a/charts/agent/tests/conditional_flag_test.yaml b/charts/agent/tests/conditional_flag_test.yaml index 50fa6ef68..f17e1e87b 100644 --- a/charts/agent/tests/conditional_flag_test.yaml +++ b/charts/agent/tests/conditional_flag_test.yaml @@ -46,3 +46,76 @@ tests: - equal: path: spec.template.spec.containers[*].image value: quay.io/sysdig/agent-slim:12.9.0 + + - it: Checking privileged flag set to true + set: + privileged: true + asserts: + - equal: + path: spec.template.spec.containers[*].securityContext.privileged + value: true + + - it: Checking privileged flag set to false with disabled ebpf + set: + privileged: false + ebpf: + enabled: false + asserts: + - failedTemplate: + errorMessage: "Disabling 'privileged' flag requires eBPF and Sysdig Agent 13.3.0 or newer" + + - it: Checking privileged flag set to false with old agent version + set: + privileged: false + ebpf: + enabled: true + image: + tag: 13.2.0 + asserts: + - failedTemplate: + errorMessage: "Disabling 'privileged' flag requires eBPF and Sysdig Agent 13.3.0 or newer" + + - it: Checking privileged flag set to false, agent version 13.3.0 + set: + privileged: false + ebpf: + enabled: true + image: + tag: 13.3.0 + asserts: + - equal: + path: spec.template.metadata.annotations['container.apparmor.security.beta.kubernetes.io/sysdig'] + value: "unconfined" + - notExists: + path: spec.template.spec.containers[*].securityContext.privileged + - equal: + path: spec.template.spec.containers[*].securityContext.seccompProfile.type + value: Unconfined + - contains: + path: spec.template.spec.containers[*].securityContext.capabilities.drop + content: ALL + - exists: + path: spec.template.spec.containers[*].securityContext.capabilities.add + + - it: Checking privileged flag set to false, not semver agent version + set: + privileged: false + ebpf: + enabled: true + image: + tag: whatever + asserts: + - equal: + path: spec.template.metadata.annotations + value: + container.apparmor.security.beta.kubernetes.io/sysdig: unconfined + - notExists: + path: spec.template.spec.containers[*].securityContext.privileged + - equal: + path: spec.template.spec.containers[*].securityContext.seccompProfile.type + value: Unconfined + - contains: + path: spec.template.spec.containers[*].securityContext.capabilities.drop + content: ALL + - exists: + path: spec.template.spec.containers[*].securityContext.capabilities.add diff --git a/charts/agent/tests/security_context_constraints_test.yaml b/charts/agent/tests/security_context_constraints_test.yaml new file mode 100644 index 000000000..5d7ba58a2 --- /dev/null +++ b/charts/agent/tests/security_context_constraints_test.yaml @@ -0,0 +1,76 @@ +suite: Testing Security Context Constraint +templates: + - securitycontextconstraint.yaml + +capabilities: + apiVersions: + - security.openshift.io/v1 + +kubernetesProvider: + scheme: + "v1/Node": + gvr: + version: "v1" + resource: "nodes" + namespaced: false + objects: + - apiVersion: v1 + kind: Node + metadata: + name: fakenode + status: + nodeInfo: + osImage: fake-os-image + +tests: + - it: Testing that SCS is not created if not enabled + set: + scc: + create: false + asserts: + - hasDocuments: + count: 0 + + - it: Testing that SCS is created when required + set: + scc: + create: true + asserts: + - hasDocuments: + count: 1 + - isKind: + of: SecurityContextConstraints + + - it: Testing that SCS capabilities are empty by default + set: + scc: + create: true + asserts: + - isEmpty: + path: allowedCapabilities + + - it: Testing that SCS capabilities are empty when privileged is true + set: + privileged: true + image: + tag: '13.3.0' + ebpf: + enabled: true + scc: + create: true + asserts: + - isEmpty: + path: allowedCapabilities + + - it: Testing that SCS capabilities are not empty when privileged is false + set: + privileged: false + image: + tag: '13.3.0' + ebpf: + enabled: true + scc: + create: true + asserts: + - isNotEmpty: + path: allowedCapabilities diff --git a/charts/agent/values.schema.json b/charts/agent/values.schema.json index 01ee9fdbd..1baad6deb 100644 --- a/charts/agent/values.schema.json +++ b/charts/agent/values.schema.json @@ -64,6 +64,9 @@ } } } + }, + "privileged": { + "type": "boolean" } }, "$defs": { diff --git a/charts/agent/values.yaml b/charts/agent/values.yaml index bd9d496a8..ef20b0349 100644 --- a/charts/agent/values.yaml +++ b/charts/agent/values.yaml @@ -200,6 +200,8 @@ ebpf: enabled: false # Define the kind of eBPF driver that will be used by the agent. Can be `legacy_ebpf` or `universal_ebpf` kind: legacy_ebpf +# Run the Sysdig Agent container as privileged. When set to false, eBPF must be enabled +privileged: true slim: # Uses a slim version of the Sysdig Agent enabled: true diff --git a/charts/sysdig-deploy/Chart.yaml b/charts/sysdig-deploy/Chart.yaml index db33b8ad6..31c3380c2 100644 --- a/charts/sysdig-deploy/Chart.yaml +++ b/charts/sysdig-deploy/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: sysdig-deploy description: A chart with various Sysdig components for Kubernetes type: application -version: 1.58.0 +version: 1.59.0 maintainers: - name: AlbertoBarba email: alberto.barba@sysdig.com @@ -26,7 +26,7 @@ dependencies: - name: agent # repository: https://charts.sysdig.com repository: file://../agent - version: ~1.26.0 + version: ~1.27.0 alias: agent condition: agent.enabled - name: common