如何给 Docker 镜像进行安全签名

公众号关注 「奇妙的 Linux 世界」

设为「星标」,每天带你玩转 Linux !

5d8ef91a2f22e0dbe41d2050c50f3092.png

幸运的是,Docker 通过一种称为 Docker 内容信任的功能来实现信任机制。

在网络系统之间传输数据时,信任是一个核心问题。特别是,当通过不受信任的互联网网络进行通信时,确保系统操作的所有数据的完整性和可信任的发布者,是至关重要的。使用 Docker Engine 将镜像推、拉到公共或私有仓库中,镜像签名能够保证,通过任何渠道从仓库获取到的镜像是完整的和可信任的。


1信任机制

介绍 DCT 到底是什么,其作用是为了干什么!

Docker Content Trust(DCT)提供了对从远程 Docker 仓库上传和下载的镜像文件,使用数字签名的能力,其能够保证镜像文件的完整性和发布者的可信性。DCT 通过 Docker 标签对镜像文件是否进行签名进行区分,镜像发布者可以自行决定在哪些标签上进行签名。

DCT 实现的是客户端的签名和验证,意味着由 Docker 客户端执行它们。显然,类似这样的密码机制,对于确保在互联网上拉取和推送的软件的可信性是非常重要的,其在整个技术栈的各个层次,以及软件交付流水线的各个环节都在发挥越来越重要的作用。c942feddcea4d7ce44efeb248051b304.png

在Docker中进行镜像签名

2镜像签名

介绍对镜像文件进行签名,秘钥使用流程和关系!

镜像标签的信任是,通过使用签名密钥来管理的。第一次使用 DCT 来操作时,将创建密钥集,由以下类密钥组成:

  • 根密钥 - root key

    • 它用于创建和签名新的库密钥,因此应该被妥善保管

    • an offline key that is the root of DCT for an image tag

  • 库密钥 - 标签密钥 - repository key

    • 用于对需要推送到指定镜像库的打标签的镜像进行签名

    • repository or tagging keys that sign tags

  • 时间戳密钥 - timeStamp key

    • 它被保存在远程镜像库中,用于一些更加高级的使用场景以确保时效性

    • server-managed keys such as the timestamp key, which provides freshness security guarantees for your repository

f70435d714de1777f42dbbb222da3ab3.png
在Docker中进行镜像签名

0f8ae4b4df95aeb7c0d876776a11cdf5.png

点击上方图片,打开小程序,『美团外卖』红包天天免费领!

下图描述了各种签名密钥及其关系,但需要注意的是根密钥的丢失是很难恢复的,所以应该将根密钥备份到一个安全的地方。

c01e9446b04b40cd441733b4502b4f67.png
在Docker中进行镜像签名

3初次使用

使用我们自建的 notary(一个用于建立内容之间信任的平台)服务进行容器签名

Docker CLI 中,我们可以使用 docker trust 命令对容器文件进行签名和推送。但是需要注意的是,必须要部署一个公证服务器(notary)才可以对容器镜像进行签名。

# Notary Server
$ git clone https://github.com/theupdateframework/notary.git
$ docker-compose up -d
a5de13f58e4201ac362b583f63ae7900.png
在Docker中进行镜像签名

要签名一个 Docker 镜像,需要一个密钥对,其可以使用命令在本地生成(默认情况下存储在 ~/.docker/trust/ 中),也可以由来自证书机构。

# 本地生成
$ docker trust key generate point_me
Generating key for point_me...
Enter passphrase for new point_me key with ID 9deed25:
Repeat passphrase for new point_me key with ID 9deed25:
Successfully generated and loaded private key.

# 使用已有
$ docker trust key load key.pem --name point_me
Loading key from "key.pem"...
Enter passphrase for new point_me key with ID 8ae710e:
Repeat passphrase for new point_me key with ID 8ae710e:
Successfully imported key from key.pem

接下来,我们将公钥添加到公证服务器上。如果是第一次执行的话,需要输入一些相关信息,才可以使用。

$ docker trust signer add --key cert.pem point_me registry.example.com/admin/demo
Adding signer "point_me" to registry.example.com/admin/demo...
Enter passphrase for new repository key with ID 10b5e94:

最后,我们将使用私钥对特定镜像文件的标签进行签名,并将其推到仓库中去。

# 签名
$ docker trust sign registry.example.com/admin/demo:1
Signing and pushing trust data for local image registry.example.com/admin/demo:1, may overwrite remote trust data
The push refers to repository [registry.example.com/admin/demo]
7bff100f35cb: Pushed
1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528
Signing and pushing trust metadata
Enter passphrase for signer key with ID 8ae710e:
Successfully signed registry.example.com/admin/demo:1
# 启用
$ export DOCKER_CONTENT_TRUST=1

# 推送
$ docker push registry.example.com/admin/demo:1
The push refers to repository [registry.example.com/admin/demo:1]
7bff100f35cb: Pushed
1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528
Signing and pushing trust metadata
Enter passphrase for signer key with ID 8ae710e:
Successfully signed registry.example.com/admin/demo:1

# 查看
$ docker trust inspect --pretty registry.example.com/admin/demo:1

# 删除远程服务器对该镜像的信任
$ docker trust revoke registry.example.com/admin/demo:1
Enter passphrase for signer key with ID 8ae710e:
Successfully deleted signature for registry.example.com/admin/demo:1

Docker 客户端默认禁用镜像签名,如果希望启用,则将 DOCKER_CONTENT_TRUST 环境变量设置为 1 即可。这将阻止用户使用带有非签名的图像文件,对应对应的客户端命令,比如 pushbuildcreatepullrun

# 拉取失败
$ docker pull registry.example.com/user/image:1
Error: remote trust data does not exist for registry.example.com/user/image: registry.example.com does not have trust data for registry.example.com/user/image

# 拉取成功
$ docker pull registry.example.com/user/image@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a
sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1: Pulling from user/image
ff3a5c916c92: Pull complete
a59a168caba3: Pull complete
Digest: sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1
Status: Downloaded newer image for registry.example.com/user/image@sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1

4使用示例

直接基于 hub.docker 仓库服务进行操作!

下面通过一个简单的配置 DCT 的实战例子予以阐述。我们需要一个 Docker 客户端和一个用来推送镜像的库,Docker Hub 上的镜像库即可。

# 启用特性
$ export DOCKER_CONTENT_TRUST

# 登录hub.docker仓库
$ docker login

#  对镜像打标签并推送到目标镜像库
$ docker image tag alpine:latest escape/dockerbook:v1

# 推送打了新标签的镜像
# 在签名时会创建两个密钥,根密钥和库密钥
$ docker image push nigelpoulton/dockerbook:v1

# 在拉取镜像时使用如下命令来覆盖DCT设置
$ docker image pull --disable-content-trust nigelpoulton/dockerbook:unsigned

# 尝试运行未签名的镜像容器
$ docker container run -d --rm nigelpoulton/dockerbook:unsigned
docker: No trust data for unsigned.

5参考链接

  • Content trust in Docker

  • Deploy Notary Server with Compose

  • 容器镜像签名

本文转载自:「 Escape 的博客 」,原文:https://tinyurl.com/59badcrb ,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。

acd456a3ce81fef5863b84c450046e84.gif

ddff9522e3d604e98c1681a7b47bd924.png

你可能还喜欢

点击下方图片即可阅读

5d642390a50c83c282ee658217b34f71.png

Wintun:一款惊艳的 WireGuard 虚拟网卡接口驱动

180ba38ebc2722b9ca5d28e7e6f1e731.png
『美团|饿了么』外卖红包天天免费领,吃饭省钱杠杠滴!

10930d27cdc31ebb0d149863016291d6.png

更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 重命名 Docker 镜像的方法如下: 1. 先使用 `docker pull` 命令把镜像拉取到本地。 2. 然后使用 `docker tag` 命令为镜像打上新的标签。 例如: ``` docker tag old_image_name new_image_name ``` 3. 最后使用 `docker push` 命令把新命名的镜像推送到 Docker 仓库。 例如: ``` docker push new_image_name ``` 注意: 在执行 `docker push` 命令时, 需要确保你已登录到目标仓库。 ### 回答2: 在Docker中,可以使用`docker tag`命令来重命名镜像。 `docker tag`命令的语法是: ``` docker tag <旧镜像名> <新镜像名> ``` 首先,我们需要查看已有的镜像列表,可以使用以下命令: ``` docker images ``` 找到你想要重命名的镜像,并记录下其`REPOSITORY`和`TAG`。 然后,使用`docker tag`命令来重命名镜像。例如,如果要将镜像`myimage:latest`重命名为`myimage:newtag`,需要运行以下命令: ``` docker tag myimage:latest myimage:newtag ``` 运行该命令后,Docker将为该镜像创建一个新的标签,同时保留原始标签。现在,你可以使用新的标签来引用这个镜像,例如: ``` docker run myimage:newtag ``` 注意,`docker tag`命令只是为镜像创建了一个新的标签,并没有复制或修改镜像本身。因此,重命名镜像是非常高效和快速的操作。 希望以上解答对你有所帮助! ### 回答3: 要重命名Docker镜像,可以按照以下步骤进行操作: 1. 首先,使用`docker image ls`命令列出当前的镜像列表。找到你想要重命名的镜像的ID或者Repo和Tag。 2. 使用`docker tag`命令为镜像创建一个新的标签。命令的格式为`docker tag <原镜像名>:<原标签名> <新镜像名>:<新标签名>`。例如,要重命名名为`myimage:tag1`的镜像为`myimage:tag2`,可以运行`docker tag myimage:tag1 myimage:tag2`命令。 3. 运行`docker image ls`命令验证新标签是否成功创建。你应该能够看到原镜像和新镜像的两条记录,但是它们拥有相同的镜像ID。 4. 如果你只需要重命名镜像的标签而不改变镜像的内容,你可以通过删除原标签来完成。使用`docker image rm`命令来删除原标签的镜像。命令的格式为`docker image rm <镜像名>:<标签名>`。例如,要删除标签为`myimage:tag1`的镜像,可以运行`docker image rm myimage:tag1`命令。 5. 最后,运行`docker image ls`命令验证是否只剩下了新标签的镜像
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值