01 · 镜像生命周期风险面
容器供应链的风险沿"源代码→构建→分发→运行"链路逐级放大:构建环境的污染会进入每一个下游镜像;公开仓库中的恶意基础镜像可污染所有派生镜像;集群若不做准入校验,任何持有镜像推送权限的主体都可直接部署任意代码。NIST SP 800-190(2017)早已指出:镜像与注册表是容器安全六大关切中的两大核心。
| 阶段 | 风险 | 控制点 |
|---|---|---|
| 源代码/依赖 | 开源组件漏洞(如Log4Shell)、恶意依赖包、私有库投毒 | SCA扫描、锁文件(lockfile)与哈希固定、私有代理仓库 |
| 构建 | Dockerfile危险指令、构建机凭证泄露、构建工具被篡改 | 可信基础镜像、最小化构建上下文、隔离构建机、构建可追溯 |
| 分发 | 公网仓库中间人篡改、仓库账号泄露、标签被覆盖(标签可变) | TLS拉取、内容寻址digest固定、签名验证 |
| 存储 | 公开仓库的恶意镜像、过期镜像漏洞累积 | 私有仓库(Harbor)、镜像扫描、留存与清理策略 |
| 部署/运行 | 未校验的镜像直接运行、latest标签漂移、准入缺失 | 准入策略验签、PSS限制、运行时检测 |
02 · 镜像构建安全
2.1 可信基础镜像
- 基础镜像只取自官方或经内部评审的仓库,固定到内容寻址digest(sha256:...)而非可变tag——tag可被重新指向,digest不可篡改。
- 优先选用极简基础镜像(distroless、alpine、scratch)减小攻击面:没有shell与包管理器的镜像显著增加攻击者驻留难度。
- 维护组织级"黄金镜像"流水线:基础镜像由安全团队统一构建、扫描、签名,业务团队禁止直接使用公网基础镜像。
2.2 Dockerfile安全基线
| 项 | 基线要求 | 风险 |
|---|---|---|
| USER指令 | 显式指定非root用户运行 | 默认root运行的镜像逃逸后权限面最大(第4页) |
| .dockerignore | 排除 .git、.env、凭证文件、密钥目录 | 构建上下文上传至构建守护进程,凭证极易混入镜像层 |
| 多阶段构建 | 编译工具链与运行时镜像分离 | 减小最终镜像体积与工具链泄露面 |
| 包管理清理 | 同一层内安装后立即清理缓存(apt/yum缓存) | 减小镜像体积与残留包数据库信息 |
| ADD vs COPY | 优先COPY(不自动解压缩/远程拉取) | ADD的远程URL拉取能力引入不可控外部内容 |
| 避免curl | sh | 外部脚本先下载校验后执行 | 构建期供应链投毒入口 |
# 反例:危险的基础镜像引用 FROM ubuntu:latest # 可变tag + 无digest # 正例:可信基座示例(截断示意) FROM gcr.io/distroless/static-debian12:nonroot@sha256:<DIGEST> COPY --from=builder /app/server /server USER nonroot:nonroot ENTRYPOINT ["/server"]
03 · 镜像扫描与漏洞治理
3.1 扫描工具与环节
| 环节 | 工具(示例) | 说明 |
|---|---|---|
| 开发侧 | Trivy、Grype、Docker Scout | 本地与IDE集成,前置拦截高危依赖 |
| CI门禁 | Trivy(--exit-code / severity阈值) | 流水线中强制:检出高危(如CRITICAL)即失败,禁止推送 |
| 仓库侧 | Harbor内置Trivy扫描器 | 镜像入库即扫描,策略阻止漏洞镜像被拉取 |
| 准入侧 | Kyverno/Gatekeeper验签+扫描报告校验 | 部署时校验"签名+扫描通过"双条件 |
| 运行侧 | 持续监测(新CVE回溯扫描存量镜像) | 应对"今天披露的漏洞存在于三月前构建的镜像" |
3.2 漏洞治理原则
- 基线分级:内部工具镜像可放宽,互联网暴露镜像从严;以CISA KEV(已知被利用漏洞目录)为优先修复输入(与子课题01联动)。
- 扫描的边界:静态扫描无法发现运行时配置错误、硬编码密钥、恶意行为——扫描是必要非充分条件,须与签名、准入、运行时检测(第4页)组合成链。
- 修复SLA:按严重度与暴露面定级:互联网面CRITICAL漏洞24—72小时,内部中危随下次发布;SLA未达成自动升级。
04 · 镜像签名与准入验证
扫描回答"镜像里有什么漏洞",签名回答"这个镜像是不是我们构建的那个"。两者缺一不可——SolarWinds事件证明:即使来源看起来可信,构建链也可能被污染,因此必须对每个部署到集群的镜像验证签名来源。
4.1 sigstore/cosign无密钥签名体系
- cosign是sigstore生态的镜像签名工具:支持keyless模式(基于Fulcio短期证书与Rekor透明日志,无需长期保管私钥,签名记录公开可审计),也支持传统的硬件密钥/KMS私钥。
- CI流水线完成构建后自动执行
cosign sign,签名随镜像推送到同一仓库;集群侧通过验签策略拒绝未签名镜像。 - Rekor透明日志使签名事件可公开审计,第三方可监控"是否出现意外的签名活动"。
4.2 集群准入验签落地
| 方案 | 做法 | 特点 |
|---|---|---|
| Kyverno verifyImages | 集群策略声明校验镜像签名与密钥 | 原生支持cosign验签,可按namespace/镜像仓库豁免 |
| sigstore policy-controller | 官方验签准入控制器 | sigstore官方方案,支持CIP策略声明 |
| OPA Gatekeeper + 验签库 | Rego策略调用验签逻辑 | 灵活但需自行维护验签集成 |
# Kyverno验签策略(截断示意)
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: verify-cosign-signature
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- imageReferences:
- "registry.internal.example.com/*"
attestors:
- entries:
- keys:
publicKeys: |
-----BEGIN PUBLIC KEY-----
...(组织CI签名公钥)
-----END PUBLIC KEY-----落地要点:①先Audit模式统计"未签名镜像存量",分期强制Enforce;②豁免清单(系统命名空间镜像)需安全评审并登记;③验签公钥/策略的变更走GitOps双人评审——验签体系自身的配置漂移即供应链防线失效;④结合digest引用(image@sha256:...)阻断tag覆盖攻击。
05 · SBOM在容器场景的落地
- 生成:构建流水线中用syft/Trivy等工具对镜像生成SBOM(SPDX或CycloneDX格式,SPDX已标准化为ISO/IEC 5962:2021),随镜像元数据归档;格式细节与子课题03总纲一致,本页聚焦容器侧集成点。
- 消费:①新CVE披露时按SBOM秒级定位受影响镜像与在跑Pod清单——Log4Shell应急中,具备SBOM的组织在小时级完成排查,无SBOM者以周计;②与许可证合规(GPL污染检测)共用同一数据。
- 归档:SBOM与镜像digest绑定存储,退役镜像的SBOM保留期与审计要求对齐;集群侧可经准入策略校验"无SBOM镜像不得部署"(渐进要求)。
- 局限认知:SBOM只声明"包含什么",不声明"是否安全"——其价值依赖与漏洞库(OSV、GitHub Advisory)的持续关联。
06 · CI/CD流水线安全
CI/CD系统持有代码仓库、镜像仓库与集群的写凭证,是供应链中"凭证密度"最高的环节,也历来是攻击者优先目标。
| 风险 | 真实案例 | 防护 |
|---|---|---|
| 构建脚本投毒 | Codecov事件(2021):Bash Uploader脚本被篡改,CI环境变量(含凭证)被外传,影响数千家使用方 | 锁定外部脚本版本与哈希;CI变量最小化;分叉流水线(PR不可触密) |
| 长期凭证泄露 | Docker Hub 2019事件:约19万账户哈希密码与部分CI令牌泄露(见专题首页指标卡) | 短期令牌/OIDC联邦认证;凭证按环境隔离;泄露即自动轮换 |
| 构建机逃逸 | 恶意PR在CI执行任意代码(自托管runner风险) | PR流水线隔离于无凭证沙箱;容器化/ephemeral runner;禁挂载Docker socket |
| 集群部署凭证 | kubeconfig落盘CI服务器被横向利用 | 使用第3页TokenRequest短期令牌;部署经GitOps(集群单向拉取,CI不持集群凭证) |
GitOps收敛建议:让CI只负责构建、测试、推送镜像与更新Git仓库中的清单;集群经Argo CD/Flux从Git单向拉取并同步——CI系统不再持有集群任何凭证,爆炸半径收窄至"能否向Git推送",而Git侧有分支保护与双人评审兜底。
07 · 供应链事件档案
| 时间 | 事件 | 关键事实与容器供应链启示 |
|---|---|---|
| 2019.05 | Docker Hub数据库泄露 | 约19万账户的用户名、哈希密码及部分GitHub/Bitbucket访问令牌泄露,直接威胁自动化构建流水线(见专题首页核心指标)。启示:仓库与CI凭证必须短期化与自动轮换。 |
| 2020.12 | SolarWinds SUNBURST | 构建系统投毒波及约1.8万客户。启示:仅"来源可信"不足为凭,必须验签+构建可追溯(SLSA分级),运行时仍需异常检测兜底。 |
| 2021.04 | Codecov供应链事件 | Bash Uploader脚本被篡改外传CI凭证。启示:CI执行的外部脚本必须锁版本、验哈希,CI变量默认最小化。 |
| 2021.12 | Log4Shell(CVE-2021-44228) | CVSS 10.0,Java生态基础组件漏洞,波及海量容器镜像。启示:SBOM+在跑镜像清单是漏洞应急的基础设施;扫描门槛需区分"构建时"与"新披露回溯"。 |
| 2020—至今 | 公开仓库恶意镜像活动 | 各类安全厂商与云厂商持续披露公开镜像仓库中的挖矿镜像、后门镜像及仿冒流行镜像命名(typosquatting)活动。启示:生产镜像一律来自私有仓库且经扫描+验签,禁止Pod直接拉取公网镜像(准入策略强制registry白名单)。 |
本节参考来源(第6页)
NIST SP 800-190《Application Container Security Guide》(2017):镜像、注册表安全章节。
sigstore/cosign官方文档:docs.sigstore.dev;Kyverno验签策略文档:kyverno.io(verifyImages);policy-controller:docs.sigstore.dev(policy-controller)。
Trivy文档:trivy.dev;Grype(Anchore):anchore.com/opensource;Harbor文档(含镜像扫描与策略):goharbor.io/docs;syft(SBOM生成):anchore.com/syft。
SLSA框架:slsa.dev;SPDX规范(ISO/IEC 5962:2021):spdx.dev;CycloneDX:cyclonedx.org;OSV漏洞库:osv.dev。
事件来源:Codecov官方事件通报(2021);美国EO 14028(2021)与NIST SSDF(SP 800-218);Docker官方2019年安全通报;CISA KEV目录:cisa.gov(KEV)。