Little Snitch for Linux 是一个基于 eBPF 的开源网络监控与阻断工具包,使用 Rust 编写。它把 eBPF 程序挂载到 Linux 内核以拦截网络连接,再通过 eBPF maps 在内核空间与用户空间之间共享数据。开源部分包括 eBPF 程序、共享类型和一个演示运行器;Objective Development 的完整产品还包含额外的专有 UI 与规则引擎组件。
用途 该项目用于在 Linux 上监控和阻断网络连接。演示运行器会加载 eBPF 程序、填充 eBPF maps,并从内核读取连接事件。
架构 整体分为三层:demo-runner(用户空间)负责加载 eBPF 程序、填充 eBPF maps、读取内核事件;ebpf crate(内核空间)包含 eBPF 程序(TC、LSM 等),拦截网络系统调用;common crate 提供内核与用户空间共用的共享类型与函数。两者通过 eBPF maps(共享内存)通信。
仓库中的 crate 包括:ebpf/(编译为 BPF 字节码的内核空间 eBPF 程序)、common/(内核与用户空间共享类型)、demo-runner/(用户空间加载器与事件消费者)、webroot/(JavaScript Web UI)。
前置条件 Rust 工具链:安装 stable 工具链;安装带 rust-src 的 nightly 工具链(eBPF 编译所需)。 系统依赖:安装 bpf-linker;安装 clang(eBPF 编译所需),Ubuntu/Debian 使用 sudo apt install clang,Fedora/RHEL 使用 sudo dnf install clang,Arch Linux 使用 sudo pacman -S clang。 内核要求:Linux 内核 5.15+(支持 BTF 与 CO-RE);内核配置启用 eBPF(CONFIG_BPF=y、CONFIG_BPF_SYSCALL=y);加载 eBPF 程序需要 CAP_BPF 或 root 权限。
构建与运行 克隆仓库后进入目录,执行 cargo build --release 构建全部内容(eBPF 程序通过构建脚本自动编译);使用 sudo cargo run --release 运行演示运行器(需要 root 或 CAP_BPF);可用 cargo check 仅检查而不构建。注意:Cargo 构建脚本会自动编译 eBPF 程序并将其嵌入二进制文件,无需手动编译 eBPF。
阻断列表配置 演示运行器在启动时加载两个阻断列表文件:blocked_hosts.txt(每行一个 IP 地址或主机名)和 blocked_domains.txt(每行一个域名后缀,会阻断该域名及其所有子域名)。运行前需将这两个文件放在工作目录中。
共享类型(common crate) common crate 定义内核 eBPF 代码与用户空间共享的类型。扩展项目时,新的共享类型应添加在此处。示例中定义了 ConnectionEvent(通过 perf/ring buffer 从内核发送到用户空间的连接事件,包含 pid、uid、源/目标地址、源/目标端口、协议、动作)和 IpKey(被阻断主机 map 的键类型)。
eBPF 程序(ebpf crate) eBPF 程序位于 ebpf/src/,使用 nightly 工具链编译为 BPF 字节码。示例展示了一个 TC(Traffic Control)eBPF 程序结构:定义与用户空间共享的 BLOCKED_HOSTS map,通过 classifier 函数从数据包头提取目标 IP,若命中阻断列表则返回 TC_ACT_SHOT 丢弃数据包,否则返回 TC_ACT_OK。
演示运行器(用户空间加载器) demo-runner 使用 Aya 加载 eBPF 程序并与 maps 交互。示例展示了加载编译后的 eBPF 对象、将 TC 分类器挂载到网络接口(如 eth0)、从文件填充被阻断主机 map,以及保持运行并处理 Ctrl+C 的流程。
添加新的被阻断域名 示例展示了在 demo-runner 中填充域名阻断列表 map 的模式:读取文件内容,将每个域名转为固定长度字节数组作为键插入 map。
从内核读取事件 示例展示了从 ring buffer 消费连接事件的模式:使用 RingBuf 与 AsyncFd 异步读取,解析 ConnectionEvent 并打印 pid、目标地址端口与动作(BLOCKED/ALLOWED)。
Cargo.toml 结构 文档给出了 demo-runner 与 ebpf 两个 crate 的 Cargo.toml 示例,包含 aya、aya-log、common、anyhow、tokio、log、env_logger 等依赖,以及 aya-build、aya-ebpf、aya-log-ebpf 等构建/内核依赖。
故障排查 加载 eBPF 时提示“Operation not permitted”:使用 sudo 运行,或在构建后用 setcap 授予 cap_bpf、cap_net_admin 能力。 构建失败提示 bpf-linker not found:执行 cargo install bpf-linker;若失败,确保安装 LLVM(Debian/Ubuntu 使用 sudo apt install llvm-dev libclang-dev)。 eBPF 验证器拒绝程序:减小 map 大小或循环边界;确保所有内存访问都做了边界检查;检查内核版本是否支持所用 helper(uname -r 应为 5.15+)。 Map not found 错误:确认 eBPF 对象已正确构建并嵌入(demo-runner/build.rs 中的构建脚本会自动处理)。 blocked_hosts.txt not found:从仓库根目录运行,或显式指定路径;可先创建空的 blocked_hosts.txt 与 blocked_domains.txt。
许可 仓库中所有代码以 GPL-2.0 许可发布,提交到该项目的贡献也以相同条款授权。