如何使用Cosign对容器镜像进行签名与验证?

来源:JQuery教程作者:唐僧头衔:草根站长
导读:本期聚焦于唐僧创作的《如何使用Cosign对容器镜像进行签名与验证?》,敬请观看详情。把未签名的镜像直接推到生产集群,等于给攻击者留了替换后门的通道。Cosign作为Sigstore生态里的轻量签名工具,用非对称密钥就能给OCI镜像打上不可伪造的签名。它不依赖中心化证书机构,既支持本地密钥对,也能对接KMS和硬件令牌。验证阶段,集群准入控制器可自动拒绝无签名或签名不符的拉取请求,从供应链源头阻断篡改风险。掌握初始化密钥、签名推送、跨环境验证三步,中小团队也能低成本落地镜像完整性防护。

容器镜像在分发过程中面临被篡改、投毒的风险,Cosign提供了一套开源的签名与验证机制,让开发者和平台方能够确认镜像来源与内容完整性。它通过与OCI仓库的标准交互,将签名作为独立的制品附加在镜像索引上,而不改变镜像本身的层数据。理解这套机制,是构建可信软件供应链的基础环节。

如何使用Cosign对容器镜像进行签名与验证?

Cosign的核心工作原理与密钥模型

Cosign本质上是一个符合Sigstore规范的命令行工具,它利用非对称加密算法对镜像的摘要(digest)进行签名,而不是对庞大的镜像层逐字节加密。每一个容器镜像在注册表中都有唯一的sha256摘要,Cosign使用私钥对该摘要生成数字签名,并将签名推送到同仓库的附属标签(如sha256-xxx.sig)。验证时,只需用公钥核对摘要与签名是否匹配,即可判断镜像自签名后是否被改动。

在密钥管理上,Cosign支持多种模式。最基础的是生成本地ECDSA或RSA密钥对,以PEM文件保存在磁盘;进阶用法可对接云厂商的KMS(密钥管理服务),例如AWS KMS、GCP KMS,私钥永不导出;还可使用硬件令牌或Sigstore的Fulcio证书颁发加Rekor透明日志实现短期证书签名。对于大多数内部平台,本地密钥对加定期轮换已经能满足基本可信需求,而跨组织分发则更适合引入KMS或透明日志。

需要特别区分的是,Cosign签名保护的是镜像的“内容身份”,并不对镜像做加密处理。也就是说,别人依然可以拉取你的镜像层,但无法在不知晓私钥的情况下生成有效签名。当验证策略设为必须存在有效签名时,任何中间人替换层内容都会导致摘要变化,从而验证失败。这种轻量设计让Cosign能无缝接入现有CI流水线和Kubernetes准入控制。

从零开始生成密钥并签名镜像

使用Cosign的第一步是安装二进制并生成密钥对。在Linux或macOS上,可通过官方脚本或包管理器获取cosign命令,随后执行生成命令,工具会提示设置密码以保护私钥文件。公钥可自由分发给验证方,私钥必须严格保密并备份。以下示例展示密钥生成与对本地构建镜像的签名过程:

# 生成ECDSA密钥对,私钥加密保存为cosign.key,公钥为cosign.pub
cosign generate-key-pair

# 登录镜像仓库(以ipipp.com镜像服务为例)
docker login registry.ipipp.com

# 对镜像打标签并推送
docker tag myapp:latest registry.ipipp.com/team/myapp:v1
docker push registry.ipipp.com/team/myapp:v1

# 使用私钥签名,会推送到同仓库的签名附件
cosign sign --key cosign.key registry.ipipp.com/team/myapp:v1

签名完成后,在注册表中会出现一个名为sha256-<digest>.sig的附属制品。此时若其他人拉取该镜像,可用对应公钥执行验证。如果镜像被恶意修改并重推,摘要改变,旧签名即刻失效。在CI环境中,通常把私钥作为Secret注入,签名步骤放在构建与推送之后,保证出厂即带签名。

对于使用KMS的团队,签名命令可改为cosign sign --key awskms:///arn:aws:kms:...形式,这样私钥驻留云端,本地仅持调用权限,降低泄露风险。此外,Cosign也支持在签名时附加证书链或透明日志条目,便于后续审计。无论哪种方式,验证端只需拥有对应公钥或证书根,就能独立确认,无需实时访问签名者系统。

在Kubernetes中落地自动验证策略

仅有签名动作还不够,必须在消费侧强制验证才能真正起到防护作用。在Kubernetes集群中,常用Connaisseur或Kyverno等策略引擎来拦截未签名镜像。以Kyverno为例,通过编写ClusterPolicy,要求所有来自特定仓库的镜像必须经过Cosign验证且密钥匹配,否则APIServer拒绝创建Pod。这样开发人员在本地即便误用未签名镜像,也无法进入集群。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: check-cosign-signature
spec:
  validationFailureAction: enforce
  rules:
  - name: verify-image
    match:
      resources:
        kinds:
        - Pod
    verifyImages:
    - image: "registry.ipipp.com/team/*"
      key: |-
        -----BEGIN PUBLIC KEY-----
        MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEexamplepubkeydata
        -----END PUBLIC KEY-----

上述配置中,verifyImages字段指定了镜像匹配规则和内联公钥。当Pod引用不符合签名的镜像时,准入控制器返回拒绝信息,部署直接失败。相比人工审查,这种自动化门禁大幅降低运维负担。在离线环境中,可将公钥预置到策略里;在多租户平台,则可为不同团队配置不同公钥,实现分权管理。

除了集群内验证,CI/CD的出口处也应加入验证步骤,防止将错误镜像流入下个阶段。例如在GitLab Runner中,部署前先运行cosign verify --key cosign.pub 镜像地址,命令非零退出即阻断流水线。结合镜像扫描工具,可形成“漏洞扫描+签名验证”双保险。长远来看,把Cosign纳入企业镜像仓库的强制策略,是供应链安全成熟度的关键标志。

常见问题与签名轮换实践

实际使用中,团队常遇到私钥泄露或人员离职带来的密钥轮换难题。Cosign本身不提供中心化吊销列表,因此推荐做法是:定期生成新密钥对,用新私钥重新签名所有活跃镜像,并将新公钥同步到验证策略中,旧公钥保留一段时间以兼容存量签名。过渡期结束后移除旧公钥,完成软轮换。若怀疑私钥泄露,则立即用新密钥重签并缩短过渡期。

另一个误区是认为签名一次永久有效。实际上,当基础镜像升级或补丁重打后,摘要变化,原签名失效,必须重新签名。因此在Dockerfile变更触发构建时,流水线要自动包含签名环节,而不是手动补充。对于多架构镜像(manifest list),Cosign会分别对各个架构子镜像及整体索引签名,验证时也会逐级检查,确保全平台一致。

最后要注意注册表兼容性。主流如Harbor、Docker Hub、ECR均支持Cosign的附属制品存储,但部分老旧私有仓库可能不支持OCIArtifact类型,导致签名无法推送。此时可改用--attachment-tag-prefix参数调整签名标签格式,或升级仓库版本。理清这些边界情况,才能让Cosign在复杂环境中稳定运行。

Cosign镜像签名容器安全修改时间:2026-08-17 06:38:33

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