一句话总结
供应链安全确保"部署的东西确实是构建出来的东西", 没有被篡改, 没有被注入恶意代码, 来源可追溯.
通过 SBOM 记录成分, Cosign 签名防篡改, SLSA 框架量化供应链安全等级.
供应链攻击案例
2020-2024 年发生的真实供应链攻击:
| 事件 | 攻击方式 | 影响 |
|---|---|---|
| SolarWinds(2020) | 攻击者入侵 CI 系统, 在构建过程中注入后门 | 18,000+ 企业和政府机构 |
| Codecov(2021) | 篡改 CI 脚本, 窃取环境变量中的密钥 | 数百企业的 CI/CD 密钥泄露 |
| ua-parser-js(2021) | npm 包被注入加密货币挖矿代码 | 每周 800 万下载量的包被投毒 |
| Log4Shell(2021) | Log4j 库本身的漏洞 | 数十亿 Java 应用受影响 |
共同模式: 攻击者不直接攻击目标, 而是攻击目标的依赖, 工具链或构建系统.
传统安全 = 检查送到门口的包裹.
供应链安全 = 追溯包裹从工厂到快递到家门口的每一个环节, 是否被拆过, 是否被替换, 是否来自合法工厂.
SBOM(软件物料清单)
SBOM(Software Bill of Materials)列出软件中包含的所有组件及其版本, 类似食品的配料表.
为什么需要 SBOM
- 漏洞响应: Log4Shell 公布后, 有 SBOM 的团队 10 分钟内就知道哪些服务受影响; 没有的要花几天排查
- 合规要求: 美国行政令 14028 要求向联邦政府供应的软件必须提供 SBOM
- 许可证管理: 确保没有使用与商业许可冲突的 GPL 组件
生成 SBOM
|
镜像签名(Cosign / Sigstore)
签名证明"这个镜像确实是我(或我的 CI)构建的", 防止中间人篡改, 防止部署来源不明的镜像.
Sigstore 生态
| 组件 | 职责 |
|---|---|
| Cosign | 签名和验证容器镜像/SBOM |
| Fulcio | 短期证书颁发(无需管理长期密钥) |
| Rekor | 透明日志(签名不可否认, 可公开审计) |
Cosign 使用
|
Keyless 签名是最佳实践
传统签名需要管理私钥, 私钥本身又成了需要保护的 Secret. Keyless 模式通过 OIDC(GitHub Actions / Google Workload Identity)认证身份, Fulcio 签发短期证书(10 分钟有效), 签名记录到 Rekor 公开透明日志.
不需要管理任何长期密钥.
集群内验证镜像签名
配合准入控制器(Kyverno/Connaisseur)拒绝未签名或签名无效的镜像:
|
SLSA 框架
SLSA(Supply-chain Levels for Software Artifacts, 读作"salsa")是 Google 提出的供应链安全成熟度框架:
| 等级 | 要求 | 防御的攻击 |
|---|---|---|
| SLSA 1 | 构建过程有文档记录(provenance) | 知道构建来源 |
| SLSA 2 | 构建使用版本控制 + 可信构建平台 | 防止开发者本机被入侵后注入恶意代码 |
| SLSA 3 | 构建平台不可被单人篡改 + 来源证明可验证 | 防止 CI 被入侵(SolarWinds 级别) |
| SLSA 4 | 双人审查 + 密封构建 + 完整依赖声明 | 防止内部恶意行为 |
来源证明(Provenance)
SLSA 的核心产出物, 记录"谁, 在哪里, 用什么源码, 什么时间构建了这个制品":
|
|
供应链安全最佳实践
- 固定依赖版本: go.sum / package-lock.json / poetry.lock, 确保构建可复现
- 定期更新依赖: Dependabot / Renovate 自动创建升级 PR
- 私有镜像仓库: 不从公共 Docker Hub 直接拉取生产镜像
- 签名所有生产镜像: CI 构建后 Cosign 签名 + 集群内验证
- 生成 SBOM: 与镜像一起存储, 漏洞响应时能快速定位
- 最小化构建环境: CI runner 最小权限, 构建完成后销毁环境
快速回顾
- 供应链攻击目标是依赖, 工具链和构建系统, 而非直接攻击目标
- SBOM: 软件配料表, 漏洞响应时快速定位受影响组件
- Cosign: 镜像签名防篡改, Keyless 模式无需管理密钥
- SLSA: 供应链安全成熟度框架(1-4 级), 来源证明(Provenance)是核心产出
- 准入验证: Kyverno 拒绝未签名镜像, 确保只有可信来源的镜像能部署
动手练习
- 生成 SBOM: 用 Syft 为一个 Docker 镜像生成 SBOM(SPDX 格式), 检查其中包含的依赖列表
- Cosign 签名验证: 用 Cosign 为一个测试镜像签名(先用密钥对模式), 然后验证签名
- 准入策略拦截: 配置 Kyverno 策略要求镜像必须有 Cosign 签名才能部署, 尝试部署未签名镜像验证被拒绝
- SLSA provenance: 查看 GitHub Actions 的 SLSA generator, 理解 provenance 文件的结构