3. SBOM 生成工具链实战:syft、cyclonedx-bom、spdx-sbom-generator

说实话,刚开始做物联网安全那会儿,我最大的困惑就是——SBOM 到底怎么生成?

那时候团队里有人提议手动整理物料清单。我一听就摇头。你想想看,一个智能网关里可能有上百个开源组件,手动记?不出三天就得乱套。

所以,工具链是必须的。今天我就带你走一遍三个主流生成工具:syft、cyclonedx-bom 和 spdx-sbom-generator。我会结合自己的踩坑经历,给你讲讲它们怎么用、有什么区别、什么时候该选哪个。

核心观点:没有完美的工具,只有适合场景的工具。选型的关键在于你的交付格式、集成环境和团队技术栈。

3.1 工具全景:一张图看懂生成链

在动手之前,我们先搭个框架。SBOM 生成工具链的核心逻辑其实很简单:扫描 → 分析 → 输出。但不同工具在扫描深度、格式支持和性能上差异很大。

SBOM 生成工具链全景图 输入:项目源码/镜像 扫描工具 分析引擎 格式生成器 输出:SBOM 文档 典型工具:syft(扫描+分析)、cyclonedx-bom(格式生成)、spdx-sbom-generator(全链路)

3.2 syft:轻量级扫描利器

syft 是我个人最常用的工具。为什么?因为它快,而且对容器镜像的支持特别好。

我记得有一次,客户要求对一批物联网网关的固件做 SBOM 审计。固件是 Yocto 构建的,里面包了上百个包。用 syft 扫一遍,不到两分钟就出了清单。

3.2.1 安装与基本用法

# 安装 syft(macOS/Linux)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

# 扫描本地目录
syft dir:./my-iot-firmware -o cyclonedx-json

# 扫描 Docker 镜像
syft my-image:latest -o spdx-json

这里有个细节:syft 默认输出格式是 CycloneDX,但你也可以用 -o 参数指定 SPDX。我个人习惯在开发阶段用 CycloneDX,在合规交付时用 SPDX。

小技巧:syft 支持 --exclude 参数跳过某些目录。比如扫描 Linux 固件时,可以排除 /proc、/sys 这些虚拟文件系统,能省不少时间。

3.2.2 实战案例:扫描一个 Node.js 项目

# 创建一个测试项目
mkdir test-iot-app && cd test-iot-app
npm init -y
npm install express

# 用 syft 生成 SBOM
syft dir:. -o cyclonedx-json > sbom.cdx.json

输出文件里会列出所有依赖,包括传递依赖。我曾经遇到过一个坑:某个物联网项目里用了 lodash 的旧版本,syft 直接标了出来。要不是它,那个漏洞可能就漏过去了。

3.3 cyclonedx-bom:专精 CycloneDX 格式

如果你对 CycloneDX 格式有特殊要求,cyclonedx-bom 是个好选择。它由 OWASP 社区维护,对 CycloneDX 标准的支持最完整。

3.3.1 安装与使用

# 安装 cyclonedx-bom(需要 Java 环境)
# 从 Maven 中央仓库下载 JAR
wget https://github.com/CycloneDX/cyclonedx-core-java/releases/latest/download/cyclonedx-cli.jar

# 生成 SBOM
java -jar cyclonedx-cli.jar -i ./my-project -o sbom.xml

嗯,这里要注意:cyclonedx-bom 对 Java 项目的支持最好。如果你用的是 Maven 或 Gradle,它可以直接从构建文件里提取依赖信息,准确率很高。

但如果是 C/C++ 项目,它的表现就一般了。我试过用它扫描一个基于 CMake 的物联网项目,结果漏掉了好几个静态链接的库。

避坑指南:cyclonedx-bom 对非 Java 项目的支持有限。如果你的项目是 C/C++、Rust 或 Go,建议先用 syft 做初步扫描,再用 cyclonedx-bom 做格式转换。

3.4 spdx-sbom-generator:SPDX 标准的最佳搭档

spdx-sbom-generator 是 Linux 基金会旗下的工具,专门针对 SPDX 格式。如果你需要向客户或监管机构交付 SPDX 格式的 SBOM,这个工具是首选。

3.4.1 安装与使用

# 安装 spdx-sbom-generator
# 从 GitHub Releases 下载对应平台的二进制
wget https://github.com/spdx/spdx-sbom-generator/releases/latest/download/spdx-sbom-generator-linux-amd64.tar.gz
tar -xzf spdx-sbom-generator-linux-amd64.tar.gz

# 生成 SPDX SBOM
./spdx-sbom-generator -p ./my-project -o spdx.json

这个工具的一个亮点是:它支持多种包管理器,包括 npm、pip、Maven、Go Modules 等。我曾在一次审计中用它扫描了一个混合语言项目(Python + Node.js),结果很干净。

3.5 工具对比:一张表说清楚

下面这个表是我根据实际项目经验整理的。你可以把它当作选型参考。

特性 syft cyclonedx-bom spdx-sbom-generator
开发语言 Go Java Go
主要格式 CycloneDX、SPDX CycloneDX SPDX
容器镜像支持 优秀 一般 一般
Java 项目支持 良好 优秀 良好
C/C++ 项目支持 良好 较差 一般
扫描速度 快 中等 中等
社区活跃度 高 中 中
适用场景 快速扫描、容器镜像 Java 项目、CycloneDX 交付 SPDX 合规交付

3.6 选型建议:我踩过的坑

说了这么多,到底该怎么选?我给你三个建议:

  1. 如果你主要做容器镜像扫描——选 syft。它在这方面是王者,速度快、准确率高。
  2. 如果你需要交付 CycloneDX 格式——选 cyclonedx-bom。它对 CycloneDX 标准的支持最完整,尤其是 Java 项目。
  3. 如果你需要交付 SPDX 格式——选 spdx-sbom-generator。它生成的 SPDX 文档最规范,合规审计时不容易被挑刺。

我曾经在一个项目里犯过错误:客户要求 SPDX 格式,我图省事用了 syft 的 SPDX 输出。结果客户那边的合规工具解析报错,说缺少某些必填字段。后来换成 spdx-sbom-generator,一次通过。

我的建议:不要只依赖一个工具。在实际项目中,我通常用 syft 做快速扫描和初步分析,然后用 cyclonedx-bom 或 spdx-sbom-generator 做格式转换和合规交付。这样既保证了效率,又确保了格式的规范性。

3.7 实战演练:完整生成一条 SBOM

最后,我们走一遍完整的流程。假设你有一个物联网网关项目,基于 Alpine Linux + Node.js。

# 步骤1:用 syft 扫描容器镜像
syft alpine:latest -o cyclonedx-json > alpine-sbom.json

# 步骤2:用 cyclonedx-bom 验证格式
java -jar cyclonedx-cli.jar -v -i alpine-sbom.json

# 步骤3:用 spdx-sbom-generator 生成 SPDX 版本
./spdx-sbom-generator -p ./my-gateway -o spdx.json

# 步骤4:对比两个输出
diff <(jq . alpine-sbom.json) <(jq . spdx.json) | head -20

你看,整个过程其实不复杂。关键是要理解每个工具的长处和短处,然后根据场景灵活组合。

好了,这一章的内容就到这里。工具链是 SBOM 落地的第一步,选对了工具,后面的事就顺了。