saschagrunert/nri-supply-chain

GitHub: saschagrunert/nri-supply-chain

基于 NRI 的容器运行时级供应链证明验证插件,在容器创建阶段强制校验 SLSA、VEX 和 VSA 证明,实现无法被 Kubernetes API 层绕过的镜像来源验证。

Stars: 1 | Forks: 0

# 供应链 NRI Plugin [![ci](https://static.pigsec.cn/wp-content/uploads/repos/cas/99/993938d8ce5e902ccfb9d6747725c320d855dea3235ed9a304cedf0d94c9321f.svg)](https://github.com/saschagrunert/nri-supply-chain/actions/workflows/ci.yml) [![deploy](https://static.pigsec.cn/wp-content/uploads/repos/cas/b8/b810711b4925b8ee5fb854ba540557717565270abe528ed5586124c80571b72b.svg)](https://github.com/saschagrunert/nri-supply-chain/actions/workflows/deploy.yml) [![GitHub release](https://img.shields.io/github/v/release/saschagrunert/nri-supply-chain)](https://github.com/saschagrunert/nri-supply-chain/releases/latest) [![codecov](https://codecov.io/gh/saschagrunert/nri-supply-chain/graph/badge.svg?token=xIALlTOulw)](https://codecov.io/gh/saschagrunert/nri-supply-chain) [![Go Reference](https://pkg.go.dev/badge/github.com/saschagrunert/nri-supply-chain.svg)](https://pkg.go.dev/github.com/saschagrunert/nri-supply-chain) 一个用于在容器 runtime 级别进行供应链证明验证的 [NRI](https://github.com/containerd/nri) plugin。它会拦截 [CRI-O](https://cri-o.io) 或 [containerd](https://containerd.io) 上的容器创建事件,并在容器被允许运行之前验证 SLSA provenance、VEX 和 VSA 证明。 Runtime 级别的强制执行无法通过配置错误的 admission webhook、被禁用的策略控制器或直接的 kubelet API 调用来绕过。该 plugin 运行在 Kubernetes API 层之下,因此在节点上运行的每个容器都必须通过验证。 - [快速入门](#quickstart) - [兼容性](#compatibility) - [架构](#architecture) - [验证](#verification) - [配置](#configuration) - [部署与示例](#deployment-and-examples) - [运维](#operations) - [验证发布版本](#verifying-releases) ## 快速入门 1. 从 [发布页面](https://github.com/saschagrunert/nri-supply-chain/releases) 下载最新的发布版二进制文件或容器镜像。 2. 创建一个配置文件 (`config.toml`): verification = "enforce" policy_dir = "/etc/nri-supply-chain/policies" 3. 创建一个默认策略 (`/etc/nri-supply-chain/policies/default.json`): { "trust": { "issuers": ["https://token.actions.githubusercontent.com"], "sanPatterns": ["https://github.com/saschagrunert/nri-supply-chain/**"], "sources": ["github.com/saschagrunert/*"] }, "slsa": { "missingPolicy": "deny" }, "vex": { "missingPolicy": "deny" } } 4. 验证单个镜像以测试配置: nri-supply-chain --config config.toml \ --verify-image ghcr.io/saschagrunert/nri-supply-chain:0.1.5 输出为包含各项检查详细信息的 JSON: { "image": "ghcr.io/saschagrunert/nri-supply-chain:0.1.5", "digest": "sha256:1a8b39eeff74b8bb3e20c7f9fa773d4a9935241f7cc4e1217067c8186c2cee3c", "namespace": "default", "allowed": true, "checkResults": [ { "type": "slsa", "passed": true, "status": "pass", "detail": "SLSA provenance verified" }, { "type": "vex", "passed": true, "status": "pass", "detail": "VEX verification passed" } ] } 要启用 VSA 加速的验证,请添加一个 `trust.verifiers` 条目。受信任的 VSA 会对 SLSA 和 VEX 检查进行短路(跳过后续检查): { "trust": { "issuers": ["https://token.actions.githubusercontent.com"], "sanPatterns": ["https://github.com/saschagrunert/nri-supply-chain/**"], "sources": ["github.com/saschagrunert/*"], "verifiers": [ { "id": "https://github.com/saschagrunert/nri-supply-chain/.github/workflows/release.yml" } ] }, "slsa": { "missingPolicy": "deny" }, "vex": { "missingPolicy": "deny" } } 使用此策略后,输出变为: { "image": "ghcr.io/saschagrunert/nri-supply-chain:0.1.5", "digest": "sha256:1a8b39eeff74b8bb3e20c7f9fa773d4a9935241f7cc4e1217067c8186c2cee3c", "namespace": "default", "allowed": true, "reason": "VSA verification passed, skipping direct verification", "checkResults": [ { "type": "vsa", "passed": true, "status": "pass", "detail": "VSA verification passed" } ] } 在 `enforce` 模式下,未通过验证的镜像将被拒绝。使用 `verification = "warn"` 可以在不进行拒绝的情况下观察哪些内容会被阻止。有关完整的验证流程,请参阅 [docs/verification.md](docs/verification.md)。 5. 部署 plugin(有关所有选项,请参阅 [部署](docs/deployment.md)): kubectl apply -f deploy/kubernetes/ 6. 检查日志和指标以观察验证决策。 ## 兼容性 | 组件 | 支持版本 | | ---------- | ------------------- | | Kubernetes | 1.26+ | | CRI-O | 1.28+ (启用 NRI) | | containerd | 1.7+ (启用 NRI) | | NRI | 0.6+ | | Go (构建) | 1.26+ | 必须在容器 runtime 配置中启用 NRI。有关详细信息,请参阅 [Runtime 要求](docs/deployment.md#runtime-requirements)。 ## 架构
验证流程图 ``` flowchart TD Runtime["Container Runtime\n(CRI-O / containerd)"] NRI["NRI Hook\n(CreateContainer)"] Plugin["nri-supply-chain"] Extract["Extract image ref + digest"] Policy["Policy lookup\n(namespace or default)"] Exclude{"Excluded?"} Cache{"Cache hit?"} Fetch["Fetch attestations\n(OCI Referrers API +\ncosign tag fallback)"] VSA{"Trusted VSA?"} Parallel["SLSA + VEX\n(parallel)"] Enforce{"Enforce / Warn"} Allow["Allow container"] Reject["Reject container"] Registry["OCI Registry"] Runtime --> NRI --> Plugin --> Extract --> Policy --> Exclude Exclude -- yes --> Allow Exclude -- no --> Cache Cache -- hit --> Enforce Cache -- miss --> Fetch Fetch <--> Registry Fetch --> VSA VSA -- "PASSED" --> Enforce VSA -- "FAILED" --> Enforce VSA -- "untrusted / stale / missing" --> Parallel Parallel --> Enforce Enforce -- pass --> Allow Enforce -- "fail (enforce mode)" --> Reject Enforce -- "fail (warn mode)" --> Allow ```
该 plugin 作为一个长期运行的进程运行,通过 NRI 连接到容器 runtime。它暴露 Prometheus 指标,并支持通过 SIGHUP 进行实时的配置重载。 启动时,NRI Synchronize 回调会传递节点上已经运行的 pod 和容器列表。该 plugin 收集它们的镜像引用,并在需要时通过 registry 的 `HEAD` 请求来解析缺失的 digest(例如,在 containerd 中,NRI annotation 可能会省略 digest)。它按 digest 和 namespace 进行去重,然后生成一个后台 goroutine 对每个镜像进行预验证。这会预热缓存,以便在这些容器重启时可以立即获得验证结果,从而避免冷缓存抓取造成的性能损失。 ## 验证 该 plugin 验证 SLSA provenance、VEX 和 VSA 证明。它从 CRI-O 或 containerd 的 NRI annotation 中提取镜像引用和 digest,通过 registry 的 HEAD 请求解析缺失的 digest,并应用基于 namespace 的策略。来自受信任验证器的 VSA 可以短路所有其他检查。 有关完整的验证流程、annotation 处理细节以及各类型的检查,请参阅 [docs/verification.md](docs/verification.md)。 ## 配置 该 plugin 使用两个配置层: - **操作配置** (TOML):控制 plugin 的行为(模式、超时、缓存、指标)。有关完整的字段参考和 CLI 标志,请参阅 [docs/config.md](docs/config.md)。 - **策略文件** (JSON):定义每个 namespace 的信任根和验证要求。有关字段参考、模式匹配语义和部署模式,请参阅 [docs/policy.md](docs/policy.md)。 ## 部署与示例 有关所有部署选项(DaemonSet、systemd、DEB/RPM、容器镜像、预安装的 NRI plugin)和示例配置(逐步推出、严格的生产环境、VSA 加速),请参阅 [docs/deployment.md](docs/deployment.md)。 请参阅 [`deploy/examples/policies/`](deploy/examples/policies/) 获取开箱即用的策略文件,涵盖无密钥、基于密钥、严格 VEX、VSA 加速以及其他场景。 ## 运维 该 plugin 暴露 Prometheus 指标、`/healthz` 和 `/readyz` endpoint,并支持通过 SIGHUP 或文件系统监视进行实时的配置重载。有关指标参考、告警规则、故障排除指南、内部限制和安全注意事项,请参阅 [docs/operations.md](docs/operations.md)。 ## 验证发布版本 发布的二进制文件附带了使用 [cosign](https://github.com/sigstore/cosign) 签名的 SHA-256 校验和文件。每个版本都会使用 [syft](https://github.com/anchore/syft) 生成 SBOM (Software Bill of Materials)。构建来源证明是通过 GitHub 的 `actions/attest-build-provenance` action 生成的。容器镜像还包含一个 [VSA](https://slsa.dev/spec/v1.0/verification_summary) 证明,用于记录发布管道的验证结果。 要验证发布版本: 1. 使用 cosign 验证校验和文件的签名: cosign verify-blob --bundle checksums.txt.sigstore.json checksums.txt 2. 根据校验和文件验证二进制文件: sha256sum --check checksums.txt 3. 验证容器镜像签名: cosign verify ghcr.io/saschagrunert/nri-supply-chain:latest \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --certificate-identity-regexp 'https://github.com/saschagrunert/nri-supply-chain/' 4. 验证构建来源证明: gh attestation verify nri-supply-chain__linux_amd64 \ --repo saschagrunert/nri-supply-chain 5. 验证容器镜像上的 VSA (Verification Summary Attestation): cosign verify-attestation ghcr.io/saschagrunert/nri-supply-chain:latest \ --type https://slsa.dev/verification_summary/v1 \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --certificate-identity-regexp 'https://github.com/saschagrunert/nri-supply-chain/' 6. 检查 SBOM(使用 syft 生成,完整性由步骤 1 中签名的校验和文件覆盖): cat nri-supply-chain__linux_amd64.sbom.json | jq .
标签:attestation校验, EVTX分析, Go, NRI插件, Ruby工具, Web截图, 子域名突变, 容器安全, 容器运行时, 日志审计, 自定义请求头