woolkingx/peekd
GitHub: woolkingx/peekd
一款基于 eBPF 的轻量级 Linux 守护进程,实现进程级网络监控、告警与流量报告。
Stars: 0 | Forks: 0
# peekd
轻量级 Linux 守护进程,用于每个进程的网络监控、告警和流量报告 —— 由 eBPF 提供支持。
使用 Rust 重写 [picosnitch](https://github.com/elesiuta/picosnitch),以获得更好的性能与正确性。
## 功能
- 通过 `fexit/sock_sendmsg` 和 `fexit/sock_recvmsg` 捕获所有 AF_INET/AF_INET6 的发送/接收数据 — 单钩点覆盖 TCP、UDP、ICMP 和原始 IP
- 通过 kprobe 跟踪 TCP 连接生命周期(连接、接受、关闭)
- 通过对 `getaddrinfo` 的 uprobe 解析 DNS 域名
- 解析可执行文件路径、命令行参数并计算每个进程的 SHA256 哈希
- 将连接数据存储到 SQLite,并支持可配置的保留策略
- 根据可配置规则触发告警(执行脚本或 Webhook)
- 检测二进制篡改:当已知可执行文件获得新的 SHA256 时标记 `NEW_HASH`
- 将运行时指标导出到 `/run/peekd/metrics.json`
- 提供 Web 仪表板,展示实时流量图表和每个进程的详细数据
## 架构
```
kernel BPF (fexit/kprobe/kretprobe/uprobe)
│
▼
bpf.rs (perf buffer poll)
│ RawEvent broadcast
├──► dns.rs (IP→domain cache)
├──► resolver.rs (RawEvent→BpfEvent, /proc enrichment)
│ │ BpfEvent broadcast
│ ▼
│ hasher.rs (sha256 via fanotify fd / /proc/pid/exe)
│ │ hashed BpfEvent broadcast
│ ▼
│ filter.rs + enrich (EventMeta: NEW_EXE | NEW_HASH flags)
│ │ filtered BpfEvent broadcast
│ ├──► storage.rs (SQLite writer thread)
│ ├──► alerts.rs (rule matching, exec/webhook actions)
│ ├──► state.rs (exe/hash tracking, state.json)
│ └──► notify.rs (desktop notifications)
│
├──► query.rs (Unix socket RPC + CLI)
└──► web.rs (HTTP dashboard, optional)
```
## 要求
- Linux 内核 >= 5.8,并启用 BTF(`CONFIG_DEBUG_INFO_BTF=y`)
- 需具备 Root 权限或 `CAP_BPF` + `CAP_NET_ADMIN`
## 构建
```
# 构建 eBPF 字节码(需要 nightly + bpf 目标)
cargo xtask build-ebpf --release
# 构建用户空间守护进程
cargo build --release -p peekd
```
## 安装
```
sudo install -m 755 target/release/peekd /usr/local/sbin/
sudo mkdir -p /etc/peekd /var/lib/peekd /var/log/peekd /run/peekd
sudo install -m 640 config/config.toml /etc/peekd/
```
## 使用
```
# 运行守护进程(前台)
sudo peekd daemon
# 在自定义端口上运行守护进程并启用 Web 仪表板
sudo peekd daemon --web-port 5100
# 独立提供 Web 仪表板(需要守护进程运行)
sudo peekd web --port 5100
# 流量报告(最近 24 小时)
peekd report
# 指定时间窗口的报告,无行限制
peekd report --since 7d
# 带行限制的报告
peekd report --since 24h --top 20
# JSON 输出
peekd report --since 1h --json
# 通过 Unix 套接字 RPC 进行实时查询
peekd query --since 1h
peekd query --name curl --since 24h
peekd query --sum-bytes --since 7d
# 守护进程状态
peekd status
```
## Web 仪表板
启动时加上 `--web-port` 或运行 `peekd web` 后,打开 `http://localhost:5100`。
特性:
- 按小时/天显示发送与接收流量图表
- 按远程端口显示主要目标(柱状图)
- 完整的目标表格,包含主机名解析和每个进程的详细数据
- 时间窗口选择器(1h / 6h / 24h / 7d)
主机名解析顺序:系统 PTR 查询(`/etc/resolv.conf`)→ 对公 IP 进行 Whois 查册。
## 配置
`/etc/peekd/config.toml`:
```
[database]
enabled = true
retention_days = 30
write_limit_seconds = 5
[monitoring]
every_exe = false # track exec events even without network activity
[log]
ignore_ports = [53]
ignore_domains = ["localhost"]
ignore_networks = ["127.0.0.0/8", "::1/128"]
[metrics]
enabled = true
interval_seconds = 60
[web]
enabled = false
port = 5100
```
告警规则位于 `/etc/peekd/alerts.toml`:
```
[[alerts]]
name = "curl-outbound"
exe = "/usr/bin/curl"
rport = 443
action = "exec"
exec = "logger 'peekd: {exe} → {raddr}:{rport} ({domain})'"
[[alerts]]
name = "binary-tampered"
on_new_hash = true # fires only on NEW_HASH (known exe, new sha256)
action = "exec"
exec = "logger 'peekd: binary tampered: {exe} sha256={sha256}'"
```
## 运行时文件
| 路径 | 内容 |
|------|------|
| `/var/lib/peekd/peekd.db` | SQLite 连接数据库 |
| `/var/lib/peekd/state.json` | 已知可执行文件及其哈希 |
| `/var/log/peekd/peekd.log` | 结构化守护进程日志(按日滚动) |
| `/run/peekd/metrics.json` | 运行时指标快照 |
| `/run/peekd/peekd.sock` | 用于 RPC 查询的 Unix 套接字 |
## 信号
| 信号 | 效果 |
|------|------|
| `SIGINT` / `SIGTERM` | 优雅关闭并刷新最终状态 |
| `SIGHUP` | 重新加载 `alerts.toml` 中的告警规则 |
## EventMeta 标志
`NEW_EXE`(位 0):首次看到可执行文件路径 — 正常(软件安装)。
`NEW_HASH`(位 1):已知可执行文件的 SHA256 发生变化 — 可疑(可能的二进制篡改)。
启用 `on_new_hash = true` 的告警规则仅在 `NEW_HASH` 时触发,而非 `NEW_EXE`。
## eBPF 钩子点
| 钩子 | 内核函数 | 捕获内容 |
|------|----------|----------|
| `fexit/sock_sendmsg` | `sock_sendmsg` | 所有 IP 发送数据(TCP/UDP/ICMP/原始) |
| `fexit/sock_recvmsg` | `sock_recvmsg` | 所有 IP 接收数据(TCP/UDP/ICMP/原始) |
| `kprobe/tcp_v4_connect` | `tcp_v4_connect` | TCP 连接入口(暂存套接字指针) |
| `kretprobe/tcp_v4_connect` | `tcp_v4_connect` | TCP 连接完成 |
| `kretprobe/inet_csk_accept` | `inet_csk_accept` | TCP 接受连接 |
| `kprobe/tcp_close` | `tcp_close` | TCP 关闭 |
| `kretprobe/__x64_sys_execve` | `__x64_sys_execve` | 进程执行 |
| `uprobe/getaddrinfo` | libc 的 `getaddrinfo` | DNS 查询主机名 |
| `uretprobe/getaddrinfo` | libc 的 `getaddrinfo` | DNS 解析结果地址 |
标签:DNS解析, Docker镜像, ICMP监控, Linux守护进程, Mutation, RPC, Rust高性能, SQLite, TCP连接跟踪, UDP监控, Unix域套接字, Web仪表盘, 二进制篡改检测, 内存哈希, 原始IP监控, 可疑执行告警, 可视化, 可视化界面, 子域名枚举, 开源项目, 性能监控, 数据库存储, 时间线生成, 流量报表, 系统安全, 进程级监控, 通知系统