许多开源软件项目每天都在软件构建中使用,这对于几乎每个组织都至关重要。开源软件带来了许多好处,并帮助软件开发人员专注于创新和效率,而不是重复造轮子。
有时,您无法识别和验证第三方软件的完整性,持续进行验证可能会为供应链攻击打开大门。因此,sigstore 项目应运而生。sigstore 项目旨在保护供应链技术,并最终保护开源软件本身的安全。
sigstore 项目由其保护伞下的几个开源组件组成:
在本文中,我将着眼于项目中的 cosign
部分,以及如何使用它来签名和验证容器镜像(以及其他受支持的对象)。cosign
的理念是使签名和验证过程成为开发人员的 不可变基础设施。
安装和构建 cosign
在本示例中,我将在基于 macOS 的系统上安装 cosign
。首先,确保系统已安装并运行 Docker,以便管理容器镜像。
使用 brew,我安装 cosign
。
$ brew install sigstore/tap/cosign
==> Installing sigstore/tap/cosign
? /usr/local/Cellar/cosign/1.3.1: 3 files, 82.5MB, built in 2 seconds
接下来,我确保已登录到目标注册表,在本示例中为 docker.io。
$ docker login docker.io
Login Succeeded
签名和验证容器镜像
在我可以签名和验证任何镜像之前,我需要生成公钥和私钥对。然后,我使用此私钥对对象进行签名,并在以后使用相应的公钥对其进行验证。我还应该使用强密码来保护密钥对。理想情况下,此密码应存储在保险库中以用于安全和审计目的。
$ cosign generate-key-pair
Enter password for private key:
Enter again:
Private key written to cosign.key
Public key written to cosign.pub
既然我已经有了开始签名所需的密钥,我将对之前推送到注册表的测试镜像进行签名。
$ cosign sign --key cosign.key docker.io/mzali/test:latest
Enter password for private key:
使用 triangulate
选项,我可以从注册表中找到 cosign 镜像引用。
$ cosign triangulate docker.io/mzali/test:latest
index.docker.io/mzali/test:sha256-25ca0d9c2f4e70ce3bfba7891065dfef09760d2cbace7a2d21fb13c569902133.sig
现在,这是我要根据公钥验证镜像并验证签名真实性的部分。使用公钥,我可以验证镜像签名密钥签名。
$ cosign verify --key cosign.pub docker.io/mzali/test:latest
Verification for index.docker.io/mzali/test:latest --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
- Any certificates were verified against the Fulcio roots.
[{"critical":{"identity":{"docker-reference":"index.docker.io/mzali/test"},"image":{"docker-manifest-digest":"sha256:25ca0d9c2f4e70ce3bfba7891065dfef09760d2cbace7a2d21fb13c569902133"},"type":"cosign container image signature"},"optional":null}]
对 SBOM 执行相同的操作
接下来,我还想 签名 SBOM。在本示例中,我使用 alpine:latest
镜像来展示如何执行此操作。
alpine 容器镜像已经推送到注册表。我首先需要从镜像生成 SBOM,我使用 syft 项目 中的 syft
二进制文件。由于我在基于 macOS 的系统上进行测试,因此我将使用 brew 来安装它。
$ brew tap anchore/syft
$ brew install syft
我检查以查看注册表中的 alpine 容器镜像中包含哪些软件包,使用 syft
。
$ syft packages mzali/alpine
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
NAME VERSION TYPE
alpine-baselayout 3.2.0-r16 apk
alpine-keys 2.4-r0 apk
apk-tools 2.12.7-r0 apk
busybox 1.33.1-r6 apk
ca-certificates-bundle 20191127-r5 apk
libc-utils 0.7.2-r3 apk
libcrypto1.1 1.1.1l-r0 apk
libretls 3.3.3p1-r2 apk
libssl1.1 1.1.1l-r0 apk
musl 1.2.2-r3 apk
musl-utils 1.2.2-r3 apk
scanelf 1.3.2-r0 apk
ssl_client 1.33.1-r6 apk
zlib 1.2.11-r3 apk
现在我将要签名此 SBOM。我希望 SBOM 采用 SPDX 2.2 标签值格式(或另一种受支持的格式,在本示例中,我选择 SPDX 格式),然后将其附加到镜像。
$ syft packages mzali/alpine -o spdx > latest.spdx
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [14 packages]
$ ls -lrt latest.spdx
-rw-r--r-- 1 yanked yanked 10058 Nov 17 15:52 latest.spdx
$ cosign attach sbom --sbom latest.spdx mzali/alpine
Uploading SBOM file for [index.docker.io/mzali/alpine:latest] to [index.docker.io/mzali/alpine:sha256-5e604d3358ab7b6b734402ce2e19ddd822a354dc14843f34d36c603521dbb4f9.sbom] with mediaType [text/spdx].
使用上述摘要输出,我在注册表中签名 SBOM 并对其进行验证。
$ cosign sign --key cosign.key docker.io/mzali/alpine:sha256-5e604d3358ab7b6b734402ce2e19ddd822a354dc14843f34d36c603521dbb4f9.sbom
Enter password for private key: %
$ cosign verify --key cosign.pub docker.io/mzali/alpine:sha256-5e604d3358ab7b6b734402ce2e19ddd822a354dc14843f34d36c603521dbb4f9.sbom
Verification for index.docker.io/mzali/alpine:sha256-5e604d3358ab7b6b734402ce2e19ddd822a354dc14843f34d36c603521dbb4f9.sbom --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
- Any certificates were verified against the Fulcio roots.
[{"critical":{"identity":{"docker-reference":"index.docker.io/mzali/alpine"},"image":{"docker-manifest-digest":"sha256:00a101b8d193c294e2c9b3099b42a7bc594b950fbf535d98304d4c61fad5491b"},"type":"cosign container image signature"},"optional":null}]
下一步是什么?
使用 cosign
最简单的方法是将其包含到您的 SDLC 管道中,例如 Jenkins 或 Tekton 工具。使用 cosign
,我可以将其包含到构建过程中,以签名和验证我的软件。如果您正在使用 Kubernetes,则有一个 Kubernetes cosigned 准入控制器,它可以查看您的镜像签名并将其与指定的公钥进行比较。如果镜像未签名或使用未知密钥,则准入控制器会因违规而阻止它。
$ kubectl apply -f unsigned-deployment.yaml
Error from server (BadRequest): error when creating "unsigned-deployment.yaml": admission webhook "cosigned.sigstore.dev" denied the request: validation failed: invalid image signature: spec.template.spec.containers[0].image
再次强调,cosign
只是整个 sigstore 项目的冰山一角。这些组件是协作的、集成的,并提供防篡改性、强大的验证点,并使用相同的标准更轻松地保护软件!
评论已关闭。