使用 Cosign 对容器镜像进行签名,并确保未签名的镜像不被部署

通过对容器镜像进行签名,可以防止意外使用第三方镜像导致的安全事件。这次我们将使用cosign对容器镜像进行签名,并确认签名的具体运作方式。在此不讨论cosign是什么。knqyf263的sigstore上有一篇关于容器镜像和软件签名的文章非常易懂,如果想了解cosign的话推荐阅读该文章。

前提 tí)

以满足以下条件的状态开始。

    • クライアントPCでDocker Daemonが起動済み

 

    • Kubernetesが構築済み

 

    Harborが構築済み

为了确认Harbor的签名是否有效,可以使用它。但如果没有Harbor,也可以使用DockerHub等,但需要注意部分步骤可能会有变化。

署名的使用

安装cosign。
从官方网站获取安装步骤,但需要额外进行符号链接操作,所以请注意。
针对每个操作系统都有相应的安装步骤可供使用,除了Debian系统的用户外,其他用户需要参考各自的安装步骤进行安装。

wget "https://github.com/sigstore/cosign/releases/download/v1.6.0/cosign_1.6.0_amd64.deb"
sudo dpkg -i "cosign_1.6.0_amd64.deb"
sudo ln -s /usr/local/bin/cosign-linux-amd64 /usr/local/bin/cosign

在进行cosign签名之前,需要提前创建密钥对。在这里,我们将密码设置为hogefuga。

$ 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

执行完成后,将在当前目录下创建私钥和公钥。

$ ls
cosign.key  cosign.pub

使用创建的密钥对对容器镜像进行签名。

cosign sign --key cosign.key myharbor.info/myapp/mynginx
1669014999318.png
1669015038366.png

确认署名的效果

1669015147536.png

将未署名的映像为了测试目的,将DockerHub上的nginx复制到自己的Harbor上。

docker pull nginx
docker tag nginx myharbor.info/myapp/nginx-not-signed
docker push myharbor.info/myapp/nginx-not-signed
1669015790797.png

尝试使用各自的形象来启动Pod。

kubectl run --image myharbor.info/myapp/nginx-not-signed nginx-not-signed
kubectl run --image myharbor.info/myapp/mynginx mynginx

可以发现只有使用了未署名的图像的Pod启动失败。

$ kubectl get pod
NAME               READY   STATUS             RESTARTS   AGE
mynginx            1/1     Running            0          81s
nginx-not-signed   0/1     ImagePullBackOff   0          72s

查看错误详情,如下所示。

$ kubectl describe pod nginx-not-signed
:(省略)
  Warning  Failed     17s (x4 over 111s)  kubelet            Failed to pull image "myharbor.info/myapp/nginx-not-signed": rpc error: code = Unknown desc = failed to pull and unpack image "myharbor.info/myapp/nginx-not-signed:latest": failed to resolve reference "myharbor.info/myapp/nginx-not-signed:latest": pulling from host myharbor.info failed with status code [manifests latest]: 412 Precondition Failed

如果未署名,则会返回错误代码412。