镜像签名与内容信任
什么是镜像签名
镜像签名(Image Signing)是通过密码学手段验证 Docker 镜像的发布者和内容完整性的机制。它确认了:
1. 谁发布了这个镜像(身份认证)
2. 镜像内容未被篡改(完整性验证)
Docker Content Trust(DCT)
Docker Content Trust 是 Docker 内置的镜像签名和验证机制,基于 The Update Framework(TUF)。
启用内容信任
# 启用内容信任
export DOCKER_CONTENT_TRUST=1
# 或永久启用
echo 'export DOCKER_CONTENT_TRUST=1' >> ~/.bashrc
签名流程
# 1. 生成签名密钥(首次使用)
docker trust key generate mykey
# 生成 root 密钥和仓库密钥
# 2. 签名并推送镜像
export DOCKER_CONTENT_TRUST=1
docker build -t myrepo/myapp:1.0 .
docker push myrepo/myapp:1.0
# 推送过程会自动签名
验证签名
# 启用内容信任后拉取会自动验证
export DOCKER_CONTENT_TRUST=1
docker pull myrepo/myapp:1.0
# 如果签名无效或未签名,拉取失败
# 手动查看签名信息
docker trust inspect --pretty myrepo/myapp:1.0
密钥管理
# 查看密钥列表
docker trust key list
# 添加签名者
docker trust signer add --key mykey.pub alice myrepo/myapp
# 撤销签名者
docker trust signer remove alice myrepo/myapp
# 恢复密钥
docker trust key load mykey.pem --name mykey
Notary
Notary 是 Docker Content Trust 的底层实现,也可以独立使用:
# 启动 Notary 服务
docker run -d -p 4443:4443 \
-v $(pwd)/config:/etc/notary \
notary-server
# 使用 Notary CLI
notary list myrepo/myapp
# 添加签名
notary add myrepo/myapp 1.0 \
--sha256 abc123... \
--publish
Cosign(Sigstore)
Cosign 是 Sigstore 项目的一部分,提供更现代的签名机制:
安装 Cosign
# 安装 Cosign
curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64"
mv cosign-linux-amd64 /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign
使用 Cosign 签名
# 生成密钥对
cosign generate-key-pair
# 签名镜像
cosign sign --key cosign.key myrepo/myapp:1.0
# 验证签名
cosign verify --key cosign.pub myrepo/myapp:1.0
# 使用密钥管理服务(KMS)
cosign sign --key gcpkms://projects/... myrepo/myapp:1.0
Cosign 验证输出
$ cosign verify --key cosign.pub myrepo/myapp:1.0
Verification for myrepo/myapp:1.0 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified using the specified public key
[
{
"critical": {
"identity": {
"docker-reference": "myrepo/myapp"
},
"image": {
"docker-manifest-digest": "sha256:abc123..."
},
"type": "cosign container image signature"
},
"optional": null
}
]
在 CI/CD 中集成签名
GitHub Actions(Cosign)
name: Sign and Push
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
- name: Build and Push
run: |
docker build -t myrepo/myapp:${{ github.sha }} .
docker push myrepo/myapp:${{ github.sha }}
- name: Sign the Image
uses: sigstore/cosign-installer@main
- run: |
cosign sign \
--tlog-upload=false \
--key env://COSIGN_PRIVATE_KEY \
myrepo/myapp@${{ steps.push.outputs.digest }}
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
镜像签名验证策略
实施策略
# Kubernetes 使用 Kyverno 验证签名
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image
spec:
validationFailureAction: enforce
rules:
- name: verify-cosign
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- image: "myrepo/*"
key: |
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
密钥管理和轮换
安全存储密钥
# 使用硬件安全模块(HSM)
# 使用密钥管理服务(AWS KMS, GCP KMS, Azure Key Vault)
# 使用 CI/CD secrets 管理
# 不要将私钥提交到 git
# 不要将私钥放在镜像中
密钥轮换
# Cosign 密钥轮换
cosign generate-key-pair
cosign sign --key cosign.key myrepo/myapp:1.0
# 支持多密钥验证
cosign verify --key old.pub --key new.pub myrepo/myapp:1.0
内容信任的开销
| 方面 | 影响 | 缓解措施 |
|---|---|---|
| 性能 | 签名/验证增加构建时间 | CI 中处理 |
| 密钥管理 | 需要安全存储私钥 | 使用密钥管理服务 |
| 兼容性 | 需所有消费者支持验证 | 分阶段实施 |
| 流程 | 增加发布步骤 | CI/CD 自动化 |
最佳实践
- 总是启用内容信任:在 CI/CD 中配置
DOCKER_CONTENT_TRUST=1 - 使用强密钥:至少 2048 位 RSA 或等效 ECDSA
- 定期轮换密钥:至少每年一次
- 分离密钥角色:root 密钥离线存储,仓库密钥用于日常
- 在部署端验证:Kubernetes 准入控制器验证签名
- 自动化签名流程:在 CI/CD 中自动签名
- 监控签名异常:未签名镜像的拉取尝试应报警
镜像签名与内容信任是容器安全供应链的基石,确保从构建到部署的整个链路中镜像的完整性和真实性。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容