How to Prevent Data Exfiltration with eBPF
Tags: ebpf, security
Published: 2021-11-03 15:31:45

---
title: How to Prevent Data Exfiltration with eBPF
published: true
description: 
tags: ["ebpf", "security"]
---

Restricting server network connections is one of the security best practices. Supply chain attacks on software and SSRF are hot topics, so there is a need to monitor and block unintended network access.

However, traditional firewalls (such as iptables and more), are not flexible enough. For example, there are cases where you want to restrict communication only from CI or the container environment where the application is running.

In this article, I will introduce [bouheki](https://github.com/mrtc0/bouheki), a tool that blocks data exfiltration by supply chain attacks and SSRF.

## KRSI (LSM + eBPF)

KRSI is a mechanism to apply MAC / Audit Policy by LSM and eBPF.
By using this, you can control communication on a per-process basis using eBPF.
For example, the following BPF program can block a connection if the destination IP address is included in the denylist.

```c
SEC("lsm/socket_connect")
int BPF_PROG(socket_connect, struct socket *sock, struct sockaddr *address, int addrlen) {
  struct sockaddr_in *inet_addr = (struct sockaddr_in*)address;

  if (bpf_map_lookup_elem(&denylist, &inet_addr->sin_addr))
    return -EPERM;

  return 0;
}
```

This is very exciting!

This means that you can filter by command name, UID or GID, and whether it is a container or not.

## bouheki

[https://github.com/mrtc0/bouheki](https://github.com/mrtc0/bouheki)

[bouheki](https://github.com/mrtc0/bouheki) is tool for preventing data exfiltration with KRSI. 

bouheki has the following features:

- While firewalls such as iptables apply to the entire machine, bouheki can be restricted on a per-container or per-process basis.
- bouheki does not restrict ingress, only egress.

bouheki is configured in YAML. For example, the following configuration would apply the following policy:

- Only allow access to `10.0.1.1/24`, but block access to `10.0.1.71`
- Blocks only communication from the container, but allows communication from host.

```yaml
network:
  # Block or monitor the network.
  # If block is specified, communication that matches the policy will be blocked.
  mode: block
  # Restriction to the whole host or to a container
  # If a container is specified, only the container's communication will be restricted.
  # This is determined by the value of namespace
  target: container
  cidr:
    allow:
      - 10.0.1.1/24
    deny:
      - 10.0.1.71/32
```

Let's try this.

```bash
$ sudo ./bouheki -config config/container.yaml
```

```
# Access 10.0.1.1 from the container.
$ docker run --rm curlimages/curl:latest -s -I http://10.0.1.1
HTTP/1.1 301 Moved Permanently 👈
Location: https://10.0.1.1:443/
Date: Sun, 26 Sep 2021 13:21:36 GMT
Server: Server

# Cannot connect to 10.0.1.71 from containers
$ docker run --rm curlimages/curl:latest http://10.0.1.71
curl: (7) Couldn't connect to server 👈

# The host can connect to 10.0.1.71
$ curl -I -s 10.0.1.71
HTTP/1.1 301 Moved Permanently 👈
Date: Sun, 26 Sep 2021 13:23:10 GMT
Location: https://10.0.1.71/
Connection: close
Content-Type: text/html
Content-Length: 56
```

bouheki's log for then:

```json
{
  "Action": "BLOCKED",
  "Addr": "10.0.1.71",
  "Comm": "curl",
  "Hostname": "cdb99d181368",
  "PID": 936350,
  "Port": 80,
  "level": "info",
  "msg": "Traffic is trapped in the filter.",
  "time": "2021-09-26T13:21:58Z"
}
```

bouheki can also be filtered by command, UID, and more.

**A policy that restricts `curl` connections**

```yaml
network:
  mode: block
  target: host
  cidr:
    allow:
      - 0.0.0.0/0
    deny:
      - 93.184.216.34/32
  command:
    allow:
      - 'wget'
    deny:
      - 'curl'
log:
  format: json
```

```
$ sudo ./bouheki -config testdata/command_deny.yml
...
$ curl 93.184.216.34
curl: (7) Couldn't connect to server 👈

$ wget 93.184.216.34/index.html
--2021-09-26 13:31:38--  http://93.184.216.34/index.html
Connecting to 93.184.216.34:80... connected. 👈
HTTP request sent, awaiting response... 200 OK
Length: 94 [text/html]
Saving to: ‘index.html’

index.html                        100%[==========================================================>]      94  --.-KB/s    in 0s

2021-09-26 13:31:39 (17.5 MB/s) - ‘index.html’ saved [94/94]
```

**Policy that `UID 0` can be connected, but `UID 1000` cannot be connected**

```yaml
network:
  mode: block
  target: host
  cidr:
    allow:
      - 0.0.0.0/0
    deny: []
  uid:
    allow:
      - 0
    deny:
      - 1000
log:
  format: json
```

```
$ curl 93.184.216.34
curl: (7) Couldn't connect to server 👈

$ sudo curl http://93.184.216.34
...
<?xml version="1.0" encoding="iso-8859-1"?> 👈
...
```

## Conclusion

KRSI is very exciting! Not only can you restrict the network, but you can also restrict system calls, which provides very strong security.

bouheki is tool for preventing data exfiltration with KRSI. Feedback is welcome!

## References

- [https://www.kernel.org/doc/html/latest/bpf/bpf_lsm.html](https://www.kernel.org/doc/html/latest/bpf/bpf_lsm.html)
- [https://archive.fosdem.org/2020/schedule/event/security_kernel_runtime_security_instrumentation/attachments/slides/3842/export/events/attachments/security_kernel_runtime_security_instrumentation/slides/3842/Kernel_Runtime_Security_Instrumentation.pdf](https://archive.fosdem.org/2020/schedule/event/security_kernel_runtime_security_instrumentation/attachments/slides/3842/export/events/attachments/security_kernel_runtime_security_instrumentation/slides/3842/Kernel_Runtime_Security_Instrumentation.pdf)
- [https://goteleport.com/blog/preventing-data-exfiltration-with-ebpf/](https://goteleport.com/blog/preventing-data-exfiltration-with-ebpf/)
- [https://kinvolk.io/blog/2021/04/extending-systemd-security-features-with-ebpf/](https://kinvolk.io/blog/2021/04/extending-systemd-security-features-with-ebpf/)