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 thanSECCOMP_RET_ALLOW
. - The Seccomp profile does not have the flag
SECCOMP_FILTER_FLAG_LOG
but returnsSCMP_ACT_LOG
orSCMP_ACT_KILL*
.
Getting started
- kubectl gadget
- ig
$ kubectl gadget run ghcr.io/inspektor-gadget/gadget/audit_seccomp:latest [flags]
$ sudo ig run ghcr.io/inspektor-gadget/gadget/audit_seccomp:latest [flags]
Flags
No flags.
Guide
First, we need to create a pod / container with a seccomp profile that executes some fordibben syscalls.
- kubectl gadget
- ig
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
- Install the Security Profiles Operator
- Install a SeccompProfile that logs the
mkdir
and blocks theunshare
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
- 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
- Prepare a Seccomp Profile.
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"action": "SCMP_ACT_KILL",
"names": [
"unshare"
]
}
]
}
Create a container using that profile:
$ docker run --name test-audit-seccomp -d --security-opt seccomp=profile.json \
busybox /bin/sh -c 'while true ; do unshare -i; sleep 1 ; done'
Then, start the audit_seccomp gadget and observe how it logs the unshare
syscall being denied.
- kubectl gadget
- ig
$ kubectl gadget run audit_seccomp:latest
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
$ sudo -E ig run audit_seccomp:latest
RUNTIME.CONTAINERNAME COMM PID TID CODE SYSCALL
test-audit-seccomp unshare 485855 485855 …_KILL_THREAD SYS_UNSHARE
test-audit-seccomp unshare 485865 485865 …_KILL_THREAD SYS_UNSHARE
test-audit-seccomp unshare 485868 485868 …_KILL_THREAD SYS_UNSHARE
test-audit-seccomp unshare 485888 485888 …_KILL_THREAD SYS_UNSHARE
^C
Finally, clean the system:
- kubectl gadget
- ig
$ kubectl delete -f mypod.yaml
$ kubectl delete -f seccompprofile.yaml
$ docker rm -f test-trace-bind