Skip to main content
Version: v0.39.0

audit_seccomp

The audit seccomp gadget provides a stream of events with syscalls that had their seccomp filters generating an audit log. An audit log can be generated in one of these two conditions:

  • The Seccomp profile has the flag SECCOMP_FILTER_FLAG_LOG (supported from runc v1.2.0, see runc#3390) and returns any action other than SECCOMP_RET_ALLOW.
  • The Seccomp profile does not have the flag SECCOMP_FILTER_FLAG_LOG but returns SCMP_ACT_LOG or SCMP_ACT_KILL*.

Getting started

$ kubectl gadget run ghcr.io/inspektor-gadget/gadget/audit_seccomp:v0.39.0 [flags]

Flags

No flags.

Guide

First, we need to create a pod / container with a seccomp profile that executes some fordibben syscalls.

We'll use the Security Profiles Operator to handle seccomp profiles, however them can be handled manually as explained in Restrict a Container's Syscalls with seccomp

  1. Install the Security Profiles Operator
  2. Install a SeccompProfile that logs the mkdir and blocks the unshare syscalls.
# seccompprofile.yaml
apiVersion: security-profiles-operator.x-k8s.io/v1beta1
kind: SeccompProfile
metadata:
name: log
annotations:
description: "Log some syscalls"
spec:
defaultAction: SCMP_ACT_ALLOW
syscalls:
- action: SCMP_ACT_KILL
names:
- unshare
- action: SCMP_ACT_LOG
names:
- mkdir
$ kubectl apply -f seccompprofile.yaml
  1. Start a pod with that SeccompProfile.
# mypod.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: operator/default/log.json
restartPolicy: Never
containers:
- name: container1
image: busybox
command: ["sh"]
args: ["-c", "while true ; do mkdir /tmp/dir42 ; unshare -i; sleep 1; done"]
$ kubectl apply -f mypod.yaml

Then, start the audit_seccomp gadget and observe how it logs the unshare syscall being denied.

$ kubectl gadget run audit_seccomp:v0.39.0
K8S.NODE K8S.NAMESPACE K8S.PODNAME K8S.CONTAINERN… COMM PID TID CODE SYSCALL
minikube-docker default mypod container1 mkdir 60482 60482 …_RET_LOG SYS_MKDIR
minikube-docker default mypod container1 unshare 60483 60483 …L_THREAD SYS_UNSH…
minikube-docker default mypod container1 mkdir 60553 60553 …_RET_LOG SYS_MKDIR
minikube-docker default mypod container1 unshare 60554 60554 …L_THREAD SYS_UNSH…
^C

In the previous examples, it is straightforward why the application is performing the syscall. The unshare program executes the unshare syscall and the mkdir program executes the mkdir syscall. For bigger applications, it can be useful to show the user stack trace.

$ kubectl gadget run audit_seccomp:v0.39.0 --collect-ustack -o jsonpretty
...
"ustack": {
"addresses": "[0]0x000000000040332e; [1]0x00000000004771e6; [2]0x000000000047752e; [3]0x000000000048250b; [4]0x00000000004829ae; [5]0x0000000000482a7e; [6]0x0000000000482afe; [7]0x0000000000482b7e; [8]0x0000000000435a9d; [9]0x00000000004625a1; ",
...
"symbols": "[0]runtime/internal/syscall.Syscall6; [1]syscall.Syscall; [2]syscall.Syscall.abi0; [3]golang.org/x/sys/unix.Chroot; [4]main.level3; [5]main.level2; [6]main.level1; [7]main.main; [8]runtime.main; [9]runtime.goexit.abi0; "
}
^C

Finally, clean the system:

$ kubectl delete -f mypod.yaml
$ kubectl delete -f seccompprofile.yaml