Skip to content

Commit 4997d44

Browse files
authored
fix(shield): set seLinuxOptions to control_t for unprivileged host shield bottlerocket deployment (#2416)
Signed-off-by: Roberto Scolaro <[email protected]>
1 parent 3599af3 commit 4997d44

File tree

7 files changed

+257
-12
lines changed

7 files changed

+257
-12
lines changed

charts/shield/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ maintainers:
1313
- name: mavimo
1414
1515
type: application
16-
version: 1.23.0
16+
version: 1.23.1
1717
appVersion: "1.0.0"

charts/shield/templates/host/_helpers.tpl

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ capabilities:
201201
allowPrivilegeEscalation: false
202202
seccompProfile:
203203
type: Unconfined
204+
{{- if eq (include "host.response_actions_needs_higher_privileges" .) "true" }}
205+
seLinuxOptions:
206+
type: control_t
207+
{{- end }}
204208
capabilities:
205209
drop:
206210
- ALL
@@ -227,20 +231,48 @@ true
227231

228232
{{/*
229233
This function checks if the response_actions feature is enabled for the host.
230-
It first checks the additional_settings and then the features.
234+
It first checks host.additional_settings.features.respond/responding, then features.respond/responding.
231235
If neither is found, it defaults to false.
232236
*/}}
233237
{{- define "host.response_actions_enabled" }}
234-
{{- $feature_respond := dig "respond" (dict) .Values.features }}
238+
{{- $respondKey := include "host.respond_key" .Values.features }}
235239
{{- $additional_features := dig "features" (dict) .Values.host.additional_settings }}
236-
{{- $additional_respond := dig "respond" (dict) $additional_features }}
240+
{{- $additional_respond := dig $respondKey (dict) $additional_features }}
241+
{{- $feature_respond := dig $respondKey (dict) .Values.features }}
237242
{{- if hasKey $additional_respond "response_actions" }}
238243
{{- dig "response_actions" "enabled" false $additional_respond -}}
239244
{{- else if hasKey $feature_respond "response_actions" }}
240245
{{- dig "response_actions" "enabled" false $feature_respond -}}
241246
{{- end }}
242247
{{- end }}
243248

249+
{{/*
250+
This function checks if response actions that need higher privileges are enabled.
251+
These include: file_acquire, file_quarantine, and get_logs.
252+
Returns true if response_actions is enabled AND at least one of these actions has trigger != "none".
253+
Checks host.additional_settings first, then features.
254+
*/}}
255+
{{- define "host.response_actions_needs_higher_privileges" }}
256+
{{- if eq (include "host.response_actions_enabled" .) "true" }}
257+
{{- $respondKey := include "host.respond_key" .Values.features }}
258+
{{- $additional_features := dig "features" (dict) .Values.host.additional_settings }}
259+
{{- $additional_respond := dig $respondKey (dict) $additional_features }}
260+
{{- $feature_respond := dig $respondKey (dict) .Values.features }}
261+
{{- $response_actions := dict }}
262+
{{- if hasKey $additional_respond "response_actions" }}
263+
{{- $response_actions = get $additional_respond "response_actions" }}
264+
{{- else if hasKey $feature_respond "response_actions" }}
265+
{{- $response_actions = get $feature_respond "response_actions" }}
266+
{{- end }}
267+
{{- $file_acquire_trigger := dig "file_acquire" "trigger" "all" $response_actions }}
268+
{{- $file_quarantine_trigger := dig "file_quarantine" "trigger" "all" $response_actions }}
269+
{{- $get_logs_trigger := dig "get_logs" "trigger" "all" $response_actions }}
270+
{{- if or (ne $file_acquire_trigger "none") (ne $file_quarantine_trigger "none") (ne $get_logs_trigger "none") }}
271+
{{- true -}}
272+
{{- end }}
273+
{{- end }}
274+
{{- end }}
275+
244276
{{- define "host.rapid_response_password" }}
245277
{{- $feature_respond := get .Values.features (include "host.respond_key" .Values.features) }}
246278
{{- if (dig "rapid_response" "password" nil $feature_respond) }}

charts/shield/tests/cluster/deployment_test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,7 @@ tests:
14411441

14421442
- it: Host Alias are not included by default
14431443
asserts:
1444-
- notContains:
1444+
- isNull:
14451445
path: spec.template.spec.hostAliases
14461446
template: templates/cluster/deployment.yaml
14471447

charts/shield/tests/host/daemonset-windows_test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ tests:
467467

468468
- it: Host Alias are not included by default
469469
asserts:
470-
- notContains:
470+
- isNull:
471471
path: spec.template.spec.hostAliases
472472

473473
- it: Single Host Alias is included if configured

charts/shield/tests/host/daemonset_test.yaml

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,83 @@ tests:
144144
readOnlyRootFilesystem: false
145145
allowPrivilegeEscalation: true
146146

147+
- it: Test host.privileged=false with response_actions needing higher privileges adds seLinuxOptions
148+
set:
149+
host:
150+
privileged: false
151+
features:
152+
respond:
153+
response_actions:
154+
enabled: true
155+
file_acquire:
156+
trigger: all
157+
asserts:
158+
- isSubset:
159+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
160+
content:
161+
allowPrivilegeEscalation: false
162+
seccompProfile:
163+
type: Unconfined
164+
seLinuxOptions:
165+
type: control_t
166+
capabilities:
167+
drop:
168+
- ALL
169+
add:
170+
- DAC_READ_SEARCH
171+
- KILL
172+
- SETGID
173+
- SETUID
174+
- SYS_ADMIN
175+
- SYS_CHROOT
176+
- SYS_PTRACE
177+
- SYS_RESOURCE
178+
179+
- it: Test host.privileged=false without higher privilege response_actions does not add seLinuxOptions
180+
set:
181+
host:
182+
privileged: false
183+
features:
184+
respond:
185+
response_actions:
186+
enabled: true
187+
file_acquire:
188+
trigger: none
189+
file_quarantine:
190+
trigger: none
191+
get_logs:
192+
trigger: none
193+
asserts:
194+
- isSubset:
195+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
196+
content:
197+
allowPrivilegeEscalation: false
198+
seccompProfile:
199+
type: Unconfined
200+
- isNotSubset:
201+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
202+
content:
203+
seLinuxOptions:
204+
type: control_t
205+
206+
- it: Test host.privileged=false with response_actions defaults to enabled when not specified
207+
set:
208+
host:
209+
privileged: false
210+
features:
211+
respond:
212+
response_actions:
213+
enabled: true
214+
asserts:
215+
- isSubset:
216+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
217+
content:
218+
allowPrivilegeEscalation: false
219+
seccompProfile:
220+
type: Unconfined
221+
seLinuxOptions:
222+
type: control_t
223+
147224
- it: Test user specified priority class
148225
set:
149226
host:
@@ -797,7 +874,7 @@ tests:
797874

798875
- it: Host Alias are not included by default
799876
asserts:
800-
- notContains:
877+
- isNull:
801878
path: spec.template.spec.hostAliases
802879

803880
- it: Single Host Alias is included if configured

charts/shield/tests/host/secrets_test.yaml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ tests:
7777
enabled: true
7878
password_existing_secret: existing-secret
7979
asserts:
80-
- notExists:
80+
- containsDocument:
8181
kind: Secret
8282
apiVersion: v1
8383
name: release-name-shield-host-rapid-response
8484
namespace: shield-namespace
85-
template: templates/host/secrets.yaml
85+
not: true
86+
template: host/secrets.yaml
8687
- equal:
8788
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].env[?(@.name == "PASSWORD")]
8889
value:
@@ -91,7 +92,7 @@ tests:
9192
secretKeyRef:
9293
name: existing-secret
9394
key: password
94-
template: templates/host/daemonset.yaml
95+
template: templates/host/daemonset.yaml
9596

9697
- it: Test Rapid Response using existing secret for password with custom key
9798
set:
@@ -102,11 +103,12 @@ tests:
102103
password_existing_secret: existing-secret
103104
password_existing_secret_key: custom-key
104105
asserts:
105-
- notExists:
106+
- containsDocument:
106107
kind: Secret
107108
apiVersion: v1
108109
name: release-name-shield-host-rapid-response
109110
namespace: shield-namespace
111+
not: true
110112
template: templates/host/secrets.yaml
111113
- equal:
112114
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].env[?(@.name == "PASSWORD")]
@@ -116,7 +118,7 @@ tests:
116118
secretKeyRef:
117119
name: existing-secret
118120
key: custom-key
119-
template: templates/host/daemonset.yaml
121+
template: templates/host/daemonset.yaml
120122

121123
- it: Test Local Forwarder secret is not created when disabled
122124
asserts:

charts/shield/tests/host/security_context_test.yaml

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,140 @@ tests:
5656
runAsNonRoot: false
5757
runAsUser: 0
5858

59+
- it: Ensure the securityContext with response_actions file_acquire includes seLinuxOptions
60+
set:
61+
host:
62+
privileged: false
63+
driver: universal_ebpf
64+
features:
65+
respond:
66+
response_actions:
67+
enabled: true
68+
file_acquire:
69+
trigger: all
70+
asserts:
71+
- isSubset:
72+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
73+
content:
74+
allowPrivilegeEscalation: false
75+
seccompProfile:
76+
type: Unconfined
77+
seLinuxOptions:
78+
type: control_t
79+
80+
- it: Ensure the securityContext with response_actions file_quarantine includes seLinuxOptions
81+
set:
82+
host:
83+
privileged: false
84+
driver: universal_ebpf
85+
features:
86+
respond:
87+
response_actions:
88+
enabled: true
89+
file_quarantine:
90+
trigger: all
91+
asserts:
92+
- isSubset:
93+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
94+
content:
95+
allowPrivilegeEscalation: false
96+
seccompProfile:
97+
type: Unconfined
98+
seLinuxOptions:
99+
type: control_t
100+
101+
- it: Ensure the securityContext with response_actions get_logs includes seLinuxOptions
102+
set:
103+
host:
104+
privileged: false
105+
driver: universal_ebpf
106+
features:
107+
respond:
108+
response_actions:
109+
enabled: true
110+
get_logs:
111+
trigger: all
112+
asserts:
113+
- isSubset:
114+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
115+
content:
116+
allowPrivilegeEscalation: false
117+
seccompProfile:
118+
type: Unconfined
119+
seLinuxOptions:
120+
type: control_t
121+
122+
- it: Ensure the securityContext without response_actions does not include seLinuxOptions
123+
set:
124+
host:
125+
privileged: false
126+
driver: universal_ebpf
127+
features:
128+
respond:
129+
response_actions:
130+
enabled: false
131+
asserts:
132+
- isSubset:
133+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
134+
content:
135+
allowPrivilegeEscalation: false
136+
seccompProfile:
137+
type: Unconfined
138+
- isNotSubset:
139+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
140+
content:
141+
seLinuxOptions:
142+
type: control_t
143+
144+
- it: Ensure the securityContext with response_actions but no higher privilege actions does not include seLinuxOptions
145+
set:
146+
host:
147+
privileged: false
148+
driver: universal_ebpf
149+
features:
150+
respond:
151+
response_actions:
152+
enabled: true
153+
file_acquire:
154+
trigger: none
155+
file_quarantine:
156+
trigger: none
157+
get_logs:
158+
trigger: none
159+
kill_process:
160+
trigger: all
161+
asserts:
162+
- isSubset:
163+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
164+
content:
165+
allowPrivilegeEscalation: false
166+
seccompProfile:
167+
type: Unconfined
168+
- isNotSubset:
169+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
170+
content:
171+
seLinuxOptions:
172+
type: control_t
173+
174+
- it: Ensure the securityContext with response_actions defaults to enabled when actions not specified
175+
set:
176+
host:
177+
privileged: false
178+
driver: universal_ebpf
179+
features:
180+
respond:
181+
response_actions:
182+
enabled: true
183+
asserts:
184+
- isSubset:
185+
path: spec.template.spec.containers[?(@.name == "sysdig-host-shield")].securityContext
186+
content:
187+
allowPrivilegeEscalation: false
188+
seccompProfile:
189+
type: Unconfined
190+
seLinuxOptions:
191+
type: control_t
192+
59193
- it: Ensure the security_context is honored
60194
set:
61195
host:

0 commit comments

Comments
 (0)