如何验证Docker镜像签名以确保镜像来源可信?

来源:Apache教程作者:小鱼头衔:草根站长
导读:本期聚焦于小鱼创作的《如何验证Docker镜像签名以确保镜像来源可信?》,敬请观看详情。攻击者替换镜像仓库中的镜像会导致严重安全事件,验证镜像签名能确认镜像来源未被篡改。Docker 镜像签名依赖内容信任机制,通过私钥对镜像清单摘要进行签名,客户端拉取时使用公钥验证摘要一致性。Docker Content Trust 集成 Notary 项目实现这一过程,而 Cosign 等新工具支持更灵活的 OCI 签名规范。验证流程通常包括启用内容信任、获取签名密钥、推送或拉取时进行校验,以及在 CI/CD 中强制验证。本文梳理签名生成与验证的底层逻辑,对比 DCT 与 Cosign 的差异,给出命令行示例和自动化脚本,帮助读者在部署前阻止未签名或签名无效的镜像。

软件供应链攻击日益频繁,镜像仓库一旦被攻破,攻击者可以替换标签对应的镜像内容。如果部署流程只依据镜像标签拉取,无法感知内容是否被篡改。镜像签名验证正是为了解决这一问题:发布者使用私钥对镜像摘要进行签名,使用者在拉取后通过公钥确认摘要与签名匹配,从而判断镜像是否来自可信来源。

如何验证Docker镜像签名以确保镜像来源可信?

一、镜像签名验证的核心原理

Docker 镜像在仓库中以清单文件描述层和配置信息。每个清单文件都有一个由内容计算得出的摘要,例如 sha256:abc123...。签名并不是对镜像所有层进行加密,而是对清单摘要进行私钥签名。验证时,客户端从仓库获取镜像清单、计算摘要,并使用发布者公钥验证附带的签名数据。如果摘要与签名不匹配,或者签名不存在,说明镜像可能被篡改或未经授权发布。

内容信任机制依赖非对称加密。私钥由发布者持有,绝不能泄露;公钥可以公开分发给使用者。Docker Content Trust 使用 Notary 项目管理信任元数据,Notary 在一个独立的服务中存储签名、密钥角色和过期时间等信息。客户端在启用内容信任后,不仅验证目标镜像的摘要签名,还会递归验证其依赖的基础镜像的信任关系,形成信任链。

这种设计可以防止中间人攻击和仓库内容替换,但并不能防止发布者自身发布恶意镜像。因此签名验证需要结合密钥管理和发布流程审计,确保私钥只被可信的 CI 系统或发布者使用。

二、使用 Docker Content Trust 验证签名

Docker Content Trust 是 Docker CLI 内置的功能,默认关闭。启用方式为设置环境变量 DOCKER_CONTENT_TRUST=1。在该模式下,docker pulldocker rundocker build 等命令都会执行签名验证。如果镜像没有签名或签名无效,命令会直接失败。

首次在客户端使用 DCT 拉取镜像时,Docker 会初始化本地信任目录,通常位于 ~/.docker/trust。如果发布者使用自签名密钥,客户端需要将发布者的公钥导入信任列表。对于 Docker Hub 上的官方镜像,Docker 会使用 Docker 的根密钥进行信任链验证。

下面示例展示启用 DCT 后拉取一个已签名镜像的过程。命令在终端中执行,输出为验证成功信息。

export DOCKER_CONTENT_TRUST=1
docker pull alpine:3.19

如果镜像没有签名或签名已过期,会看到类似下面的错误:

Error: remote trust data does not exist for docker.io/library/alpine: not found

推送镜像时,DCT 要求发布者输入密钥密码,并在推送成功后自动将签名元数据上传到 Notary 服务。发布者需要先创建签名密钥对,通常通过 docker trust 命令管理。DCT 的不足在于它依赖 Notary 服务端,自建 Notary 的部署和维护成本较高,而且对某些私有仓库的支持有限。

三、使用 Cosign 验证镜像签名

Cosign 是 Sigstore 社区推出的镜像签名工具,支持 OCI 注册表原生的签名存储方式。与 DCT 不同,Cosign 将签名作为单独的 OCI 工件推送到镜像所在仓库,不依赖额外的 Notary 服务。签名者可以使用传统密钥对,也可以使用无密钥模式,通过 OIDC 身份提供商完成短期签名。

使用 Cosign 前需要安装二进制文件。生成密钥对并签名镜像的命令如下:

cosign generate-key-pair
cosign sign --key cosign.key myregistry.com/myapp:v1.0

上面的命令会在当前目录生成 cosign.keycosign.pub。签名完成后,验证方只需要使用公钥验证:

cosign verify --key cosign.pub myregistry.com/myapp:v1.0

验证成功会输出镜像摘要和签名者信息。Cosign 还支持通过 verify-blob 验证任意制品,使用 verify-attestation 验证软件物料清单。它的优势在于不依赖中心化信任服务,兼容几乎所有支持 OCI 1.1 的注册表,因此在云原生生态中逐渐成为主流。

四、在 CI/CD 中强制执行验证

手动执行验证命令只能作为临时检查,真正有效的做法是把签名验证纳入持续集成和部署流水线。发布阶段由 CI 系统持有私钥完成签名,部署阶段在拉取镜像前用公钥验证。这样可以确保只有通过验证的镜像才能进入生产环境。

下面是一个在部署流水线中集成 Cosign 验证的 Bash 脚本示例:

#!/bin/bash
IMAGE="$1"
PUBLIC_KEY="cosign.pub"

cosign verify --key "$PUBLIC_KEY" "$IMAGE"
if [ $? -ne 0 ]; then
  echo "镜像签名验证失败,禁止部署"
  exit 1
fi

docker pull "$IMAGE"

对于 Kubernetes 环境,可以通过准入控制器在创建 Pod 时校验镜像签名。例如使用 Sigstore Policy Controller 或 Open Policy Agent 编写策略,拒绝未签名或签名不匹配的镜像。这种架构下,即使开发者绕过了 CI 流程直接提交部署配置,集群也会阻止不安全的镜像运行。

需要注意的是,镜像标签可能被覆盖。如果使用可变标签如 latest,即使验证通过,后续同一标签可能指向不同镜像。因此建议在部署时使用镜像摘要而不是标签,或将标签设置为不可变。

五、常见问题与安全建议

镜像签名验证经常遇到两类问题:一是签名密钥管理不当导致私钥泄露,攻击者可以伪造签名;二是验证流程只覆盖了部分镜像入口,例如只验证了应用镜像却忽略基础镜像。私钥应存储在专用密钥管理系统中,例如云 KMS 或硬件安全模块,并定期轮换。

另一个常见误区是认为签名验证可以替代漏洞扫描。实际上签名只证明镜像来自可信发布者且未被篡改,并不保证镜像内部没有已知漏洞。签名验证应作为供应链安全的第一道关,后续仍需进行漏洞扫描、配置审计和运行时监控。

在网络隔离环境中,无法访问公网信任服务时,需要提前将公钥和签名元数据同步到内网。Cosign 可以将签名工件复制到内网仓库,而 DCT 则需要部署内网 Notary 服务。选择方案时应结合团队规模、仓库类型和运维能力。

下表对比 DCT 与 Cosign 在几个维度上的差异:

维度Docker Content TrustCosign
签名存储Notary 服务OCI 工件
依赖组件Notary 服务器、数据库兼容 OCI 的注册表
密钥模式私钥+角色委派传统密钥或无密钥
验证方式Docker CLI 内置cosign 命令或 SDK
适用场景Docker 生态早期用户云原生、Kubernetes、供应链安全

综合来看,新项目优先选择 Cosign 会更灵活,而仍在大量使用 Docker CLI 和 Docker Hub 官方镜像的团队可以继续使用 DCT,但需要评估 Notary 服务的维护成本。

Docker镜像签名签名验证镜像供应链安全修改时间:2026-09-07 18:31:47

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260907/52376.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。