Files
xingrin/docs/nuclei-template-architecture.md
2025-12-17 18:20:50 +08:00

18 KiB
Raw Permalink Blame History

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_hashlast_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_urlcommit_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 或环境变量中配置:

# 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 不一致并自动同步。