geminishkv/sbom_genform
GitHub: geminishkv/sbom_genform
一款集成多扫描器的SBOM自动化生成、漏洞分析与报告导出工具,支持CycloneDX签名和ФСТЭК BDU合规标注。
Stars: 4 | Forks: 1
[](https://github.com/geminishkv/sbom_genform/actions/workflows/ci.yml)
[](https://hub.docker.com/r/geminishkvdev/sbom-pipeline)
[](https://pypi.org/project/sbom-pipeline/)
[](https://pypi.org/project/sbom-pipeline/)
[](LICENSE.md)
[](https://github.com/geminishkv/sbom_genform/packages)
安全生成、分析和格式化 **Software Bill of Materials (SBOM)** 的工具。
**功能:**
- 从本地目录或 Git 仓库 (GitHub / GitLab) 生成 SBOM
- 根据 PURL 去重组件,根据 CVE+组件去重漏洞
- 创建 **两个已签名的 SBOM**:一个不含漏洞,一个包含漏洞
- 通过 **Trivy**、**OWASP Dependency-Check**、**Clair** 扫描漏洞
- 将发现的漏洞嵌入到 SBOM 中 (CycloneDX 1.5)
- 可选:使用 **БДУ ФСТЭК** (俄罗斯联邦技术出口监督局) 标识符丰富漏洞信息
- 导出可读报告:**Excel (.xlsx)**、**Word (.docx)**、**ODT (.odt)**
## 主 CLI

## 运行帮助

## 安装
**PyPI:**
```
pip install sbom-pipeline
```
**GitHub Packages:**
```
pip install sbom-pipeline \
--index-url https://${GITHUB_TOKEN}@pypi.pkg.github.com/geminishkv/
```
**源码:**
```
git clone https://github.com/geminishkv/sbom_genform.git
cd sbom_genform
python3 -m venv venv && source venv/bin/activate
pip install -e ".[dev]"
```
## 输出工件
### SBOM JSON
| 文件 | 描述 |
| ------------------------------------------------- | ------------------------------------------ |
| `secgensbom_out/app-bom-cdxgen.json` | 原始 SBOM |
| `secgensbom_out/app-bom-dedup.json` | 组件去重后的 SBOM |
| `secgensbom_out/app-bom-dedup-signed.json` | **不含**漏洞的已签名 SBOM |
| `secgensbom_out/app-bom-dedup-signed.sig` | SHA-256 校验和 (不含漏洞) |
| `secgensbom_out/merged-bom-signed.json` | **包含**漏洞的已签名 SBOM |
| `secgensbom_out/report_name(cert)` | 添加了 GOST 字段的报告 |
| `secgensbom_out/merged-bom-signed.sig` | SHA-256 校验和 (包含漏洞) |
| `secgensbom_out/vulns-normalized.json` | 标准化后的漏洞信息 |
如果启用了 BDU 丰富功能,在 `merged-bom-signed.json` 中,BDU 标识符将作为名为 `ru.fstec.bdu:id` 的属性写入 `vulnerabilities[].properties[]` 中。
### 扫描器报告
| 路径 | 扫描器 |
| --- | --- |
| `secgensbom_out/trivy/trivy-fs.json` | Trivy — 文件系统 |
| `secgensbom_out/trivy/sbom-vulns.json` | Trivy — SBOM 分析 |
| `secgensbom_out/dependency-check/` | OWASP Dependency-Check |
| `secgensbom_out/clair/` | Clair (如果启用) |
### 报告
| 路径 | 格式 | 内容 |
| --------------------------------- | ------ | ----------------------------------------- |
| `secgensbom_reports/excel/*.xlsx` | Excel | 工作表 1:组件,工作表 2:漏洞 |
| `secgensbom_reports/docx/*.docx` | Word | 组件表 + 漏洞表 |
| `secgensbom_reports/odt/*.odt` | ODT | 同上 |
#### “组件”工作表
| 列 | 来源 |
| ------- | -------- |
| 序号 | 顺序号 |
| 组件名称 | 来自 SBOM 的 `components[].name` |
| 组件版本 | 来自 SBOM 的 `components[].version` |
| 包类型 / 组件类型 | PURL 中的生态系统类型 (`pypi`, `maven`, `npm`, `apk`, …) |
| PURL / 组件技术标识符 | 来自 SBOM 的 `components[].purl` |
| 语言 | 根据 PURL 类型确定 (`dependency.py`) |
| 是否属于攻击面标志 | CycloneDX 组件属性:`attack-surface` / `attackSurface` / `isAttackSurface` |
| 是否执行安全功能标志 | CycloneDX 组件属性:`security-function` / `securityFunction` / `isSecurityFunction` |
| 所属容器镜像 | `metadata.component.name` (仅当 `type = "container"` 时) |
| 组件在容器镜像中的角色 | 组件属性:`container-role` / `containerRole` / `cdx:docker:layer` / `layer` |
| Web 资源地址 | 根据 PURL 计算出的仓库 URL |
#### “漏洞”工作表
| 列 | 来源 |
| ------- | -------- |
| 组件 | 来自扫描器的包名 |
| 版本 | 扫描时的版本 |
| CVE / ID | 漏洞标识符 |
| CVSS | CVSS v3 / v2 评分 |
| 严重性 | `CRITICAL` / `HIGH` / `MEDIUM` / `LOW` / `UNKNOWN` |
| 描述 | 描述的前 200 个字符 |
| 扫描器 | `trivy` / `clair` / `dependency-check` |
| 修复版本 | 包含修复的版本 (如果已知) |
| 建议 / 缓解措施 | Trivy:`PrimaryURL` → “升级到 X”;Clair:`Links[0]`;Dependency-Check:`notes` → `references[].url` |
| 当前配置下的可接受状态 | Trivy:`Status` 字段 (`fixed`、`affected`、`will_not_fix`、`end_of_life`、…) |
如果流水线使用 `--bdu` 或 `BDU=true` 启动,在所有漏洞报告格式中都会出现单独的 `BDU / ID` 列。如果未启用 BDU 丰富功能,则不会输出此列。
## BDU 丰富功能
使用 БДУ ФСТЭК 标识符进行丰富的功能默认是关闭的。
通过 CLI 启用:
```
secsbom run --bdu
```
通过环境变量启用:
```
export BDU=true
secsbom run
```
当启用 BDU 时,流水线会:
- 通过 `bdu.fstec.ru` 查询 `CVE -> BDU ID` 的对应关系
- 将 BDU ID 作为漏洞属性添加到最终的 CycloneDX SBOM 中
- 在导出的报告中输出 BDU ID
SBOM 片段示例:
```
{
"id": "CVE-2023-1234",
"properties": [
{
"name": "ru.fstec.bdu:id",
"value": "BDU:2023-01813"
}
]
}
```
## Docker
镜像包含 Python、Trivy、Docker CLI 和 Node.js/npx (cdxgen,用于非 Python 项目)。
OWASP Dependency-Check 通过 `docker run` 在工具内部运行 (Docker-in-Docker),因为其 Java 依赖会使基础镜像增加约 400 MB。
Clair 需要一个独立运行的 HTTP 服务器——因此它被移至 `docker-compose.yml` 中配置。
### Docker Hub (仅含 Trivy,不含 Clair/Dependency-Check)
```
docker pull geminishkv/sbom-pipeline:latest
docker run --rm \
-v "$(pwd)/examples/project_inject:/app/project_inject" \
-v "$(pwd)/secgensbom_out:/app/secgensbom_out" \
-v "$(pwd)/secgensbom_reports:/app/secgensbom_reports" \
-v /var/run/docker.sock:/var/run/docker.sock \
geminishkv/sbom-pipeline:latest
```
### Docker Compose (Trivy + Dependency-Check + Clair)
包含 OWASP Dependency-Check 和 Clair v4 的完整堆栈通过 `docker-compose.yml` 启动:
```
docker compose up --build
```
**启动顺序:**
1. `clair-db` (Postgres) — Clair 数据库,等待健康检查完成
2. `clair` — Clair v4 漏洞 HTTP 服务器,等待数据库就绪
3. `secgensbom` — 主流水线,在 Clair 通过健康检查后启动
**在 `secgensbom` 内部发生了什么:**
- Trivy 直接运行 (内置于镜像中)
- OWASP Dependency-Check 通过 `docker run owasp/dependency-check` 运行 (通过 `/var/run/docker.sock` 实现 Docker-in-Docker)
- Clair 通过 `clairctl` 扫描镜像,连接到 `http://clair:8080`
**环境变量:**
| 变量 | 默认值 | 描述 |
| ----------------- | ----------------------------------------- | -------------------------------------------- |
| `SOURCE` | `local` | 项目来源:`local`、`github`、`gitlab` |
| `PROJECT_DIR` | `/app/project_inject` | 容器内项目的路径 |
| `SKIP_CLAIR` | `false` | 禁用 Clair 扫描 (`true`/`false`) |
| `CLAIR_ENDPOINT` | `http://clair:8080` | Clair API 地址 |
| `IMAGE_NAME` | — | 要通过 Clair 扫描的 Docker 镜像 |
| `BDU` | `false` | 启用 БДУ ФСТЭК 标识符丰富功能 |
| `DEP_CHECK_DATA` | `/app/.dependency-check-data` | Dependency-Check 的 NVD 缓存 |
## CI/CD
### GitHub Actions
| Workflow | 触发器 | 用途 |
| ---------------- | -------------------- | ------------------------------------------------------- |
| `ci.yml` | push / PR → main | lint + mypy + pytest (3.11–3.13) |
| `secgensbom.yml` | push → main,手动 | 运行流水线,保存 SBOM 和报告 |
| `publish.yml` | 标签 `v*.*.*` | GitHub Packages + PyPI + Docker Hub + GitHub Release |
**发布新版本** — 一个标签即可触发所有流程:
```
git tag v2.1.0
git push --tags
```
### 共享模板
`secgensbom/secgensbom.yml` 文件是 GitLab 的一个**可复用 CI 模板**。GitLab 中的任何其他项目都可以通过一行代码接入现成的 SBOM 步骤,而无需复制配置:
## 架构
### `secsbom run` 流水线
```
flowchart TD
IN(["Источник\nlocal / github / gitlab"]) --> GEN
subgraph pipeline["secsbom run — этапы"]
subgraph STEP1["1 · Генерация SBOM"]
direction TB
GEN["generate.py\napp-bom-cdxgen.json"]
CLAIR_SCAN["clair.py — run_scan_report()\nclair-*.json\nполучение пакетов образа"]
CLAIR_ENRICH["clair.py — enrich_sbom_with_clair_packages()\nдобавление пакетов образа в SBOM\n(только добавление, без обновления)"]
GEN --> CLAIR_SCAN --> CLAIR_ENRICH
end
STEP1 --> DEDUP["2 · dedup.py\napp-bom-dedup.json\nдедупликация компонентов по PURL\n(объединение данных из cdxgen и Clair)"]
DEDUP --> SIGN1["3 · sign.py\napp-bom-dedup-signed.json + .sig\nSHA-256 — SBOM без уязвимостей"]
SIGN1 --> SCAN
subgraph SCAN["4 · scanner/"]
direction LR
TRIVY["trivy.py\ntrivy-fs.json\nsbom-vulns.json"]
DEPCHECK["depcheck.py\ndependency-check-report.*"]
CLAIR_VULNS["clair.py — parse_report_findings()\nизвлечение уязвимостей\nиз уже готового отчёта"]
end
TRIVY & DEPCHECK & CLAIR_VULNS --> DDUP2["5 · dedup.py\nдедупликация уязвимостей\nпо CVE + компонент"]
DDUP2 --> MERGE["6 · vuln_merger.py\nvulnerabilities[] в SBOM"]
MERGE --> SIGN2["7 · sign.py\nmerged-bom-signed.json + .sig\nSHA-256 — SBOM с уязвимостями"]
SIGN2 --> EXPORT["8 · exporter.py"]
end
CLAIR_SCAN -.->|"отчёт повторно используется\nна этапе 4"| CLAIR_VULNS
EXPORT --> XLSX["secgensbom_reports/\n*.xlsx"]
EXPORT --> DOCX["secgensbom_reports/\n*.docx"]
EXPORT --> ODT["secgensbom_reports/\n*.odt"]
```
## 仓库结构
```
sbom_genform/
├── src/sbom_pipeline/
│ ├── cli.py # secsbom / secsbom-pipeline (typer)
│ ├── pipeline.py # оркестратор
│ ├── generate.py # генерация SBOM
│ ├── dedup.py # дедупликация
│ ├── sign.py # SHA-256 подпись
│ ├── exporter.py # xlsx / docx / odt
│ ├── vuln_merger.py # встраивание уязвимостей
│ ├── config.py # конфигурация
│ └── scanner/
│ ├── trivy.py
│ ├── depcheck.py
│ └── clair.py
├── docker/
│ └── Dockerfile.secgensbom
├── examples/project_inject/ # уязвимый PHP проект
├── secgensbom/secgensbom.yml # GitLab CI shared template
├── .github/workflows/
│ ├── ci.yml
│ ├── secgensbom.yml
│ └── publish.yml
├── tests/test_smoke.py
├── pyproject.toml
└── .env.example
```
Copyright (c) 2026 Elijah S Shmakov
标签:AI应用开发, DevSecOps, Docker, PyPI, Python, SBOM, 上游代理, 后端开发, 安全防御评估, 开源框架, 持续集成, 无后门, 格式化工具, 漏洞分析, 版权保护, 硬件无关, 自动化生成, 请求拦截, 跌倒检测, 路径探测, 软件物料清单, 逆向工具