DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 967,611 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
mrtc0
mrtc0

Posted on

How to Prevent Data Exfiltration with eBPF

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, 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.

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;
}
Enter fullscreen mode Exit fullscreen mode

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

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.
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
Enter fullscreen mode Exit fullscreen mode

Let's try this.

$ sudo ./bouheki -config config/container.yaml
Enter fullscreen mode Exit fullscreen mode
# 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
Enter fullscreen mode Exit fullscreen mode

bouheki's log for then:

{
  "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"
}
Enter fullscreen mode Exit fullscreen mode

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

A policy that restricts curl connections

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
Enter fullscreen mode Exit fullscreen mode
$ 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]
Enter fullscreen mode Exit fullscreen mode

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

network:
  mode: block
  target: host
  cidr:
    allow:
      - 0.0.0.0/0
    deny: []
  uid:
    allow:
      - 0
    deny:
      - 1000
log:
  format: json
Enter fullscreen mode Exit fullscreen mode
$ 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"?> πŸ‘ˆ
...
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)

🌚 Browsing with dark mode makes you a better developer.

It's a scientific fact.