饮墨

子安饮墨馀三斗,留与卿儿作赋来

Nuclei 漏洞扫描实战:3 步构建自动化安全巡检 Pipeline,覆盖 Web 应用到云配置

3 views

痛点

安全巡检是运维绑定死的任务,但现实往往是这样:

  • 工具碎片化:Web 漏洞用 OWASP ZAP、端口扫描用 Nmap、SSL 检查用 testssl.sh、云配置用 ScoutSuite——5 种工具 5 套配置,结果散落各处
  • 手动执行效率低:每次安全审计人工跑一遍扫描、筛结果、写报告,耗时半天起步
  • 覆盖面不稳定:全靠工程师经验和记忆,这次扫了 SQL 注入,下次忘了检查 CORS 配置
  • CI/CD 集成困难:大多数扫描工具不适合自动化,塞进 Pipeline 后要么太慢、要么误报淹没告警

你需要的是一个统一的、模板驱动的、能嵌入 CI/CD 的自动化扫描引擎

方案:Nuclei — 模板驱动的开源漏洞扫描框架

Nuclei 是 ProjectDiscovery 开源的漏洞扫描框架,核心设计思路:一切扫描逻辑都是 YAML 模板。官方 nuclei-templates 仓库包含 8000+ 模板,覆盖 CVE 漏洞、错误配置、默认凭据、信息泄露等场景。

核心优势:

  • 单二进制文件,Go 编写,无依赖,部署秒级
  • 模板化:扫描规则可复用、可版本管理、可 Code Review
  • 协议全覆盖:HTTP、DNS、TCP、SSL/TLS、WebSocket、gRPC
  • 高性能并发:默认并发 25 模板 × 25 主机,万级 URL 分钟级完成
  • CI/CD 友好:JSON/SARIF 输出,原生支持 GitHub Actions、GitLab CI

实操步骤

Step 1:安装与初始化

# 方式一:Go install(推荐,获取最新版)
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# 方式二:直接下载二进制
curl -sL https://github.com/projectdiscovery/nuclei/releases/latest/download/nuclei_$(uname -s)_amd64.zip -o nuclei.zip
unzip nuclei.zip && sudo mv nuclei /usr/local/bin/
\n# 首次运行自动拉取模板库(默认存放 ~/nuclei-templates/)
nuclei -update-templates

验证安装:

nuclei -version
# Nuclei Engine Version: v3.x.x
# 模板数: 8000+

Step 2:执行安全扫描

基础单目标扫描:

# 对单个域名跑全量模板
nuclei -u https://example.com -o results.txt

# 只扫 critical 和 high 级别
nuclei -u https://example.com -severity critical,high

# 按类别扫描(只跑 CVE 检测)
nuclei -u https://example.com -tags cve -o cve-results.txt

批量资产并行扫描:

# 准备目标列表
cat > targets.txt <<EOF
https://app1.example.com
https://app2.example.com
https://api.example.com
EOF

# 批量扫描 + JSON 输出
nuclei -l targets.txt \
  -severity critical,high,medium \
  -json -o scan-$(date +%Y%m%d).json \
  -rate-limit 100 \
  -bulk-size 25 \
  -concurrency 25

常用模板分类速查:

模板标签 用途 场景举例
cve 已知 CVE 漏洞 Log4Shell、Spring4Shell
misconfig 服务错误配置 Nginx 目录遍历、.env 暴露
exposure 敏感信息泄露 API Key 泄露、调试接口
default-login 默认凭据 Grafana admin/admin
ssl TLS/SSL 配置 弱加密套件、证书过期
dns DNS 配置问题 Zone Transfer、子域名接管

Step 3:CI/CD 集成与自定义模板

GitHub Actions 自动化扫描:

# .github/workflows/security-scan.yml
name: Weekly Security Scan
on:
  schedule:
    - cron: '0 2 * * 1'  # 每周一凌晨 2 点
  workflow_dispatch:

jobs:
  nuclei-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: projectdiscovery/nuclei-action@v2
        with:
          target: https://your-app.example.com
          flags: "-severity critical,high -tags cve,misconfig,exposure"
          output: nuclei-report.sarif
          sarif-export: nuclei-report.sarif

      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: nuclei-report.sarif

Shell 定时巡检脚本(适合自建环境):

#!/bin/bash
# security-scan.sh — 定期安全巡检 + 告警
TARGETS="/etc/nuclei/targets.txt"
OUTPUT_DIR="/var/log/nuclei-scans"
DATE=$(date +%Y%m%d)

mkdir -p "$OUTPUT_DIR"
nuclei -update-templates -silent

nuclei -l "$TARGETS" \
  -severity critical,high,medium \
  -tags cve,misconfig,exposure,default-login \
  -json -o "$OUTPUT_DIR/scan-$DATE.json" \
  -silent -rate-limit 50

# 统计高危结果
CRITICAL=$(jq '[.[] | select(.info.severity=="critical")] | length' "$OUTPUT_DIR/scan-$DATE.json")
HIGH=$(jq '[.[] | select(.info.severity=="high")] | length' "$OUTPUT_DIR/scan-$DATE.json")

if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
    curl -X POST "$WEBHOOK_URL" -H 'Content-Type: application/json' \
      -d "{\"text\": \"⚠️ 安全巡检: ${CRITICAL} critical + ${HIGH} high 漏洞,详见 $OUTPUT_DIR/scan-$DATE.json\"}"
fi

编写自定义模板 — 检测内部接口暴露:

# custom-templates/internal-api-exposure.yaml
id: internal-api-exposed
info:
  name: Internal API Endpoint Exposed
  severity: high
  description: 内部调试/管理端点暴露在公网
  tags: exposure,custom

http:
  - method: GET
    path:
      - "{{BaseURL}}/actuator/health"
      - "{{BaseURL}}/debug/pprof/"
      - "{{BaseURL}}/_internal/status"
    matchers-condition: or
    matchers:
      - type: status
        status:
          - 200
      - type: word
        words:
          - "\"status\":\"UP\""
          - "pprof"

运行自定义模板:

nuclei -u https://your-app.example.com -t custom-templates/ -severity high,critical

避坑指南

1. 扫描前必须获得授权,否则后果自负

Nuclei 会向目标发送真实请求。对未授权目标扫描可能触发 WAF 封禁甚至法律风险。生产环境只扫自有资产,并在 WAF/CDN 白名单中加入扫描源 IP,避免触发防护策略反锁自己。

2. 控制扫描速率,别打崩自家服务

默认并发配置对小型应用可能过于激进。生产环境务必加速率限制:

# 保守配置:适合核心业务系统
nuclei -l targets.txt -rate-limit 30 -bulk-size 10 -concurrency 10

建议在低峰期(凌晨 2-5 点)执行。首次对新目标扫描时,先用 -tags ssl,tech-detect 做轻量探测,确认无影响后再跑全量。

3. 误报管理:建立白名单 + 二次验证机制

8000+ 模板覆盖面广,误报不可避免。用 .nuclei-ignore 文件排除已确认的误报:

# .nuclei-ignore
tech-detect:nginx
tech-detect:cloudflare

severity: info 级别的多数是信息收集(技术栈识别、端口发现),不算漏洞,生产告警中建议过滤掉,只关注 medium 以上。

总结

  • 工具统一:Nuclei 一个二进制 + YAML 模板替代多个安全扫描工具,CVE、错误配置、信息泄露、默认凭据一站覆盖
  • 自动化闭环:JSON/SARIF 输出 + CI/CD 原生支持,安全巡检像跑单测一样嵌入 Pipeline
  • 模板可控:8000+ 社区模板开箱即用,自定义模板 10 行 YAML 即可扩展内部合规检查
  • 落地路径:从周度全量扫描(critical + high)起步 → 逐步加入自定义模板覆盖内部合规 → 扫描结果接入钉钉/飞书/Slack 告警通道,发现即通知,闭环修复