Image Signature Verification
在 Tekton Chains 中,可以自动为构建的镜像生成签名,并将签名记录在 SLSA Provenance 中。
目录
功能概述
该方法使用 Tekton Chains 自动为构建的镜像生成签名,然后使用 cosign 或 Kyverno 验证签名:
- 配置 Tekton Chains 自动为构建的镜像生成签名。
- 使用
buildah
Tekton 任务构建镜像。
- (可选)使用
cosign
CLI 验证签名。
- 配置 Kyverno 规则,仅允许已签名的镜像。
- 使用该镜像创建 Pod 以验证签名。
使用场景
以下场景需要参考本文档中的指导:
- 在 Kubernetes 集群中使用 Kyverno 实现镜像签名验证
- 强制安全策略,仅允许部署已签名的镜像
- 在 CI/CD 流水线中设置自动镜像签名验证
- 确保生产环境中镜像的完整性和真实性
- 为容器镜像实施供应链安全控制
前提条件
- 已安装 Tekton Pipelines、Tekton Chains 和 Kyverno 的 Kubernetes 集群
- 支持镜像推送的镜像仓库
- 已安装并配置好访问集群的
kubectl
CLI
- 已安装
cosign
CLI 工具
- 已安装
jq
CLI 工具
流程概览
步骤 | 操作 | 说明 |
---|
1 | 生成签名密钥 | 使用 cosign 创建用于签名工件的密钥对 |
2 | 设置认证 | 配置镜像仓库凭证以支持镜像推送 |
3 | 配置 Tekton Chains | 设置 Chains 使用 OCI 存储并配置签名 |
4 | 创建示例流水线 | 创建包含必要任务和工作空间的流水线定义 |
5 | 运行示例流水线 | 创建并运行配置正确的 PipelineRun |
6 | 等待签名 | 等待 PipelineRun 被 Chains 签名 |
7 | 获取镜像信息 | 从 PipelineRun 中提取镜像 URI 和摘要 |
8 | 使用 Kyverno 验证签名 | 配置并使用 Kyverno 策略验证镜像签名 |
9 | 清理资源 | 删除测试 Pod 和策略 |
逐步操作指南
步骤 1-7:基础设置
这些步骤与 快速开始:签名的 Provenance 指南完全相同。请参照该指南完成以下操作:
步骤 8:使用 Kyverno 验证签名
在 步骤 8:验证镜像和证明 中,我们使用 cosign
CLI 验证签名。
这里我们改用 Kyverno 来验证签名。
步骤 8.1:创建 Kyverno 策略,仅允许已签名镜像部署
策略如下:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: only-cosign-image-deploy
spec:
webhookConfiguration:
failurePolicy: Fail
timeoutSeconds: 30
background: false
rules:
- name: check-image
match:
any:
- resources:
kinds:
- Pod
namespaces:
- policy
verifyImages:
- imageReferences:
- "*"
# - "<registry>/test/*"
skipImageReferences:
- "ghcr.io/trusted/*"
failureAction: Enforce
verifyDigest: false
required: false
useCache: false
imageRegistryCredentials:
allowInsecureRegistry: true
secrets:
# 凭证需存在于 Kyverno 所部署的命名空间
- registry-credentials
attestors:
- count: 1
entries:
- keys:
publicKeys: |- # <- 签名者的公钥
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFZNGfYwn7+b4uSdEYLKjxWi3xtP3
UkR8hQvGrG25r0Ikoq0hI3/tr0m7ecvfM75TKh5jGAlLKSZUJpmCGaTToQ==
-----END PUBLIC KEY-----
ctlog:
ignoreSCT: true
rekor:
ignoreTlog: true
:::details {title="YAML 字段说明"}
spec.rules[].match.any[].resources
:匹配并验证的资源。
kinds
:匹配并验证的资源类型。
namespaces
:匹配并验证的资源所在命名空间。
policy
:匹配并验证 policy
命名空间中的资源。
spec.rules[].verifyImages
:需要验证的镜像
imageReferences
:要验证的镜像引用。
*
:验证所有镜像引用。
<registry>/test/*
:仅验证 <registry>/test
仓库中的镜像引用。
skipImageReferences
:跳过验证的镜像引用。
ghcr.io/trusted/*
:跳过 ghcr.io/trusted
仓库中的镜像引用。
imageRegistryCredentials
:
allowInsecureRegistry
:是否允许不安全的仓库。
secrets
:用于镜像仓库凭证的 Secret。
registry-credentials
:Secret 名称,需存在于 Kyverno 所部署的命名空间。
attestors
:用于镜像验证的验证者。
count
:需要匹配的验证者数量。
entries
:验证者条目。
keys
:验证者的密钥。
publicKeys
:验证者的公钥。
- 此公钥与
signing-secrets
Secret 中的公钥 cosign.pub
相同。
ctlog
:验证者的 ctlog。
rekor
:验证者的 rekor。
需要调整配置
spec.rules[].attestors[].entries[].keys.publicKeys
:签名者的公钥。
- 此公钥与
signing-secrets
Secret 中的公钥 cosign.pub
相同。
- 公钥可从 获取签名公钥 部分获得。
保存为名为 kyverno.only-cosign-image-deploy.yaml
的 yaml 文件,并通过以下命令应用:
$ kubectl apply -f kyverno.only-cosign-image-deploy.yaml
clusterpolicy.kyverno.io/only-cosign-image-deploy configured
步骤 8.2:验证策略
在定义该策略的 policy
命名空间中,创建一个 Pod 来验证该策略。
使用流水线创建的已签名镜像创建 Pod。
$ export NAMESPACE=<policy>
$ export IMAGE=<<registry>/test/chains/demo-1:latest@sha256:93635f39cb31de5c6988cdf1f10435c41b3fb85570c930d51d41bbadc1a90046>
$ kubectl run -n $NAMESPACE signed --image=${IMAGE} -- sleep 3600
pod/signed created
Pod 将成功创建。
$ export NAMESPACE=<policy>
$ kubectl get pod -n $NAMESPACE signed
NAME READY STATUS RESTARTS AGE
signed 1/1 Running 0 10s
使用未签名镜像创建 Pod。
$ export NAMESPACE=<policy>
$ export IMAGE=<<registry>/test/chains/unsigned:latest>
$ kubectl run -n $NAMESPACE unsigned --image=${IMAGE} -- sleep 3600
收到如下输出,表示 Pod 被策略阻止。
Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request:
resource Pod/policy/unsigned was blocked due to the following policies
only-cosign-image-deploy:
check-image: 'failed to verify image ubuntu:latest:
.attestors[0].entries[0].keys: no signatures found'
步骤 9:清理资源
删除前面步骤中创建的 Pod。
$ export NAMESPACE=<policy>
$ kubectl delete pod -n $NAMESPACE signed
pod "signed" deleted
删除策略。
$ kubectl delete clusterpolicy only-cosign-image-deploy
预期结果
完成本指南后:
- 您已成功搭建了使用 Tekton Chains 进行镜像签名和 Kyverno 进行签名验证的环境
- 容器镜像在构建过程中自动签名
- 仅允许已签名的镜像在指定命名空间中部署
- 未签名的镜像会被 Kyverno 策略自动阻止
- 实现了容器镜像的基础供应链安全控制
本指南为在 CI/CD 流水线中实施供应链安全提供了基础。在生产环境中,您还应:
- 配置合适的命名空间隔离和访问控制
- 实施签名密钥的安全管理
- 设置策略违规的监控和告警
- 定期轮换签名密钥并更新安全策略
- 考虑实施漏洞扫描等额外安全控制
参考资料