mirror of
https://github.com/yyhuni/xingrin.git
synced 2026-01-31 11:46:16 +08:00
更新架构文档
This commit is contained in:
229
docs/nuclei-template-architecture.md
Normal file
229
docs/nuclei-template-architecture.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# Nuclei 模板管理架构
|
||||
|
||||
本文档介绍 XingRin 中 Nuclei 模板的存储、同步和使用机制。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
/opt/xingrin/nuclei-repos/
|
||||
├── nuclei-templates/ # 官方模板仓库(按仓库名命名)
|
||||
│ ├── .git/
|
||||
│ ├── http/
|
||||
│ ├── network/
|
||||
│ └── ...
|
||||
└── custom-repo/ # 自定义模板仓库
|
||||
```
|
||||
|
||||
## 一、存储位置
|
||||
|
||||
| 配置项 | 默认值 | 说明 |
|
||||
|--------|--------|------|
|
||||
| `NUCLEI_TEMPLATES_REPOS_BASE_DIR` | `/opt/xingrin/nuclei-repos` | 模板仓库根目录 |
|
||||
|
||||
每个模板仓库会在根目录下创建独立子目录,目录名由仓库名称 slugify 生成。
|
||||
|
||||
## 二、数据模型
|
||||
|
||||
```
|
||||
NucleiTemplateRepo
|
||||
├── id # 仓库 ID
|
||||
├── name # 仓库名称(用于前端展示和 Worker 查询)
|
||||
├── repo_url # Git 仓库地址
|
||||
├── local_path # 本地克隆路径(自动生成)
|
||||
├── commit_hash # 当前同步的 commit hash
|
||||
└── last_synced_at # 最后同步时间
|
||||
```
|
||||
|
||||
## 三、Server 端同步流程
|
||||
|
||||
1. 用户在前端添加模板仓库(填写名称和 Git URL)
|
||||
2. 点击「同步」触发 `NucleiTemplateRepoService.refresh_repo()`
|
||||
3. 首次同步:`git clone --depth 1`(浅克隆,节省空间)
|
||||
4. 后续同步:`git pull --ff-only`(快进合并)
|
||||
5. 同步成功后更新数据库:`commit_hash`、`last_synced_at`
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────┐
|
||||
│ Server 容器 │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 前端 UI │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||||
│ │ │ 添加仓库 │ │ 同步仓库 │ │ 浏览模板 │ │ │
|
||||
│ │ │ name + url │ │ 点击刷新 │ │ 目录树 │ │ │
|
||||
│ │ └──────┬───────┘ └──────┬───────┘ └──────────────┘ │ │
|
||||
│ └─────────┼───────────────────┼───────────────────────────────────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ NucleiTemplateRepoViewSet │ │
|
||||
│ │ POST /api/nuclei/repos/ | POST .../refresh/ │ │
|
||||
│ └─────────────────────────────┬───────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ NucleiTemplateRepoService │ │
|
||||
│ │ │ │
|
||||
│ │ ┌────────────────────┐ ┌────────────────────────────────┐ │ │
|
||||
│ │ │ ensure_local_path()│ │ refresh_repo() │ │ │
|
||||
│ │ │ 生成本地目录路径 │ │ 执行 Git 同步 │ │ │
|
||||
│ │ └────────────────────┘ └───────────────┬────────────────┘ │ │
|
||||
│ └────────────────────────────────────────────┼────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────────┴───────────────┐ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ 首次同步(无 .git) │ │ 后续同步(有 .git) │ │
|
||||
│ └──────────┬──────────┘ └──────────┬──────────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||
│ │ git clone --depth 1 │ │ git pull --ff-only │ │
|
||||
│ │ <repo_url> │ │ │ │
|
||||
│ └──────────┬──────────┘ └──────────┬──────────┘ │
|
||||
│ │ │ │
|
||||
│ └──────────────┬─────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ git rev-parse HEAD │ │
|
||||
│ │ 获取当前 commit hash │ │
|
||||
│ └──────────────────────────┬──────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ PostgreSQL 数据库 │ │
|
||||
│ │ │ │
|
||||
│ │ UPDATE nuclei_template_repo SET │ │
|
||||
│ │ local_path = '/opt/xingrin/nuclei-repos/xxx', │ │
|
||||
│ │ commit_hash = 'abc123...', │ │
|
||||
│ │ last_synced_at = NOW() │ │
|
||||
│ │ WHERE id = ? │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 文件系统 │ │
|
||||
│ │ /opt/xingrin/nuclei-repos/ │ │
|
||||
│ │ ├── nuclei-templates/ # 官方模板 │ │
|
||||
│ │ │ ├── .git/ │ │
|
||||
│ │ │ ├── http/ │ │
|
||||
│ │ │ ├── network/ │ │
|
||||
│ │ │ └── ... │ │
|
||||
│ │ └── custom-repo/ # 自定义模板 │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ git clone / pull
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ GitHub / GitLab │
|
||||
│ 远程 Git 仓库 │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## 四、Worker 端同步流程
|
||||
|
||||
Worker 执行扫描任务时,通过 `ensure_nuclei_templates_local()` 确保本地模板与 Server 版本一致:
|
||||
|
||||
1. 从数据库查询仓库记录,获取 `repo_url` 和 `commit_hash`
|
||||
2. 检查本地是否存在仓库目录
|
||||
- 不存在:`git clone --depth 1`
|
||||
- 存在:比较本地 commit hash 与 Server 的 `commit_hash`
|
||||
3. 如果 commit 不一致:`git fetch` + `git checkout <commit_hash>`
|
||||
4. 返回本地模板目录路径,供 nuclei 命令使用
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────┐
|
||||
│ Worker 容器 │
|
||||
│ │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ 扫描任务 │ │
|
||||
│ │ 开始执行 │ │
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────┐ ┌─────────────────────────────────┐ │
|
||||
│ │ ensure_nuclei_ │ │ PostgreSQL │ │
|
||||
│ │ templates_local() │─────▶│ 查询 NucleiTemplateRepo 表 │ │
|
||||
│ │ │ │ 获取 repo_url, commit_hash │ │
|
||||
│ └───────────┬─────────────┘ └─────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 检查本地 .git 目录 │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────┴───────┐ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌────────┐ ┌────────────┐ │
|
||||
│ │ 不存在 │ │ 存在 │ │
|
||||
│ └───┬────┘ └─────┬──────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌────────────┐ ┌─────────────────────┐ │
|
||||
│ │ git clone │ │ 比较 commit hash │ │
|
||||
│ │ --depth 1 │ │ local vs server │ │
|
||||
│ └─────┬──────┘ └──────────┬──────────┘ │
|
||||
│ │ │ │
|
||||
│ │ ┌───────┴───────┐ │
|
||||
│ │ │ │ │
|
||||
│ │ ▼ ▼ │
|
||||
│ │ ┌──────────┐ ┌──────────────┐ │
|
||||
│ │ │ 一致 │ │ 不一致 │ │
|
||||
│ │ │ 直接使用 │ │ │ │
|
||||
│ │ └────┬─────┘ └───────┬──────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ │ ▼ │
|
||||
│ │ │ ┌──────────────────┐ │
|
||||
│ │ │ │ git fetch origin │ │
|
||||
│ │ │ │ git checkout │ │
|
||||
│ │ │ │ <commit_hash> │ │
|
||||
│ │ │ └────────┬─────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 返回本地模板目录路径 │ │
|
||||
│ │ /opt/xingrin/nuclei-repos/<repo-name>/ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 执行 nuclei 扫描 │ │
|
||||
│ │ nuclei -t /opt/xingrin/nuclei-repos/xxx/ -l targets.txt │ │
|
||||
│ └─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 五、版本一致性保证
|
||||
|
||||
- Server 同步时记录 `commit_hash`
|
||||
- Worker 使用前检查本地 hash 是否与 Server 一致
|
||||
- 不一致时自动同步到指定 commit
|
||||
- 确保所有节点使用相同版本的模板
|
||||
|
||||
## 六、配置项
|
||||
|
||||
在 `docker/.env` 或环境变量中配置:
|
||||
|
||||
```bash
|
||||
# Nuclei 模板仓库根目录
|
||||
NUCLEI_TEMPLATES_REPOS_BASE_DIR=/opt/xingrin/nuclei-repos
|
||||
```
|
||||
|
||||
## 七、常见问题
|
||||
|
||||
### Q: Worker 报错「未找到模板仓库」?
|
||||
|
||||
A: 需要先在 Server 端添加并同步模板仓库,Worker 通过数据库查询仓库信息。
|
||||
|
||||
### Q: 如何添加自定义模板仓库?
|
||||
|
||||
A: 在前端「Nuclei 模板」页面点击添加,填写仓库名称和 Git URL,然后点击同步即可。
|
||||
|
||||
### Q: 模板更新后 Worker 如何获取最新版本?
|
||||
|
||||
A: 在 Server 端点击「同步」更新模板,Worker 下次执行扫描时会检测到 commit hash 不一致并自动同步。
|
||||
Reference in New Issue
Block a user