Docker Content Trust:签名与镜像完整性
Docker Content Trust 实战指南:签名与镜像完整性
什么是内容信任
在现代容器化交付流程中,镜像来源的可信度与内容完整性成为安全基石。Docker Content Trust(DCT)正是为此设计的机制,它基于Notary项目实现数字签名与验证,确保你拉取或运行的镜像自签名后未被篡改,且确实来自可信发布者。
启用内容信任后,Docker 客户端只允许操作已签名的镜像,任何未经签名或签名失效的镜像会直接被拒绝。这一机制覆盖 docker pull、docker run、docker build 等常用命令,从根本上阻断供应链攻击。
核心组件:Notary 架构
Notary 项目由 Docker 孵化,现已移交 CNCF。它实现了 The Update Framework (TUF) 规范,通过分层信任与角色分离来保护软件更新系统。
TUF 信任角色
- 根密钥(Root Key):离线保存,用于签名信任元数据和管理其他角色密钥。
- 目标密钥(Targets Key):控制仓库中的实际文件(如镜像清单)签名,通常也离线,可委派给更细粒度的角色。
- 快照密钥(Snapshot Key):在线签名,确保仓库元数据一致性与新鲜性,防止回滚攻击。
- 时间戳密钥(Timestamp Key):短周期在线签名,保证快照的时效性。
在 Docker 生态中,每个镜像仓库对应一个 Notary 仓库,存放该镜像各标签的签名元数据。
实战前准备
环境要求
- Docker Engine 1.10+
- Docker Compose(如需要搭建本地 Notary 服务)
- 能访问 Docker Hub 或私有 Registry 且其支持 Notary(如 Harbor、Docker Trusted Registry 等)
初始化信任环境
首次使用前,需通过 docker trust 命令组生成密钥并初始化仓库。
# 查看信任管理子命令
docker trust --help
建议先配置环境变量,确保后续操作不经询问:
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER=https://notary.docker.io # 默认即可
设置 DOCKER_CONTENT_TRUST=1 会全局启用内容信任,后续所有操作均会强制验证签名。
步骤一:生成签名密钥
假设你已拥有 Docker Hub 账号 myorg,要对仓库 myapp 签名。首先为仓库生成委派密钥对:
docker trust key generate myreleaser
此命令会生成一个加密的私钥(myreleaser.key)和对应公钥,私钥密码需牢记。生成后,系统会输出公钥内容,稍后用于添加签名者。
你也可以直接让 Docker 自动使用仓库现有密钥,但最佳实践是使用独立委派密钥,便于团队管理和吊销。
步骤二:添加签名者到仓库
利用 docker trust signer add 将公钥注册为仓库的签名者。
docker trust signer add --key myreleaser.pub myreleaser myorg/myapp
myreleaser 是签名者别名,myorg/myapp 是目标镜像仓库。此后该签名者即可对该仓库的标签进行签名。
步骤三:签名并推送镜像
构建镜像并打标签
docker build -t myorg/myapp:1.0 .
签名推送
docker trust sign myorg/myapp:1.0
如果之前已设置 DOCKER_CONTENT_TRUST=1,直接 docker push 就会触发签名流程,但明确使用 docker trust sign 更直观。系统会提示输入签名者私钥密码,成功后签名元数据自动推送至 Notary 服务。
查看仓库签名状态
docker trust inspect --pretty myorg/myapp:1.0
输出示例:
Signatures for myorg/myapp:1.0
SIGNED TAG DIGEST SIGNERS
1.0 sha256:abc123... myreleaser
同时会显示根密钥、目标密钥等关键 ID,便于审计。
步骤四:消费端验证镜像
当用户拉取镜像时,若已启用内容信任(DOCKER_CONTENT_TRUST=1),Docker 会自动验证签名。
export DOCKER_CONTENT_TRUST=1
docker pull myorg/myapp:1.0
如果签名有效且信任链完整,pull 成功;否则会报错:
Error: remote trust data does not exist for myorg/myapp: 1.0: ...
这表示该标签未签名或签名不受信任,防御中间人篡改。
未设置环境变量时强制验证
即使全局未开启,也可以针对单次操作强制验证:
docker pull --disable-content-trust=false myorg/myapp:1.0
密钥管理与安全实践
根密钥与目标密钥备份
- 根密钥一般在生成时会提示备份。可通过
docker trust key load恢复。 - 所有脱机密钥务必离线加密存储,避免泄露。
密钥轮换
当怀疑私钥泄露时,应及时吊销旧签名者并添加新签名者。
吊销签名者:
docker trust signer remove myreleaser myorg/myapp
之后推送镜像时旧签名不再生效,需由新签名者重新签名。
使用硬件安全模块
Notary 支持基于 PKCS#11 的 HSM,可通过配置文件指定,适合企业级安全需求。
常见问题与排错
Q:签名推送时提示“no valid signing keys”
A:说明该仓库未添加有效签名者,先用 docker trust signer add 注册。
Q:拉取时提示“certificate signed by unknown authority”
A:如果使用私有 Notary 服务,需将信赖的 CA 证书添加到 Docker 信任存储(通常位于 /etc/docker/certs.d/)。
Q:离线环境如何使用 DCT?
A:可以搭建本地 Notary 服务,并配置 DOCKER_CONTENT_TRUST_SERVER 指向内部地址。需注意证书信任链的配置。
总结
Docker Content Trust 是镜像供应链安全的最后一道防线。通过简单的命令和合理的密钥管理,你可以:
- 确保任何拉取的镜像都由组织内授权签名者发布
- 防止标签被篡改或回滚攻击
- 构建从 CI/CD 到产线全链路信任
无论是个人开发者保护开源镜像,还是企业构建私有 Registry 安全策略,内容信任都应当成为标准配置。立即为你的关键镜像启用签名,将中间人风险和恶意注入隔绝在运行环境之外。