Managing seccomp profiles
Create and manage seccomp profiles and bind them to workloads.
The Security Profiles Operator supports only Red Hat Enterprise Linux CoreOS (RHCOS) worker nodes. Red Hat Enterprise Linux (RHEL) nodes are not supported.
Create seccomp profiles
Use the SeccompProfile object to create seccomp profiles.
SeccompProfile objects can restrict syscalls within a container, limiting the access of your application.
Procedure
-
Create a project by running the following command:
$ oc new-project my-namespace -
Create the
SeccompProfileobject:apiVersion: security-profiles-operator.x-k8s.io/v1beta1kind: SeccompProfilemetadata:name: profile1spec:defaultAction: SCMP_ACT_LOGThe seccomp profile will be saved in
/var/lib/kubelet/seccomp/operator/<namespace>/<name>.json.An
initcontainer creates the root directory of the Security Profiles Operator to run the Operator withoutrootgroup or user ID privileges. A symbolic link is created from the rootless profile storage/var/lib/openshift-security-profilesto the defaultseccomproot path inside of the kubelet root/var/lib/kubelet/seccomp/operator.
Apply seccomp profiles to a pod
To enforce a recorded or custom seccomp profile on a workload, create a pod that references the profile in its security context.
Procedure
-
Create a pod object that defines a
securityContext:apiVersion: v1kind: Podmetadata:name: test-podspec:securityContext:runAsNonRoot: trueseccompProfile:type: LocalhostlocalhostProfile: operator/profile1.jsoncontainers:- name: test-containerimage: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21securityContext:allowPrivilegeEscalation: falsecapabilities:drop: [ALL] -
View the profile path of the
seccompProfile.localhostProfileattribute by running the following command:$ oc get seccompprofile profile1 --output wideExample outputNAME STATUS AGE SECCOMPPROFILE.LOCALHOSTPROFILEprofile1 Installed 14s operator/profile1.json -
View the path to the localhost profile by running the following command:
$ oc get sp profile1 --output=jsonpath='{.status.localhostProfile}'Example outputoperator/profile1.json -
Apply the
localhostProfileoutput to the patch file:spec:template:spec:securityContext:seccompProfile:type: LocalhostlocalhostProfile: operator/profile1.json -
Apply the profile to any other workload, such as a
Deploymentobject, by running the following command:$ oc -n my-namespace patch deployment myapp --patch-file patch.yaml --type=mergeExample outputdeployment.apps/myapp patched
Verification
-
Confirm the profile was applied correctly by running the following command:
$ oc -n my-namespace get deployment myapp --output=jsonpath='{.spec.template.spec.securityContext}' | jq .Example output{"seccompProfile": {"localhostProfile": "operator/profile1.json","type": "localhost"}}
Bind workloads to profiles with ProfileBindings
You can use the ProfileBinding resource to bind a security profile to the SecurityContext of a container.
Procedure
-
To bind a pod that uses a
quay.io/security-profiles-operator/test-nginx-unprivileged:1.21image to the exampleSeccompProfileprofile, create aProfileBindingobject in the same namespace with the pod and theSeccompProfileobjects:apiVersion: security-profiles-operator.x-k8s.io/v1alpha1kind: ProfileBindingmetadata:namespace: my-namespacename: nginx-bindingspec:profileRef:kind: SeccompProfilename: profileimage: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21where:
spec.profileRef.kind- Specifies the kind of the profile.
spec.profileRef.name- Specifies the name of the profile.
spec.image- Allows you to enable a default security profile by using a wildcard in the image attribute:
image: "*"
warningUsing the
image: "*"wildcard attribute binds all new pods with a default security profile in a given namespace. -
Label the namespace with
enable-binding=trueby running the following command:$ oc label ns my-namespace spo.x-k8s.io/enable-binding=true -
Define a pod named
test-pod.yaml:apiVersion: v1kind: Podmetadata:name: test-podspec:containers:- name: test-containerimage: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21 -
Create the pod:
$ oc create -f test-pod.yamlnoteIf the pod already exists, you must re-create the pod for the binding to work properly.
Verification
-
Confirm the pod inherits the
ProfileBindingby running the following command:$ oc get pod test-pod -o jsonpath='{.spec.containers[*].securityContext.seccompProfile}'Example output{"localhostProfile":"operator/profile.json","type":"Localhost"}
Record profiles from workloads
The Security Profiles Operator can record system calls with ProfileRecording objects to create baseline profiles for applications.
When using the log enricher for recording seccomp profiles, verify the log enricher feature is enabled. See Additional resources for more information.
A container with privileged: true security context restraints prevents log-based recording. Privileged containers are not subject to seccomp policies, and log-based recording makes use of a special seccomp profile to record events.
Procedure
-
Create a project by running the following command:
$ oc new-project my-namespace -
Label the namespace with
enable-recording=trueby running the following command:$ oc label ns my-namespace spo.x-k8s.io/enable-recording=true -
Create a
ProfileRecordingobject containing arecorder: logsvariable:apiVersion: security-profiles-operator.x-k8s.io/v1alpha1kind: ProfileRecordingmetadata:namespace: my-namespacename: test-recordingspec:kind: SeccompProfilerecorder: logspodSelector:matchLabels:app: my-app -
Create a workload to record:
apiVersion: v1kind: Podmetadata:namespace: my-namespacename: my-podlabels:app: my-appspec:securityContext:runAsNonRoot: trueseccompProfile:type: RuntimeDefaultcontainers:- name: nginximage: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21ports:- containerPort: 8080securityContext:allowPrivilegeEscalation: falsecapabilities:drop: [ALL]- name: redisimage: quay.io/security-profiles-operator/redis:6.2.1securityContext:allowPrivilegeEscalation: falsecapabilities:drop: [ALL] -
Confirm the pod is in a
Runningstate by entering the following command:$ oc -n my-namespace get podsExample outputNAME READY STATUS RESTARTS AGEmy-pod 2/2 Running 0 18s -
Confirm the enricher indicates that it receives audit logs for those containers:
$ oc -n openshift-security-profiles logs --since=1m --selector name=spod -c log-enricherExample outputI0523 14:19:08.747313 430694 enricher.go:445] log-enricher "msg"="audit" "container"="redis" "executable"="/usr/local/bin/redis-server" "namespace"="my-namespace" "node"="xiyuan-23-5g2q9-worker-eastus2-6rpgf" "pid"=656802 "pod"="my-pod" "syscallID"=0 "syscallName"="read" "timestamp"="1684851548.745:207179" "type"="seccomp"
Verification
-
Remove the pod:
$ oc -n my-namespace delete pod my-pod -
Confirm the Security Profiles Operator reconciles the two seccomp profiles:
$ oc get seccompprofiles -lspo.x-k8s.io/recording-id=test-recordingExample output for seccomp profileNAME STATUS AGEtest-recording-nginx Installed 2m48stest-recording-redis Installed 2m48s
Merge per-container profile instances
To reuse one recorded profile when deploying applications with a ReplicaSet or Deployment, configure the Security Profiles Operator to merge per-container profile instances into a single profile instead of keeping a separate profile for each container.
Procedure
-
Edit a
ProfileRecordingobject to include amergeStrategy: containersvariable:apiVersion: security-profiles-operator.x-k8s.io/v1alpha1kind: ProfileRecordingmetadata:# The name of the Recording is the same as the resulting SeccompProfile CRD# after reconciliation.name: test-recordingnamespace: my-namespacespec:kind: SeccompProfilerecorder: logsmergeStrategy: containerspodSelector:matchLabels:app: sp-record -
Label the namespace by running the following command:
$ oc label ns my-namespace security.openshift.io/scc.podSecurityLabelSync=false pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/audit=privileged pod-security.kubernetes.io/warn=privileged --overwrite=true -
Create the workload with the following YAML:
apiVersion: apps/v1kind: Deploymentmetadata:name: nginx-deploynamespace: my-namespacespec:replicas: 3selector:matchLabels:app: sp-recordtemplate:metadata:labels:app: sp-recordspec:serviceAccountName: spo-record-sacontainers:- name: nginx-recordimage: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21ports:- containerPort: 8080 -
To record the individual profiles, delete the deployment by running the following command:
$ oc delete deployment nginx-deploy -n my-namespace -
To merge the profiles, delete the profile recording by running the following command:
$ oc delete profilerecording test-recording -n my-namespace -
To start the merge operation and generate the results profile, run the following command:
$ oc get seccompprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespaceExample output for seccomp profileNAME STATUS AGEtest-recording-nginx-record Installed 55s -
To view the permissions used by any of the containers, run the following command:
$ oc get seccompprofiles test-recording-nginx-record -o yaml
Additional resources