I came to eBPF the way most people do: I had a problem in the kernel and no good place to stand. I was trying to spot a denial-of-service pattern against EV charging hardware early enough to do something about it, and I needed to see traffic decisions at a layer where patching the kernel was not an option. eBPF was the place to stand. I have not really left.
Here is the plain version. eBPF lets you load a small, sandboxed program into the running Linux kernel and attach it to events: a syscall, a network packet, a function entry, a tracepoint. The kernel verifies your program cannot crash it or loop forever, then runs it in-place when the event fires. You get to observe and sometimes steer what the kernel is doing, at kernel speed, without recompiling anything or rebooting. It is the closest thing we have to a debugger for the entire machine at once.
You do not need to write C and wrestle a loader to feel this. bpftrace gives you awk-like one-liners over the same machinery. Install it (apt install bpftrace on Debian-ish systems), and run these as root on a reasonably recent kernel.
See every file anything opens, live:
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%-16s %s\n", comm, str(args->filename)); }'
Watch which processes are making outbound connections, the moment they do:
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_connect { printf("%s (pid %d) is connecting\n", comm, pid); }'
Count syscalls per program for ten seconds, then print a tidy histogram:
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); } interval:s:10 { exit(); }'
Run that last one and watch a “quiet” laptop. You will see processes you forgot existed, all chattering. That is the feeling I want you to have, because it reframes what a black box even is.
Why this matters for security and measurement: most of the systems I study do not want to be understood. A smart TV, a proprietary daemon, a vendor binary. You cannot read their source, but you can sit underneath them at the syscall and packet boundary and watch what they actually do, not what the manual claims. eBPF turns “trust me” into “show me.” A binary can lie in its documentation. It has a much harder time lying about the connect() it just made, because you are reading that straight from the kernel.
A few honest caveats. You need root and a kernel new enough to have the hooks (most things from the last several years are fine). The verifier will reject programs it cannot prove safe, which is annoying right up until you remember it is the reason this is safe to run at all. And tracing has a cost, small, but real, so do not leave a firehose attached in production without thinking.
Start with the three one-liners above. Point them at something you are curious about. The first time you watch a closed-source program reveal exactly which servers it talks to, you will understand why I never left.