eBPF #126
Replies: 29 comments 1 reply
-
Happy new year! 🎉 nope, I tried but on debian I was unable to compile "complex" programs, outside of the kernel tree (due to headers import errors). Using bp2go looks trivial to use: |
Beta Was this translation helpful? Give feedback.
-
I created a branch for ebpf: The commit message contains info on how to build the dependencies and to run. A few observations:
I intend to investigate those odd behaviours as time permits. |
Beta Was this translation helpful? Give feedback.
-
superb @themighty1 ! 🎉 Some questions and considerations:
We could use in a near future XDP to drop packets, and not depend on nfqueue. themighty1@f45c3c3#diff-15d7687250ed7ebda3aa02642d66c977276676567dc914a625eb47f5185fcfbcR87 Since we get the PID from eBPF, is it necessary to lookup the inode? We should go directly to
Does the kprobes depend on having mounted debugfs? It's something I have not very clear. I guess no. What Ubuntu version did you use? |
Beta Was this translation helpful? Give feedback.
-
hey, now that v1.3.5 is out, I wanted to test this branch, but it looks that it's gone. Could we work on it? I think even if we depend on debugfs, it's a better approach than parsing |
Beta Was this translation helpful? Give feedback.
-
@gustavo-iniguez-goya , hi. |
Beta Was this translation helpful? Give feedback.
-
ok, no problem. I want to finish some things first, but definitely I'd like to test it. |
Beta Was this translation helpful? Give feedback.
-
Huh, I switched to a Ubuntu 20.04 machine and I cannot compile the ebpf branch anymore. I get a boatload of kernel header errors. Sad. I'll try to chroot into Ubuntu 18. |
Beta Was this translation helpful? Give feedback.
-
I was able to get rid of the errors by removing ubuntu's bcc lib and installing bcc from source |
Beta Was this translation helpful? Give feedback.
-
I just updated https://github.com/themighty1/opensnitch/tree/ebpf_onmaster It is in a more polished state, works with tcp/udp/tcp6/udp6 The code will exit if it encounters a connection from netfilter queue which is not accounted for. |
Beta Was this translation helpful? Give feedback.
-
👍 ok, ubuntu18 installed, bcc libs compiled, and opensnitchd compiled. I'll test it soon. I guess that if we commit this, I'd need a ubuntu18 to build the packages. It worries me if we'll be able to compile for multiple architectures as we do now. Or maybe install the bcc libs inside the pbuilder chroot environments.. no idea. |
Beta Was this translation helpful? Give feedback.
-
fwiw, I am running this on Ubuntu 20 with no compilation problems. |
Beta Was this translation helpful? Give feedback.
-
The thing is if we use a platform like build.opensuse.org or launchpad.net to build the packages, the compilation and installation of the bcc libs should be integrated as part of the build process, no? By the way, Transmission and probably others apps close connections without waiting to finish. This causes some weird behaviour, from not being able to get the pid to not even know that there was an attempt to establish a connection. I mimicked this behaviour with this simple prog: This prog causes to exit in this line: https://github.com/themighty1/opensnitch/blob/ebpf_onmaster/daemon/conman/connection.go#L143 |
Beta Was this translation helpful? Give feedback.
-
@gustavo-iniguez-goya , yes the bcc lib should be built as part of the build process. Thanks for pointing out that offending line with os.Exit(). You can just comment it out. In your C code the app quits immediately. But in the case of Transmission it keeps running even after it closes the socket immediately, so Transmission should be found by its PID. |
Beta Was this translation helpful? Give feedback.
-
Testing it now, it's working fine so far. On the other hand, we should also distribute the libcc because in Debian for example it's not packaged:
If instead of kprobes we'd use ebpf programs we could distribute just the .o object file. |
Beta Was this translation helpful? Give feedback.
-
From this post https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html |
Beta Was this translation helpful? Give feedback.
-
I made a new branch https://github.com/themighty1/opensnitch/tree/newbpf I was not correct to say that .o is not portable. It is portable to a degree. |
Beta Was this translation helpful? Give feedback.
-
I've finally compiled and tested it. Flawlessly using the instructions of the commit, awesome! (sorry for the delay...) So the only thing left is testing it to get an idea where it'll work (just out of curiosity). As it's a eBPF module there's no risk of freeze the system if it doesn't load or fail. We still need to have debugfs mounted:
For now opensnitch.o tested on Debian Sid, kernel 5.10, and working fine. |
Beta Was this translation helpful? Give feedback.
-
Ok, back with this again @themighty1 . Can we tidy everything up and remove all the debug Println() towards pushing a PR? Some suggestions:
I can help with these changes. |
Beta Was this translation helpful? Give feedback.
-
hi, @gustavo-iniguez-goya , I've been stress-testing my code and found corner-cases when connections were not picked-up by ebpf. btw, regarding your 3rd point, we only query for UID when connection was not found in ebpf. The reason why an in-kernel connection will not be caught by our ebpf is because our ebpf hooks only to tcp...connect() and udp...send() kernel functions. But these 2 functions are NOT the only ones that can be used to establish a connection. Some in-kernel connections may be established using more low-level functions. (if memory serves me, wireguard uses ip...tunnel() function or similar). |
Beta Was this translation helpful? Give feedback.
-
thank you @themighty1 ! I know that we'll miss some connections, but this is better than what we have right now. If we wait til it's perfect we'll never add it. We'll keep improving it over time. On the other hand, we still rely on I've modified the commands tcptracer-bpfcc/tcpconnect-bpfcc (bpfcc-tools package) to get the full path to the binary from a task_struct, and although I haven't managed to get it properly (without garbage), it's definitely possible:
The
Definitely. Besides investigating all those corner cases, maybe we could also hook fork and exec to get the path of a process in a easy way, and later correlate it by PID. Since kernel 5.11 there's also this framework: |
Beta Was this translation helpful? Give feedback.
-
I looked at bpf_get_current_comm() and realized that it return only the exe name excluding the path, so, yes, parsing task_struct is what we'll need to get the full path. |
Beta Was this translation helpful? Give feedback.
-
by the way, talking about (dark) corner cases: another dark corner?
notice that between TCP_SYN_SENT and TCP_ESTABLISHED states, the reported PID is not 17215, it changes to 622:
and this is a connection from inside a container:
the process that opened that connection is
|
Beta Was this translation helpful? Give feedback.
-
https://github.com/aquasecurity/tracee/blob/main/tracee-ebpf/tracee/tracee.bpf.c#L1112 |
Beta Was this translation helpful? Give feedback.
-
thank you very much for this @themighty1 . I used to reproduce the "unknown connection" issue with maps, either with maps.google.com (firefox or chrome) or gnome-maps, zooming in and out continuously and now the problem is gone. |
Beta Was this translation helpful? Give feedback.
-
regarding Linux Kernel connections, the ones I've seen are from chrome, but with wrong PID and UID and empty cmdline (because the PID is not found): All connections to the same IP, so I'm going to remove the "Linux Kernel" -100 check, and see if we find it on already known connections. Maybe we should just discard, or not add to the map those connections if PID + UID are invalid. |
Beta Was this translation helpful? Give feedback.
-
@gustavo-iniguez-goya, you're welcome! Thank you for moving the project forward. |
Beta Was this translation helpful? Give feedback.
-
yes, even after all the checks, sometimes I got "kernel" connections, but since I stopped the docker daemon I haven't had these problems again. I'll try to reproduce it this week. Regarding this log:
at least in my case, it's caused by connections traversing the box. Typically connections originated from a VM or a container.
But all in all it's working great. |
Beta Was this translation helpful? Give feedback.
-
module cross-compiled for i386 and arm successfully. On raspberry pi, the kernel lacks some BPF features (CONFIG_BPF_SYSCALL), so it fails with the error: On the other hand, |
Beta Was this translation helpful? Give feedback.
-
great, well done! |
Beta Was this translation helpful? Give feedback.
-
Happy new year one and all !!!
@gustavo-iniguez-goya , have you done any coding towards using eBPF in Opensnitch?
Should be easy to implement.
Here's a small prog from
https://github.com/iovisor/bcc/blob/master/examples/tracing/tcpv4connect.py
gets access to kernel struck sock from which sport, dport, saddr, daddr can be obtained.
Beta Was this translation helpful? Give feedback.
All reactions