用 AWS Signer 实现代码签名 - Lambda 函数与容器镜像的可信性保证

对 Lambda 函数和容器镜像应用代码签名,在 CI/CD 流水线中强制签名验证。还介绍通过签名撤销应对入侵。

代码签名的必要性

代码签名是以密码学方式确认部署的代码来自可信发行者且未被篡改的机制。为应对供应链攻击侵入构建流水线的情况,可通过签名验证拒绝部署没有可信签名的代码。如 2020 年 SolarWinds 事件所示,存在构建环境成为入侵对象的案例,代码签名是其对策之一。AWS Signer 是可用于 Lambda 函数部署包和容器镜像的签名和验证的完全托管式代码签名服务。

Lambda 的代码签名

Lambda 的代码签名配置 (Code Signing Configuration) 中定义信任的签名配置文件 ARN (最多 20 个) 和签名验证失败时的操作 (Warn 或 Enforce)。Enforce 模式下,未签名的函数或用不受信任的签名配置文件签名的函数的部署会被阻止。Warn 模式记录验证失败但允许部署,适用于分阶段导入。CI/CD 流水线中,在 CodeBuild 构建的 ZIP 包通过 Signer 的 StartSigningJob API 签名,将签名后包的 S3 URL 传给 Lambda 的 UpdateFunctionCode。签名作业异步执行,完成后可向 EventBridge 发送通知。

容器镜像签名与 CI/CD 集成

AWS Signer 支持对 ECR 容器镜像的 Notation 格式签名。CI/CD 流水线的构建阶段构建镜像,用 Signer 签名后推送到 ECR。EKS 的准入控制器强制签名验证,拒绝未签名镜像的部署。签名配置文件定义签名使用的加密算法 (ECDSA P-256 或 RSA) 和有效期,配置文件过期后无法生成新签名但已有签名仍然有效。签名的撤销 (Revocation) 可使被侵入的签名配置文件签名的代码失效。撤销后进行签名验证会失败,相关代码的部署会被阻止。

签名配置文件的运维设计

签名配置文件的设计应匹配组织的部署体制。为每个团队创建单独的配置文件,可在某个配置文件被侵入时将影响范围限制在该团队的制品内。配置文件有效期过短会增加轮换运维负担,过长则在侵入时延长风险窗口,应根据组织的风险承受度设置。若通过 IAM 策略将 signer:StartSigningJob 的执行限制在特定角色 (CI/CD 流水线的构建角色),使开发者个人无法签名,则只有这些构建角色能够签名。在 CloudTrail 中记录签名操作,留下谁在何时签了什么的审计跟踪。

与其他签名方式的比较

除 AWS Signer 外,代码签名还有其他选择。Cosign (Sigstore 项目) 是开源容器签名工具,支持无密钥签名 (短期证书),但需要自行管理签名基础设施和密钥。AWS Signer 提供托管的密钥生成、存储和轮换,通过 KMS 集成确保密钥由硬件安全模块 (HSM) 保护。GPG 签名用于 git commit 签名,Lambda 或 ECR 的部署时验证则使用其他机制。AWS Signer 可与 Lambda Code Signing Configuration 和 EKS 准入控制器结合,在不增加额外基础设施的情况下强制执行部署时的验证。另一方面,在采用统一签名策略的多云环境中,可以采用使用 Notation 或 Cosign 的配置。

Signer 的费用

将 AWS Signer 与 AWS Lambda、Amazon ECR、Amazon EKS 等服务配合使用时,不收取额外费用。签名验证免费。签名配置文件的管理不产生额外费用。

总结

AWS Signer 是为 Lambda 函数和容器镜像提供代码签名的完全托管服务,用于确认部署代码的完整性。在 CI/CD 流水线的构建阶段签名,通过 Lambda 的代码签名配置或 EKS 的准入控制器强制签名验证,为供应链攻击添加了防御层。采用按团队分离签名配置文件并通过 IAM 限制签名权限的设计,可在侵入时缩小影响范围。

参考资料(AWS 官方)

本页的第一手信息来源是 AWS 官方网站及官方文档。最新的规格与价格请以下列官方页面为准。

如本页内容与官方文档不一致,请以官方文档为准。

分享