21

使用 Harbor 提供可信镜像

 4 years ago
source link: https://blog.fleeto.us/post/content-trust-with-harbor/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

应用上云的过程中,过了部署关和应用改造关之后,安全就是下一个大问题了。对于容器化应用来说,镜像的安全是个非常根本的问题,例如 Harbor 中集成了 Clair 组件,用于对镜像进行漏洞扫描; 之前介绍的 Trivy 也能够提供对镜像各层进行扫描的能力,类似的工具还有很多。在完成镜像本身的安全保障之后,一方面要把安全构建出来的镜像能够”原汁原味“的提供给运行时进行使用,同时还要对运行时环境进行约束,只允许获取和运行可靠镜像,如此才能够保证镜像供应链的完整。

快速上手

Harbor 中提供了 Notary 服务来提供了这方面的保障,Docker 17.12 之后也提供了对应的运行时支持。

这里用 1.10.0 版本的 Harbor 为例,在安装命令中加入参数 --with-notary 就可以启用这个服务了。启动 Harbor 之后,使用 Docker 客户端的终端设置环境变量: export DOCKER_CONTENT_TRUST=1 。启用 Docker 的内容信任模式。

使用 docker login 命令登录仓库,然后进行镜像推送,例如:

$ docker push 10.211.55.27/sign/clare:s1
The push refers to repository [10.211.55.27/sign/clare]
bbef02a499c4: Layer already exists
...
47a4bb1cfbc7: Layer already exists
s1: digest: sha256:bafc293fd765dbbad5ed3d57d771f0566e5d63a668213f1f61c469cbb199fca6 size: 1162
Signing and pushing trust metadata
You are about to create a new root signing key passphrase. This passphrase
...
Enter passphrase for new root key with ID b52c1ba:
Repeat passphrase for new root key with ID b52c1ba:
Enter passphrase for new repository key with ID c37e6d2:
Repeat passphrase for new repository key with ID c37e6d2:
Error: trust data missing for remote repository 10.211.55.27/sign/clare or remote repository not found: timestamp key trust data unavailable.  Has a notary repository been initialized?

这里多出了一个初始化过程,在我们照章输入密码之后,发现出了错,这是因为我们没有设置 Notary 服务地址,加入环境变量来解决: export DOCKER_CONTENT_TRUST_SERVER=https://10.211.55.27:4443

再次推送:

$ docker push 10.211.55.27/sign/clare:s1
The push refers to repository [10.211.55.27/sign/clare]
...
Repeat passphrase for new repository key with ID d6068a9:
Finished initializing "10.211.55.27/sign/clare"
Successfully signed 10.211.55.27/sign/clare:s1

可以看到,推送已经成功了,并且还有签署成功的反馈。查看一下他的签名信息:

$ docker trust inspect 10.211.55.27/sign/clare:s1
[
    {
        "Name": "10.211.55.27/sign/clare:s1",
        "SignedTags": [
            {
                "SignedTag": "s1",
                "Digest": "bafc293fd765dbbad5ed3d57d771f0566e5d63a668213f1f61c469cbb199fca6",
                "Signers": [
                    "Repo Admin"
                ]
            }

...

如果我们取消 Docker 内容信任: unset DOCKER_CONTENT_TRUST 。接下来推送一个新镜像:

$ docker push 10.211.55.27/sign/alpine:latest
The push refers to repository [10.211.55.27/sign/alpine]
77cae8ab23bf: Pushed

再次开启 Docker 内容信任开关: export DOCKER_CONTENT_TRUST=1 ,尝试拉取:

$ docker pull 10.211.55.27/sign/alpine:latest
Error: remote trust data does not exist for 10.211.55.27/sign/alpine: 10.211.55.27:4443 does not have trust data for 10.211.55.27/sign/alpine

可以看到 Docker 拒绝了未经签署的镜像。

幕后

Docker 包含了简写为 DCT 的内容签名(Docker Content Trust)支持,能够借助 Notary 进行内容签署和校验。首次签署时会要求生成根密钥,每次创建一个新的 Repository 时候,会为其单独生成签署密钥。接下来,每个 Tag 的推送都会进行签署,从而保证内容的稳定性。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK