syscall_monitor

基于 eBPF 的 Linux 系统调用计数监控器,附带 Flask 可视化界面

python flask bcc platform license

## 📖 项目简介 `syscall_monitor` 在 Linux 内核 `raw_syscalls:sys_enter` 跟踪点上挂载一段 eBPF 程序,按系统调用号在内核态做哈希计数;用户态由 Python 每秒读取一次快照,并在 Flask Web 页面上展示配置项中关心的系统调用调用次数。 由于挂载 eBPF 需要内核能力(CAP_BPF / root),整个程序必须以 root 权限运行。 ## ✨ 主要特性 - 内核态全量计数,用户态按需展示:BPF 程序对所有系统调用号自增计数,配置变化无需重新挂载探针。 - 可在 Web 页面动态增删需要监控的系统调用名称,无需重启进程。 - `/api/counts` JSON 接口供前端每秒轮询,页面实时刷新。 - 后台采集线程 + 配置文件原子写入(`tmp` → `replace`),并发读写不丢更新。 - 提供 `setup.sh` / `run.sh` / `stop.sh` 三个部署脚本,配套 Gitea Actions CI/CD 工作流。 ## 🧰 技术栈 | 类别 | 选型 | 来源 | |------|------|------| | 运行环境 | Linux(需 root,要求内核支持 eBPF/tracepoints) | [main.py](main.py), [collector/syscall_tracer.py](collector/syscall_tracer.py) | | 语言 | Python 3 | [requirements.txt](requirements.txt) | | Web 框架 | Flask 3.1 + Jinja2 | [requirements.txt](requirements.txt), [web/app.py](web/app.py) | | 内核采集 | bcc 0.29(BPF Compiler Collection) | [requirements.txt](requirements.txt), [collector/syscall_tracer.py](collector/syscall_tracer.py) | | 前端 | 服务端模板 + 原生 JS `fetch` 轮询 | [web/templates/](web/templates/) | | CI/CD | Gitea Actions(self-hosted runner) | [.gitea/workflows/](.gitea/workflows/) | ## 📁 项目结构 ```text 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 ``` ## 🧬 模块关系 ```mermaid flowchart LR Kernel[Linux Kernel
raw_syscalls:sys_enter] -->|tracepoint| BPF[BPF_HASH counts] BPF -->|每秒读取| Tracer[SyscallTracer
后台线程] 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](.gitea/README.md)): ```bash sudo apt install -y python3-venv python3-bpfcc bpfcc-tools rsync curl linux-headers-$(uname -r) ``` ### 安装 ```bash ./setup.sh ``` 脚本会创建启用 `--system-site-packages` 的 `.venv`(让 apt 安装的 bcc 在虚拟环境中可见),并按 `requirements.txt` 安装依赖。 ### 配置 监控项保存在 [config/monitors.json](config/monitors.json) 的 `syscalls` 字段中,默认包含:`openat`、`read`、`write`、`execve`、`close`。 也可在 Web 配置页通过表单新增或移除监控项,文件会被原子化写入。 ### 运行 ```bash sudo ./run.sh ``` 默认监听 `0.0.0.0:5000`,可通过环境变量覆盖: | 变量 | 默认值 | 说明 | |------|--------|------| | `HOST` | `0.0.0.0` | Flask 监听地址 | | `PORT` | `5000` | Flask 监听端口 | 启动日志位于 `logs/app.log`,进程号写入 `.pid`。 ### 停止 ```bash 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=`,PRG 后重定向回配置页 | 来源:[web/app.py](web/app.py)。 ## 🚢 部署 仓库内附带的 Gitea Actions 工作流面向 **self-hosted Linux runner**: - [.gitea/workflows/ci.yml](.gitea/workflows/ci.yml):push / PR 到 `main` 触发,做 Python 语法检查并在临时 venv 中安装依赖。 - [.gitea/workflows/cd.yml](.gitea/workflows/cd.yml):推送 `v*` tag 或手动触发 `workflow_dispatch`。流程依次为:停旧实例 → `rsync --delete` 同步代码到固定目录 → `setup.sh` → `run.sh` → 进程存活校验 → HTTP 健康检查 → 输出启动日志。 完整的 runner 准备步骤(系统包安装、部署目录创建、免密 sudo 配置等)见 [.gitea/README.md](.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](LICENSE)。