3、SBOM生成工具:Syft与Trivy实战
好,咱们进入实操环节。前面聊了那么多SBOM的理论和标准,说白了,最终都得靠工具把软件物料清单给“吐”出来。这一章,我带你亲手装两个最主流的工具——Syft和Trivy,然后生成你职业生涯里的第一个SBOM文件。
我个人习惯是把这两个工具都装上。Syft快、轻量,适合快速扫描;Trivy功能更全,还能扫漏洞。你想想看,一个负责“清点”,一个负责“安检”,搭配着用才顺手。
3.1 Syft:轻量级SBOM生成器
Syft是Anchore公司开源的工具,专为生成SBOM而生。它支持多种包格式和输出标准,比如CycloneDX和SPDX。我在项目中遇到过好几次,客户只要SPDX格式的SBOM,Syft一键就能搞定,省了我不少事。
3.1.1 安装Syft
安装方式很灵活,我推荐用自动安装脚本,省心。
# 方式一:自动安装脚本(推荐)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# 方式二:用Docker跑(适合不想污染环境)
docker pull anchore/syft:latest
docker run --rm anchore/syft version
# 方式三:macOS用Homebrew
brew install syft
装完之后,验证一下:
syft version
看到版本号输出,就说明装好了。嗯,这里要注意,如果你在公司内网,自动脚本可能被墙,那就用Docker方式,或者提前下载好二进制包。
3.1.2 Syft基本用法
Syft的用法非常直观。核心命令就一个:syft [source]。source可以是Docker镜像、文件系统、OCI归档等等。
常用命令速查表
| 命令 | 说明 | 示例 |
|---|---|---|
syft [镜像名] |
扫描Docker镜像 | syft nginx:latest |
syft dir:[路径] |
扫描本地目录 | syft dir:./myapp |
syft [镜像] -o [格式] |
指定输出格式 | syft nginx -o cyclonedx |
syft [镜像] -o [格式]=[文件] |
输出到文件 | syft nginx -o cyclonedx=sbom.json |
3.2 Trivy:全能型安全扫描器
Trivy是Aqua Security家的明星产品。它不仅能生成SBOM,还能扫漏洞、检查IaC配置、扫描密钥。说白了,Trivy是个瑞士军刀。我经常在CI/CD流水线里用Trivy,一次扫描,SBOM和漏洞报告全有了。
3.2.1 安装Trivy
安装Trivy同样简单。我个人习惯用RPM包,因为公司服务器大多是CentOS。
# 方式一:RPM安装(CentOS/RHEL)
rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.50.1/trivy_0.50.1_Linux-64bit.rpm
# 方式二:Debian/Ubuntu
sudo apt-get install trivy
# 方式三:macOS
brew install trivy
# 方式四:Docker
docker pull aquasec/trivy:latest
验证安装:
trivy --version
避坑指南
我曾经在旧版Linux上装Trivy,结果报glibc版本不兼容。后来改用Docker方式运行,完美解决。如果你遇到类似问题,别纠结,直接上Docker。
3.2.2 Trivy生成SBOM
Trivy生成SBOM的命令稍微复杂一点,但逻辑很清晰:
# 生成CycloneDX格式的SBOM
trivy image --format cyclonedx --output result.cdx.json nginx:latest
# 生成SPDX格式的SBOM
trivy image --format spdx-json --output result.spdx.json nginx:latest
# 只生成SBOM,不扫漏洞(加--scanners sbom参数)
trivy image --scanners sbom --format cyclonedx --output sbom-only.json nginx:latest
注意看,--scanners sbom这个参数很关键。默认情况下Trivy会同时扫漏洞,如果你只想生成SBOM,加上这个参数能省一半时间。
3.3 生成你的第一个SBOM文件
理论讲完了,工具也装好了。咱们来点实际的——生成第一个SBOM文件。我选一个最常见的Nginx镜像做演示。
3.3.1 用Syft生成
# 第一步:拉取镜像(如果本地没有)
docker pull nginx:latest
# 第二步:生成SBOM,输出为CycloneDX JSON格式
syft nginx:latest -o cyclonedx-json=nginx-syft.cdx.json
# 第三步:看一眼结果
cat nginx-syft.cdx.json | head -50
你会看到类似这样的输出:
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:...",
"version": 1,
"metadata": {
"timestamp": "2024-01-15T10:30:00Z",
"tools": [
{
"vendor": "anchore",
"name": "syft",
"version": "0.100.0"
}
],
"component": {
"name": "nginx",
"version": "1.25.3",
"type": "container"
}
},
"components": [
{
"bom-ref": "pkg:deb/debian/libc6@2.36-9+deb12u3?arch=amd64",
"type": "library",
"name": "libc6",
"version": "2.36-9+deb12u3",
"purl": "pkg:deb/debian/libc6@2.36-9+deb12u3?arch=amd64"
}
// ... 后面还有几百个组件
]
}
3.3.2 用Trivy生成
# 生成SPDX格式的SBOM
trivy image --format spdx-json --output nginx-trivy.spdx.json nginx:latest
# 查看文件大小
ls -lh nginx-trivy.spdx.json
小技巧
我第一次生成SBOM时,看到文件里列出了几百个组件,吓了一跳。其实这很正常,一个基础镜像就包含大量系统库和依赖。你可以用jq工具统计一下组件数量:jq '.packages | length' nginx-trivy.spdx.json
3.3.3 对比两个工具的输出
咱们把两个工具生成的SBOM做个对比,看看差异:
| 对比维度 | Syft | Trivy |
|---|---|---|
| 扫描速度 | 快(约3秒) | 中等(约8秒,含漏洞库加载) |
| 组件数量 | 约120个 | 约130个 |
| 输出格式 | CycloneDX、SPDX等 | CycloneDX、SPDX等 |
| 额外功能 | 纯SBOM生成 | SBOM + 漏洞扫描 + IaC检查 |
| 适用场景 | 快速生成、CI流水线 | 安全审计、合规检查 |
你可能会问,为什么组件数量不一样?其实是因为两个工具的包管理器解析策略不同。Syft更保守,只解析明确安装的包;Trivy会尝试解析更多层级的依赖。两者都没错,只是视角不同。
3.4 本章知识体系
下面这张图,帮你理清本章的核心逻辑:
3.5 常见问题与避坑
最后,分享几个我踩过的坑,你遇到了能少走弯路:
- 网络问题:第一次运行Syft或Trivy时,它们会下载漏洞库或包索引。如果在内网环境,记得提前配置代理或离线导入。
- 权限问题:扫描Docker镜像时,确保当前用户有Docker socket的访问权限。我曾经忘了加
sudo,结果报权限错误,排查了半天。 - 输出格式混淆:Syft的
-o cyclonedx-json和-o cyclonedx不一样,前者是JSON格式,后者是XML格式。我刚开始用的时候搞混过,导致下游解析失败。 - 版本兼容性:不同版本的Syft/Trivy生成的SBOM字段略有差异。建议在CI/CD中固定工具版本,避免因升级导致格式变化。
我的建议
刚开始接触SBOM,别追求一步到位。先用Syft扫一个小项目,看看生成的JSON结构,理解每个字段的含义。等你熟悉了,再上Trivy做全量扫描。循序渐进,比一次性啃完所有文档要高效得多。