基于Cosign容器镜像签名/验证工具能力,实现Pod可信验证
腾讯云TKE集群,在23年5月,上线了一特性: Cerberus 组件支持对签名镜像进行可信验证
支持在Kubernetes
集群中只部署可信授权方签名
的容器镜像,降低在容器环境中的镜像安全
风险。
因此,cosign-webhook
, 功能上类似腾讯Cerberus
. 为了实现一套多云可用
,并支持Docker hub
、Harbor
和Quay
镜像仓库 签名sig
存储的通用解决方案
背景:Cosign 工具
[Cosign](https://github.com/sigstore/cosign)
是 谷歌开源容器镜像的签名和验证工具。 此二进制
工具支持 容器镜像 签名与验证。并继承到谷歌内部容器基础设施distroless中。
Cosign 除了提供给用户可以方便的对镜像签名和验证,还提供免费 OIDC PKI (Fucio)
和内置二进制透明度和时间戳服务 Rekor
, 来托管签名和验证过程中的公钥和私钥
cosign基本使用
1. 签名:cosign keyless
模式,签名证书托管在googleapi open OIDC PKI
上
以Dockerhub
上的dongjiang1989/node-metrics:latest
镜像为例:
因为,是keyless
模式,直接行cosign sign <image>@sha256:<digest>
dongjiang@MacBook Pro:~ $ cosign sign dongjiang1989/node-metrics@sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282
Generating ephemeral keys...
Retrieving signed certificate...
The sigstore service, hosted by sigstore a Series of LF Projects, LLC, is provided pursuant to the Hosted Project Tools Terms of Use, available at https://lfprojects.org/policies/hosted-project-tools-terms-of-use/.
Note that if your submission includes personal data associated with this signed artifact, it will be part of an immutable record.
This may include the email address associated with the account with which you authenticate your contractual Agreement.
This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later, and is subject to the Immutable Record notice at https://lfprojects.org/policies/hosted-project-tools-immutable-records/.
By typing 'y', you attest that (1) you are not submitting the personal data of any other person; and (2) you understand and agree to the statement and the Agreement terms at the URLs listed above.
Are you sure you would like to continue? [y/N] y
error opening browser: exec: "xdg-open": executable file not found in $PATH
Go to the following link in a browser:
https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=L_clEcpY7BXtgaJ0W5qZJq74ovXNnznXpwYluzCUPEQ&code_challenge_method=S256&nonce=2TSKHjXGVJMxbj4TgFNe6wtXXKg&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=openid+email&state=2TSKHg5tyauZ3PaaVJHyNfRAf1D
Enter verification code: yql4si3wqdvkzrm25ohncuk45
Successfully verified SCT...
tlog entry created with index: 29886419
Pushing signature to: index.docker.io/dongjiang1989/node-metrics
执行期间会跳转到到 https://oauth2.sigstore.dev/auth/auth?xxx
连接 需要用github
或者 google
或者 microsoft
统一登入,验证邮箱, 并在平台上保留公钥和私钥
.
完成验证后,会将signature
文件,提交到镜像仓库
2. 验证:cosign keyless
模式
keyless
模式,直接通过:
cosign verify --certificate-identity <keyless邮箱地址> --certificate-oidc-issuer <认证平台地址> <image>@sha256:<digest>
其中,认证平台地址根据sign in平台,不通进行设置
- github认证: https://github.com/login/oauth
- google认证: https://accounts.google.com
- 微软认证:https://login.microsoftonline.com
dongjiang@MacBook Pro:~ $ cosign verify --certificate-identity dongjiang1989@126.com --certificate-oidc-issuer https://github.com/login/oauth dongjiang1989/node-metrics@sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282
Verification for index.docker.io/dongjiang1989/node-metrics@sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The code-signing certificate was verified using trusted certificate authority certificates
[{"critical":{"identity":{"docker-reference":"index.docker.io/dongjiang1989/node-metrics"},"image":{"docker-manifest-digest":"sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282"},"type":"cosign container image signature"},"optional":{"1.3.6.1.4.1.57264.1.1":"https://github.com/login/oauth","Bundle":{"SignedEntryTimestamp":"xxxxxxxxx","Payload":{"body":"xxxxxxxxxxxx=","integratedTime":1691030975,"logIndex":29886419,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}},"Issuer":"https://github.com/login/oauth","Subject":"dongjiang1989@126.com"}}]
3. 本地key方式签名和验证
a. 先创建创建密钥对
dongjiang@MacBook Pro:~ $ cosign generate-key-pair
Enter password for private key:
Enter password for private key again:
Private key written to cosign.key
Public key written to cosign.pub
dongjiang@MacBook Pro:~ $ ls
aaa cosign.key cosign.pub go src tools
b. 通过cosign.key
, 镜行容器镜行签名 cosign sign --key cosign.key <image>@sha256:<digest>
dongjiang@MacBook Pro:~ $ cosign sign --key cosign.key dongjiang1989/node-metrics:sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282
Enter password for private key:
Error: signing [dongjiang1989/node-metrics:sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282]: parsing reference: could not parse reference: dongjiang1989/node-metrics:sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282
main.go:74: error during command execution: signing [dongjiang1989/node-metrics:sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282]: parsing reference: could not parse reference: dongjiang1989/node-metrics:sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282
[root@VM-0-5-centos ~]# cosign sign --key cosign.key dongjiang1989/node-metrics@sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282
Enter password for private key:
The sigstore service, hosted by sigstore a Series of LF Projects, LLC, is provided pursuant to the Hosted Project Tools Terms of Use, available at https://lfprojects.org/policies/hosted-project-tools-terms-of-use/.
Note that if your submission includes personal data associated with this signed artifact, it will be part of an immutable record.
This may include the email address associated with the account with which you authenticate your contractual Agreement.
This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later, and is subject to the Immutable Record notice at https://lfprojects.org/policies/hosted-project-tools-immutable-records/.
By typing 'y', you attest that (1) you are not submitting the personal data of any other person; and (2) you understand and agree to the statement and the Agreement terms at the URLs listed above.
Are you sure you would like to continue? [y/N] y
tlog entry created with index: 29887689
Pushing signature to: index.docker.io/dongjiang1989/node-metrics
c. 通过cosign.pub
, 镜行容器镜行验证 cosign verify --key cosign.pub <image>@sha256:<digest>
[root@VM-0-5-centos ~]# cosign verify --key cosign.pub dongjiang1989/node-metrics@sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282
Verification for index.docker.io/dongjiang1989/node-metrics@sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The signatures were verified against the specified public key
[{"critical":{"identity":{"docker-reference":"index.docker.io/dongjiang1989/node-metrics"},"image":{"docker-manifest-digest":"sha256:c1aa0f2861d2eb744efb8f82a1d7d5f1b74919d1cc6501e799daeac1991fc282"},"type":"cosign container image signature"},"optional":{"Bundle":{"SignedEntryTimestamp":"xxxxxxxxxx","Payload":{"body":"xxxxxxxxxx=","integratedTime":1691032440,"logIndex":29887689,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}}}]
由于国内对国外google,github访问限制,使用本地签名
方式更有利于与私有化 和 跨云验证
具体实现方式
先通过 CRD
描述 namespace
下 CosignKey
扩展限制
设计如下:
apiVersion: cosignkey.kubeservice.cn/v1
kind: CustomCosignKey
metadata:
name: test-cosignkey
namespace: xxxxx
spec:
authorities:
key:
- |
-----BEGIN PUBLIC KEY-----
......
-----END PUBLIC KEY-----
在namespace
可以是添加label
设置 cosignkey.kubernetes.io/verify : disabled
, 可支持 ignore
namespace下Cosign
验证
注意
- 只有
namespace
添加label
设置cosignkey.kubernetes.io/verify : enabled
且namespace
CustomCosignKey被定义, 才生效 - 同一个
namespace
CRD 只能背定义一次,重复定义出错; - 会对pod中的 initContainer、Container 都会进行验证;
1.为什么CRD需要说明支持多个key?
一个namespace(属于1个租户
),他部署的pod中的容器,可能有几个来源
。 这几个来源的public key可能不通,支持轮训检查
2.配置namespace label
flag 作用?
用于 功能上线
,持续替换 或者 特殊场景下排ta处理
周边生态
- Harbor 直接镜像同步 支持 cosign 签名和验证:https://github.com/goharbor/harbor/releases/tag/v2.5.0
- Skopeo 镜像迁移工具 支持 cosign 镜像迁移: https://github.com/containers/skopeo/pull/1849
- KMS: aws、google 和 azure kms都支持 cosign 容器验证
source
https://github.com/kubeservice-stack/cosign-webhook