漏洞扫描与验证
在 ACP (Alauda Container Platform) 中,您可以使用 Tekton Pipeline 来构建镜像并扫描其中的漏洞。
具体来说,使用 trivy task 生成漏洞扫描结果,然后使用 cosign 上传漏洞扫描结果的 attestation,最后使用 kyverno 验证漏洞扫描结果的 attestation。
目录
功能概览使用场景前提条件流程概览逐步说明步骤 1-3:基础设置步骤 4:创建示例 Pipeline步骤 5:运行示例 Pipeline步骤 6:等待 PipelineRun 完成签名步骤 7:从 PipelineRun 获取镜像步骤 8:(可选)获取 cosign vuln attestation步骤 9:使用 Kyverno 验证漏洞扫描结果步骤 9.1:创建一个 Kyverno policy,拒绝存在高风险漏洞的镜像步骤 9.2:验证 policy步骤 10:(可选)要求漏洞扫描结果在 168 小时内步骤 11:清理资源预期结果参考功能概览
此方法使用类似 trivy 的工具扫描镜像中的漏洞,然后使用 Kyverno 验证漏洞扫描结果:
- 使用
trivyTekton Task 扫描镜像中的漏洞。 - 使用
cosignTekton Task 将漏洞扫描结果上传到镜像。 - 配置 Kyverno 规则以验证漏洞扫描结果。
- 使用该镜像创建一个 Pod,以验证漏洞扫描结果。
使用场景
以下场景需要参考本文档中的指导:
- 在 Kubernetes 集群中使用 Kyverno 实现漏洞扫描与验证
- 强制实施安全策略,仅允许部署漏洞等级可接受的镜像
- 在 CI/CD 流水线中设置自动化漏洞扫描与验证
- 确保生产环境中的镜像安全与漏洞合规性
- 通过验证容器镜像的漏洞状态来实现供应链安全控制
前提条件
- 已安装 Tekton Pipelines、Tekton Chains 和 Kyverno 的 Kubernetes 集群
- 已启用镜像推送的 registry
- 已安装并配置可访问集群的
kubectlCLI - 已安装
cosignCLI 工具 - 已安装
jqCLI 工具
流程概览
逐步说明
步骤 1-3:基础设置
这些步骤与 Quick Start: Signed Provenance 指南完全相同。请按照该指南中的说明完成以下内容:
- 步骤 1:生成签名密钥
- 步骤 2:设置认证
- 步骤 3:配置 Tekton Chains
- 获取签名 secret
- 重要:此处仅为方便起见,因此这里使用 Chains 的全局签名证书。在实际使用中,您可以使用单独的证书来签名镜像漏洞信息。
- 将 secret 导入到执行 pipeline 的 namespace 中。
步骤 4:创建示例 Pipeline
这是一个 Pipeline 资源,用于构建镜像并生成 cosign 漏洞 attestation。
本教程通过在 pipeline 中内联生成 Containerfile 和 git-clone task 输出,展示了一个简化的工作流。
在生产环境中,通常会:
- 使用
git-clonetask 从您的仓库获取源代码 - 使用源代码中已有的 Containerfile 构建镜像
- 这种方式可以确保正确的版本控制,并保持代码与 pipeline 配置之间的分离
YAML 字段说明
- 与 步骤 4:创建示例 Pipeline 中的内容基本一致,但新增了以下内容:
workspaces:signkey:用于镜像签名的私钥和密码所在的 workspace。
tasks:trivy-scanner:用于扫描镜像漏洞的 task。cosign-uploads:用于上传漏洞扫描结果 attestation 的 task。 :::
保存为名为 chains-demo-4.yaml 的 yaml 文件,并使用以下命令应用:
步骤 5:运行示例 Pipeline
这是一个 PipelineRun 资源,用于运行该 pipeline。
:::details {title="YAML 字段说明"}
- 与 步骤 5:运行示例 Pipeline 中的内容基本一致。下面仅介绍差异。
workspacessignkey:签名密钥的 secret 名称。secret.secretName:上一阶段 获取签名 secret 中准备好的签名 secret。但您需要在与 pipeline run 相同的 namespace 中创建一个新的 secret。 :::
保存为名为 chains-demo-4.pipelinerun.yaml 的 yaml 文件,并使用以下命令应用:
等待 PipelineRun 完成。
步骤 6:等待 PipelineRun 完成签名
等待 PipelineRun 带有 chains.tekton.dev/signed: "true" 注解。
一旦 PipelineRun 带有 chains.tekton.dev/signed: "true" 注解,就表示镜像已签名。
步骤 7:从 PipelineRun 获取镜像
该镜像将用于验证漏洞扫描结果。
步骤 8:(可选)获取 cosign vuln attestation
如果您对 cosign vuln attestation 的内容感兴趣,可以继续阅读下面的内容。
关于 cosign vuln attestation 的更多细节,请参阅 cosign vuln attestation
按照 获取签名公钥 小节获取签名公钥。
输出将类似于以下内容,其中包含漏洞扫描结果。
:::details {title="cosign vuln attestation"}
:::details {title="字段说明"}
predicateType:predicate 的类型。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 policy,拒绝存在高风险漏洞的镜像
此步骤需要集群管理员权限。
关于 Kyverno ClusterPolicy 的更多细节,请参阅 Kyverno ClusterPolicy
policy 如下:
:::details {title="YAML 字段说明"}
- 该 policy 与 镜像签名验证 中的 policy 大体一致
spec.rules[0].verifyImages[].attestations[0].conditionstype:cosign vuln attestation 的类型为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。 :::
将 policy 保存为名为 kyverno.reject-high-risk-image.yaml 的 yaml 文件,并使用以下命令应用:
步骤 9.2:验证 policy
在定义了该 policy 的 policy namespace 中,创建一个 Pod 来验证该 policy。
使用已构建的镜像创建一个 Pod。
如果您的镜像存在高风险漏洞,Pod 将被该 policy 阻止。 您将收到如下输出:
更改 ClusterPolicy 中的条件,允许存在高风险漏洞但 CVSS 分数低于 10.0 的镜像。
然后再次创建一个 Pod 以验证该 policy。
Pod 将会成功创建。
步骤 10:(可选)要求漏洞扫描结果在 168 小时内
如果您想为 policy 添加更多条件,可以继续阅读以下内容。
由于 Cosign Vulnerability Scan Record Attestation 包含 scanFinishedOn 字段,
并且 trivy 符合该规范,因此我们可以使用该字段来判断漏洞扫描结果是否在 168 小时内。
我们只需在 ClusterPolicy 中添加一个条件,用于检查 scanFinishedOn 字段是否在 168 小时内。
这里不再演示,感兴趣的读者可以自行尝试。
步骤 11:清理资源
删除前面步骤中创建的 Pod。
删除 policy。
预期结果
完成本指南后:
- 您将拥有一个可工作的 Tekton Chains 漏洞扫描与 Kyverno 漏洞验证环境
- 您的容器镜像会自动在其 attestation 中包含漏洞扫描结果
- 只有漏洞等级可接受的镜像才能在指定 namespace 中部署
- 存在高风险漏洞的镜像会被 Kyverno policy 自动阻止
- 您已经通过验证容器镜像的漏洞状态,实现了基础的供应链安全控制
本指南为在 CI/CD 流水线中实现供应链安全提供了基础。在生产环境中,您应该:
- 配置适当的 namespace 隔离和访问控制
- 为签名密钥实现安全的密钥管理
- 为 policy 违规设置监控和告警
- 定期轮换签名密钥并更新安全 policy