Managing seccomp profiles
Create and manage seccomp profiles and bind them to workloads.
Creating seccomp profiles
Use the SeccompProfile
object to create profiles.
SeccompProfile
objects can restrict syscalls within a container, limiting the access of your application.
Procedure
Create the
SeccompProfile
object:apiVersion: security-profiles-operator.x-k8s.io/v1beta1
kind: SeccompProfile
metadata:
namespace: my-namespace
name: profile1
spec:
defaultAction: SCMP_ACT_LOG
The seccomp profile will be saved in /var/lib/kubelet/seccomp/operator/<namespace>/<name>.json
.
An init
container creates the root directory of the Security Profiles Operator to run the Operator without root
group or user ID privileges. A symbolic link is created from the rootless profile storage /var/lib/openshift-security-profiles
to the default seccomp
root path inside of the kubelet root /var/lib/kubelet/seccomp/operator
.
Applying seccomp profiles to a pod
Create a pod to apply one of the created profiles.
Procedure
Create a pod object that defines a
securityContext
:apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: operator/my-namespace/profile1.json
containers:
- name: test-container
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
View the profile path of the
seccompProfile.localhostProfile
attribute by running the following command:$ oc -n my-namespace get seccompprofile profile1 --output wide
Example output
NAME STATUS AGE SECCOMPPROFILE.LOCALHOSTPROFILE
profile1 Active 14s operator/my-namespace/profile1.json
View the path to the localhost profile by running the following command:
$ oc get sp profile1 --output=jsonpath='{.status.localhostProfile}'
Example output
operator/my-namespace/profile1.json
Apply the
localhostProfile
output to the patch file:spec:
template:
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: operator/my-namespace/profile1.json
Apply the profile to a
Deployment
object by running the following command:$ oc -n my-namespace patch deployment myapp --patch-file patch.yaml --type=merge
Example output
deployment.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/my-namespace/profile1.json",
"type": "localhost"
}
}
Binding 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.21
image to the exampleSeccompProfile
profile, create aProfileBinding
object in the same namespace with the pod and theSeccompProfile
objects:apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileBinding
metadata:
namespace: my-namespace
name: nginx-binding
spec:
profileRef:
kind: SeccompProfile (1)
name: profile (2)
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
1 The kind:
variable refers to the name of the profile.2 The name:
variable refers to the name of the profile.Label the namespace with
enable-binding=true
by running the following command:$ oc label ns my-namespace spo.x-k8s.io/enable-binding=true
Delete and re-create the pod to use the
ProfileBinding
object:$ oc delete pods test-pod && oc create -f pod01.yaml
Verification
Confirm the pod inherits the
ProfileBinding
by running the following command:$ oc get pod test-pod -o jsonpath='{.spec.containers[*].securityContext.seccompProfile}'
Example output
{"localhostProfile":"operator/my-namespace/profile.json","type":"Localhost"}
Recording profiles from workloads
The Security Profiles Operator can record system calls with ProfileRecording
objects, making it easier 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 |
Procedure
Label the namespace with
enable-recording=true
by running the following command:$ oc label ns my-namespace spo.x-k8s.io/enable-recording=true
Create a
ProfileRecording
object containing arecorder: logs
variable:apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileRecording
metadata:
name: test-recording
spec:
kind: SeccompProfile
recorder: logs
podSelector:
matchLabels:
app: my-app
Create a workload to record:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
spec:
containers:
- name: nginx
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
ports:
- containerPort: 8080
- name: redis
image: quay.io/security-profiles-operator/redis:6.2.1
Confirm the pod is in a
Running
state by entering the following command:$ oc -n openshift-security-profiles get pods
Example output
NAME READY STATUS RESTARTS AGE
my-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-enricher
Example output
I0517 13:55:36.383187 348295 enricher.go:376] log-enricher "msg"="audit" "container"="redis" "namespace"="my-namespace" "node"="ip-10-0-189-53.us-east-2.compute.internal" "perm"="name_bind" "pod"="my-pod" "profile"="test-recording_redis_6kmrb_1684331729" "scontext"="system_u:system_r:selinuxrecording.process:s0:c4,c27" "tclass"="tcp_socket" "tcontext"="system_u:object_r:redis_port_t:s0" "timestamp"="1684331735.105:273965" "type"="seccomp"
Verification
Remove the pod:
$ oc -n openshift-security-profiles delete pod my-pod
Confirm the Security Profiles Operator reconciles the two seccomp profiles:
$ oc get seccompprofiles -n my-namespace
Example output
NAME USAGE STATE
test-recording-nginx test-recording-nginx_my-namespace.process Installed
test-recording-redis test-recording-redis_my-namespace.process Installed
Merging per-container profile instances
By default, each container instance records into a separate profile. The Security Profiles Operator can merge the per-container profiles into a single profile. Merging profiles is useful when deploying applications using ReplicaSet
or Deployment
objects.
Procedure
Edit a
ProfileRecording
object to include amergeStrategy: containers
variable:apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileRecording
metadata:
# The name of the Recording is the same as the resulting SeccompProfile CRD
# after reconciliation.
name: test-recording
spec:
kind: SeccompProfile
recorder: logs
mergeStrategy: containers
podSelector:
matchLabels:
app: sp-record
Create the workload:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: sp-record
template:
metadata:
labels:
app: sp-record
spec:
serviceAccountName: spo-record-sa
containers:
- name: nginx-record
image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
ports:
- containerPort: 8080
To record the individual profiles, delete the deployment by running the following command:
$ oc delete deployment nginx-deploy
To merge the profiles, delete the profile recording by running the following command:
$ oc delete profilerecording test-recording
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
Example output
NAME USAGE STATE
test-recording-nginx-record test-recording-nginx-record_mytest1.process Installed
To view the permissions used by any of the containers, run the following command:
$ oc get seccompprofiles test-recording-nginx-record -o yaml