镜像签名与内容信任

镜像签名与内容信任

什么是镜像签名

镜像签名(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 自动化

最佳实践

  1. 总是启用内容信任:在 CI/CD 中配置 DOCKER_CONTENT_TRUST=1
  2. 使用强密钥:至少 2048 位 RSA 或等效 ECDSA
  3. 定期轮换密钥:至少每年一次
  4. 分离密钥角色:root 密钥离线存储,仓库密钥用于日常
  5. 在部署端验证:Kubernetes 准入控制器验证签名
  6. 自动化签名流程:在 CI/CD 中自动签名
  7. 监控签名异常:未签名镜像的拉取尝试应报警

镜像签名与内容信任是容器安全供应链的基石,确保从构建到部署的整个链路中镜像的完整性和真实性。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容