cosign使用实践(一)本地验证二进制与镜像

一、cosign说明

1、来源

Sigstore是由红帽、谷歌联合几所美国高校主导开发维护的供应链安全开源项目,旨在提供一个新的软件加签、验签和防护的标准。通过Sigstore,我们可以自动对云原生下的各类开源制品进行数字签名并校验,帮助构建一个更安全、可追溯的供应监控链。

2、工作原理

cosign使用 ECDSA-P256 签名算法和公钥。私钥作为加密的 PEM 文件存储。

3、包含组件

主要包含三个核心组件:

  • Fulcio: 用于签发免费短时证书的根CA组件,同时会和OIDC认证流程结合,将OIDC身份供应商中的邮箱地址作为用户身份签发到短时证书中,证书的有效时长是20分钟。
  • Rekor:取名源自希腊语的“Record”。它旨在构建软件供应链环节的不可变防篡改账本,制品开发者或构建系统可以通过它产生一个不可变的签名元数据记录,同时它也提供了用于验签或查看 transparency日志中签名实体的restful API 和CLI工具,方便制品的使用者进行可信验证。
  • Cosign:基于Fulcio和Rekor的签名工具,负责加签指定的制品并将加签信息推送到指定的OCI仓库中。

4、 Sigstore工作流程

在这里插入图片描述

  • 开发人员通过 OIDC(Google、Github、Mircosoft 等账号)进行身份认证

  • 认证通过后,Fulcio 给开发者颁发关联邮箱身份的短期证书,也同步给 Rekor

  • 开发人员使用对应的短期密钥对制品进行签名,并发布制品,会将签名和验证证据同步给 Rekor

  • 使用者在使用制品前可以通过 Cosign 使用 Rekor 数据验证签名的有效性

  • 监督者通过 Rekor 的日志对证书的颁发记录进行审计

二、安装

采用源码安装

1、安装go

本人使用gvm来安装和管理go

root@zishen:/home/btg/install# gvm list

gvm gos (installed)

   go1.17.10
   go1.20.3
   system

root@zishen:/home/btg/install# gvm use go1.20.3
Now using version go1.20.3
root@zishen:/home/btg/install# gvm list

gvm gos (installed)

   go1.17.10
=> go1.20.3
   system

2、配置gopath

gvm需要设置自己的go工作路径,

root@zishen:/home/btg/install# go env
...
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/usr/workspace/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/usr/workspace/go"
GOPRIVATE=""
...

3、使用源码安装

root@zishen:/home/btg/install# cd /usr/workspace/go/
root@zishen:/usr/workspace/go/src# go install github.com/sigstore/cosign/v2/cmd/cosign@latest
go: downloading github.com/sigstore/cosign/v2 v2.0.2
go: downloading github.com/sigstore/cosign v1.13.1
go: downloading github.com/sigstore/sigstore v1.6.3
...

4、验证是否安装成功

root@zishen:/usr/workspace/go/src# cosign version
  ______   ______        _______. __    _______ .__   __.
 /      | /  __  \      /       ||  |  /  _____||  \ |  |
|  ,----'|  |  |  |    |   (----`|  | |  |  __  |   \|  |
|  |     |  |  |  |     \   \    |  | |  | |_ | |  . `  |
|  `----.|  `--'  | .----)   |   |  | |  |__| | |  |\   |
 \______| \______/  |_______/    |__|  \______| |__| \__|
cosign: A tool for Container Signing, Verification and Storage in an OCI registry.

GitVersion:    v2.0.2
GitCommit:     unknown
GitTreeState:  unknown
BuildDate:     unknown
GoVersion:     go1.20.3
Compiler:      gc
Platform:      linux/amd64

三、验证二进制

使用kubernetes官网提供的验证方式:

1、下载二进制和签名

在工作目录创建test.sh,内容如下:

URL=https://dl.k8s.io/release/v1.27.1/bin/linux/amd64
BINARY=kubectl

FILES=(
    "$BINARY"
    "$BINARY.sig"
    "$BINARY.cert"
)

for FILE in "${FILES[@]}"; do
    curl -sSfL --retry 3 --retry-delay 3 "$URL/$FILE" -o "$FILE"
done

执行后,目录得到如下内容:

root@zishen:/home/btg/install/cosign# ll
total 48112
drwxr-xr-x 2 root root     4096 May  4 14:59 ./
drwxr-xr-x 3 root root     4096 May  4 14:58 ../
-rw-r--r-- 1 root root 49246208 May  4 14:59 kubectl
-rw-r--r-- 1 root root     1432 May  4 14:59 kubectl.cert
-rw-r--r-- 1 root root       96 May  4 14:59 kubectl.sig
-rw-r--r-- 1 root root      233 May  4 14:58 test.sh
root@zishen:/home/btg/install/cosign# 

2、验证

使用cosign进行验证:

root@zishen:/home/btg/install/cosign# cosign verify-blob kubectl --signature kubectl.sig --certificate kubectl.cert
Error: --certificate-identity or --certificate-identity-regexp is required for verification in keyless mode
main.go:74: error during command execution: --certificate-identity or --certificate-identity-regexp is required for verification in keyless mode
root@zishen:/home/btg/install/cosign# 

发现报错,研究cosign官网:

issue-2632和,发现对二进制的支持以及如何支持还存在讨论和进一步完善。

四、验证镜像

1、推送镜像

首先需要注册dockerhub,并创建自己的仓库。

在服务器中登录镜像仓库:

root@zishen:/home/btg/install/cosign# docker login docker.io
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: zishen1988
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
root@zishen:/home/btg/install/cosign# 

给需要的镜像打tag。

注意:除了帐号和仓库外,不要有多余的"/".

推送镜像:

root@zishen:/home/btg/install/cosign# docker tag 6c359c411258 zishen1988/karmada-aggregated-apiserver:latest
root@zishen:/home/btg/install/cosign# docker images|grep apiserver
karmada/karmada-aggregated-apiserver                    latest             6c359c411258   7 days ago      93.3MB
zishen1988/karmada-aggregated-apiserver                 latest             6c359c411258   7 days ago      93.3MB
root@zishen:/home/btg/install/cosign# docker push zishen1988/karmada-aggregated-apiserver
Using default tag: latest
The push refers to repository [docker.io/zishen1988/karmada-aggregated-apiserver]
40b74373e2a4: Pushed 
c3818d28dc0e: Pushed 
8e012198eea1: Pushed 
latest: digest: sha256:6866234a86dd08e9d55e1d0bd525ce809648a03f80b7a0a221a52203332a5d83 size: 950
root@zishen:/home/btg/install/cosign# 

2、生成密钥对

root@zishen:/home/btg/install/cosign# 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
root@zishen:/home/btg/install/cosign# 

所在目录存在密钥对:

root@zishen:/home/btg/install/cosign# ll
total 48120
drwxr-xr-x 2 root root     4096 May  4 17:49 ./
drwxr-xr-x 3 root root     4096 May  4 14:58 ../
-rw------- 1 root root      653 May  4 17:49 cosign.key
-rw-r--r-- 1 root root      178 May  4 17:49 cosign.pub

3、给镜像签名

root@zishen:/home/btg/install/cosign# cosign sign --key cosign.key zishen1988/karmada-aggregated-apiserver:latest
Enter password for private key: 
WARNING: Image reference zishen1988/karmada-aggregated-apiserver:latest uses a tag, not a digest, to identify the image to sign.
    This can lead you to sign a different image than the intended one. Please use a
    digest (example.com/ubuntu@sha256:abc123...) rather than tag
    (example.com/ubuntu:latest) for the input to cosign. The ability to refer to
    images by tag will be removed in a future release.


	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: 19678374
Pushing signature to: index.docker.io/zishen1988/karmada-aggregated-apiserver
root@zishen:/home/btg/install/cosign# 

4、验证镜像

root@zishen:/home/btg/install/cosign# cosign verify --key cosign.pub zishen1988/karmada-aggregated-apiserver:latest

Verification for index.docker.io/zishen1988/karmada-aggregated-apiserver:latest --
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/zishen1988/karmada-aggregated-apiserver"},"image":{"docker-manifest-digest":"sha256:6866234a86dd08e9d55e1d0bd525ce809648a03f80b7a0a221a52203332a5d83"},"type":"cosign container image signature"},"optional":{"Bundle":{"SignedEntryTimestamp":"MEYCIQCfzkoftK1mqcFKQ+FPCoS/aVYPN6bhsYgXkNEsV/EI3wIhAMQoBijS96ekUbf3+zP8iQGHbSSV802/G44T8rRkfbmW","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI5NjJmZDM0OWVlZjUxMjM1Njg0MTJkYTJmNTg1ZjZjNGIyNjMyZmQzMmQwYmU0N2E4MDZiYzY1YzEyNDM5NDg5In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJQU9uOWVzTjUrdXlxZGRiYk54aUdsQWxRTmpmOTJ3M1ZERGl3NUE5dkd5dkFpQmlHVjcvdHdaNitwQjg3WkVTRGhaS0xkQUtmT2tzRytSQVU3Qk9IenJQTnc9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCUVZVSk1TVU1nUzBWWkxTMHRMUzBLVFVacmQwVjNXVWhMYjFwSmVtb3dRMEZSV1VsTGIxcEplbW93UkVGUlkwUlJaMEZGUlhsNGVIcGtkV041YldOM2NETmFaMHhUTXpWclpsQm5NMjk0ZWdwNVVISTJWakp2YkVNNEsxQnJRMFJDU1U1TFJtUm9UbVZLYVc5U2JXMU1TWFpxTTJodVpVcHdNRFpuTjJwS0sxcHRhMEk1ZVdSd0t6aG5QVDBLTFMwdExTMUZUa1FnVUZWQ1RFbERJRXRGV1MwdExTMHRDZz09In19fX0=","integratedTime":1683202277,"logIndex":19678374,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}}}]
root@zishen:/home/btg/install/cosign# 

至此,验证镜像功能走通。

五、k8s中的自动验证

1、安装kyverno筛选器

安装Kyverno 步骤如下:

1)、安装helm

root@zishen:/home/btg/install/cosign/k8s# curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
root@zishen:/home/btg/install/cosign/k8s# ll
total 24
drwxr-xr-x 2 root root  4096 May  5 19:57 ./
drwxr-xr-x 5 root root  4096 May  5 19:36 ../
-rw-r--r-- 1 root root 11345 May  5 19:57 get_helm.sh
root@zishen:/home/btg/install/cosign/k8s# chmod 700 get_helm.sh
root@zishen:/home/btg/install/cosign/k8s# ./get_helm.sh
Downloading https://get.helm.sh/helm-v3.11.3-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
root@zishen:/home/btg/install/cosign/k8s# 

2)、安装kyverno

root@zishen:/home/btg/install/cosign/k8s# helm repo add kyverno https://kyverno.github.io/kyverno/
"kyverno" has been added to your repositories
root@zishen:/home/btg/install/cosign/k8s# kubectl create namespace kyverno
namespace/kyverno created
root@zishen:/home/btg/install/cosign/k8s# helm install kyverno --namespace kyverno kyverno/kyverno
NAME: kyverno
LAST DEPLOYED: Fri May  5 20:00:10 2023
NAMESPACE: kyverno
STATUS: deployed
REVISION: 1
NOTES:
Chart version: 2.7.2
Kyverno version: v1.9.2

Thank you for installing kyverno! Your release is named kyverno.
⚠️  WARNING: Setting replicas count below 3 means Kyverno is not running in high availability mode.

💡 Note: There is a trade-off when deciding which approach to take regarding Namespace exclusions. Please see the documentation at https://kyverno.io/docs/installation/#security-vs-operability to understand the risks.
root@zishen:/home/btg/install/cosign/k8s#

3)、检查是否有对应的api和资源

root@zishen:/home/btg/install/cosign/k8s# kubectl api-versions |grep kyverno
kyverno.io/v1
kyverno.io/v1alpha2
kyverno.io/v1beta1
kyverno.io/v2alpha1
kyverno.io/v2beta1
root@zishen:/home/btg/install/cosign/k8s# kubectl api-resources|grep ClusterPolicy
clusterpolicies                   cpol         kyverno.io                     false        ClusterPolicy
clusterpolicyreports              cpolr        wgpolicyk8s.io                 false        ClusterPolicyReport
root@zishen:/home/btg/install/cosign/k8s# 

如上所示表示成功。

2、部署镜像验证策略

参照kyverno.io官网给出的验证例子编写clusterPolicy.yaml,内容如下:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: check-image
spec:
  validationFailureAction: Enforce
  background: false
  webhookTimeoutSeconds: 30
  failurePolicy: Fail
  rules:
    - name: check-image
      match:
        any:
        - resources:
            kinds:
              - Pod
      verifyImages:
      - imageReferences:
        - "ghcr.io/kyverno/test-verify-image*"
        attestors:
        - count: 1
          entries:
          - keys:
              publicKeys: |-
                -----BEGIN PUBLIC KEY-----
                MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
                5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
                -----END PUBLIC KEY-----     

部署该 ClusterPolicy :

root@zishen:/home/btg/install/cosign/k8s# kubectl apply -f clusterPolicy.yaml 
clusterpolicy.kyverno.io/check-image created
root@zishen:/home/btg/install/cosign/k8s# kubectl get ClusterPolicy -A
NAME          BACKGROUND   VALIDATE ACTION   READY   AGE
check-image   false        Enforce           true    14s
root@zishen:/home/btg/install/cosign/k8s#

使用验证过的镜像如下:

root@zishen:/home/btg/install/cosign/k8s# kubectl run signed --image=ghcr.io/kyverno/test-verify-image:signed
pod/signed created
root@zishen:/home/btg/install/cosign/k8s# kubectl get pod -A
NAMESPACE            NAME                                            READY   STATUS    RESTARTS   AGE
default              signed                                          1/1     Running   0          9s

使用未验证的镜像如下效果:

root@zishen:/home/btg/install/cosign/k8s# kubectl run unsigned --image=ghcr.io/kyverno/test-verify-image:unsigned
Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request: 

policy Pod/default/unsigned for resource violation: 

check-image:
  check-image: |
    failed to verify image ghcr.io/kyverno/test-verify-image:unsigned: .attestors[0].entries[0].keys: no matching signatures:

替换成我们在第四节中使用的镜像(使用生成的pub,修改镜像匹配前缀:我的是docker.io/zishen1988/,非打标签的zishen1988),效果如下:

root@zishen:/home/btg/install/cosign/k8s# kubectl run unsigned --image=zishen1988/kube-apiserver-amd64:latest
Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request: 

policy Pod/default/unsigned for resource violation: 

check-image:
  check-image: |
    failed to verify image docker.io/zishen1988/kube-apiserver-amd64:latest: .attestors[0].entries[0].keys: no matching signatures:
root@zishen:/home/btg/install/cosign/k8s# kubectl run unsigned --image=zishen1988/karmada-aggregated-apiserver:latest
pod/unsigned created
root@zishen:/home/btg/install/cosign/k8s# 

至此k8s的自动镜像验证也成功。

六、参考

osign安装

验证二进制签名

软件完整性保护方案之Sigstore

云原生供应链安全利器Sigstore - keyless模式浅析

Verify Images

安装Helm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值