# Restrict a Container's Syscalls with seccomp

Restrict a Container's Syscalls with seccompFEATURE STATE: Kubernetes v1.19 [stable]Seccomp stands for secure computing mode and has been a feature of the Linux kernel since version 2.6.12. It can be used to sandbox the privileges of a process, restricting the calls it is able to make from userspace into the kernel. Kubernetes lets you automatically apply seccomp profiles loaded onto a node to your Pods and containers.Identifying the privileges required for your workloads can be difficult. In this tutorial, you will go through how to load seccomp profiles into a local Kubernetes cluster, how to apply them to a Pod, and how you can begin to craft profiles that give only the necessary privileges to your container processes.ObjectivesLearn how to load seccomp profiles on a nodeLearn how to apply a seccomp profile to a containerObserve auditing of syscalls made by a container processObserve behavior when a missing profile is specifiedObserve a violation of a seccomp profileLearn how to create fine-grained seccomp profilesLearn how to apply a container runtime default seccomp profileBefore you beginIn order to complete all steps in this tutorial, you must install kind and kubectl.The commands used in the tutorial assume that you are using Docker as your container runtime. (The cluster that kind creates may use a different container runtime internally). You could also use Podman but in that case, you would have to follow specific instructions in order to complete the tasks successfully.This tutorial shows some examples that are still beta (since v1.25) and others that use only generally available seccomp functionality. You should make sure that your cluster is configured correctly for the version you are using.The tutorial also uses the curl tool for downloading examples to your computer. You can adapt the steps to use a different tool if you prefer.Note:It is not possible to apply a seccomp profile to a container running with privileged: true set in the container's securityContext. Privileged containers always run as Unconfined.Download example seccomp profilesThe contents of these profiles will be explored later on, but for now go ahead and download them into a directory named profiles/ so that they can be loaded into the cluster.pods/security/seccomp/profiles/audit.json { "defaultAction": "SCMP_ACT_LOG" }pods/security/seccomp/profiles/violation.json { "defaultAction": "SCMP_ACT_ERRNO" }pods/security/seccomp/profiles/fine-grained.json { "defaultAction": "SCMP_ACT_ERRNO", "architectures": [ "SCMP_ARCH_X86_64", "SCMP_ARCH_X86", "SCMP_ARCH_X32" ], "syscalls": [ { "names": [ "accept4", "epoll_wait", "pselect6", "futex", "madvise", "epoll_ctl", "getsockname", "setsockopt", "vfork", "mmap", "read", "write", "close", "arch_prctl", "sched_getaffinity", "munmap", "brk", "rt_sigaction", "rt_sigprocmask", "sigaltstack", "gettid", "clone", "bind", "socket", "openat", "readlinkat", "exit_group", "epoll_create1", "listen", "rt_sigreturn", "sched_yield", "clock_gettime", "connect", "dup2", "epoll_pwait", "execve", "exit", "fcntl", "getpid", "getuid", "ioctl", "mprotect", "nanosleep", "open", "poll", "recvfrom", "sendto", "set_tid_address", "setitimer", "writev", "fstatfs", "getdents64", "pipe2", "getrlimit" ], "action": "SCMP_ACT_ALLOW" } ] }Run these commands:mkdir ./profiles curl -L -o profiles/audit.json https://k8s.io/examples/pods/security/seccomp/profiles/audit.json curl -L -o profiles/violation.json https://k8s.io/examples/pods/security/seccomp/profiles/violation.json curl -L -o profiles/fine-grained.json https://k8s.io/examples/pods/security/seccomp/profiles/fine-grained.json ls profiles You should see three profiles listed at the end of the final step:audit.json fine-grained.json violation.json Create a local Kubernetes cluster with kindFor simplicity, kind can be used to create a single node cluster with the seccomp profiles loaded. Kind runs Kubernetes in Docker, so each node of the cluster is a container. This allows for files to be mounted in the filesystem of each container similar to loading files onto a node.pods/security/seccomp/kind.yaml apiVersion: kind.x-k8s.io/v1alpha4 kind: Cluster nodes: - role: control-plane extraMounts: - hostPath: "./profiles" containerPath: "/var/lib/kubelet/seccomp/profiles"Download that example kind configuration, and save it to a file named kind.yaml:curl -L -O https://k8s.io/examples/pods/security/seccomp/kind.yaml You can set a specific Kubernetes version by setting the node's container image. See Nodes within the kind documentation about configuration for more details on this. This tutorial assumes you are using Kubernetes v1.34.As a beta feature, you can configure Kubernetes to use the profile that the container runtime prefers by default, rather than falling back to Unconfined. If you want to try that, see enable the use of RuntimeDefault as the default seccomp profile for all workloads before you continue.Once you have a kind configuration in place, create the kind cluster with that configuration:kind create cluster --config=kind.yaml After the new Kubernetes cluster is ready, identify the Docker container running as the single node cluster:docker ps You should see output indicating that a container is running with name kind-control-plane. The output is similar to:CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6a96207fed4b kindest/node:v1.18.2 "/usr/local/bin/entr…" 27 seconds ago Up 24 seconds 127.0.0.1:42223->6443/tcp kind-control-plane If observing the filesystem of that container, you should see that the profiles/ directory has been successfully loaded into the default seccomp path of the kubelet. Use docker exec to run a command in the Pod:# Change 6a96207fed4b to the container ID you saw from "docker ps" docker exec -it 6a96207fed4b ls /var/lib/kubelet/seccomp/profiles audit.json fine-grained.json violation.json You have verified that these seccomp profiles are available to the kubelet running within kind.Create a Pod that uses the container runtime default seccomp profileMost container runtimes provide a sane 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.Note:If you have the seccompDefault configuration enabled, then Pods use the RuntimeDefault seccomp profile whenever no other seccomp profile is specified. Otherwise, the default is Unconfined.Here's a manifest for a Pod that requests the RuntimeDefault seccomp profile for all its containers:pods/security/seccomp/ga/default-pod.yaml apiVersion: v1 kind: Pod metadata: name: default-pod labels: app: default-pod spec: securityContext: seccompProfile: type: RuntimeDefault containers: - name: test-container image: hashicorp/http-echo:1.0 args: - "-text=just made some more syscalls!" securityContext: allowPrivilegeEscalation: falseCreate that Pod:kubectl apply -f https://k8s.io/examples/pods/security/seccomp/ga/default-pod.yaml kubectl get pod default-pod The Pod should be showing as having started successfully:NAME READY STATUS RESTARTS AGE default-pod 1/1 Running 0 20s Delete the Pod before moving to the