Falco’s eBPF probe is the modern way to get syscall event data on newer Linux kernels, replacing the older kernel module approach.
Let’s see it in action. Imagine you’ve got a containerized application, and you want to detect if any process inside tries to write to a sensitive configuration file like /etc/shadow.
Here’s how Falco, using the eBPF probe, would detect that:
First, you need to have Falco installed with eBPF support. This usually involves installing the falco package and ensuring the falco-probe-installer script is run, which handles downloading and loading the eBPF probe.
# Example installation command (may vary based on your distro and Falco version)
sudo apt-get install falco
sudo falco-ctl set-probe falco-bpf
Once Falco is running, its eBPF probe is attached to the kernel, silently observing syscalls.
Now, let’s simulate a malicious action within a container. We’ll use docker for this example.
# Start a simple container
docker run -it --rm ubuntu:latest /bin/bash
Inside the container, try to write to /etc/shadow:
# Inside the container
echo "malicious_user:x:1000:1000::/home/malicious_user:/bin/bash" > /etc/shadow
Falco, running on the host, will immediately detect this and generate an alert. A typical Falco rule that would trigger this is:
# In your falco.yaml or a separate rules file
- rule: Write to sensitive file
desc: Detects writing to sensitive system files.
condition: >
openat and
(
(evt.dir = 'open' and fd.name = "/etc/shadow") or
(evt.dir = 'open' and fd.name = "/etc/passwd") or
(evt.dir = 'open' and fd.name = "/etc/sudoers")
) and
evt.type = 'open' and fd.flags.O_WRONLY = 1
output: >
Write to sensitive file (user: %(evt.user.name) container_id: %(container.id)
image: %(container.image.name) file: %(fd.name))
priority: critical
source: syscall
When you execute the echo command inside the container, Falco will produce an output similar to this:
16:30:00.123456789: Critical: Write to sensitive file (user: root container_id: abcdef1234567890 image: ubuntu:latest file: /etc/shadow)
This shows how Falco, by leveraging the eBPF probe, can intercept kernel events (syscalls like openat in this case) and apply rules to detect suspicious activity in real-time, even within isolated containers.
The core problem Falco solves is providing deep visibility into kernel activity without requiring kernel recompilation or complex kernel module management. Traditionally, tools like this relied on kernel modules, which were prone to breaking with kernel upgrades and had security implications. The eBPF probe, however, is loaded into the kernel as sandboxed bytecode, making it much more robust and secure.
Here’s how it works internally:
- eBPF Program Loading: When Falco starts,
falco-probe-installer(or a similar mechanism) loads a pre-compiled eBPF program into the kernel. This program is designed to attach to specific kernel tracepoints or kprobes (hooks into kernel functions). - Syscall Interception: The eBPF program is triggered by the kernel whenever a specific syscall (like
openat,execve,connect, etc.) is invoked. - Event Data Collection: The eBPF program collects relevant context about the syscall, such as the process ID, user, command, file path, network information, and any flags associated with the operation.
- User-Space Communication: This collected data is efficiently passed from the kernel’s eBPF verifier and execution environment to a user-space buffer managed by Falco. This is done with minimal overhead.
- Falco Rule Engine: Falco’s user-space engine reads these events from the buffer. It then evaluates them against its loaded set of detection rules.
- Alerting: If an event matches a rule, Falco generates an alert, which can be sent to various outputs like the console, a file, syslog, or a SIEM.
The beauty of the eBPF probe is its ability to leverage the kernel’s own tracing infrastructure. You don’t need to compile kernel modules that match your exact kernel version. Instead, the eBPF bytecode is verified and executed safely within the kernel’s sandbox. This dramatically simplifies deployment and maintenance.
The eBPF probe works by mapping specific kernel functions or tracepoints to actions. For instance, when an openat syscall occurs, the eBPF program is invoked. It can then inspect the arguments passed to openat, such as the filename (fd.name) and the flags (fd.flags). This allows Falco to distinguish between opening a file for reading (O_RDONLY) versus writing (O_WRONLY), or even appending (O_APPEND). This granular information is crucial for writing precise detection rules.
The one thing most people don’t grasp is the directness and efficiency of eBPF. It’s not just "observing" syscalls; the eBPF program is part of the kernel’s execution path for those syscalls. This means it can access state and arguments directly at the point of execution, rather than relying on more indirect mechanisms. The kernel itself ensures the eBPF program is safe and won’t crash the system, and the data transfer to user-space is optimized through ring buffers, minimizing context switches and data copying.
The next step in your journey is likely exploring how to tune Falco’s rules for your specific environment to reduce false positives while maximizing security coverage.