2. 镜像供应链基础:容器镜像的构建、存储、分发流程与常见安全风险
容器镜像作为云原生应用交付的核心载体,其供应链安全直接决定了生产环境的信任边界。本章从镜像的构建、存储、分发三个环节出发,梳理标准流程并剖析各阶段的高危风险,为后续在 Envoy 代理层面实施流量验证奠定基础。
2.1 容器镜像构建流程与关键组件
镜像构建的本质是将应用及其运行时依赖打包为不可变文件系统快照。标准构建流程包含以下阶段:
| 阶段 | 输入 | 输出 | 关键工具/文件 |
|---|---|---|---|
| 1. 基础镜像选择 | 操作系统发行版、运行时库 | 基础层(Base Layer) | Docker Hub、Harbor、Alpine、Distroless |
| 2. 依赖安装 | 包管理器、第三方库 | 中间层(Intermediate Layer) | apt、yum、pip、npm、go mod |
| 3. 应用代码注入 | 源码、编译产物、配置文件 | 应用层(App Layer) | COPY / ADD 指令、多阶段构建 |
| 4. 构建参数与元数据 | 环境变量、启动命令、健康检查 | 镜像配置(Config) | ENV、CMD、ENTRYPOINT、HEALTHCHECK |
| 5. 签名与标签 | 数字签名、版本标签 | 已签名镜像 Manifest | cosign、docker trust、Notary |
实践要点:多阶段构建(Multi-stage Build)可有效减小镜像体积并减少攻击面。建议将构建工具链与运行环境分离,最终镜像仅保留运行时依赖。
2.2 镜像存储与分发机制
镜像仓库(Registry)是供应链的核心枢纽,负责存储 Manifest、Blob 和签名数据。分发流程遵循 OCI Distribution Spec 标准:
- Push 阶段:客户端将镜像层(Blob)分片上传至 Registry,完成后上传 Manifest 文件。
- Pull 阶段:客户端先拉取 Manifest,解析层列表后并行下载各 Blob,最后在本地组装为可运行容器。
- 认证与授权:Registry 通过 Bearer 或 mTLS 验证客户端身份,并基于 RBAC 控制拉取/推送权限。
- 内容寻址:每个 Blob 通过 SHA256 哈希值唯一标识,确保内容完整性。
2.3 常见安全风险清单
根据 CNCF 供应链安全白皮书及实际攻防案例,镜像供应链各阶段的主要风险可归纳如下:
| 阶段 | 风险类型 | 攻击示例 | 影响等级 |
|---|---|---|---|
| 构建 | 基础镜像投毒 | 使用被植入后门的官方镜像 | 严重 |
| 依赖混淆 | 恶意包名与内部包同名,被自动拉取 | 高 | |
| 存储 | 镜像篡改 | 攻击者覆盖已有标签指向恶意镜像 | 严重 |
| 未授权拉取 | 公开仓库暴露敏感内部镜像 | 中 | |
| 分发 | 中间人劫持 | 在 HTTP 代理层替换镜像层数据 | 严重 |
| 缓存投毒 | 在镜像缓存节点注入恶意层 | 高 | |
| 运行时 | 镜像层泄露 | 通过容器逃逸读取其他镜像层数据 | 高 |
| 签名失效 | 未验证签名直接运行镜像 | 严重 |
关键风险提示:在 Envoy 代理场景下,分发阶段的中间人劫持是最容易被忽视的攻击面。如果镜像拉取流量未经过 mTLS 或 Envoy 的流量验证策略,攻击者可以在代理层替换镜像层内容,导致整个集群运行恶意负载。
2.4 信任边界模型
镜像供应链的信任边界应遵循“零信任”原则:
- 不信任任何未签名的镜像:所有镜像在拉取前必须验证 cosign 签名或 Notary 签名。
- 不信任未扫描的镜像:镜像必须通过漏洞扫描(Trivy / Grype)且高危漏洞数为 0 才允许部署。
- 不信任未审计的构建过程:构建日志、SBOM、构建环境哈希必须可追溯。
- 不信任明文传输:镜像仓库与客户端之间的所有通信必须使用 TLS 1.3 或 mTLS。