Before writing your first seccomp filter, there are several skills and tools you must prepare, from understanding syscalls through strace, the basic concepts of BPF, to installing libseccomp, seccomp-tools, strace, and bpftool on a Linux kernel 5.15 or newer.

Welcome to the Learn Seccomp series! This series will take you from zero to production-ready mastery of seccomp — the Linux kernel mechanism for filtering system calls: starting with history and architecture, modes & return actions, the libseccomp API, Docker/runc container profiles, systemd and Kubernetes integration, up to designing secure filters for production applications.
Seccomp is one of the most important sandboxing mechanisms in modern Linux. It is used by Docker, Kubernetes, Chromium, systemd, and nearly every container runtime to restrict the syscalls a process is allowed to make. But before diving into all of that, you need a foundation: the ability to read code, an understanding of syscalls, and a Linux environment ready for testing. Episode 0 is the roadmap that makes sure you're fully prepared.
Why are these prerequisites so important? Seccomp operates at the kernel level and communicates through syscalls. Unlike learning a web framework where mastering one programming language suffices, seccomp requires you to understand what happens "underneath" your application: how programs interact with the kernel. Without this foundation, you'll read the libseccomp documentation without understanding what is really happening — like trying to fly a plane without knowing how the engines work.
You'll use these four skills in every episode. Get them ready now so your learning journey goes smoothly.
Seccomp is a kernel technology operated from the terminal. You need to be comfortable changing directories, creating config files, running commands with sudo, and reading log output. You don't need to be a pro sysadmin — just fluent with the basic commands below:
pwd # print the current working directory
mkdir -p ~/lab-seccomp # create the lab directory
cd ~/lab-seccomp # move into the lab directory
ls -la # list directory contents (including hidden files)Throughout this series, almost every experiment runs through gcc, strace, bpftool, and compiled binaries. If you still get confused by error output in the terminal, take some time to practice first — because seccomp debugging errors almost always appear in the terminal.
This is the core skill. Seccomp filters system calls — so you must understand what a syscall is. In simple terms: applications running in user mode cannot touch hardware or kernel memory directly. Every time an application needs a kernel service — reading a file, opening a socket, creating a new process — it invokes a syscall. Examples: read, write, openat, execve, socket, clone.
The fastest way to build this intuition is with strace, a tool that records every syscall a program makes:
strace -c /bin/echo "halo dunia"
# Abbreviated example output
% time seconds usecs/call calls syscall
------ ----------- ----------- ------- ----------------
0.00 0.000000 0 12 write
0.00 0.000000 0 1 execve
0.00 0.000000 0 2 mmap
0.00 0.000000 0 1 exit_groupSee? A tiny program like echo alone invokes over a dozen syscalls. Now imagine how many syscalls a complex program like a web server or database makes — and every one of those syscalls is a potential entry point for an attacker. That's the main reason seccomp exists, and we'll dissect it fully in episode 1.
Modern seccomp (seccomp-bpf) expresses its rules as BPF programs — Berkeley Packet Filter, a small bytecode language originally designed for filtering network packets. A seccomp filter is a list of BPF instructions the kernel runs every time a process makes a syscall, and the kernel executes those instructions in sequence until it reaches a return action.
You don't need to write BPF by hand — libseccomp composes it automatically from declarative rules. But understanding the concept of "sequential instructions evaluated per syscall" will help a lot when we disassemble filters and debug them in the following episodes.
Most examples in this series use the libseccomp API in C because that's the language the library fully supports. You don't need to be a C expert, but you must be able to read and compile simple C programs. If your environment doesn't have a compiler yet, install one first:
sudo apt install -y gcc make
gcc --version
gcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0Alternatively, you can experiment quickly with Python using ctypes to call libseccomp functions — great for prototyping filters without the hassle of compiling. But to follow this series fully, set up a C compiler from the start.
Tip
Don't be afraid of C. The code examples in this series always come with line-by-line explanations. What matters is that you can recognize basic syntax like #include, int main(void), and function calls. That alone is enough for most episodes.
Seccomp-bpf has existed since kernel 3.5 (2012), but important features — like SECCOMP_RET_NOTIFY (kernel 5.0), cleaner multi-ABI support, and performance improvements — only matured in modern kernels. We recommend kernel 5.15 or newer because:
SECCOMP_RET_NOTIFY.Verify your kernel version:
uname -r
6.8.0-45-genericIf your kernel is older than 5.15, consider upgrading your distro or using a VM with a recent distro (Ubuntu 22.04+, Debian 12+, Fedora 38+).
| Tool | Function | Notes |
|---|---|---|
libseccomp | C library for building and loading seccomp filters | Dev package required: libseccomp-dev / libseccomp-devel |
seccomp-tools | BPF filter analysis toolkit (disassemble, dump) | Ruby gem by David942j |
strace | Records the syscalls a process makes | Already used above |
bpftool | Inspects BPF programs and maps in the kernel | Helps verify installed filters |
sudo apt update
sudo apt install -y libseccomp-dev strace bpftoolFor seccomp-tools, install via the Ruby gem since it isn't available in the apt repos. Make sure Ruby is installed on your system:
sudo gem install seccomp-toolssudo dnf install -y libseccomp-devel strace bpftool
sudo gem install seccomp-toolsOnce everything is installed, make sure it all works correctly:
gcc --version
pkg-config --modversion libseccomp
2.6.1seccomp-tools version
SeccompTools Version: v1.7.0Note
The output of pkg-config --modversion libseccomp shows the version of the installed library. The current stable version is on the 2.6.x line — in episode 1 we'll discuss why keeping this library up to date matters from a security standpoint.
This is the part people often overlook but is the most important. A wrong seccomp filter can break a process (or the entire system) — for example, if you block a syscall that turns out to be needed by an application. For experiments, never load filters directly on your work machine.
Set up one of the following:
Warning
Don't test aggressive seccomp filters (e.g. default-deny) directly on a production host or your main machine. One wrong rule — like blocking exit_group — can make your system unable to shut down normally. Always test in a VM or container first.
In episode 0 you've set up a complete foundation:
strace, basic BPF concepts, and the ability to read and compile C.uname -r.libseccomp-dev, strace, bpftool, and seccomp-tools.The most important takeaway: seccomp operates at the syscall level, so understanding syscalls isn't a nice-to-have — it's the heart of this entire series.
Make sure all the tools above are installed and you can compile a simple C program, because the next episode covers the history and background of seccomp — from kernel 2.6.12 in 2005, the birth of seccomp-bpf in kernel 3.5, its adoption by Chromium, Docker, and systemd, to why the modern world needs it so badly. See you in episode 1!