开头先说个经历。我接手过不少新机器的环境搭建,每次给安全团队配扫描器,看似简单的一个工具,实际装下来总有人卡在莫名其妙的地方。Nuclei 是 ProjectDiscovery 出品的基于 YAML 模板的快速漏洞扫描器,它把漏洞验证逻辑拆成一个个模板文件,整个社区都在持续提交新模板,所以它的能力和更新速度比传统扫描器要高不少。这篇文章就专门讲 Nuclei 扫描器安装,从方案选型、环境准备、具体命令到常见报错排查都过一遍,不限基础,给你一份照着抄就能跑通的安装笔记。
1. 这个项目要解决什么问题:Nuclei在安全评估中的定位
1.1 为什么选择Nuclei而不是其他扫描器
先说一个很现实的场景:很多人拿到授权目标后,第一反应是往上面砸重型扫描器。重型扫描器有它的优势,但缺点也明显——跑一轮要几个小时,误报率还高,最后人工复核能把人累死。Nuclei 的定位不是替代这些工具,而是做“快速验证”。它把已知漏洞的检测逻辑写成一个个 YAML 模板,每个模板只做非常具体的请求和匹配,比如检测某个组件是否存在未授权访问、某个接口是否泄露了敏感字段、某个 CVE 的利用条件是否满足。相当于你手里有几千个已经定义好的检测插件,按需调用就行。
为什么团队里越来越多人在用 Nuclei 替代一部分传统扫描流程?我总结下来有三点。第一是速度,它是并发执行的,针对大批量资产做快速探测时效率很高。第二是模板生态,官方维护的 nuclei-templates 模板库已经有数千个模板,覆盖 Web 漏洞、暴露面、配置错误、CVE 等常见场景,而且社区一直在更新。第三是自动化友好,它支持 JSONL 输出,能和 CI/CD、漏洞管理平台、消息通知机器人无缝对接,安装完放到流水线里就能用。
1.2 从安装角度确定使用场景
安装工具之前必须想清楚一个事:你打算怎么用这个工具。这决定了你该选哪种安装方式。如果只是自己本机做快速验证,二进制直接下载最省事;如果不想污染宿主机环境,想用完就扔,Docker 容器是首选;如果想集成到 CI 流水线,那要么用官方 Docker 镜像,要么在构建阶段直接下载二进制;如果公司在离线环境里做资产巡检,那你需要把二进制和模板目录一起打包带进去。
这里说明一下,Nuclei 的安装本身非常轻量,它没有复杂的运行时依赖,二进制文件是静态编译的。真正麻烦的是模板库的管理,因为首次运行或者更新模板时,它要从远程仓库拉取数千个 YAML 文件。所以在安装阶段就要想好模板目录放哪、怎么更新、离线环境怎么处理。后面我会把这块单独拿出来讲。
2. 安装前的环境准备与方案选型
2.1 四种常见安装方式横向对比
很多教程直接甩一个install.sh让你跑,但对生产环境来说,盲目跑脚本不是好习惯。下面这个表是我实际用下来对几种安装方式的真实感受。
| 安装方式 | 操作复杂度 | 适用场景 | 备注 |
|---|---|---|---|
| 官方预编译二进制 | 低 | 个人本机、服务器、自动化脚本 | 推荐优先使用,静态编译无依赖 |
| Docker 镜像 | 低 | CI/CD、临时环境、团队统一版本 | 需注意模板目录的持久化 |
| 包管理器(apt/brew等) | 极低 | 快速体验、Kali 环境 | 版本可能滞后,生产慎用 |
| Go 源码编译 | 中高 | 开发调试、二次开发 | 需要 Go 工具链,编译时间较长 |
从我的经验来看,优先推荐官方预编译二进制。它不需要装 Go、不需要处理一堆依赖,下载解压就能跑,升级时也只要把旧文件替换掉。包管理器唯一的问题是版本滞后,系统仓库里的版本可能和官方最新版差很远,而 Nuclei 的模板更新机制又和版本强相关,版本太老会导致部分新模板的字段解析失败。Docker方式适合做版本隔离,尤其适合团队统一固定一个版本跑扫描,避免“我本机能跑、别人那跑不了”的玄学。
2.2 安装前需要确认的三件事
动手装之前,先花两分钟确认三件事,能帮你省掉后面大量排查时间。
第一,确认系统架构。Nuclei 的 release 页面按不同架构分了好几个压缩包,x86_64 的机器如果下成 arm64 的包,运行时会直接告诉你exec format error。用uname -m看一眼,x86_64 对应 amd64,aarch64 对应 arm64。
第二,确认目标机器的目录权限。推荐把二进制放到/usr/local/bin,这个目录通常在 PATH 里,任何用户都能直接敲nuclei命令。如果当前用户没权限往里面写文件,还要记得用sudo执行chmod +x和移动操作。
第三,确认模板库的存储位置。Nuclei 默认把模板下载到用户配置目录下,具体路径取决于操作系统,Linux 下一般是~/.local/share/nuclei-templates。如果你用 Docker 运行,要提前想好挂载哪个目录,避免容器删掉后模板又要重新下载。
这些表面上是小问题,但我在给别人排查安装问题的时候,至少三分之一的情况都出在这三个环节。
3. 实操:Linux环境下的Nuclei完整安装流程
3.1 官方二进制安装(推荐)
我用 Linux 服务器做演示,Windows 和 macOS 的过程类似,只是下载的包名不一样。假设当前版本是 v3.3.9,实际安装时去 GitHub Releases 页面找最新版本号替换即可。
第一步,下载二进制压缩包。在终端里执行:
cd /tmp wget https://github.com/projectdiscovery/nuclei/releases/download/v3.3.9/nuclei_3.3.9_linux_amd64.zip下载完后解压:
unzip nuclei_3.3.9_linux_amd64.zip解压出来会有一个nuclei可执行文件,把它移动到系统 PATH 目录:
sudo mv nuclei /usr/local/bin/ sudo chmod +x /usr/local/bin/nuclei验证是否安装成功:
nuclei -version看到版本号输出,说明二进制已经能正常运行了。这一步是整个安装流程的核心,后续所有等待、报错、更新,都在这个基础上展开。我建议任何时候都先跑一下nuclei -version,这是最直接的“活着没活着”的判断标准。
这里有一个细节必须提醒:下载前先确认你拿到的压缩包版本号与官方 release 一致。别在网页上看到最新版是 3.3.9,结果手动改成 3.3.8 去下载,虽然也能用,但版本不匹配会让后续的模板更新出现一些很隐蔽的问题。
3.2 Docker方式安装与持久化配置
不想在宿主机上装一堆环境的人,用 Docker 是最干净的方案。Nuclei 官方维护了镜像,拉下来就能跑:
docker pull projectdiscovery/nuclei:latest最简单的运行方式直接给它一个目标地址:
docker run -it projectdiscovery/nuclei:latest -u https://example.com但这里有个坑,容器的默认用户是 root,模板默认下载到容器内部的/root/.local/share/nuclei-templates。每次执行完docker run创建的临时容器,退出后容器被回收,重新跑一次又要重新下载模板,极其浪费时间。所以一定要做模板目录持久化。
我的做法是把模板目录挂载到宿主机:
mkdir -p ~/nuclei-templates docker run -it -v ~/nuclei-templates:/root/.local/share/nuclei-templates \ projectdiscovery/nuclei:latest -update-templates这样模板先下载到宿主机的~/nuclei-templates,后面每次跑容器都挂载同一个目录,第一次更新后就不再重复下载了。扫描结果也可以用同样的方式输出到宿主机:
docker run -it -v ~/nuclei-templates:/root/.local/share/nuclei-templates \ -v ~/nuclei-results:/root/results \ projectdiscovery/nuclei:latest -u https://example.com -o /root/results/output.txtDocker 方式最适合的场景是 CI 流水线,镜像版本在流水线里锁死,团队成员不需要各自下载二进制,整个扫描环境保持一致。
3.3 升级与卸载
Nuclei 升级非常频繁,因为模板库会不断适配新的漏洞和研究公开的技术细节。二进制的升级方式很简单,回到官网下载新版压缩包,把旧文件替换掉。有人在升级前喜欢删掉整个配置目录,这我是不建议的,升级工具本身不需要清空模板。模板单独用命令更新:
nuclei -update-templates使用 Docker 的话,升级镜像:
docker pull projectdiscovery/nuclei:latest旧的镜像可以先留着,万一新版有兼容问题,还能快速回退到上一版继续跑。卸载同样简洁,二进制方式删除文件即可:
sudo rm /usr/local/bin/nuclei rm -rf ~/.local/share/nuclei-templatesDocker 方式在不需要时移除容器和镜像:
docker rmi projectdiscovery/nuclei:latest整个安装、升级、卸载链路都不涉及系统级包依赖的残留问题,这是它另一个让我省心的地方。
4. 安装完成后的首次配置与快速验证
4.1 初始化模板库
二进制安装完成只能说明程序能跑,但真正让 Nuclei 起作用的是模板。第一次运行任意扫描命令时,Nuclei 会自动下载官方模板库。不过我更推荐先主动初始化一次,避免在正式扫描时因为下载模板而超时或者中断。
主动更新模板:
nuclei -update-templates这个命令会从官方源拉取最新的 nuclei-templates 仓库内容。模板库体积在几百 MB 量级,具体大小随版本变化。如果你处于下载受限的环境,这步可能会卡住,后面我会讲排查思路。
选择合适的模板也很关键。官方模板库包含很多目录,比如cves/、exposures/、misconfiguration/、vulnerabilities/、takeovers/等。新手容易犯的错是拿整库直接扫,扫描时间拉满,输出结果良莠不齐。更聪明的做法是先用-t指定特定模板文件,或者用-tags按标签筛选。
4.2 第一次扫描验证安装结果
不扫描一次就收工,等于没装。我推荐用一个可授权测试的地址快速验证。比如想检测一个 Web 站点的基础信息泄露和配置问题:
nuclei -u https://example.com -severity low,medium,high,critical执行后你会看到输出面板,每个命中的模板会显示模板名称、目标地址、匹配到的细节、风险等级。看到这种输出说明整个安装链路已经打通,二进制、模板、网络请求都正常。
如果你不想真的对外发起请求,还能用一个更保守的验证方式——直接扫描本地服务。比如起一个简单的 HTTP 服务,然后让 Nuclei 去探测。这个在内部测试环境尤其常用,既能验证安装又不产生任何外部流量。哪个模板命中了,说明安装和模板加载都是好的。
扫描结束后记得指定输出文件,方便后续写报告:
nuclei -u https://example.com -o result.txt输出文件支持多种格式,-jsonl可以输出 JSON Lines,方便接入其他系统,这个在自动化场景里是标配。
4.3 常用参数快速上手
安装只是开始,绝大多数人卡在不会用参数上。这里列几个最常用的:
-u:指定单个目标 URL。-l:指定目标列表文件,每行一个 URL 或域名。-t:指定要运行的模板文件或模板目录。-tags:按标签筛选模板,例如-tags cve,rce。-severity:按风险等级筛选,例如-severity critical,high。-exclude-templates:排除某些模板。-o:结果输出到文件。-jsonl:以 JSON Lines 格式输出结果,适合程序解析。-rate-limit:限制每秒请求数,控制扫描速率防止把业务系统打挂。
我通常的推荐做法是第一次只扫high,critical两个等级,先看最严重的问题,再逐步放开等级和模板范围。你还必须注意,扫描目标必须是经过授权的,没有授权就在业务系统上跑扫描,这和拿着钥匙随便开别人家门没有本质区别,出了问题后果需要自负。
5. 安装与使用中的常见问题排查
5.1 常见问题速查表
安装和首次运行阶段,我遇到了大量相似的问题,这里整理成一张速查表,方便收藏。
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 执行 nuclei 提示 command not found | 文件不在 PATH 目录,或没有执行权限 | 确认二进制在/usr/local/bin,执行sudo chmod +x |
| 下载模板一直卡住或失败 | 模板仓库下载失败,或磁盘空间不足 | 检查目标可达性;确认磁盘剩余空间;重试nuclei -update-templates |
| 提示 no usable templates found | 模板目录为空,或指定的模板路径不对 | 更新模板;确认-t路径存在;用-tags代替指定文件 |
| 执行时报 exec format error | 架构下载错误 | 用uname -m确认架构,重新下载对应包 |
| Docker 容器扫描后模板反复下载 | 模板目录没有挂载到宿主机 | 用-v挂载/root/.local/share/nuclei-templates |
| 扫描结果为空 | 模板筛选太严,或者目标没有命中 | 放开等级范围;去掉刚加的-tags再做一次基础扫描 |
| 二进制运行提示缺少动态库 | 理论上不会发生,但若出现 | 确认下载的是完整压缩包而不是某个依赖文件 |
这表后面几行是我见过的高频问题,不是说理论会这样,是实际真的有人这样踩过。
5.2 几个被问得最多的细节坑
这里单独说三个容易忽略的细节,都是实际操作中真实出现过的。
第一个坑是关于模板目录位置的误解。有些新手以为nuclei -update-templates会把模板下载到当前目录,然后在别的目录下运行就找不到模板,报“no usable templates”之类的错误。其实 Nuclei 的模板缓存目录是固定的,在 Linux 下默认在用户主目录的.local/share下。你可以在任意目录运行命令,它都会找到自己的模板。如果你手动设置过NUCLEI_TEMPLATES环境变量,那它以环境变量为准。我在做自动化脚本时,一般显式写死模板目录参数,例如:
nuclei -u https://example.com -t /root/nuclei-templates这样脚本不管在哪个用户环境下跑,模板路径都是可控的。
第二个坑是版本和模板的匹配问题。Nuclei 的引擎版本决定了它能解析哪些模板语法。某个模板用了新版本才支持的字段,而你安装的 Nuclei 是老版本,它会直接跳过这个模板,甚至报语法错误。所以遇到“某个模板怎么都不执行”的情况,第一反应不是模板错了,而是检查 Nuclei 版本是不是跟不上。保持工具和模板同时更新是很省心的习惯。我也见过有人为了兼容某些内部系统,故意锁住旧版本不升级,这种情况要理解新模板会终身无法使用,风险自己权衡。
第三个坑是磁盘空间。模板库更新一次可能会有比较大的文件变动,加上扫描输出、数据备份,长期使用下来目录会膨胀。平时没怎么注意,等到磁盘满了,扫描结果写不进去,那时候排查起来非常被动。建议设置一个定时任务定期清理旧模板或者临时文件,或者至少在使用前跑一下df -h看看容量。
最后再分享一个实际操作中的细节,Docker 方式安装后不要只用latest标签。我在生产流水线里吃过亏,某天官方推送了新版本,流水线自动拉取了变更,结果模板解析行为细微变化,让一批历史告警结果对不上了。所以在 CI 里最好固定到具体的版本号,比如projectdiscovery/nuclei:v3.3.9,每次升级是显式操作而不是隐式的意外。这个道理同样适用于本机安装,固定一个已知可用的版本,能让你踩坑时知道到底该怪谁。