Containers, Kubernetes, OpenShift on Power

 View Only

Configuring Seccomp Profile on OpenShift Container Platform for Security and Compliance on Power

By PAUL BASTIDE posted Thu December 14, 2023 08:46 PM

  

This post was originally posted to link The post has been updated and posted to this community. 

Do you want to make your container safe and isolated by limiting the syscalls? And you still want to meet the secure application requirement on OpenShift Container Platform (OCP)? This post helps you understand how to achieve this with Secure Computing Mode (seccomp) .

Secure computing mode, seccomp, is a Linux kernel feature used to restrict process running in a container to only using a subset of the available system kernel API calls. Users can create custom seccomp profiles to match application requirements. Administrators have greater control over the security of workload running on the platform.

On the Red Hat OpenShift Container Platform (OCP), a container or a pod runs a single application that performs one or more well-defined tasks. The application usually requires only a small subset of the underlying operating system kernel APIs.

Using securityContext you can use seccomp profiles on your pods or containers. Later in this blogpost we are going to see an example of a Pod that uses a seccomp profile. The profile can be specified inside the Pod or the container, the difference is that when you do it inside the Pod all the containers inside it use the same profile. It is also important to set allowPrivilegeEscalation to false to prevent the container from trying to acquire more power than is allowed. Otherwise, the seccomp profile won’t be applied.

What is the need of seccomp?

Syscalls are typically not filtered, so securing your workload and containers with seccomp profiles considerably enhances clusters’ security. Basically, seccomp profiles are enforcing defined syscalls that your application requires from the kernel, for example, read files, communicate, or any of the about 200 syscalls that can be calibrated with seccomp profiles

Seccomp in OCP:

In OCP, the restricted-v2 Security Context Constraints (SCC) applies to all newly created pods. The default seccomp profile runtime/default is applied to these pods. However, seccomp profiles cannot be applied to privileged containers. The seccomp profiles are stored as JSON files on the disk on each node.

Now that you know basic about seccomp profile, we can switch to how we can attach seccomp profile at container/pod level.

Configuring the default seccomp profile:

OpenShift has a default seccomp profile that is referenced as runtime/default.
Most container runtimes provide a set of default syscalls that are allowed or not. You can adopt these defaults for your workload by setting the seccomp type in the security context of a Pod or container to RuntimeDefault. You can enable the default seccomp profile for a pod or container workload by setting RuntimeDefault as following:

spec:
securityContext:
seccompProfile:
type: RuntimeDefault

Configuring per Pod securityContext

In the Pod definition, one adds the securityContext option for attaching default seccomp profile.

1. Create the file seccomp-default.yaml for pod definition for attaching default seccomp profile as follows

apiVersion: v1
kind: Pod
metadata:
name: default-pod
labels:
app: default-pod
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: test-container
image: tomcat:9.0
securityContext:
allowPrivilegeEscalation: false

2. Create the Pod

# oc create -f seccomp-default.yaml
pod/default-pod created

3. Check the Pod

# oc get pods | grep default-pod
default-pod 1/1 Running 0 5m33s

4. Confirm the Security Context

# oc describe pod default-pod | grep seccomp
seccomp.security.alpha.kubernetes.io/pod: runtime/default

The container is created on worker node associated with Pod, and one may check the seccomp profile contents.

For validating the seccomp profile contents on worker node use below command:

1. Check for which node pod is attached

# oc get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default-pod 1/1 Running 0 83s *.*.*.* syd05-worker-1.rdr-shw-412.xyz <none> <none>

2. Run chroot command

# oc debug node/syd05-worker-1.rdr-shw-412.xyz
Temporary namespace openshift-debug-b6s6k is created for debugging node...
Starting pod/syd05-worker-1.rdr-shw-412xyz-debug ...
To use host binaries, run `chroot /host`
Pod IP: *.*.*.*
If you don't see a command prompt, try pressing enter.
sh-4.4# chroot /host

3. Run below command to check profile contents

sh-4.4# crictl inspect $(crictl ps - - name=test-container -q) | jq .info.runtimeSpec.linux.seccomp

After executing above command, you will be able to see the seccomp profile attached along with the syscalls that are allowed by default.

The output should look similar as follows:

sh-4.4# crictl inspect $(crictl ps  -- name=test-container -q) | jq .info.runtimeSpec.linux.seccomp
{
"defaultAction": "SCMP_ACT_ERRNO",
"defaultErrnoRet": 38,
"syscalls": [
{
"names": [
"bdflush",
"io_pgetevents",
"kexec_file_load",
"kexec_load",
"migrate_pages",
"move_pages",
"nfsservctl",
"nice",
"oldfstat",
"oldlstat",
"oldolduname",
"oldstat",
"olduname",
"pciconfig_iobase",
"pciconfig_read",
"pciconfig_write",
"sgetmask",
"ssetmask",
"swapcontext",
"ustat",
"vm86",
"vm86old",
"vmsplice"
],

Note: This is not the entire output log. Actual output is slightly larger than specified.

Configuring custom seccomp profile:

You can configure a custom seccomp profile, which allows you to update the filters based on the application requirements. This allows cluster administrators to have greater control over the security of workloads running in OpenShift Container Platform.

You can enable the custom seccomp profile for a pod or container workload by setting securityContext.seccompProfile.type field as follows:

spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile:<custom-name>.json

1. Upload your custom seccomp profile to /var/lib/kubelet/seccomp/<custom-name>.json by using the Machine Config.

MachineConfig example:

 apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 99-worker-seccomp
spec:
config:
ignition:
version: 3.2.0
storage:
files:
— contents:
source: data:text/plain;charset=utf-8;base64,ewogICAgImRlZmF1bHRBY3Rpb24iOiAiU0NNUF9BQ1RfTE9HIgp9Cg==
mode: 420
overwrite: true
path: /var/lib/kubelet/seccomp/profiles/audit.json

In above example you create seccomp profile that will audit all the syscalls. In seccomp Profile you enable the pod security by limiting the unnecessary actions to be performed. The base64 content added above is the custom seccomp profile audit.json as follows:

{
"defaultAction": "SCMP_ACT_LOG"
}

By uploading this you can attach seccomp profile to all worker nodes. After applying this file all worker nodes got rebooted and it will take 5–10 mins to be in ready state.

2. Create the Machine Config

# oc create -f 99-audit-mc.yaml
machineconfig.machineconfiguration.openshift.io/99-worker-seccomp created

3. Create the pod with following definition

cat << EOF | oc apply -f - 
apiVersion: v1
kind: Pod
metadata:
name: audit-pod
labels:
app: audit-pod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/audit.json
containers:
- name: test-container
image: tomcat:9.0
securityContext:
allowPrivilegeEscalation: false

EOF
pod/audit-pod created

4. Check the Pod

# oc get pods | grep audit-pod
NAME READY STATUS RESTARTS AGE
audit-pod 1/1 Running 0 115s

5. Confirm the Security Context

# oc describe pod audit-pod | grep seccomp
seccomp.security.alpha.kubernetes.io/pod: localhost/profiles/audit.json
# oc describe pod audit-pod | grep scc
openshift.io/scc: restricted-v2

The container is created on worker node associated with Pod, and one may check the seccomp profile contents.

For validating the seccomp profile contents on worker node use below command:

1. Check for which node pod is attached

# oc get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
audit-pod 1/1 Running 0 2m29s *.*.*.* syd05-worker-1.rdr-shw-412.xyz <none> <none>

2. Run chroot command

# oc debug node/syd05-worker-1.rdr-shw-412.xyz
Temporary namespace openshift-debug-b6s6k is created for debugging node...
Starting pod/syd05-worker-1.rdr-shw-412xyz-debug ...
To use host binaries, run `chroot /host`
Pod IP: *.*.*.*
If you don't see a command prompt, try pressing enter.
sh-4.4# chroot /host

3. Run command to check profile contents as follows

sh-4.4# crictl inspect $(crictl ps --name=test-container -q) | jq .info.runtimeSpec.linux.seccomp
{
"defaultAction": "SCMP_ACT_LOG"
}

Important

Ensure that the seccomp profile is deployed to all worker nodes.

Note: You can also attach the seccomp profile to custom SCC (more permissive than default or restricted SCC). Hence whenever you create new deployment the seccomp profile will get attached to it.

As you can see here, we have covered two different types of seccomp profiles. You can alter the syscalls in custom seccomp profile as per your application requirement. We have tested seccomp profile with OCP 4.12 and 4.13 and 4.14.
Thus, we can conclude this blogpost for now.

Thanks for reading! I hope you found this tutorial helpful :)

References:

https://docs.openshift.com/container-platform/4.14/security/seccomp-profiles.html

https://code.google.com/archive/p/seccompsandbox/wikis/overview.wiki

Permalink