$ oc -n openshift-security-profiles patch spod spod --type merge \
-p '{"spec":{"allowedSyscalls": ["exit", "exit_group", "futex", "nanosleep"]}}'
Use advanced tasks to enable metrics, configure webhooks, or restrict syscalls.
The Security Profiles Operator does not restrict syscalls
in seccomp
profiles by default. You can define the list of allowed syscalls
in the spod
configuration.
To define the list of allowedSyscalls
, adjust the spec
parameter by running the following command:
$ oc -n openshift-security-profiles patch spod spod --type merge \
-p '{"spec":{"allowedSyscalls": ["exit", "exit_group", "futex", "nanosleep"]}}'
The Operator will install only the When the list of allowed |
You can use the baseProfileName
attribute to establish the minimum required syscalls
for a given runtime to start a container.
Edit the SeccompProfile
kind object and add baseProfileName: runc-v1.0.0
to the spec
field:
apiVersion: security-profiles-operator.x-k8s.io/v1beta1
kind: SeccompProfile
metadata:
namespace: my-namespace
name: example-name
spec:
defaultAction: SCMP_ACT_ERRNO
baseProfileName: runc-v1.0.0
syscalls:
- action: SCMP_ACT_ALLOW
names:
- exit_group
The controller running inside of spod
daemon process watches all pods available in the cluster when profile recording is enabled. This can lead to very high memory usage in large clusters, resulting in the spod
daemon running out of memory or crashing.
To prevent crashes, the spod
daemon can be configured to only load the pods labeled for profile recording into the cache memory.
SPO memory optimization is not enabled by default. |
Enable memory optimization by running the following command:
$ oc -n openshift-security-profiles patch spod spod --type=merge -p '{"spec":{"enableMemoryOptimization":true}}'
To record a security profile for a pod, the pod must be labeled with spo.x-k8s.io/enable-recording: "true"
:
apiVersion: v1
kind: Pod
metadata:
name: my-recording-pod
labels:
spo.x-k8s.io/enable-recording: "true"
# ...
The default resource requirements of the daemon container can be adjusted by using the field daemonResourceRequirements
from the spod
configuration.
To specify the memory and cpu requests and limits of the daemon container, run the following command:
$ oc -n openshift-security-profiles patch spod spod --type merge -p \
'{"spec":{"daemonResourceRequirements": { \
"requests": {"memory": "256Mi", "cpu": "250m"}, \
"limits": {"memory": "512Mi", "cpu": "500m"}}}}'
The default priority class name of the spod
daemon pod is set to system-node-critical
. A custom priority class name can be configured in the spod
configuration by setting a value in the priorityClassName
field.
Configure the priority class name by running the following command:
$ oc -n openshift-security-profiles patch spod spod --type=merge -p '{"spec":{"priorityClassName":"my-priority-class"}}'
securityprofilesoperatordaemon.openshift-security-profiles.x-k8s.io/spod patched
The openshift-security-profiles
namespace provides metrics endpoints, which are secured by the kube-rbac-proxy container. All metrics are exposed by the metrics
service within the openshift-security-profiles
namespace.
The Security Profiles Operator includes a cluster role and corresponding binding spo-metrics-client
to retrieve the metrics from within the cluster. There are two metrics paths available:
metrics.openshift-security-profiles/metrics
: for controller runtime metrics
metrics.openshift-security-profiles/metrics-spod
: for the Operator daemon metrics
To view the status of the metrics service, run the following command:
$ oc get svc/metrics -n openshift-security-profiles
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
metrics ClusterIP 10.0.0.228 <none> 443/TCP 43s
To retrieve the metrics, query the service endpoint using the default ServiceAccount
token in the openshift-security-profiles
namespace by running the following command:
$ oc run --rm -i --restart=Never --image=registry.fedoraproject.org/fedora-minimal:latest \
-n openshift-security-profiles metrics-test -- bash -c \
'curl -ks -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://metrics.openshift-security-profiles/metrics-spod'
# HELP security_profiles_operator_seccomp_profile_total Counter about seccomp profile operations.
# TYPE security_profiles_operator_seccomp_profile_total counter
security_profiles_operator_seccomp_profile_total{operation="delete"} 1
security_profiles_operator_seccomp_profile_total{operation="update"} 2
To retrieve metrics from a different namespace, link the ServiceAccount
to the spo-metrics-client
ClusterRoleBinding
by running the following command:
$ oc get clusterrolebinding spo-metrics-client -o wide
NAME ROLE AGE USERS GROUPS SERVICEACCOUNTS
spo-metrics-client ClusterRole/spo-metrics-client 35m openshift-security-profiles/default
The controller-runtime metrics
and the DaemonSet endpoint metrics-spod
provide a set of default metrics. Additional metrics are provided by the daemon, which are always prefixed with security_profiles_operator_
.
Metric key | Possible labels | Type | Purpose |
---|---|---|---|
|
|
Counter |
Amount of seccomp profile operations. |
|
|
Counter |
Amount of seccomp profile audit operations. Requires the log enricher to be enabled. |
|
|
Counter |
Amount of seccomp profile bpf operations. Requires the bpf recorder to be enabled. |
|
|
Counter |
Amount of seccomp profile errors. |
|
|
Counter |
Amount of SELinux profile operations. |
|
|
Counter |
Amount of SELinux profile audit operations. Requires the log enricher to be enabled. |
|
|
Counter |
Amount of SELinux profile errors. |
The Security Profiles Operator contains a log enrichment feature, which is disabled by default. The log enricher container runs with privileged
permissions to read the audit logs from the local node. The log enricher runs within the host PID namespace, hostPID
.
The log enricher must have permissions to read the host processes. |
Patch the spod
configuration to enable the log enricher by running the following command:
$ oc -n openshift-security-profiles patch spod spod \
--type=merge -p '{"spec":{"enableLogEnricher":true}}'
securityprofilesoperatordaemon.security-profiles-operator.x-k8s.io/spod patched
The Security Profiles Operator will re-deploy the |
View the audit logs by running the following command:
$ oc -n openshift-security-profiles logs -f ds/spod log-enricher
I0623 12:51:04.257814 1854764 deleg.go:130] setup "msg"="starting component: log-enricher" "buildDate"="1980-01-01T00:00:00Z" "compiler"="gc" "gitCommit"="unknown" "gitTreeState"="clean" "goVersion"="go1.16.2" "platform"="linux/amd64" "version"="0.4.0-dev"
I0623 12:51:04.257890 1854764 enricher.go:44] log-enricher "msg"="Starting log-enricher on node: 127.0.0.1"
I0623 12:51:04.257898 1854764 enricher.go:46] log-enricher "msg"="Connecting to local GRPC server"
I0623 12:51:04.258061 1854764 enricher.go:69] log-enricher "msg"="Reading from file /var/log/audit/audit.log"
2021/06/23 12:51:04 Seeked /var/log/audit/audit.log - &{Offset:0 Whence:2}
You can use the Security Profiles Operator log enricher to trace an application.
To trace an application, create a SeccompProfile
logging profile:
apiVersion: security-profiles-operator.x-k8s.io/v1beta1
kind: SeccompProfile
metadata:
name: log
namespace: default
spec:
defaultAction: SCMP_ACT_LOG
Create a pod object to use the profile:
apiVersion: v1
kind: Pod
metadata:
name: log-pod
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: Localhost
localhostProfile: operator/default/log.json
containers:
- name: log-container
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
Examine the log enricher output by running the following command:
$ oc -n openshift-security-profiles logs -f ds/spod log-enricher
…
I0623 12:59:11.479869 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=3 "syscallName"="close" "timestamp"="1624453150.205:1061" "type"="seccomp"
I0623 12:59:11.487323 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=157 "syscallName"="prctl" "timestamp"="1624453150.205:1062" "type"="seccomp"
I0623 12:59:11.492157 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=157 "syscallName"="prctl" "timestamp"="1624453150.205:1063" "type"="seccomp"
…
I0623 12:59:20.258523 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=12 "syscallName"="brk" "timestamp"="1624453150.235:2873" "type"="seccomp"
I0623 12:59:20.263349 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=21 "syscallName"="access" "timestamp"="1624453150.235:2874" "type"="seccomp"
I0623 12:59:20.354091 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=257 "syscallName"="openat" "timestamp"="1624453150.235:2875" "type"="seccomp"
I0623 12:59:20.358844 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=5 "syscallName"="fstat" "timestamp"="1624453150.235:2876" "type"="seccomp"
I0623 12:59:20.363510 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=9 "syscallName"="mmap" "timestamp"="1624453150.235:2877" "type"="seccomp"
I0623 12:59:20.454127 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=3 "syscallName"="close" "timestamp"="1624453150.235:2878" "type"="seccomp"
I0623 12:59:20.458654 1854764 enricher.go:111] log-enricher "msg"="audit" "container"="log-container" "executable"="/usr/sbin/nginx" "namespace"="default" "node"="127.0.0.1" "pid"=1905792 "pod"="log-pod" "syscallID"=257 "syscallName"="openat" "timestamp"="1624453150.235:2879" "type"="seccomp"
…
Profile binding and profile recording objects can use webhooks. Profile binding and recording object configurations are MutatingWebhookConfiguration
CRs, managed by the Security Profiles Operator.
To change the webhook configuration, the spod
CR exposes a webhookOptions
field that allows modification of the failurePolicy
, namespaceSelector
, and objectSelector
variables. This allows you to set the webhooks to "soft-fail" or restrict them to a subset of a namespaces so that even if the webhooks failed, other namespaces or resources are not affected.
Set the recording.spo.io
webhook configuration to record only pods labeled with spo-record=true
by creating the following patch file:
spec:
webhookOptions:
- name: recording.spo.io
objectSelector:
matchExpressions:
- key: spo-record
operator: In
values:
- "true"
Patch the spod/spod
instance by running the following command:
$ oc -n openshift-security-profiles patch spod \
spod -p $(cat /tmp/spod-wh.patch) --type=merge
To view the resulting MutatingWebhookConfiguration
object, run the following command:
$ oc get MutatingWebhookConfiguration \
spo-mutating-webhook-configuration -oyaml