dkorunic/pktstat-bpf

GitHub: dkorunic/pktstat-bpf

Stars: 134 | Forks: 7

# pktstat-bpf [![GitHub 许可证](https://img.shields.io/github/license/dkorunic/pktstat-bpf)](https://github.com/dkorunic/pktstat-bpf/blob/master/LICENSE) [![GitHub 发布版](https://img.shields.io/github/release/dkorunic/pktstat-bpf)](https://github.com/dkorunic/pktstat-bpf/releases/latest) ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/13318edf55111810.png) ## 关于 pktstat-bpf 是基于 ncurses/libpcap 的 [pktstat](https://github.com/dleonard0/pktstat) 的轻量级替代品,由 Linux eBPF ([extended Berkeley Packet Filter](https://prototype-kernel.readthedocs.io/en/latest/bpf/)) 程序驱动。即使在 **极高的流量** 下,它也能收集数据包统计信息——通常在普通服务器上每秒可处理数百万个数据包。在 DoS 攻击等高容量场景中,传统的数据包捕获解决方案通常会因为丢包率增加而变得不可靠,这使得基于 eBPF 的捕获成为一种更稳健的替代方案。 程序执行结束时,会显示每个 IP 和每个协议的统计信息,并按每个连接的 bps(每秒比特数)、数据包数量以及(源 IP:端口,目的 IP:端口)元组进行排序。 该程序由 [用 C 语言编写的 eBPF 代码](bpf/counter.bpf.c) 和一个纯 Go 语言的用户空间组件组成,后者负责解析并输出最终的 IP/端口/协议/比特率统计信息。Go 组件使用 [cilium/ebpf](https://github.com/cilium/ebpf) 库来加载和运行 eBPF 程序,并与 eBPF map 进行交互。 默认情况下,eBPF 组件使用带有 TCX 挂载方式的 **TC** (Traffic Control) eBPF 钩子,要求至少为 Linux 内核 **v6.6**,并收集 TCP、UDP、ICMPv4 和 ICMPv6 的入口和出口流量统计信息。它也可以切换到更快的 [XDP](https://github.com/xdp-project/xdp-tutorial) (eXpress Data Path) 钩子,但代价是 **丢失出口统计信息**,因为 **XDP** 仅在入口路径中运行。由于程序到接口的挂载调用需求,XDP 模式要求至少为 Linux 内核 **v5.9**。某些发行版(特别是 Red Hat Enterprise Linux)已经向后移植了 XDP/TC 补丁,因此 eBPF 程序可能也可以在较旧的内核上运行(详情请参见需求部分)。 或者,该工具可以使用 **KProbes** 来监控所有容器、Kubernetes pods、NAT 转换和转发流中的 TCP、UDP、ICMPv4 和 ICMPv6 流量。在此模式下,它还会显示发送到或交付给用户空间应用程序的流量的进程 ID、进程名和 cgroup 路径。KProbes 的运行位置最接近用户空间,因此开销最高,但它们提供了独特的进程级可见性。KProbes 也支持较旧的 Linux 内核,硬性依赖于启用了 [BTF](https://docs.ebpf.io/concepts/btf/) 的内核。该程序通过扫描 cgroup 文件系统并 [专用的 eBPF 代码](bpf/cgroup.bpf.c) 消费内核 cgroup mkdir 事件,将内核级 cgroup ID 解析为 cgroup 路径(位于 `/sys/fs/cgroup` 下)。 也可以直接监控特定的 **cgroup**,并完全支持入口和出口流量。你可以通过挂载到根 cgroup(例如 `/sys/fs/cgroup`)来监控所有流量。进程跟踪在 cgroup 模式下可用,但仅适用于其套接字创建被 pktstat-bpf 观察到的流量。 ![演示](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/1eb6c412cb111812.gif) ## 演讲 作者曾进行过几次关于 eBPF 的演讲,以下是相关内容以及配套的 [幻灯片](https://dkorunic.net/pdf/Korunic_eBPF.pdf): - 关于 eBPF 功能、特性及实现的简短概述(35 分钟): [![DORS/CLUC 2025: eBPF](https://img.youtube.com/vi/m8dbesXHOU4/0.jpg)](https://youtu.be/m8dbesXHOU4) - 深入探讨 eBPF 功能、特性、实现及安全的详细讲座(约 45 分钟,克罗地亚语): [![DEEP 2024: eBPF: Features, capabilities and implementation](https://img.youtube.com/vi/9mQ03Cpfq_g/0.jpg)](https://youtu.be/9mQ03Cpfq_g) ## 需求 eBPF 程序的硬性要求是启用了 BTF 的 Linux 内核 **4.10**;在较旧的内核上,KProbes 可能是唯一支持的模式(例如 RHEL/CentOS 8, Debian 10)。从内核 **5.9** 开始(RHEL/CentOS 9, Debian 11, Ubuntu 20.04),支持 XDP 模式。如果发行版已向后移植 TC eBPF 补丁,TC 可能早在 **5.14** (RHEL/CentOS 9) 就能工作。在所有最近的发行版(RHEL/CentOS 9, Debian 12, Ubuntu 24.04)上,所有 eBPF 模式均受到完全支持。 加载 eBPF 程序通常需要 root 权限。此外,eBPF 代码中的指针算术会导致 [eBPF verifier](https://docs.kernel.org/bpf/verifier.html) 明确拒绝非 root 用户的使用。内核必须启用 BTF,某些特性需要更新的内核,如下表所示。 为了获得最佳性能,应启用 BPF JIT (Just-In-Time 编译)(大多数 Linux 发行版默认启用此功能): ``` sysctl -w net.core.bpf_jit_enable=1 ``` 在 XDP 模式下,并非所有 NIC 驱动程序都支持 **Native XDP**(即 XDP 程序由 NIC 驱动程序作为初始接收路径的一部分加载;最常见的 10G 驱动程序已支持此功能)或 **Offloaded XDP**(即 XDP 程序直接在 NIC 硬件上运行而不使用 CPU)。如果原生或卸载 XDP 不可用,内核将回退到 **Generic XDP**,其性能会有所降低。Generic XDP 不需要特殊的 NIC 驱动程序支持,但在网络堆栈中的运行时间要晚得多,使其性能大致等同于 TC 钩子。 下表将捕获模式映射到其需求和预期性能: | 捕获类型 | 入口 | 出口 | 性能 | 进程跟踪 | 所需内核 | 需要 SmartNIC | | --------------------------------------------------- | ------- | ------ | -------------- | ------------------------------------------ | --------------- | ----------------- | | 通用 [PCAP](https://github.com/dkorunic/pktstat) | Yes | Yes | 低 | No | Any | No | | [AF_PACKET](https://github.com/dkorunic/pktstat) | Yes | Yes | 中等 | No | v2.2 | No | | KProbes | Yes | Yes | 中等+ | **Yes** (命令, 进程 ID, cgroup 路径) | v4.10 | No | | Cgroup (SKB) | Yes | Yes | 中等+ | 部分 (命令, 进程 ID) | v4.10 | No | | TC (SchedACT) | Yes | Yes | **高** | No | v6.6 | No | | XDP Generic | Yes | **No** | **高** | No | v5.9 | No | | XDP Native | Yes | **No** | **非常高** | No | v5.9 | No | | XDP Offloaded | Yes | **No** | **线速** | No | v5.9 | **Yes** | XDP 兼容驱动程序列表: - [xdp-project XDP 驱动列表](https://github.com/xdp-project/xdp-project/blob/master/areas/drivers/README.org) - [IO Visor XDP 驱动列表](https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md#xdp) ## 用法 ``` NAME pktstat-bpf FLAGS -?, --help display help -j, --json if true, output in JSON format -c, --cgroup STRING the path to a CGroup V2 to measure statistics on -x, --xdp if true, use XDP instead of TC (this disables egress statistics) -k, --kprobes if true, use KProbes for per-process TCP/UDP statistics -g, --tui if true, enable TUI --version display program version -i, --iface STRING interface to read from (default: anpi4) --xdp_mode STRING XDP attach mode (auto, generic, native or offload; native and offload require NIC driver support) (default: auto) -r, --refresh DURATION refresh interval in TUI (default: 1s) -t, --timeout DURATION timeout for packet capture in CLI (default: 10m0s) ``` 使用 `--iface` 指定要捕获的网络接口。 `--timeout` 在指定的持续时间后停止程序。你也可以随时使用 Ctrl-C、SIGTERM 或 SIGINT 中断它。 `--tui` 切换到专为持续监控设计的简单交互式 TUI。使用方向键导航统计表,按 `q` 或 `x` 退出。 `--json` 以 JSON 格式输出流量统计信息。 `--xdp` 从 TC eBPF 模式切换到 XDP eBPF 模式以获得更高的性能,但代价是禁用出口统计信息。请注意,程序退出时可能会重置接口,因此建议在 [screen](https://www.gnu.org/software/screen/) 或 [tmux](https://github.com/tmux/tmux) 中运行。 `--xdp_mode` 将 XDP 挂载模式从默认的 `auto`(在原生和通用模式之间尽力选择)覆盖为 `native` 或 `offload`,适用于支持这些模式的 NIC 驱动程序或硬件。 `--kprobes` 切换到 KProbe 模式以按进程跟踪 TCP 和 UDP 流量。与 TC 和 XDP 模式相比性能较低,但所有跨 cgroup、容器和 Kubernetes pods 的每进程流量均可见。显示进程命令名、进程 ID 和控制组等额外详细信息。 `--cgroup ` 测量指定控制组的入口和出口流量。在可用时显示进程命令名和进程 ID。 ## Star 趋势 [![Star 趋势图](https://api.star-history.com/svg?repos=dkorunic/pktstat,dkorunic/pktstat-bpf&type=Date)](https://star-history.com/#dkorunic/pktstat&dkorunic/pktstat-bpf&Date)
标签:CGroup, cilium/ebpf, DeepPacketInspection, Docker‑Compose, Docker镜像, DoS检测, Golang, KProbe, Linux内核, TC, XDP, 内核编程, 安全渗透, 安全编程, 客户端加密, 客户端加密, 带宽分析, 性能观测, 日志审计, 流量监控, 系统分析, 网络分析, 网络可见性, 网络统计, 进程隐藏