Kernel-level container insights: Utilizing eBPF with Cilium, Tetragon, and SBOMs for security

As applications become more distributed, traditional monitoring and security tools are failing to keep pace. This article explores how eBPF, when utilized by the graduated CNCF Cilium and its sub-project Tetragon, combined with Software Bills of Materials (SBOMs), can provide insights and a security feedback loop for modern systems.

We’ll create a container image and its SBOM. We’ll then launch it, simulate a breach, and see how our eBPF-based setup with Tetragon captures the issue. This will show how the SBOM can be used to debug and understand the incident.

Combining eBPF-driven observability and SBOM context

eBPF (extended Berkeley Packet Filter) is a Linux kernel technology that is adopted to enhance networking performance, provide deep observability, and strengthen security. It’s an enabling technology for CNCF projects such as Cilium, Falco, and Pixie. Tech companies like Google, Netflix, Cloudflare, and Microsoft use eBPF: Meta, for example, shared that it reduced CPU usage by 20% through kernel-level profiling with eBPF.

The SBOM, which provides an inventory of software components, is an essential component in understanding and securing these systems. Cloud Native Buildpacks, utilized by enterprises like Broadcom-VMware, Salesforce, and Red Hat and integrated into Google Cloud services, offer an automated way to produce SBOMs.

Why is the combination of eBPF-based tools and SBOMs useful for security? eBPF allows tools like Cilium’s Tetragon to observe kernel-level activities such as system calls, network traffic, and process executions in real time with low overhead. This provides raw data on what is happening inside containers.

Raw data, however, often needs context to be useful for security investigations. An SBOM provides this context by listing every software component and its version within the container.

Monitoring containers

This tutorial demonstrates how to use Cilium and Tetragon for eBPF-based security observability in Kubernetes, and how an SBOM helps contextualize runtime events.

Prerequisites:

Step 1: Build container & generate SBOM

We’ll use Paketo Buildpacks to produce our application image and its SBOM. While SBOMs can be generated through various means, a system like Cloud Native Buildpacks, via a Paketo Buildpacks, provides an automated method to include them in your build pipeline. In your application’s source code directory, run:

pack build my-java-app \
--builder paketobuildpacks/builder-jammy-full \
--path . \
--sbom-output-dir ./sbom-output

This creates my-java-app:latest locally and outputs SBOMs to ./sbom-output.

Step 2: Deploy to Kubernetes

Create my-app-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-java-app-deployment
spec:
replicas: 1
selector:
matchLabels:
app: my-java-app
template:
metadata:
labels:
app: my-java-app
spec:
containers:
- name: my-java-app-container
image: my-java-app
imagePullPolicy: IfNotPresent # Needed for local images with Kind
ports:
- containerPort: 8080

For local clusters like kind, load the image first:

kind load docker-image my-java-app:latest

Then apply the deployment:

kubectl apply -f my-app-deployment.yaml

Step 3: Install Cilium CNI and Tetragon

Cilium provides cluster networking and is Tetragon’s parent project. Add and update its Helm repo and install it:

helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium --version 1.15.5 --namespace kube-system

Tetragon uses eBPF for security observability. Add and update the Isovalent Helm repo and install it:

helm repo add isovalent https://helm.isovalent.com
helm repo update
helm install tetragon isovalent/tetragon --version 1.16.1 --namespace kube-system

Verify Tetragon pods are running (it may take some time): kubectl get pods -n kube-system -l app.kubernetes.io/name=tetragon

Step 4: Observe system activity with Tetragon

Stream Tetragon events. Keep this running in a separate terminal:

kubectl exec -it -n kube-system ds/tetragon -c tetragon -- tetra getevents -o compact

Step 5: Simulate an anomaly

Real-world attacks often involve a compromised binary making unexpected outbound calls. We’ll simulate this using curl. Imagine this is your my-java-app (or a component within it) attempting to exfiltrate data or contact a C2 server after being compromised.

Get your application pod’s name: kubectl get pods -l app=my-java-app

Then, execute this command (replace ):

kubectl exec -it -- /bin/sh -c \
'curl -s -L --connect-timeout 5 https://www.sylvainkalache.com -o /dev/null'

This attempts to fetch and discard content from https://www.sylvainkalache.com. The key is that this network activity might be out of character for your container.

Step 6: Detect with Tetragon and leverage the SBOM for context

Your tetra getevents stream should show events like these:

eBPF kernel-level

process default/my-java-app-deployment-85b5674f45-vj6l5 /bin/sh -c "curl -s -L --connect-timeout 5 https://www.sylvainkalache.com -o /dev/null"
process default/my-java-app-deployment-85b5674f45-vj6l5 /usr/bin/curl -s -L --connect-timeout 5 https://www.sylvainkalache.com -o /dev/null

From these Tetragon events, the outbound network request is identified. We see the shell execution, the curl process, and the TCP connect event to an external site on port 443.

Correlating Tetragon’s findings with the SBOM: A Log4Shell example

Consider a scenario like the Log4Shell vulnerability (CVE-2021-44228). An attacker exploits this in a Java application, causing the Java process to make an unexpected outbound JNDI/LDAP network connection. Tetragon, using eBPF, would detect this network activity from your Java application process.

This is where the SBOM generated in Step 1 provides context:

1. Alert contextualization: Tetragon flags an outbound connection from your my-java-app process to an unknown external IP on an LDAP/RMI port.
2. SBOM inspection: You consult the SBOM for my-java-app, since it is a Java application, you would search its dependencies for “log4j-core” (the vulnerable component in Log4Shell). The SBOM reveals the exact version of any log4j-core library present.
3. Vulnerability confirmation: Cross-referencing this version against CVE-2021-44228, if a vulnerable log4j-core is listed, this suggests the unexpected network call is due to Log4Shell exploitation.
4. Impact assessment and targeted response: The SBOM confirms which applications use the vulnerable Log4j version. You understand the Java process is compromised.

A clearer view of container security

This example is a very trivial one, and a production setup would need to be much more sophisticated, but it demonstrates the goal and a path that cloud native security team can use to monitor their containers.

While this can be achieved with other tools, Cilium has become an industry standard, with over 500 contributing companies to the project, including Google, Cisco, and RedHat, as well as fast-growing mid-size enterprises, like Datadog, Cloudflare, and SUSE. It’s a solid project worth learning and investing in.

Don't miss