Introducing eBPFGuard: A Library for Inline Mitigation of Threats using LSM Hooks

Introducing eBPFGuard: A Library for Inline Mitigation of Threats using LSM Hooks
May 11, 2023
Author:
Shyam Krishnaswamy, Thomas Legris, Tomasz Jonak & Michal Rostecki

Deepfence Introduces eBPFGuard into ThreatStryker

Hello, Deepfence community! We have some exciting news to share. We are thrilled to announce that eBPFGuard, our groundbreaking open-source Rust library, is becoming an integral part of our cutting-edge commercial solution for threat detection and mitigation, ThreatStryker!

What does this mean for you? In a cybersecurity landscape that's becoming increasingly complex and sophisticated, you need a solution that is equally advanced and robust. That's where eBPFGuard steps in. By integrating eBPFGuard into ThreatStryker, we're taking a giant leap forward in our exploitation detection capabilities. This dynamic duo will provide alerts and make mitigation decisions, applying the most suitable solutions directly at the host kernel level, right where you need it the most.

eBPFGuard is a product of our passion for securing digital landscapes. If you want to read more about how we utilize eBPF more generally within our security tools, read our blog post, “Aya: your tRusty eBPF Companion.” Developed by the brilliant minds at Deepfence, it protects applications from exploitation by selectively blocking specific kernel function calls based on user-defined policies. The best part? It does this without having you deal with the kernel directly, reducing complexity while maximizing efficiency.

But there's more! eBPFGuard also comes packed with impressive features designed to make your life easier, like managing the lifecycle of eBPF programs, ensuring kernel version independence, and alerting you with contextual data whenever a policy is enforced. One of the standout features of eBPFGuard is its utilization of eBPF programs attached to LSM hooks. This feature allows you to create custom policies using code, thereby significantly reducing your attack surface. Moreover, we have carefully designed eBPFGuard to work across a wide range of scenarios, from single-machine enforcement to enforcement in pods on the same cluster node. Let’s dig into two of these powerful features quickly. 

Execution Control: Harnessing LSM Hook Points with eBPFGuard

The Linux Security Modules (LSM) framework is a powerful tool that empowers developers to sculpt the security logic operating on the Linux kernel. For a comprehensive understanding of this framework, feel free to delve into the Linux kernel documentation for LSM.

In essence, the Linux kernel reaches out to specific LSM hooks to make a call on whether or not to continue with a given code execution. These hooks function as decision-making checkpoints, receiving a range of arguments that provide the context required for implementing informed policy decisions. The details of these arguments are neatly outlined in the lsm_hook_defs.h header.

Policy Decisions Through eBPF Hook Programs

The game changed with Linux 5.7 when the kernel began allowing eBPF objects to be tethered to LSM hook points. This change uncorked the potential to craft custom policies using code. eBPFGuard capitalizes on this capability by shaping and attaching the hooks to the LSM hook points as dictated by user requirements. Once this setup is complete, users can sculpt policies that will be brought to bear during hook execution.

As it stands, eBPFGuard paves the way for users to append policies to a suite of hooks:

  • file_open - Giving you the power to limit access to any file you choose.
  • sb_mount/sb_remount/sb_umount - Providing control over operations concerning filesystem management.
  • task_fix_setuid - Offering the ability to constrain changes to user identity, for instance, preventing a shift to root.
  • socket_bind - Enabling you to regulate the ports that applications can tap into.
  • socket_connect - Allowing you to control outbound connections.

So, step into a new world of security control with eBPFGuard, harnessing the power of LSM hook points to protect your system in a more granular and customized way.

But don’t just take our word for it! We have a hands-on demo ready for you to explore. In this demo, we walk you through the process of setting up a policy to block attackers from setting up an SSH server on a compromised machine.

Demo

In this demonstration, both the eBPFGuard application and its enforcement mechanisms run on the same local machine. We are fully cognizant of the fact that our customers have a spectrum of deployment models to consider. For instance, when an application is deployed across a suite of containers managed by orchestration platforms like Docker or Kubernetes, single-machine enforcement might not be sufficient.

The beauty of eBPFGuard is that since the hooks operate at the kernel level, it can perform policy matching and enforcement on all processes managed by a single kernel instance. This enables a broad scope of enforcement that transcends individual machines or containers. We've put eBPFGuard to the test and confirmed its effectiveness in various scenarios:

  • eBPFGuard running on a host machine, performing matching and enforcement on both the host and deployed containers
  • eBPFGuard housed within a container on a host, conducting matching and enforcement on other containers on the same host, and the host itself
  • eBPFGuard deployed as a Kubernetes DaemonSet, with enforcement carried out in pods on the same cluster node

Code Breakdown

Now, let's take a step-by-step walk through the key components of the demonstration source code and delve into the eBPFGuard APIs. We'll be examining slightly simplified versions of the samples compared to the executed demo code for clarity.

It's important to note that all example code should be viewed as if encapsulated within the following block.

eBPFGuard include line has to be present in Cargo.toml. The following snippet contains all dependencies utilized by our example code.

First, we need a top level object called PolicyManager. It will let us pick hook points we want to attach to.

Example is centered around blocking processes from listening on port 22. Processes usually do this by binding to some socket. We can use socket_bind hook to intercept and limit this operation.

After this operation we have an object representing a hook attached to socket_bind call. It is not enforcing any policies for now. Default action for hooks is to allow all calls.

Before we define any policies for this hook, we should set up alerts channel. It is a way for the hook to send us information about denied bind calls.

Policies are hook scoped, so are notifications. Granularity of policy definition is dependent on hook point. In case of bind we can currently scope ourselves to either all processes or process executing a particular binary via PolicySubject and sets of layer 4 protocol ports via allow and deny lists.

Demo policy applies to all processes and allows all ports but 22.

Finally we can add a defined policy to socket_bind hook.

When add_policy call succeeds, the socket_bind hook starts enforcing our policy. At this point we can start listening for alerts.

Putting this all together:

Roadmap and Looking Ahead

eBPFGuard is in early stages of development and we are just starting. We have a roadmap chalked out for eBPFGuard with exciting features and improvements on the horizon, including support for additional hooks, improved per-hook policy filtering granularity, and enhanced API documentation.

eBPFGuard is a testament to Deepfence's commitment to staying ahead of the curve in the cybersecurity world. We believe it will be a significant asset in your defense arsenal, helping you combat and mitigate threats like never before.

Get ready to experience a new era of cybersecurity with eBPFGuard and ThreatStryker. Let's redefine security together!

For more information, check out the project page on GitHub or join the conversation in the Deepfence Slack workspace. We're always here to answer your questions and hear your feedback. Stay safe and secure with Deepfence!