基于 DefectDojo 构建企业级漏洞管理仪表盘:Anthropic-Cybersecurity-Skills 配置模板实战指南
导读
本文以 Anthropic-Cybersecurity-Skills 仓库中的 DefectDojo 配置模板 为核心骨架,结合同目录下的 SKILL.md、API 参考、标准与合规参考、工作流 以及 agent.py 与 process.py 两个自动化脚本,系统讲解如何在企业中落地一个集中式漏洞管理仪表盘。读者读完本文后,将掌握 DefectDojo 的 Docker 部署、产品层级建模、扫描器导入映射、SLA 策略、Jira 工单联动、CI/CD 上传流水线以及基于 REST API v2 的仪表盘指标自动化采集等全套实战能力。
DefectDojo 在漏洞管理中的定位
DefectDojo 是一个开源的应用程序漏洞管理平台,它充当漏洞管理的"中央枢纽":将 200+ 安全扫描工具(Nessus、OWASP ZAP、Burp Suite、Trivy、Semgrep、Snyk、SonarQube、Checkov、Bandit、OpenVAS、Qualys 等)的产出统一汇聚到一处,对重复项进行去重(deduplication),跟踪修复进度,并提供面向管理层的高层仪表盘。它基于 Django 构建,支持 OWASP 分类体系,并对外提供 REST API v2 供自动化调用。
在 SKILL.md 的能力描述中,该技能适用于:把分散在多套扫描器中的结果整合进单一仪表盘、自动化漏洞工单(Jira)与高管汇报(executive reporting)等场景。它同时被映射到 NIST CSF 2.0 的 ID.RA-01、ID.RA-02、ID.IM-02、ID.RA-06,以及 MITRE ATT&CK 的 T1190(利用面向公网的应用程序)、T1203(利用客户端执行)、T1068(利用提权漏洞),说明该技能既承担"资产与漏洞识别",也服务于"事件指标与检测"环节。
部署与环境配置
硬件与软件前置条件
根据 standards.md 与 SKILL.md,部署 DefectDojo 的最小与推荐资源配置如下:
| 组件 | 最小配置 | 推荐配置 |
|---|---|---|
| CPU | 2 核 | 4 核 |
| 内存 | 4 GB | 8 GB |
| 磁盘 | 20 GB | 50 GB+ |
| PostgreSQL | 12+ | 15+ |
| Docker | 20.10+ | 最新稳定版 |
| Docker Compose | 2.0+ | 最新稳定版 |
| Python | 3.9+(运行 API 集成脚本) | 3.11+ |
PostgreSQL 已包含在 Docker 部署中,无需单独安装;Jira 实例(用于工单集成)与 Slack/Teams 通知渠道为可选依赖。
Docker Compose 部署步骤
# 克隆 DefectDojo 官方仓库
git clone https://github.com/DefectDojo/django-DefectDojo.git
cd django-DefectDojo
# 使用官方脚本以生产模式启动
./dc-up-d.sh
# 或使用手动方式启动
docker compose up -d
# 查看服务状态
docker compose ps
# 从 initializer 容器日志中获取初始管理员密码
docker compose logs initializer 2>&1 | grep "Admin password"
# 浏览器访问
# http://localhost:8080
首次登录后应立即修改默认管理员密码,并按 workflows.md 中的初始化流程依次完成:创建与业务单元对齐的 Product Type → 为每个应用/服务创建 Product → 配置 Jira 集成 → 配置 Slack/Teams 通知 → 设置分级 SLA 策略 → 为扫描器集成生成 API Key。
关键环境变量
在 docker-compose.yml 中需要重点关注以下环境变量:
DD_DATABASE_ENGINE=django.db.backends.postgresql
DD_DATABASE_HOST=postgres
DD_DATABASE_PORT=5432
DD_DATABASE_NAME=defectdojo
DD_DATABASE_USER=defectdojo
DD_DATABASE_PASSWORD=<secure_password>
DD_ALLOWED_HOSTS=*
DD_SECRET_KEY=<random_64_char_key>
DD_CREDENTIAL_AES_256_KEY=<random_128_bit_key>
DD_SOCIAL_AUTH_GOOGLE_OAUTH2_ENABLED=True
其中 DD_SECRET_KEY 用于 Django 会话与签名(建议 64 位随机字符串),DD_CREDENTIAL_AE_256_KEY 用于加密平台内存储的凭据(如扫描器或 Jira 的账号凭据),二者务必使用强随机值并在生产环境通过密钥管理服务注入。
组织层级:Product Type → Product → Engagement → Test → Finding
DefectDojo 采用五层树状模型来组织漏洞数据,这是模板中"Product Hierarchy Setup"的底层逻辑:
Product Type (业务单元 / Business Unit)
└── Product (应用 / 服务)
└── Engagement (评估 / 迭代)
└── Test (单次扫描器运行)
└── Finding (单条漏洞)
这一层级的价值在于:漏洞可以从"单条 Finding"向上聚合到"业务单元"维度,从而支持按产品、按部门分别统计风险,并为高管汇报提供天然的聚合视图。
通过 API 建立层级
以下 Python 脚本(基于 SKILL.md 的示例)展示了如何用 REST API 创建这一层级:
import requests
DD_URL = "http://localhost:8080/api/v2"
API_KEY = "your_api_key_here"
HEADERS = {"Authorization": f"Token {API_KEY}", "Content-Type": "application/json"}
# 1) 创建 Product Type(对应业务单元)
resp = requests.post(f"{DD_URL}/product_types/", headers=HEADERS, json={
"name": "Web Applications",
"description": "Customer-facing web application portfolio"
})
product_type_id = resp.json()["id"]
# 2) 创建 Product(关联到 Product Type,并可绑定 SLA 配置)
resp = requests.post(f"{DD_URL}/products/", headers=HEADERS, json={
"name": "Customer Portal",
"description": "Main customer-facing web application",
"prod_type": product_type_id,
"sla_configuration": 1,
})
product_id = resp.json()["id"]
# 3) 创建 Engagement(一次评估周期,例如季度安全评估或 CI/CD 迭代)
resp = requests.post(f"{DD_URL}/engagements/", headers=HEADERS, json={
"name": "Q1 2024 Security Assessment",
"product": product_id,
"target_start": "2024-01-01",
"target_end": "2024-03-31",
"engagement_type": "CI/CD",
"status": "In Progress",
})
engagement_id = resp.json()["id"]
推荐 Product Type 划分
配置模板给出了与典型企业组织架构对齐的 Product Type 划分建议:
| Product Type | 描述 |
|---|---|
| Web Applications | 面向客户的 Web 应用 |
| Mobile Applications | iOS 与 Android 应用 |
| Internal Tools | 面向员工的内网应用 |
| Infrastructure | 网络与云基础设施 |
| APIs | REST 与 GraphQL API 服务 |
扫描器接入与文件格式映射
模板中的 "Scanner Type Mappings" 表是接入扫描器时的关键对照——它把"扫描器工具"映射到"DefectDojo 中的 scan_type 字符串"以及"该工具导出的文件格式":
| 扫描器 | DefectDojo Scan Type | 文件格式 |
|---|---|---|
| Nessus | Nessus Scan | .csv 或 .nessus |
| OWASP ZAP | ZAP Scan | .xml 或 .json |
| Burp Suite | Burp XML | .xml |
| Trivy | Trivy Scan | .json |
| Semgrep | Semgrep JSON Report | .json |
| Snyk | Snyk Scan | .json |
| SonarQube | SonarQube Scan | .json |
| Checkov | Checkov Scan | .json |
| Bandit | Bandit Scan | .json |
| OpenVAS | OpenVAS CSV | .csv |
| Qualys | Qualys Scan | .xml |
api-reference.md 补充了更多可用的 scan_type 取值(如 Nuclei Scan、SARIF、Burp REST API),而 agent.py 中的 SUPPORTED_SCAN_TYPES 列表还包含 Anchore Grype、Generic Findings Import 等。实际接入前,建议以目标 DefectDojo 版本解析器的 scan_type 值为准(扫描结果中 tests 的 test_type 字段是权威来源)。
通过 API 导入扫描结果
使用 reimport-scan 端点可以上传(或重新上传)扫描结果,实现增量更新:
# 上传 Nessus 扫描结果
curl -X POST "${DD_URL}/reimport-scan/" \
-H "Authorization: Token ${API_KEY}" \
-F "scan_type=Nessus Scan" \
-F "file=@nessus_report.csv" \
-F "product_name=Customer Portal" \
-F "engagement_name=Q1 2024 Security Assessment" \
-F "auto_create_context=true" \
-F "deduplication_on_engagement=true"
# 上传 OWASP ZAP 结果
curl -X POST "${DD_URL}/reimport-scan/" \
-H "Authorization: Token ${API_KEY}" \
-F "scan_type=ZAP Scan" \
-F "file=@zap_report.xml" \
-F "product_name=Customer Portal" \
-F "engagement_name=Q1 2024 Security Assessment" \
-F "auto_create_context=true"
# 上传 Trivy 容器扫描结果
curl -X POST "${DD_URL}/reimport-scan/" \
-H "Authorization: Token ${API_KEY}" \
-F "scan_type=Trivy Scan" \
-F "file=@trivy_results.json" \
-F "product_name=Customer Portal" \
-F "engagement_name=Q1 2024 Security Assessment" \
-F "auto_create_context=true"
几个关键参数的语义:
auto_create_context=true:当product_name/engagement_name指定的产品与评估尚不存在时自动创建,是打通 CI/CD 一键上传的关键;deduplication_on_engagement=true:仅在当前 Engagement 范围内做去重,适合每个迭代重新扫描的场景;close_old_findings=true:本次扫描未再出现的旧 Finding 自动标记为已关闭,保持仪表盘"当前真实风险"的准确性。
import-scan 与 reimport-scan 的区别在于:前者新建 Test 并导入全新结果,后者用于向已存在的 Test 中增量追加/更新,两者都支持上述参数。使用 import-scan 时也可用 product 与 engagement 的数字 ID 直接指定归属。
SLA 配置
SLA(服务等级协议)是漏洞治理的核心抓手。模板给出了按严重级别设定的"修复时限":
| 严重级别 | 修复时限(天) |
|---|---|
| Critical | 7 |
| High | 30 |
| Medium | 90 |
| Low | 120 |
| Info | 无 SLA |
值得注意的细节:配置模板中 Low 级别为 120 天,而在 agent.py 的 build_dashboard_data 函数中,SLA 字典定义为 {"Critical": 7, "High": 30, "Medium": 90, "Low": 180},即脚本示例将 Low 放宽到 180 天。这说明 SLA 阈值是一个组织策略参数,应根据自身风险管理偏好配置,并通过 DefectDojo 的 sla_configuration 绑定到 Product,从而让 Dashboard 上的 sla_breached 标记与超期统计自动生效。
Jira 集成
Jira 集成让"发现漏洞 → 创建工单 → 修复 → 自动关闭"形成闭环。模板中的配置示意如下:
Jira URL: https://company.atlassian.net
Project Key: SEC
Issue Type: Bug
Priority Mapping:
Critical -> Blocker
High -> Critical
Medium -> Major
Low -> Minor
Auto-close: Yes (when finding is closed in DefectDojo)
对应到 DefectDojo 的 Jira 配置(SKILL.md 中给出了更完整的 Python 字典形式):
jira_config = {
"url": "https://company.atlassian.net",
"username": "jira-bot@company.com",
"password": "jira_api_token",
"default_issue_type": "Bug",
"critical_mapping_severity": "Blocker",
"high_mapping_severity": "Critical",
"medium_mapping_severity": "Major",
"low_mapping_severity": "Minor",
"finding_text": "**Vulnerability**: {{ finding.title }}\n**Severity**: {{ finding.severity }}\n**CVE**: {{ finding.cve }}\n**Description**: {{ finding.description }}",
"accepted_mapping_resolution": "Done",
"close_status_key": 6,
}
其中 finding_text 使用 Jinja2 模板渲染工单正文,可在其中引用 Finding 的 title、severity、cve、description 等字段;accepted_mapping_resolution 表示"风险已接受"状态映射到的 Jira 解析值;close_status_key 指定 Finding 关闭时 Jira 工单应被置为的关闭状态编号。启用"Auto-close"后,DefectDojo 中 Finding 关闭会反向关闭关联 Jira 工单,避免修复完成后工单滞留。
CI/CD 流水线集成
通用 CI/CD 上传片段(模板)
模板提供了可直接嵌入任意 CI 系统的上传步骤:
# Generic CI/CD step for DefectDojo upload
- name: Upload scan results to DefectDojo
env:
DD_URL: ${{ secrets.DEFECTDOJO_URL }}
DD_API_KEY: ${{ secrets.DEFECTDOJO_API_KEY }}
run: |
curl -X POST "${DD_URL}/api/v2/reimport-scan/" \
-H "Authorization: Token ${DD_API_KEY}" \
-F "scan_type=${SCAN_TYPE}" \
-F "file=@${SCAN_FILE}" \
-F "product_name=${PRODUCT_NAME}" \
-F "auto_create_context=true" \
-F "close_old_findings=true"
GitHub Actions 完整示例
SKILL.md 给出了面向 GitHub Actions 的完整流水线,将代码扫描与上传整合为一次 push 触发的工作流:
# .github/workflows/security-scan.yml
name: Security Scan
on: [push]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: |
pip install semgrep
semgrep --config auto --json -o semgrep_results.json .
- name: Upload to DefectDojo
run: |
curl -X POST "${{ secrets.DD_URL }}/api/v2/reimport-scan/" \
-H "Authorization: Token ${{ secrets.DD_API_KEY }}" \
-F "scan_type=Semgrep JSON Report" \
-F "file=@semgrep_results.json" \
-F "product_name=${{ github.event.repository.name }}" \
-F "engagement_name=CI/CD" \
-F "auto_create_context=true"
这一模式在 workflows.md 的 Workflow 2 中总结为标准化步骤:流水线运行扫描器 → 通过 reimport-scan 上传 → DefectDojo 与既有数据去重 → 新 Finding 触发 Jira 工单 → 关闭的 Finding 反向自动关闭 Jira 工单 → 流水线根据严重级别返回 pass/fail 状态。
命令行自动化脚本
仓库提供了两个可直接运行的 Python 脚本,将上述 API 调用封装为 CLI:
process.py 提供四个子命令:
export DD_URL="http://localhost:8080/api/v2"
export DD_API_KEY="<your_api_key>"
# 一键创建 Product Type / Product / Engagement
python process.py setup --product-type "Web Applications" --product "Customer Portal" --engagement "Q1 Security Assessment"
# 导入扫描结果(封装 reimport-scan,自动设置 auto_create_context / deduplication / close_old_findings)
python process.py import --file nessus_report.csv --scan-type "Nessus Scan" --product "Customer Portal"
# 生成仪表盘指标报告(JSON)
python process.py dashboard --product-id 1 --output defectdojo_dashboard.json
# 列出 Findings
python process.py findings --severity High --limit 20
其 import_scan 函数内部默认携带 auto_create_context=true、deduplication_on_engagement=true、close_old_findings=true,与模板中 curl 示例的参数语义保持一致,并会打印 statistics.created / closed / reactivated 三个统计值,方便在流水线日志中核对导入效果。
agent.py 则提供了面向"仪表盘数据采集"的 DefectDojoClient,支持按严重级别统计 Finding 数量、按产品聚合、以及把原始 Finding 列表加工为仪表盘指标。
指标、去重与仪表盘自动化
REST API v2 核心端点与查询
api-reference.md 汇总了仪表盘自动化最常用的端点:
| 方法 | 端点 | 说明 |
|---|---|---|
| GET | /api/v2/findings/ | 列出漏洞 Finding |
| GET | /api/v2/products/ | 列出产品 |
| GET | /api/v2/engagements/ | 列出评估 |
| GET | /api/v2/tests/ | 列出测试 |
| POST | /api/v2/import-scan/ | 导入扫描结果 |
| POST | /api/v2/reimport-scan/ | 重新导入/更新结果 |
认证方式为请求头携带 Token:Authorization: Token $DEFECTDOJO_TOKEN。
Findings 查询支持的关键过滤参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| severity | string | Critical、High、Medium、Low、Info |
| active | boolean | 仅活跃 Finding |
| verified | boolean | 仅已验证 Finding |
| duplicate | boolean | 是否包含重复项 |
| product | integer | 按产品 ID 过滤 |
| limit | integer | 每页结果数 |
| offset | integer | 分页偏移量 |
关键指标查询
# 获取按严重级别统计的活跃 Finding 数
resp = requests.get(f"{DD_URL}/findings/?limit=0&active=true",
headers=HEADERS)
findings = resp.json()
# 获取 SLA 超期 Finding 数
resp = requests.get(f"{DD_URL}/findings/?limit=0&active=true&sla_breached=true",
headers=HEADERS)
# 获取产品级指标
resp = requests.get(f"{DD_URL}/products/{product_id}/",
headers=HEADERS)
product_data = resp.json()
process.py 的 get_metrics 函数展示了按严重级别逐一遍历统计、再汇总 total active 的典型实现;而 agent.py 的 build_dashboard_data 则展示了从 Findings 列表现场计算指标的逻辑:
total_active_findings:活跃漏洞总数;by_severity:按严重级别聚合的分布;by_product:按产品聚合(取前 10);avg_age_days:漏洞平均存在天数;overdue_count:超过 SLA 阈值的漏洞数;sla_compliance_pct:SLA 合规率百分比。
该函数还演示了如何解析 Finding 的 date 字段计算年龄,并按严重级别对照 SLA 阈值判定超期,这正是"仪表盘自动生成"的核心算法。
推荐的使用闭环
workflows.md 给出了四条可落地的标准工作流:
Workflow 1 - 初始化配置:克隆部署 → 修改默认密码 → 按业务单元创建 Product Type → 创建 Product → 配置 Jira → 配置 Slack/Teams 通知 → 设置分级 SLA → 生成 API Key。
Workflow 2 - CI/CD 扫描器集成:流水线内执行扫描 → 上传结果 → 去重 → 新漏洞建 Jira 工单 → 修复后自动关闭工单 → 按严重级别输出 pass/fail。
Workflow 3 - 漏洞分诊:分析人员逐条审核 → 验证、定级、决定是否风险接受 → 有效漏洞转 Jira → 误报标记 false positive 并说明理由 → 风险接受记录补偿性控制并设置过期时间 → 通过指标跟踪修复进度。
Workflow 4 - 高管汇报:按周期拉取指标 → 计算总漏洞数、新增 vs 关闭、SLA 合规率 → 生成产品级与业务单元级摘要 → 按严重级别跟踪平均修复时间(MTTR)→ 导出仪表盘数据。
合规与标准对齐
从 standards.md 可以看出,该技能可与多项安全合规要求对接:
- OWASP ASVS:DefectDojo 使用 OWASP 分类体系组织 Finding,便于与 ASVS 验证项对照;
- NIST SP 800-53 Rev 5 - RA-5(漏洞监控与扫描):DefectDojo 的集中化漏洞跟踪能力正是 RA-5 的落地载体;
- PCI DSS v4.0 要求 6:通过 DefectDojo 跟踪应用安全发现,可支撑 PCI 合规审计;
- NIST CSF 2.0:本技能在 SKILL.md 的 frontmatter 中被映射到
ID.RA-01(资产漏洞识别)、ID.RA-02(威胁与漏洞情报接收)、ID.IM-02(检测事件指标)与ID.RA-06(漏洞响应活动); - MITRE ATT&CK:映射到 T1190、T1203、T1068 等漏洞利用相关技术,说明该技能在"检测与响应"链条中的定位。
快速起步清单
将上述内容收敛为一份可执行清单,帮助你快速完成从零到仪表盘上线的过程:
- 按资源要求部署 DefectDojo(Docker Compose),从 initializer 日志获取初始密码并立即修改;
- 通过 API 或 UI 创建 Product Type → Product(绑定 SLA 配置)→ Engagement;
- 依据"Scanner Type Mappings"表,为每种扫描器确定正确的
scan_type字符串与导出格式; - 在 CI/CD 中加入
reimport-scan上传步骤(参考模板片段与 GitHub Actions 示例),或在本地使用process.py import; - 配置 Jira 集成(严重级别映射、
finding_text模板、Auto-close); - 用
process.py dashboard或 agent.py 的build_dashboard_data生成指标报告,接入告警与高管汇报。
结语
DefectDojo 的价值不在于"多一个漏洞数据库",而在于把分散的扫描结果、工单系统、SLA 治理与汇报流程串成一条自动化链路。本文基于 配置模板 的完整骨架,结合仓库内的 SKILL.md、API 参考、标准参考、工作流 与两套 Python 自动化脚本,给出了从部署、建模、扫描接入、SLA、Jira、CI/CD 到指标自动化的完整落地路径。你可以把本文作为团队搭建漏洞管理仪表盘的实施基准,并在此基础上按组织的业务单元与风险偏好调整 Product Type、SLA 阈值与告警渠道。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.21 K637- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python270
cherry-studio🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端TypeScript2 K146
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python46066
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go20143
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java34051