Vulnerability Scanning and Verification
在 ACP(Alauda Container Platform)中,您可以使用 Tekton Pipeline 来构建镜像并扫描漏洞。
具体来说,使用 trivy 任务生成漏洞扫描结果,然后使用 cosign 上传漏洞扫描结果的证明,最后使用 kyverno 验证漏洞扫描结果的证明。
目录
功能概述
该方法使用类似 trivy 的工具扫描镜像漏洞,然后使用 Kyverno 验证漏洞扫描结果:
- 使用
trivyTekton 任务扫描镜像漏洞。 - 使用
cosignTekton 任务将漏洞扫描结果上传到镜像。 - 配置 Kyverno 规则验证漏洞扫描结果。
- 使用该镜像创建 Pod 以验证漏洞扫描结果。
使用场景
以下场景需要参考本文档的指导:
- 在 Kubernetes 集群中使用 Kyverno 实现漏洞扫描和验证
- 强制安全策略,仅允许漏洞等级可接受的镜像部署
- 在 CI/CD 流水线中设置自动化漏洞扫描和验证
- 确保生产环境中镜像的安全性和漏洞合规性
- 通过验证容器镜像的漏洞状态,实现供应链安全控制
前提条件
- 已安装 Tekton Pipelines、Tekton Chains 和 Kyverno 的 Kubernetes 集群
- 支持镜像推送的镜像仓库
- 已安装并配置好访问集群的
kubectlCLI - 已安装
cosignCLI 工具 - 已安装
jqCLI 工具
流程概览
逐步操作指南
步骤 1-3:基础设置
这些步骤与快速开始:签名溯源指南相同。请按照该指南完成:
- 步骤 1:生成签名密钥
- 步骤 2:设置认证
- 步骤 3:配置 Tekton Chains
- 获取签名 Secret
- 重要:此处仅为方便起见,使用了 Chains 的全局签名证书。实际使用中,您可以使用单独的证书对镜像漏洞信息进行签名。
- 将 Secret 导入流水线执行所在的命名空间。
步骤 4:创建示例流水线
这是一个 Pipeline 资源,用于构建镜像并生成 cosign 漏洞证明。
本教程通过在流水线中内联生成 Dockerfile 和 git-clone 任务输出,演示了简化的工作流程。
在生产环境中,通常会:
- 使用
git-clone任务从代码仓库拉取源代码 - 使用源代码中已有的 Dockerfile 构建镜像
- 该方式确保了版本控制的规范性,并保持代码与流水线配置的分离
YAML 字段说明
- 与步骤 4:创建示例流水线相同,但增加了以下内容:
workspaces:signkey:用于存放镜像签名所用私钥和密码的工作空间。
tasks:trivy-scanner:扫描镜像漏洞的任务。cosign-uploads:上传漏洞扫描结果证明的任务。 :::
保存为 chains-demo-4.yaml 文件,并执行:
步骤 5:运行示例流水线
这是一个 PipelineRun 资源,用于运行流水线。
:::details {title="YAML 字段说明"}
- 与步骤 5:运行示例流水线相同,仅介绍差异部分。
workspacessignkey:签名密钥的 Secret 名称。secret.secretName:前面步骤获取签名 Secret中准备的签名 Secret,但需要在流水线运行的命名空间中创建新的 Secret。 :::
保存为 chains-demo-4.pipelinerun.yaml 文件,并执行:
等待 PipelineRun 完成。
步骤 6:等待 PipelineRun 被签名
等待 PipelineRun 拥有 chains.tekton.dev/signed: "true" 注解。
当 PipelineRun 拥有 chains.tekton.dev/signed: "true" 注解时,表示镜像已被签名。
步骤 7:从 PipelineRun 获取镜像信息
该镜像将用于验证漏洞扫描结果。
步骤 8:(可选)获取 cosign 漏洞证明
如果您对 cosign 漏洞证明内容感兴趣,可以继续阅读以下内容。
更多关于 cosign 漏洞证明的细节,请参考 cosign vuln attestation
根据获取签名公钥章节获取签名公钥。
输出类似如下,包含漏洞扫描结果。
:::details {title="cosign 漏洞证明"}
:::details {title="字段说明"}
predicateType:谓词类型。predicate.scanner:uri:扫描器的 URI。version:扫描器版本。result:漏洞扫描结果。CreatedAt:漏洞扫描完成时间。Metadata:OS:Family:操作系统家族。Name:操作系统名称。
Results:漏洞扫描结果列表。Class:os-pkgs:操作系统包。lang-pkgs:语言包。
Packages:镜像中的包。Vulnerabilities:镜像中的漏洞。Severity:漏洞严重性。PkgID:漏洞对应的包 ID。PkgName:漏洞对应的包名。CVSS:漏洞的 CVSS 评分。nvd:NVD 评分。redhat:Red Hat 评分。 :::
步骤 9:使用 Kyverno 验证漏洞扫描结果
步骤 9.1:创建 Kyverno 策略,拒绝高风险漏洞镜像
此步骤需要集群管理员权限。
更多关于 Kyverno ClusterPolicy,请参考 Kyverno ClusterPolicy
策略如下:
:::details {title="YAML 字段说明"}
- 策略与镜像签名验证中的类似。
spec.rules[0].verifyImages[].attestations[0].conditionstype:cosign 漏洞证明类型为https://cosign.sigstore.dev/attestation/vuln/v1attestors:同上。conditions:需验证的条件。all:所有条件必须满足。key: "{{ scanner.result.Results[].Vulnerabilities[].Severity }}":漏洞严重性不得为HIGH或CRITICAL。key: "{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score >1.0][] | length(@) }}":CVSS 评分大于 1.0 的漏洞数量必须为 0。 :::
保存策略为 kyverno.reject-high-risk-image.yaml,并执行:
步骤 9.2:验证策略
在定义策略的 policy 命名空间中,创建 Pod 以验证策略。
使用构建好的镜像创建 Pod。
如果镜像存在高风险漏洞,Pod 会被策略阻止。 输出类似如下:
将 ClusterPolicy 中的条件修改为允许存在高风险漏洞,但 CVSS 评分小于 10.0 的镜像。
然后再次创建 Pod 验证策略。
Pod 将成功创建。
步骤 10:(可选)要求漏洞扫描结果在 168 小时内
如果您想为策略添加更多条件,可以继续阅读以下内容。
由于Cosign 漏洞扫描记录证明中包含 scanFinishedOn 字段,
且 trivy 符合该规范,我们可以使用此字段判断漏洞扫描结果是否在 168 小时内。
只需在 ClusterPolicy 中添加条件,检查 scanFinishedOn 字段是否在 168 小时内。
此处不做演示,有兴趣的读者可自行尝试。
步骤 11:清理资源
删除前面步骤中创建的 Pod。
删除策略。
预期结果
完成本指南后:
- 您已成功搭建 Tekton Chains 漏洞扫描和 Kyverno 漏洞验证环境
- 容器镜像自动包含漏洞扫描结果证明
- 仅允许漏洞等级可接受的镜像在指定命名空间部署
- 高风险漏洞镜像被 Kyverno 策略自动阻止
- 通过验证容器镜像漏洞状态,实现了基础的供应链安全控制
本指南为在 CI/CD 流水线中实现供应链安全提供了基础。在生产环境中,您应:
- 配置合理的命名空间隔离和访问控制
- 实施安全的签名密钥管理
- 设置策略违规的监控和告警
- 定期轮换签名密钥并更新安全策略