×

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
  1. 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
  2. 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
  3. 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
  4. Apply the localhostProfile output to the patch file:

    spec:
      template:
        spec:
          securityContext:
            seccompProfile:
              type: Localhost
              localhostProfile: operator/my-namespace/profile1.json
  5. 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
  1. To bind a pod that uses a quay.io/security-profiles-operator/test-nginx-unprivileged:1.21 image to the example SeccompProfile profile, create a ProfileBinding object in the same namespace with the pod and the SeccompProfile 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.
  2. Label the namespace with enable-binding=true by running the following command:

    $ oc label ns my-namespace spo.x-k8s.io/enable-binding=true
  3. 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 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
  1. Label the namespace with enable-recording=true by running the following command:

    $ oc label ns my-namespace spo.x-k8s.io/enable-recording=true
  2. Create a ProfileRecording object containing a recorder: 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
  3. 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
  4. 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
  5. 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
    …
    I0705 12:08:18.729660 1843190 enricher.go:136] log-enricher "msg"="audit"  "container"="redis" "executable"="/usr/local/bin/redis-server" "namespace"="default" "node"="127.0.0.1" "pid"=1847839 "pod"="my-pod" "syscallID"=232 "syscallName"="epoll_wait" "timestamp"="1625486870.273:187492" "type"="{type}"
Verification
  1. Remove the pod:

    $ oc -n openshift-security-profiles delete pod my-pod
  2. Confirm the Security Profiles Operator reconciles the two seccomp profiles:

    $ oc -n openshift-security-profiles get sp
    Example output
    NAME                   STATUS      AGE
    test-recording-nginx   Installed   15s
    test-recording-redis   Installed   15s

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
  1. Edit a ProfileRecording object to include a mergeStrategy: 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
  2. 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
  3. To record the individual profiles, delete the deployment by running the following command:

    $ oc delete deployment nginx-deploy
  4. To merge the profiles, delete the profile recording by running the following command:

    $ oc delete profilerecording test-recording
  5. To start the merge operation and generate the results profile, run the following command:

    $ oc get sp -lspo.x-k8s.io/recording-id=test-recording
    Example output
    NAME                          STATUS      AGE
    test-recording-nginx-record   Installed   17m
  6. To view the syscalls used by any of the containers, run the following command:

    $ oc get sp test-recording-nginx-record -o yaml

Additional resources