System Monitor
Welcome back to the KubeArmor tutorial! In the previous chapters, we've built up our understanding of how KubeArmor defines security rules using Security Policies, how it figures out who is performing actions using Container/Node Identity, and how it configures the underlying OS to actively enforce those rules using the Runtime Enforcer.
But even with policies and enforcement set up, KubeArmor needs to constantly know what's happening inside your system. When a process starts, a file is accessed, or a network connection is attempted, KubeArmor needs to be aware of these events to either enforce a policy (via the Runtime Enforcer) or simply record the activity for auditing and visibility.
This is where the System Monitor comes in.
What is the System Monitor?
Think of the System Monitor as KubeArmor's eyes and ears inside the operating system on each node. While the Runtime Enforcer acts as the security guard making decisions based on loaded rules, the System Monitor is the surveillance system and log recorder that detects all the relevant activity.
Its main job is to:
Observe: Watch for specific actions happening deep within the Linux kernel, like:
Processes starting or ending.
Files being opened, read, or written.
Network connections being made or accepted.
Changes to system privileges (capabilities).
Collect Data: Gather detailed information about these events (which process, what file path, what network address, etc.).
Add Context: Crucially, it correlates the low-level event data with the higher-level Container/Node Identity information KubeArmor maintains (like which container, pod, or node the event originated from).
Prepare for Logging and Processing: Format this enriched event data so it can be sent for logging (via the Log Feeder) or used by other KubeArmor components.
The System Monitor uses advanced kernel technology, primarily eBPF, to achieve this low-overhead, deep visibility into system activities without requiring modifications to the applications or the kernel itself.
Why is Monitoring Important? A Use Case Example
Let's revisit our web server example. We have a policy to Block the web server container (app: my-web-app
) from reading /etc/passwd
.
You apply the Security Policy.
KubeArmor's Runtime Enforcer translates this policy and loads a rule into the kernel's security module (say, BPF-LSM).
An attacker compromises your web server and tries to read
/etc/passwd
.The OS kernel intercepts this attempt (via the BPF-LSM hook configured by the Runtime Enforcer).
Based on the loaded rule, the Runtime Enforcer's BPF program blocks the action.
So, the enforcement worked! The read was prevented. But how do you know this happened? How do you know someone tried to access /etc/passwd
?
This is where the System Monitor is essential. Even when an action is blocked by the Runtime Enforcer, the System Monitor is still observing that activity.
When the web server attempts to read /etc/passwd
:
The System Monitor's eBPF programs, also attached to kernel hooks, detect the file access attempt.
It collects data: the process ID, the file path (
/etc/passwd
), the type of access (read).It adds context: it uses the process ID and Namespace IDs to look up in KubeArmor's internal map and identifies that this process belongs to the container with label
app: my-web-app
.It also sees that the Runtime Enforcer returned an error code indicating the action was blocked.
The System Monitor bundles all this information (who, what, where, when, and the outcome - Blocked) and sends it to KubeArmor for logging.
Without the System Monitor, you would just have a failed system call ("Permission denied") from the application's perspective, but you wouldn't have the centralized, context-rich security alert generated by KubeArmor that tells you which container specifically tried to read /etc/passwd
and that it was blocked by policy.
The System Monitor provides the crucial visibility layer, even for actions that are successfully prevented by enforcement. It also provides visibility for actions that are simply Audited by policy, or even for actions that are Allowed but that you want to monitor.
How the System Monitor Works (Under the Hood)
The System Monitor relies heavily on eBPF programs loaded into the Linux kernel. Here's a simplified flow:
Initialization: When the KubeArmor Daemon starts on a node, its System Monitor component loads various eBPF programs into the kernel.
Hooking: These eBPF programs attach to specific points (called "hooks") within the kernel where system events occur (e.g., just before a file open is processed, or when a new process is created).
Event Detection: When a user application or system process performs an action (like
open("/etc/passwd")
), the kernel reaches the attached eBPF hook.Data Collection (in Kernel): The eBPF program at the hook executes. It can access information about the event directly from the kernel's memory (like the process structure, file path, network socket details). It also gets the process's Namespace IDs Container/Node Identity.
Event Reporting (Kernel to User Space): The eBPF program packages the collected data (raw event + Namespace IDs) into a structure and sends it to the KubeArmor Daemon in user space using a highly efficient kernel mechanism, typically an eBPF ring buffer.
Data Reception (in KubeArmor Daemon): The System Monitor component in the KubeArmor Daemon continuously reads from this ring buffer.
Context Enrichment: For each incoming event, the System Monitor uses the Namespace IDs provided by the eBPF program to look up the corresponding Container ID, Pod Name, Namespace, and Labels in its internal identity map (the one built by the Container/Node Identity component). It also adds other relevant details like the process's current working directory and parent process.
Log/Alert Generation: The System Monitor formats all this enriched information into a structured log or alert message.
Forwarding: The formatted log is then sent to the Log Feeder component, which is responsible for sending it to your configured logging or alerting systems.
Here's a simple sequence diagram illustrating this:
This diagram shows how the eBPF programs in the kernel are the first point of contact for system events, collecting the initial data before sending it up to the KubeArmor Daemon for further processing, context addition, and logging.
Looking at the Code (Simplified)
Let's look at tiny snippets from the KubeArmor source code to see hints of how this works.
The eBPF programs (written in C, compiled to BPF bytecode) define the structure of the event data they send to user space. In KubeArmor/BPF/shared.h
, you can find structures like event
:
This shows the event
structure containing key fields like timestamps, Namespace IDs (pid_id
, mnt_id
), the type of event (event_id
), the syscall result (retval
), the command name, and potentially file paths (data
). It also defines the kubearmor_events
map as a BPF_MAP_TYPE_RINGBUF
, which is the mechanism used by eBPF programs in the kernel to efficiently send these event
structures to the KubeArmor Daemon in user space.
On the KubeArmor Daemon side (in Go), the System Monitor component (KubeArmor/monitor/systemMonitor.go
) reads from this ring buffer and processes the events.
This Go code shows:
The
SyscallPerfMap
reading from the eBPF ring buffer in the kernel.Raw event data being sent to the
SyscallChannel
.A loop reading from
SyscallChannel
, parsing the raw bytes into aSyscallContext
struct.Using
ctx.PidID
andctx.MntID
(Namespace IDs) to callLookupContainerID
and get thecontainerID
.Packaging the raw context (
ContextSys
), parsed arguments (ContextArgs
), and the looked-upContainerID
into aContextCombined
struct.Sending the enriched
ContextCombined
event to theContextChan
.
This ContextCombined
structure is the output of the System Monitor – it's the rich event data with identity context ready for the Log Feeder and other components.
Types of Events Monitored
The System Monitor uses different eBPF programs attached to various kernel hooks to monitor different types of activities:
Process
Process execution (execve
, execveat
), process exit (do_exit
), privilege changes (setuid
, setgid
)
Tracepoints, Kprobes, BPF-LSM
File
File open (open
, openat
), delete (unlink
, unlinkat
, rmdir
), change owner (chown
, fchownat
)
Kprobes, Tracepoints, BPF-LSM
Network
Socket creation (socket
), connection attempts (connect
), accepting connections (accept
), binding addresses (bind
), listening on sockets (listen
)
Kprobes, Tracepoints, BPF-LSM
Capability
Use of privileged kernel features (capabilities)
BPF-LSM, Kprobes
Syscall
General system call entry/exit for various calls
Kprobes, Tracepoints
The specific hooks used might vary slightly depending on the kernel version and the chosen Runtime Enforcerconfiguration (AppArmor/SELinux use different integration points than pure BPF-LSM), but the goal is the same: intercept and report relevant system calls and kernel security hooks.
System Monitor and Other Components
The System Monitor acts as a fundamental data source:
It provides the event data that the Runtime Enforcer's BPF programs might check against loaded policies in the kernel (BPF-LSM case). Note that enforcement happens at the hook via the rules loaded by the Enforcer, but the Monitor still observes the event and its outcome.
It uses the mappings maintained by the Container/Node Identity component to add context to raw events.
It prepares and forwards structured event logs to the Log Feeder.
Essentially, the Monitor is the "observer" part of KubeArmor's runtime security. It sees everything, correlates it to your workloads, and reports it, enabling both enforcement (via the Enforcer's rules acting on these observed events) and visibility.
Conclusion
In this chapter, you learned that the KubeArmor System Monitor is the component responsible for observing system events happening within the kernel. Using eBPF technology, it detects file access, process execution, network activity, and other critical operations. It enriches this raw data with Container/Node Identity context and prepares it for logging and analysis, providing essential visibility into your system's runtime behavior, regardless of whether an action was allowed, audited, or blocked by policy.
Understanding the System Monitor and its reliance on eBPF is key to appreciating KubeArmor's low-overhead, high-fidelity approach to runtime security. In the next chapter, we'll take a deeper dive into the technology that powers this monitoring (and the BPF-LSM enforcer)
Last updated
Was this helpful?