A real-time, low-overhead Linux network observability tool. eBPF Scanner hooks directly into the Linux kernel's TCP stack to monitor active network connections, associate them with user-space process IDs (PIDs), and measure transmitted bytesโall without modifying the application code or routing traffic through proxies.
- Zero-Instrumentation Tracing: Uses eBPF kprobes (
tcp_sendmsg,tcp_cleanup_rbuf) to intercept network activity directly at the kernel socket layer. - eBPF Maps for IPC: Maintains a high-performance BPF Hash Map (
BPF_MAP_TYPE_HASH) to share state (IPs, Ports, PIDs, TX Bytes) between Kernel Space and User Space securely and concurrently. - Modern eBPF Toolchain: Utilizes
bpf2go(from Cilium) to automatically compile C code into BPF bytecode and generate strictly-typed Go bindings. - Single Binary Deployment: Embeds the compiled eBPF ELF objects and the frontend HTML dashboard directly into the Go binary using
//go:embed.
eBPF applications are split into two distinct parts: Kernel Space and User Space.
graph TD
subgraph Kernel Space [Linux Kernel]
hook1([kprobe/tcp_sendmsg])
hook2([kprobe/tcp_cleanup_rbuf])
map[(BPF Hash Map<br>Connections)]
hook1 -->|1. Extract PID, IPs, Ports<br>2. Add TX bytes| map
hook2 -->|Delete connection| map
end
subgraph User Space [Go Application]
tracer[Go Tracer Daemon]
api[HTTP API :8080/stats]
ui[Web Dashboard]
tracer -->|Iterate & Read| map
tracer --> api
api -->|JSON| ui
end
Because this project compiles C code into eBPF bytecode and attaches to the Linux kernel, you need a Linux environment with specific tools installed:
- Linux Kernel 5.4+ (with BTF enabled preferably)
- Go 1.25+
- Clang & LLVM (for compiling the C code)
- Ubuntu/Debian:
sudo apt install clang llvm libbpf-dev linux-headers-$(uname -r)
- Ubuntu/Debian:
- Root privileges (required to load eBPF programs into the kernel)
-
Generate Go bindings and compile BPF C code:
go generate ./...
This command uses
bpf2goto compileinternal/bpf/scanner.cintoscanner_x86_bpfel.oand generates the corresponding Go structs. -
Build the Go binary:
go build -o ebpf-scanner ./cmd/scanner
-
Run the tracer (Requires Root):
sudo ./ebpf-scanner
-
View the Dashboard: Open your browser and navigate to:
http://localhost:8080
The C program (internal/bpf/scanner.c) attaches a kprobe to the tcp_sendmsg kernel function. Every time any process on the system attempts to send data over a TCP IPv4 socket, our eBPF program runs instantly.
- Context Extraction: It reads the kernel
sockstructure (PT_REGS_PARM1) to extract the Source IP, Dest IP, Source Port, and Dest Port. - PID Resolution: It calls
bpf_get_current_pid_tgid()to identify which process initiated the send. - State Management: It uses an atomic fetch-and-add (
__sync_fetch_and_add) to increment thetx_bytescounter in the BPF Map. - Cleanup: A separate kprobe on
tcp_cleanup_rbufcatches when the socket buffer is cleaned up (connection closed) to prevent memory leaks in the BPF Map.
The Go application (internal/tracer/tracer.go) loads the compiled ELF object into the kernel using the cilium/ebpf library. It periodically iterates over the BPF Map, parsing the raw byte data into human-readable IPs and Ports (handling Little/Big Endian conversions), and serves it via a standard net/http JSON endpoint.
This project is licensed under the MIT License - see the LICENSE file for details. The eBPF C code is GPL-licensed as required by the Linux Kernel for specific BPF helpers.
