☰
Nuclei 项目架构与开发指南:从构建测试、模板系统到扫描执行引擎的源码解析
2026/9/30 2:29:18 网站建设 项目流程
  • 网络安全
  • 应用安全
  • 漏洞扫描

【免费下载链接】nuclei

Nuclei is a fast, customizable vulnerability scanner powered by the global security community and built on a simple YAML-based DSL, enabling collaboration to tackle trending vulnerabilities on the internet. It helps you find vulnerabilities in your applications, APIs, networks, DNS, and cloud configurations.

项目地址:https://gitcode.com/GitHub_Trending/nu/nuclei
点击查看免费下载

本文是一份面向开发者的 Nuclei 工程实战指南。它以仓库根目录的 CLAUDE.md 为骨架,结合 Makefile 与cmd/、internal/、pkg/等核心目录的源码实现,系统讲解 Nuclei 的开发命令、架构分层、协议设计、模板系统、关键执行流程与目录导览。读完本文,你将掌握 Nuclei 的构建与测试工作流、理解扫描引擎的并发与聚类机制,并知道如何围绕模板开发与 JavaScript 集成进行二次开发。

一、项目概览:基于 YAML 模板的 Go 高性能漏洞扫描器

根据 CLAUDE.md 的项目概述,Nuclei 是一个用 Go 编写的现代高性能漏洞扫描器,其核心设计理念是:通过 YAML 模板定义漏洞检测逻辑,实现可定制化、可协作的漏洞检测。

关键特征包括:

  • 多协议支持:HTTP、DNS、TCP(Network)、SSL、WebSocket、WHOIS、JavaScript、Code 等协议均有独立实现。
  • 零误报设计目标:通过模拟真实世界的漏洞触发条件(而非仅做指纹匹配)来降低误报率。
  • 社区驱动:模板由全球安全社区维护,可快速响应互联网上的流行漏洞(trending vulnerabilities)。

从 go.mod 可见,该模块路径为github.com/projectdiscovery/nuclei/v3,当前 Go 版本要求为go 1.27.1,因此本地开发环境需要满足相应的 Go 工具链版本。

二、开发命令:构建、测试、校验与工具链

2.1 构建与测试

Nuclei 的所有开发命令都通过仓库根目录的 Makefile 统一封装,主要目标如下:

命令作用Makefile 实现要点
make build构建主二进制到./bin/nuclei设置GOBUILD_OUTPUT = ./bin/nuclei、GOBUILD_PACKAGES = cmd/nuclei/main.go,并启用-pgo=auto;非 macOS 平台追加-extldflags "-static"静态链接参数(Makefile 第 40-43 行)
make test运行单元测试(默认开启竞态检测)GOFLAGS = $(RACE) -v -timeout 1h -count 1,其中RACE ?= -race(Makefile 第 86-92 行)
make integration运行原生集成测试套件执行go test -tags=integration -timeout 40m ./internal/tests/integration(Makefile 第 96-97 行)
make functionalCI 专用的功能对比测试入口需要先构建./bin/nuclei,并要求 PATH 中存在 release 版nuclei二进制,通过RELEASE_BINARY与DEV_BINARY对比运行./internal/tests/functional(Makefile 第 108-115 行)
make vet运行 go vet 静态分析先执行make download与make verify校验模块,再执行go vet ./...(Makefile 第 126-127 行)
make tidy清理 go module 依赖执行go mod tidy(Makefile 第 117-118 行)

此外还有可选的回归测试入口make regression:该目标通过go test -tags=regression -timeout 30m ./lib/tests -run TestScaleRegression -v启动 HTTP 引擎的规模回归(scale regression)测试,默认拉起多个 loopback 主机并在多样化的模板集上断言检出结果的一致性;主机数量可通过环境变量覆盖,例如NUCLEI_SCALE_HOSTS=500 make regression(Makefile 第 104-106 行)。

2.2 校验与代码规范

  • 模板校验:make template-validate使用刚构建的二进制执行模板校验流程(Makefile 第 290-301 行):
    • ./bin/nuclei -ut:更新本地模板;
    • ./bin/nuclei -validate -et http/technologies -t dns -t ssl -t network -t http/exposures -ept code:排除http/technologies技术指纹类模板、排除code协议模板后,校验 DNS、SSL、Network、HTTP exposures 模板;
    • ./bin/nuclei -validate -w workflows -et http/technologies -ept code:单独校验 workflows 模板。
  • Go 代码规范:go fmt ./...统一格式,go vet ./...做静态分析。

2.3 开发工具链

  • make devtools-all:一次性构建全部 JS 开发工具 ——devtools-bindgen、devtools-tsgen、devtools-scrapefuncs,对应二进制输出到./bin/bindgen、./bin/tsgen、./bin/scrapefuncs(Makefile 第 129-141 行)。
  • make jsupdate-all:更新 JavaScript 绑定与 TypeScript 定义 ——jsupdate-bindgen以pkg/js/libs为输入、输出到pkg/js/generated,jsupdate-tsgen输出到pkg/js/generated/ts(Makefile 第 143-155 行)。
  • make docs/make syntax-docs:通过dstdocgen(yamldoc-go 工具)从模板结构生成docs.md与SYNTAX-REFERENCE.md(Makefile 第 66-84 行)。
  • make memogen:为 JavaScript 库生成 memoization 代码,输入pkg/js/libs、模板文件cmd/memogen/function.tpl,输出二进制./bin/memogen(Makefile 第 279-283 行,工具源码见 cmd/memogen/memogen.go)。
  • make dsl-docs:借助 scrapefuncs 导出内置 DSL 函数文档dsl.md(Makefile 第 285-288 行)。

2.4 运行单个测试

文档推荐以下方式精准定位问题:

# 运行某个包中的单个测试 go test -v ./pkg/path/to/package -run TestName # 集成测试统一入口 go test -tags=integration ./internal/tests/integration

集成测试位于internal/tests/integration/,涵盖 HTTP、DNS、DSL、JavaScript、WebSocket、Network、SSL、Fuzz、Interactsh、Workflow 等数十个协议与场景(如 http_test.go、dns_test.go、javascript_test.go)。

三、总体架构:CLI、Runner、引擎与模板分层

CLAUDE.md 给出了明确的模块划分,结合源码可以还原出完整的调用链:

组件职责源码位置
cmd/nuclei主 CLI 入口,负责 flag 解析与配置初始化cmd/nuclei/main.go
internal/runner核心 Runner,编排整个扫描流程internal/runner/runner.go
pkg/core执行引擎,包含 work pool 并发与模板聚类pkg/core/engine.go
pkg/templates模板的解析、编译与管理pkg/templates/templates.go
pkg/protocols各协议实现(HTTP、DNS、Network 等)pkg/protocols/protocols.go
pkg/operators匹配与提取逻辑(matchers / extractors)pkg/operators/operators.go
pkg/catalog模板发现与加载(本地磁盘 / 远程源)pkg/catalog/catalog.go

在 CLI 入口 cmd/nuclei/main.go 中,可以看到若干值得注意的初始化动作:

  • 通过runner.ConfigureOptions()完成全部 flag 的解析与校验;
  • 设置config.CurrentAppMode = config.AppModeCLI,以启用 CLI 特有的交互式行为;
  • 当用户传入-list-dsl-sigs时,直接调用dsl.GetPrintableDslFunctionSignatures()打印全部内置 DSL 函数签名并退出(main.go 第 71-75 行);
  • 当用户传入模板签名相关选项时,调用templates.UseOptionsForSigner(options)使用解析后的参数初始化模板签名器(main.go 第 77-80 行)。

3.1 协议架构:统一的 Executer 接口

每个协议(HTTP、DNS、Network 等)都遵循统一的设计模式。核心接口定义在 pkg/protocols/protocols.go:

type Executer interface { Compile() error // 编译执行生成器,预备所有可能的请求 Requests() int // 返回该规则将发起的请求总数 Execute(ctx *scan.ScanContext) (bool, error) // 执行协议组并返回是否发现结果 ExecuteWithResults(ctx *scan.ScanContext) ([]*output.ResultEvent, error) // 执行并返回结果而非写入 }

每个协议执行器还内嵌 Operators,统一获得匹配(matchers)与提取(extractors)能力,从而把"协议请求的构造与发送"和"结果的判定与提取"解耦。例如 HTTP 协议在 pkg/protocols/http/http.go 中实现Compile()时,会根据模板分析结果设置相关的执行配置(http.go 第 165、443 行)。

3.2 执行引擎:工作池与聚类

pkg/core/engine.go 是执行引擎的核心,其文档注释明确说明了设计意图:引擎内含多个线程池(work pool),允许每个协议使用不同的并发值,并承担了从模板聚类到最终由工作池执行的大部分重活。

并发配置通过GetWorkPoolConfig()从用户选项映射而来(engine.go 第 61-69 行):

  • BulkSize→ 输入(目标)并发;
  • CurrentTemplateThreads()→ 模板并发;
  • HeadlessBulkSize→ headless 浏览器输入并发;
  • HeadlessTemplateThreads→ headless 模板并发。

引擎还暴露了模板执行生命周期回调(TemplateExecutionCallback),在模板对目标开始执行(TemplateExecutionStarted)与执行结束(TemplateExecutionFinished)两个时点触发事件,回调可能被并发调用,实现必须保证并发安全(engine.go 第 11-32 行)。

四、模板系统:YAML 驱动的检测逻辑

模板是 Nuclei 的灵魂。根据 CLAUDE.md 的总结并结合 pkg/templates/templates.go 的实现:

  • 模板是 YAML 文件,Template结构体包含id(全局唯一 ID,如CVE-2021-19520)、info(元数据信息块)、requests(协议请求)、flow(多请求间的执行流程)等字段;
  • 模板会被**编译为可执行请求 + operators(matchers/extractors)**的组合;
  • 支持workflows(多模板按流程顺序执行的复合模板),相关实现位于 pkg/workflows/workflows.go;
  • 支持模板聚类:把多个模板中完全相同的请求合并为一次请求,大幅减少网络请求量。

4.1 模板聚类的实现细节

聚类逻辑位于 pkg/templates/cluster.go:

  • Cluster(list []*Template)会遍历模板列表,对 DNS、HTTP、SSL 等协议的请求调用IsClusterable()判断是否可聚类,并以TmplClusterKey()计算聚类哈希,把哈希相同的请求归为一组(cluster.go 第 48-86 行);
  • ClusterID()将聚类结果转换为可跨执行复现的数学哈希;
  • ClusterTemplates()是上层入口:当OfflineHTTP(离线 HTTP 模式)或DisableClustering(用户显式关闭聚类)时跳过聚类,否则调用Cluster()并为每个聚类组生成cluster-<id>形式的模板 ID(cluster.go 第 125-142 行)。

4.2 模板签名与验证

模板还支持签名与验证机制,相关代码位于 pkg/templates/signer/,其中handler.go提供签名处理逻辑、default.go提供默认签名器。协议层在编译时携带TemplateVerification缓存(含验证者、指纹、内容摘要等字段,见 pkg/protocols/protocols.go),Code 与 JavaScript 协议会在执行时校验模板签名是否来自可信验证者。

五、关键执行流程

CLAUDE.md 概括了扫描执行的五个阶段,与源码一一对应:

  1. 模板加载与编译:经 pkg/catalog/loader/loader.go(含远程加载器 remote_loader.go)从磁盘或远程源发现并加载模板,再由 pkg/templates/compile.go 编译。
  2. 输入提供者(targets):经 pkg/input/provider/ 处理目标输入,支持多种输入格式(Burp、OpenAPI、Raw、JSON、Swagger、YAML 等,见 pkg/input/formats/formats.go)。
  3. 引擎创建与并发:在 pkg/core/engine.go 中基于 work pool 构建并发执行环境。
  4. 模板执行与结果收集:执行各协议请求,通过 operators(pkg/operators/matchers/、pkg/operators/extractors/)完成匹配与提取,产出ResultEvent。
  5. 输出写入与报告集成:经 pkg/output/ 多路输出(文件、JSON、屏幕),并通过 pkg/reporting/ 对接 Elasticsearch、JSONL、Markdown、PDF、SARIF、Splunk、MongoDB 等导出器与 GitHub、GitLab、Jira、Linear、Gitea 等工单跟踪系统。

六、JavaScript 集成与 Code 协议

Nuclei 内置了一个自定义 JavaScript 运行时,用于支持 JavaScript / Code 协议模板。相关布局如下:

  • 运行时与编译器:pkg/js/compiler/(含池化与非池化实现、会话管理);
  • 自动生成绑定:pkg/js/generated/(go/下 32 个 Go 绑定文件、ts/下 33 个 TypeScript 定义);
  • 库实现:pkg/js/libs/(涵盖 HTTP、SMB、SMTP、SSH、LDAP、MySQL、MSSQL、Redis、Kerberos、WebSocket 等数十个交互协议库);
  • 绑定生成开发工具:pkg/js/devtools/(bindgen、tsgen、scrapefuncs)。

日常开发中通过make jsupdate-all在修改pkg/js/libs后重新生成绑定与 TypeScript 定义,通过make memogen生成 memoization 代码。模板解析层在 pkg/templates/templates.go 中同时导入了code与javascript协议,因此单个模板可以混用 HTTP + Code/JavaScript 等多种协议。

七、模板开发

根据 CLAUDE.md 的模板开发章节:

  • 模板本体存放在独立的 nuclei-templates 仓库中,本仓库负责解析、编译与执行;
  • YAML 模板由info(元信息)、requests(协议请求)、operators(匹配/提取)三个核心部分组成;
  • 单个模板可包含多种协议类型;
  • 内置 DSL 函数用于动态内容生成(如随机数、时间戳、载荷变形),完整签名可通过 CLI 的-list-dsl-sigs参数列出,底层实现见 pkg/operators/common/dsl/;
  • 模板提交前可使用make template-validate完成自动校验(参数含义见上文 2.2 节)。

八、关键目录导览

目录内容备注
lib/将 Nuclei 作为 Go 库嵌入的 SDK参见 lib/sdk.go
examples/不同场景的使用示例如 examples/simple/simple.go、examples/advanced/advanced.go
internal/tests/integration/原生集成测试套件及配套 testdata通过make integration运行
internal/tests/functional/CI 专用的原生功能对比套件通过make functional运行
pkg/fuzz/模糊测试引擎与 DAST 能力含 XSS、时间盲注分析器与频率跟踪
pkg/input/多格式输入处理Burp、OpenAPI、Swagger 等
pkg/reporting/结果导出与工单跟踪集成多种导出器与跟踪器

8.1 SDK 用法示例

lib/sdk.go 提供了NucleiEngine,可通过函数式选项(NucleiSDKOptions)定制扫描行为,并定义了ErrNoTemplatesAvailable、ErrNoTargetsAvailable等可识别错误。一个最小的嵌入示例(examples/simple/simple.go):

package main import ( "context" nuclei "github.com/projectdiscovery/nuclei/v3/lib" ) func main() { ne, err := nuclei.NewNucleiEngineCtx(context.Background(), nuclei.WithTemplateFilters(nuclei.TemplateFilters{Tags: []string{"oast"}}), nuclei.EnableStatsWithOpts(nuclei.StatsOptions{MetricServerPort: 6064}), ) if err != nil { panic(err) } // 加载目标,false 表示不对非 http/https 目标做存活探测 ne.LoadTargets([]string{"http://honey.scanme.sh"}, false) err = ne.ExecuteWithCallback(nil) if err != nil { panic(err) } defer ne.Close() }

更复杂的场景(自定义结果回调、线程安全模式、模板自动升级开关等)可参考 lib/example_test.go 与 lib/multi.go。

九、安全上下文与延伸阅读

仓库维护者在 CLAUDE.md 末尾特别提示:在编写或评审与安全相关的代码之前,务必先阅读 SECURITY_CONTEXT.md,该文件记录了本仓库已知的漏洞与反复出现的薄弱点(recurring weak spots),避免在开发中重蹈覆辙。

进一步的资料还包括:

  • DESIGN.md:整体设计文档;
  • DEBUG.md:调试排障指南;
  • SYNTAX-REFERENCE.md:模板语法参考(可由make syntax-docs重新生成);
  • CONTRIBUTING.md:贡献指南;
  • README_CN.md:中文版项目介绍。

结合以上内容,你可以从"会使用"进阶到"能开发":先用make build产出二进制,用make test/make integration守护改动,再沿着cmd/nuclei → internal/runner → pkg/core → pkg/protocols → pkg/operators这条主线深入源码,最后借助pkg/templates与pkg/catalog理解模板从文件到可执行请求的完整生命周期。

  • 网络安全
  • 应用安全
  • 漏洞扫描

【免费下载链接】nuclei

Nuclei is a fast, customizable vulnerability scanner powered by the global security community and built on a simple YAML-based DSL, enabling collaboration to tackle trending vulnerabilities on the internet. It helps you find vulnerabilities in your applications, APIs, networks, DNS, and cloud configurations.

项目地址:https://gitcode.com/GitHub_Trending/nu/nuclei
点击查看免费下载

相关推荐

上一篇:Online3DViewer:免费、3 步跑起来的在线 3D 模型查看器
下一篇:Onekey 完整使用指南:5 分钟解锁 Steam 游戏的全部 DLC

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询