3. SBOM 生成工具实战:Syft 与 Trivy 双剑合璧
好,咱们进入实战环节。前面聊了那么多 SBOM 的概念和标准,今天直接上手干活。这一章我会带你搞定三件事:用 Syft 给容器镜像生成 SBOM,用 Trivy 给文件系统生成 SBOM,最后再做个格式转换。说白了,就是让你能拿到任何软件物料清单,并且能看懂、能用起来。
3.1 为什么是 Syft 和 Trivy?
市面上 SBOM 生成工具不少,但我个人最常用的是 Anchore 家的 Syft 和 Aqua Security 家的 Trivy。原因很简单:
- Syft:专为 SBOM 生成而生,支持多种包管理器,输出格式丰富(CycloneDX、SPDX、Syft 自有格式)。我习惯把它当作 SBOM 生成的“瑞士军刀”。
- Trivy:本来是漏洞扫描工具,但它的 SBOM 生成能力也很强,尤其是文件系统扫描场景。而且它还能直接基于 SBOM 做漏洞匹配,一条命令走完两个流程。
你想想看,一个负责生成,一个负责扫描+生成,两者配合起来,基本覆盖了日常 90% 的需求。
3.2 环境准备
开始之前,先把工具装好。我假设你用的是 Linux 或 macOS,Windows 用户建议用 WSL2。
# 安装 Syft(官方推荐方式)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# 安装 Trivy(以 Ubuntu 为例)
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
# 验证安装
syft --version
trivy --version
syft version 锁定版本号是个好习惯。
3.3 使用 Syft 生成容器镜像 SBOM
容器镜像是 SBOM 生成最常见的场景。咱们拿一个 Nginx 镜像来演示。
3.3.1 基础用法
# 生成 Nginx 最新镜像的 SBOM,默认输出 Syft 格式
syft nginx:latest
# 指定输出格式为 CycloneDX JSON
syft nginx:latest -o cyclonedx-json > nginx-sbom.cdx.json
# 指定输出格式为 SPDX JSON
syft nginx:latest -o spdx-json > nginx-sbom.spdx.json
跑完第一条命令,你会看到类似这样的输出:
✔ Loaded image nginx:latest
✔ Parsed image sha256:abc123...
✔ Cataloged packages [87 packages]
NAME VERSION TYPE
apt 2.6.1 deb
base-files 12.4 deb
bash 5.2.15 deb
bsdutils 1:2.38.1 deb
coreutils 8.32 deb
...
nginx 1.25.3 deb
openssl 3.0.12 deb
zlib 1.2.13 deb
嗯,这里要注意:Syft 默认会扫描镜像里所有操作系统级别的包(deb、rpm)以及语言级别的包(npm、pip、gem 等)。87 个包,这就是 Nginx 镜像的完整物料清单。
3.3.2 指定扫描范围
有时候你只想看某个语言生态的包,比如只关注 Python 依赖:
# 只扫描 Python 包
syft nginx:latest --select-catalogers python
我个人习惯在生成 SBOM 时加上 --scope all-layers 参数,这样能扫描镜像的所有层,而不是只扫最后一层。为什么?因为有些中间层可能包含被删除但仍有安全隐患的包。
syft nginx:latest -o cyclonedx-json --scope all-layers > nginx-full-sbom.json
--scope all-layers 后,这些“幽灵包”才被揪出来。
3.4 使用 Trivy 生成文件系统 SBOM
Trivy 在文件系统扫描方面有天然优势。假设你有一个本地项目目录 /home/user/myapp,里面混合了 Go 和 Node.js 代码。
3.4.1 生成文件系统 SBOM
# 扫描文件系统并生成 CycloneDX 格式的 SBOM
trivy filesystem --format cyclonedx --output myapp-sbom.cdx.json /home/user/myapp
# 生成 SPDX 格式
trivy filesystem --format spdx-json --output myapp-sbom.spdx.json /home/user/myapp
Trivy 会自动识别项目中的 go.mod、package.json、requirements.txt 等依赖文件,并解析出完整的依赖树。
3.4.2 同时生成 SBOM 并扫描漏洞
这是 Trivy 的杀手锏——一条命令搞定 SBOM 生成和漏洞扫描:
# 生成 SBOM 并直接扫描漏洞
trivy filesystem --format cyclonedx --output myapp-sbom.cdx.json --scanners vuln /home/user/myapp
你想想看,以前要先生成 SBOM,再拿 SBOM 去扫漏洞,现在一步到位。而且 Trivy 的漏洞库更新频率很高,基本能做到 CVE 发布后 24 小时内入库。
3.5 SBOM 格式转换
现实情况是,不同工具、不同平台对 SBOM 格式的要求不一样。比如有的漏洞管理平台只认 CycloneDX,有的只认 SPDX。这时候就需要格式转换了。
3.5.1 使用 Syft 进行格式转换
Syft 本身支持多种输入格式,你可以用它来转换:
# 将 SPDX 格式转换为 CycloneDX 格式
syft convert spdx-file:nginx-sbom.spdx.json -o cyclonedx-json > nginx-converted.cdx.json
# 将 CycloneDX 格式转换为 SPDX 格式
syft convert cyclonedx-file:nginx-sbom.cdx.json -o spdx-json > nginx-converted.spdx.json
3.5.2 使用 Trivy 进行格式转换
Trivy 也支持格式转换,但更推荐用 Syft,因为 Syft 的转换引擎更成熟,对字段映射处理得更细致。
# Trivy 也可以做,但功能相对有限
trivy sbom nginx-sbom.cdx.json --format spdx-json --output nginx-converted.spdx.json
3.5.3 格式对比一览
| 特性 | CycloneDX | SPDX | Syft 自有格式 |
|---|---|---|---|
| 标准化组织 | OWASP | Linux Foundation | Anchore |
| 主要应用场景 | 漏洞管理、安全分析 | 许可证合规、法律审计 | Syft 内部使用 |
| 依赖关系表达 | 支持组件树 | 支持关系图 | 扁平列表 |
| 漏洞信息嵌入 | 原生支持 | 扩展支持 | 不支持 |
| 工具生态 | 广泛 | 广泛 | 有限 |
我个人建议:日常生成用 CycloneDX,因为它的漏洞信息嵌入能力最强,后续做漏洞优先级排序时最方便。如果客户或监管要求 SPDX,再用 Syft 做一次转换就行。
3.6 本章知识体系
下面这张图帮你梳理了本章的核心逻辑:
3.7 实战小结
这一章我们动手做了三件事:
- 用 Syft 生成容器镜像 SBOM——记住
--scope all-layers这个参数,它能帮你抓到“幽灵包”。 - 用 Trivy 生成文件系统 SBOM——一条命令同时生成 SBOM 和扫描漏洞,CI/CD 里特别好用。
- SBOM 格式转换——用 Syft convert 命令,在 CycloneDX 和 SPDX 之间自由切换。