diff --git a/charts/shield/Chart.yaml b/charts/shield/Chart.yaml index b7ecbae0f..98cb68c52 100644 --- a/charts/shield/Chart.yaml +++ b/charts/shield/Chart.yaml @@ -13,5 +13,5 @@ maintainers: - name: mavimo email: marcovito.moscaritolo@sysdig.com type: application -version: 1.21.3 +version: 1.21.4 appVersion: "1.0.0" diff --git a/charts/shield/templates/host/_helpers.tpl b/charts/shield/templates/host/_helpers.tpl index 3e70e0805..1a3d68a70 100644 --- a/charts/shield/templates/host/_helpers.tpl +++ b/charts/shield/templates/host/_helpers.tpl @@ -201,6 +201,10 @@ capabilities: allowPrivilegeEscalation: false seccompProfile: type: Unconfined +{{- if eq (include "host.response_actions_needs_higher_privileges" .) "true" }} +seLinuxOptions: + type: control_t +{{- end }} capabilities: drop: - ALL @@ -241,6 +245,31 @@ true {{- end }} {{- end }} +{{/* + This function checks if response actions that need higher privileges are enabled. + These include: file_acquire, file_quarantine, and get_logs. + Returns true if response_actions is enabled AND at least one of these actions has trigger != "none". +*/}} +{{- define "host.response_actions_needs_higher_privileges" }} +{{- if eq (include "host.response_actions_enabled" .) "true" }} +{{- $feature_respond := dig "respond" (dict) .Values.features }} +{{- $additional_features := dig "features" (dict) .Values.host.additional_settings }} +{{- $additional_respond := dig "respond" (dict) $additional_features }} +{{- $response_actions := dict }} +{{- if hasKey $additional_respond "response_actions" }} + {{- $response_actions = get $additional_respond "response_actions" }} +{{- else if hasKey $feature_respond "response_actions" }} + {{- $response_actions = get $feature_respond "response_actions" }} +{{- end }} +{{- $file_acquire_trigger := dig "file_acquire" "trigger" "all" $response_actions }} +{{- $file_quarantine_trigger := dig "file_quarantine" "trigger" "all" $response_actions }} +{{- $get_logs_trigger := dig "get_logs" "trigger" "all" $response_actions }} +{{- if or (ne $file_acquire_trigger "none") (ne $file_quarantine_trigger "none") (ne $get_logs_trigger "none") }} +{{- true -}} +{{- end }} +{{- end }} +{{- end }} + {{- define "host.rapid_response_password" }} {{- $feature_respond := get .Values.features (include "host.respond_key" .Values.features) }} {{- if (dig "rapid_response" "password" nil $feature_respond) }} diff --git a/charts/shield/tests/cluster/deployment_test.yaml b/charts/shield/tests/cluster/deployment_test.yaml index b0a1e572f..bce29f63c 100644 --- a/charts/shield/tests/cluster/deployment_test.yaml +++ b/charts/shield/tests/cluster/deployment_test.yaml @@ -1441,7 +1441,7 @@ tests: - it: Host Alias are not included by default asserts: - - notContains: + - isNull: path: spec.template.spec.hostAliases template: templates/cluster/deployment.yaml diff --git a/charts/shield/tests/host/daemonset-windows_test.yaml b/charts/shield/tests/host/daemonset-windows_test.yaml index 3dbb6e896..6a5493077 100644 --- a/charts/shield/tests/host/daemonset-windows_test.yaml +++ b/charts/shield/tests/host/daemonset-windows_test.yaml @@ -467,7 +467,7 @@ tests: - it: Host Alias are not included by default asserts: - - notContains: + - isNull: path: spec.template.spec.hostAliases - it: Single Host Alias is included if configured diff --git a/charts/shield/tests/host/daemonset_test.yaml b/charts/shield/tests/host/daemonset_test.yaml index 7152f1fe1..c265e49cb 100644 --- a/charts/shield/tests/host/daemonset_test.yaml +++ b/charts/shield/tests/host/daemonset_test.yaml @@ -144,6 +144,83 @@ tests: readOnlyRootFilesystem: false allowPrivilegeEscalation: true + - it: Test host.privileged=false with response_actions needing higher privileges adds seLinuxOptions + set: + host: + privileged: false + features: + respond: + response_actions: + enabled: true + file_acquire: + trigger: all + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + seLinuxOptions: + type: control_t + capabilities: + drop: + - ALL + add: + - DAC_READ_SEARCH + - KILL + - SETGID + - SETUID + - SYS_ADMIN + - SYS_CHROOT + - SYS_PTRACE + - SYS_RESOURCE + + - it: Test host.privileged=false without higher privilege response_actions does not add seLinuxOptions + set: + host: + privileged: false + features: + respond: + response_actions: + enabled: true + file_acquire: + trigger: none + file_quarantine: + trigger: none + get_logs: + trigger: none + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + - isNotSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + seLinuxOptions: + type: control_t + + - it: Test host.privileged=false with response_actions defaults to enabled when not specified + set: + host: + privileged: false + features: + respond: + response_actions: + enabled: true + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + seLinuxOptions: + type: control_t + - it: Test user specified priority class set: host: @@ -797,7 +874,7 @@ tests: - it: Host Alias are not included by default asserts: - - notContains: + - isNull: path: spec.template.spec.hostAliases - it: Single Host Alias is included if configured diff --git a/charts/shield/tests/host/secrets_test.yaml b/charts/shield/tests/host/secrets_test.yaml index 15afd102e..2905165b8 100644 --- a/charts/shield/tests/host/secrets_test.yaml +++ b/charts/shield/tests/host/secrets_test.yaml @@ -77,12 +77,13 @@ tests: enabled: true password_existing_secret: existing-secret asserts: - - notExists: + - containsDocument: kind: Secret apiVersion: v1 name: release-name-shield-host-rapid-response namespace: shield-namespace - template: templates/host/secrets.yaml + not: true + template: host/secrets.yaml - equal: path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].env[?(@.name == "PASSWORD")] value: @@ -91,7 +92,7 @@ tests: secretKeyRef: name: existing-secret key: password - template: templates/host/daemonset.yaml + template: templates/host/daemonset.yaml - it: Test Rapid Response using existing secret for password with custom key set: @@ -102,11 +103,12 @@ tests: password_existing_secret: existing-secret password_existing_secret_key: custom-key asserts: - - notExists: + - containsDocument: kind: Secret apiVersion: v1 name: release-name-shield-host-rapid-response namespace: shield-namespace + not: true template: templates/host/secrets.yaml - equal: path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].env[?(@.name == "PASSWORD")] @@ -116,7 +118,7 @@ tests: secretKeyRef: name: existing-secret key: custom-key - template: templates/host/daemonset.yaml + template: templates/host/daemonset.yaml - it: Test Local Forwarder secret is not created when disabled asserts: diff --git a/charts/shield/tests/host/security_context_test.yaml b/charts/shield/tests/host/security_context_test.yaml index 7364ead9b..d36c753df 100644 --- a/charts/shield/tests/host/security_context_test.yaml +++ b/charts/shield/tests/host/security_context_test.yaml @@ -56,6 +56,140 @@ tests: runAsNonRoot: false runAsUser: 0 + - it: Ensure the securityContext with response_actions file_acquire includes seLinuxOptions + set: + host: + privileged: false + driver: universal_ebpf + features: + respond: + response_actions: + enabled: true + file_acquire: + trigger: all + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + seLinuxOptions: + type: control_t + + - it: Ensure the securityContext with response_actions file_quarantine includes seLinuxOptions + set: + host: + privileged: false + driver: universal_ebpf + features: + respond: + response_actions: + enabled: true + file_quarantine: + trigger: all + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + seLinuxOptions: + type: control_t + + - it: Ensure the securityContext with response_actions get_logs includes seLinuxOptions + set: + host: + privileged: false + driver: universal_ebpf + features: + respond: + response_actions: + enabled: true + get_logs: + trigger: all + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + seLinuxOptions: + type: control_t + + - it: Ensure the securityContext without response_actions does not include seLinuxOptions + set: + host: + privileged: false + driver: universal_ebpf + features: + respond: + response_actions: + enabled: false + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + - isNotSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + seLinuxOptions: + type: control_t + + - it: Ensure the securityContext with response_actions but no higher privilege actions does not include seLinuxOptions + set: + host: + privileged: false + driver: universal_ebpf + features: + respond: + response_actions: + enabled: true + file_acquire: + trigger: none + file_quarantine: + trigger: none + get_logs: + trigger: none + kill_process: + trigger: all + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + - isNotSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + seLinuxOptions: + type: control_t + + - it: Ensure the securityContext with response_actions defaults to enabled when actions not specified + set: + host: + privileged: false + driver: universal_ebpf + features: + respond: + response_actions: + enabled: true + asserts: + - isSubset: + path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext + content: + allowPrivilegeEscalation: false + seccompProfile: + type: Unconfined + seLinuxOptions: + type: control_t + - it: Ensure the security_context is honored set: host: