7.0 KiB
syscall_monitor
基于 eBPF 的 Linux 系统调用计数监控器,附带 Flask 可视化界面
📖 项目简介
syscall_monitor 在 Linux 内核 raw_syscalls:sys_enter 跟踪点上挂载一段 eBPF 程序,按系统调用号在内核态做哈希计数;用户态由 Python 每秒读取一次快照,并在 Flask Web 页面上展示配置项中关心的系统调用调用次数。
由于挂载 eBPF 需要内核能力(CAP_BPF / root),整个程序必须以 root 权限运行。
✨ 主要特性
- 内核态全量计数,用户态按需展示:BPF 程序对所有系统调用号自增计数,配置变化无需重新挂载探针。
- 可在 Web 页面动态增删需要监控的系统调用名称,无需重启进程。
/api/countsJSON 接口供前端每秒轮询,页面实时刷新。- 后台采集线程 + 配置文件原子写入(
tmp→replace),并发读写不丢更新。 - 提供
setup.sh/run.sh/stop.sh三个部署脚本,配套 Gitea Actions CI/CD 工作流。
🧰 技术栈
| 类别 | 选型 | 来源 |
|---|---|---|
| 运行环境 | Linux(需 root,要求内核支持 eBPF/tracepoints) | main.py, collector/syscall_tracer.py |
| 语言 | Python 3 | requirements.txt |
| Web 框架 | Flask 3.1 + Jinja2 | requirements.txt, web/app.py |
| 内核采集 | bcc 0.29(BPF Compiler Collection) | requirements.txt, collector/syscall_tracer.py |
| 前端 | 服务端模板 + 原生 JS fetch 轮询 |
web/templates/ |
| CI/CD | Gitea Actions(self-hosted runner) | .gitea/workflows/ |
📁 项目结构
syscall_monitor/
├── main.py # 程序入口,校验 root 后启动 Flask
├── collector/
│ ├── __init__.py
│ └── syscall_tracer.py # eBPF 程序与采集线程
├── web/
│ ├── __init__.py
│ ├── app.py # Flask 应用工厂与路由
│ ├── static/style.css
│ └── templates/
│ ├── index.html # 实时监控页
│ └── config.html # 监控项配置页
├── config/
│ └── monitors.json # 需要展示的 syscall 名称列表
├── requirements.txt
├── setup.sh # 创建 venv(--system-site-packages)并装依赖
├── run.sh # nohup 后台启动,pid 写入 .pid
├── stop.sh # 根据 .pid 停止进程
├── .gitea/
│ ├── README.md # CI/CD 详细说明
│ └── workflows/
│ ├── ci.yml # 语法检查 + venv 构建
│ └── cd.yml # rsync 部署 + 健康检查
└── LICENSE
🧬 模块关系
flowchart LR
Kernel[Linux Kernel<br/>raw_syscalls:sys_enter] -->|tracepoint| BPF[BPF_HASH counts]
BPF -->|每秒读取| Tracer[SyscallTracer<br/>后台线程]
Tracer -->|快照| Flask[Flask app]
Config[(config/monitors.json)] --> Tracer
Config --> Flask
Flask -->|/| IndexPage[实时监控页]
Flask -->|/api/counts| IndexPage
Flask -->|/config| ConfigPage[配置页]
🚀 快速开始
环境要求
- Linux 主机,root 权限
- Python 3 + venv
bcc/python3-bpfcc等内核工具及对应内核头文件
参考安装命令(来自 .gitea/README.md):
sudo apt install -y python3-venv python3-bpfcc bpfcc-tools rsync curl linux-headers-$(uname -r)
安装
./setup.sh
脚本会创建启用 --system-site-packages 的 .venv(让 apt 安装的 bcc 在虚拟环境中可见),并按 requirements.txt 安装依赖。
配置
监控项保存在 config/monitors.json 的 syscalls 字段中,默认包含:openat、read、write、execve、close。
也可在 Web 配置页通过表单新增或移除监控项,文件会被原子化写入。
运行
sudo ./run.sh
默认监听 0.0.0.0:5000,可通过环境变量覆盖:
| 变量 | 默认值 | 说明 |
|---|---|---|
HOST |
0.0.0.0 |
Flask 监听地址 |
PORT |
5000 |
Flask 监听端口 |
启动日志位于 logs/app.log,进程号写入 .pid。
停止
sudo ./stop.sh
🔌 接口
| 方法 | 路径 | 处理函数 | 说明 |
|---|---|---|---|
| GET | / |
index |
实时监控首页,前端每秒轮询 /api/counts 刷新 |
| GET | /api/counts |
api_counts |
返回 {syscall 名: 累计次数} 的 JSON |
| GET | /config |
config_page |
监控项配置页 |
| POST | /config |
config_page |
表单字段 action=add/remove、name=<syscall>,PRG 后重定向回配置页 |
来源:web/app.py。
🚢 部署
仓库内附带的 Gitea Actions 工作流面向 self-hosted Linux runner:
- .gitea/workflows/ci.yml:push / PR 到
main触发,做 Python 语法检查并在临时 venv 中安装依赖。 - .gitea/workflows/cd.yml:推送
v*tag 或手动触发workflow_dispatch。流程依次为:停旧实例 →rsync --delete同步代码到固定目录 →setup.sh→run.sh→ 进程存活校验 → HTTP 健康检查 → 输出启动日志。
完整的 runner 准备步骤(系统包安装、部署目录创建、免密 sudo 配置等)见 .gitea/README.md。
🛠️ 开发说明
main.py中app.run(..., use_reloader=False)是关键:开启 Flask 自动重载会让主进程被 fork,导致 eBPF 探针被加载两次而冲突。- BPF 程序在内核里对所有系统调用号计数,过滤逻辑放在 Python 端
_refresh_snapshot()里,因此修改配置无需重建 BPF 程序。 SyscallTracer通过模块级_tracer单例保证 BPF 程序在进程内只挂载一次。
🔒 安全与隐私
运行该程序需要 root / CAP_BPF 权限,会读取整机所有进程的系统调用频率信息,请勿在不受信任的环境或未脱敏的多租户主机上长期开启。监听地址默认 0.0.0.0:5000,对外暴露前请自行加上反向代理与访问控制。
📄 许可证
本项目以 MIT License 发布,详见 LICENSE。