4

当初始化对 docker content trust with notary on tuf 的初始信任时,我了解 TUF、Notary 和 Content Trust 的工作原理。

但我不清楚的是,初始信任是如何设置的。

我怎么知道,第一次拉不是一个妥协的,最初的 root.json 是值得信赖的?

因此,例如,如果我docker pull启用了内容信任,我只会得到签名的图像。但是我如何验证这张图片是由正确的人签名的?

4

3 回答 3

5

公证人创建者和维护者在这里。Justin 已经给出了很好的说明,但我将更广泛地谈论 TUF 和 Notary 中的信任初始化。

除非您通过某种带外方法传达信任根,否则总会有一个下载点您隐含地信任以提供信任根。一些一般案例示例:当我们下载操作系统(即任何 Linux 发行版)或从公钥目录中获取某人的 GPG 公钥时,我们会这样做。假设资源是通过 TLS 连接传递的,并且我们相信发布者已经保护了他们的服务器,我们相信我们正在接收合法数据,并使用它来引导对所有未来交互的信任。这称为首次使用时的信任,或 TOFU。

这里的说法是人们确实保证了他们的服务器安全,并且很难执行中间人 (MiTM) 攻击,尤其是针对 TLS 安全连接。因此我们可以信任这个初始下载。

公证人有几种方法可以初始化信任。首先是这个TOFU机制。TUF 具有定义的更新流程,可确保在初始下载后对所有后续内容的信任。Notary 实施此更新流程并确保发布者在初始下载后保持一致。

如果您还想确保发布者是特定实体,Notary 提供了三种不同的方式来引导该信任。他们是:

  1. 手动将带外获取的 root.json 放置在公证缓存中的正确位置。
  2. 配置信任固定以信任公证人全局唯一名称 (GUN) 的特定根密钥 ID。
  3. 配置信任固定以信任特定公证 GUN 或 GUN 前缀的 CA。

更多关于信任固定的信息可以在我们的文档中找到。请注意,所有 3 个选项都需要带外通信,您可以在其中获取 root.json、根密钥的 ID 或用于颁发根密钥的 CA 证书。

在命令下实现信任固定docker trust在我们的 TODO 列表中,它还没有。但是,您仍然可以将选项 1 与docker trust. 缓存位于~/.docker/trust/tuf/<GUN>/metadata/

选项 3 的附加上下文:Notary 实现了一项功能,允许为 GUN 或 GUN 前缀配置 CA。此实例中的要求是公共根密钥作为 x509 证书包含在 root.json 中,该证书链接到配置的 CA。虽然 CA 可能是一个有争议的话题,但没有人被迫使用此功能,并且在大多数攻击者模型中,它绝对优于 TOFU。此外,TUF 明确没有解决如何引导信任。

于 2018-01-16T17:54:36.537 回答
1

您可以通过一些带外方式固定密钥,或者执行 ssh 之类的操作,向您显示密钥以检查首次使用。这些方法不是预定义的,但您可以灵活地自行构建它们,具体取决于您使用 Notary 的方式。对于 LinuxKit,我们计划提供一个选项,将密钥哈希值放入您用于构建的配置文件中,该文件列出了要提取的图像。或者您可以在其他地方发布根密钥 ID。

于 2018-01-16T11:13:42.027 回答
0

tl;博士

您可以执行以下操作来固定公共根密钥debian

sudo su -
mkdir -p /root/.docker/trust/tuf/docker.io/library/debian/metadata
chown -R root:root /root/.docker
chmod -R 0700 /root/.docker
echo '{"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2025-08-07T20:55:22.677722315-07:00","keys":{"5717dcd81d9fb5b73aa15f2d887a6a0de543829ab9b2d411acce9219c2f8ba3a":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsslGF2xHOYztrocb2OsRF2zth16v170QiLAyKdce1nQgOJ34FOk679ClPL9/RNnJukf2JfQXSlVV/qcsvxV2dQ=="}},"575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84":{"keytype":"ecdsa-x509","keyval":{"private":null,"public":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlVENDQVIrZ0F3SUJBZ0lRWExkUFFHTGJaOE84UXFlTzVuZlBRekFLQmdncWhrak9QUVFEQWpBak1TRXcKSHdZRFZRUURFeGhrYjJOclpYSXVhVzh2YkdsaWNtRnllUzlrWldKcFlXNHdIaGNOTVRVd09ERXhNRE0xTlRJeQpXaGNOTWpVd09EQTRNRE0xTlRJeVdqQWpNU0V3SHdZRFZRUURFeGhrYjJOclpYSXVhVzh2YkdsaWNtRnllUzlrClpXSnBZVzR3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVE1ZGkxcmxPQjBMQmRNS2N0VFQxYmwKUGd6aXYxOUJDdW9tNEFNL3BUdURtdjBnS0E5S1ptNUVjLy9VQmhSODVCYmR0cTk0cXhQM3IwUjhRc3FQV1Y4SQpvelV3TXpBT0JnTlZIUThCQWY4RUJBTUNBS0F3RXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdNd0RBWURWUjBUCkFRSC9CQUl3QURBS0JnZ3Foa2pPUFFRREFnTklBREJGQWlBOUFOZ3dPN2tBdUVIK3U2N25XNlFLWmlMdWd5UVcKaEQ3Vys5WjIza01mTndJaEFJa3RTaW1TdFdRQkFoOG9WOXhjaWNVWWVUN0pyUG82a0RqeHU1YitGZ3MxCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}},"728c96ff5e9f48d4e66d5a0c3ecabfdd90bee2b5f9f80b950ed9c668db264a70":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENtpBkDJ2oYaAAVdOkP0A6J0XwUkYGuFRk+q8N4WCPu2VnNIuBJkatPCWdEtHfQ9nNYLeanWgG62/UmJnx3E2Yg=="}},"d48327d85f0490827db7c931eedb58d293e1da5fc425ea0cde3e6c13b397ad69":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwfs26T/cpjvNTXVJpK7Wv8oDOnNKL78AT3Y1QD356OIAggwPupX2LQjZU6CVzCjm+pkJIO4clu9Q2n540gKuzQ=="}}},"roles":{"root":{"keyids":["575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84"],"threshold":1},"snapshot":{"keyids":["d48327d85f0490827db7c931eedb58d293e1da5fc425ea0cde3e6c13b397ad69"],"threshold":1},"targets":{"keyids":["5717dcd81d9fb5b73aa15f2d887a6a0de543829ab9b2d411acce9219c2f8ba3a"],"threshold":1},"timestamp":{"keyids":["728c96ff5e9f48d4e66d5a0c3ecabfdd90bee2b5f9f80b950ed9c668db264a70"],"threshold":1}},"version":1},"signatures":[{"keyid":"575d013f89e3cbbb19e0fb06aa33566c22718318e0c9f
fb1ab5cc4291e07bf84","method":"ecdsa","sig":"3WbX1VXN9E8LRmSG+E4SQlBUNqBNchhwAStWnRWLLyAOoFNBq5xmIgSO3UYYuKyJvL7kbMoONRbn5Vk2p2Wqrg=="}]}' > /root/.docker/trust/tuf/docker.io/library/debian/metadata/root.json

export DOCKER_CONTENT_TRUST=1
docker pull debian:stable-slim

长答案

⚠ 免责声明:我不是 docker 开发人员。截至 2021 年,DCT 似乎是开箱即用的,而且远没有用处。我在这里的回答是最好的猜测,但我尚未与 docker 团队确认这是否是预加载给定发布者的根密钥并将其固定到 DCT 密钥环中的“正确”方式。

请注意,谨慎行事,非常欢迎您提出意见。

它似乎没有在任何地方记录,但根据这个问题,很明显 docker 将其 DCT 元数据(包括根公钥)放在以下位置:

$HOME/.docker/trust/tuf/docker.io/library

在此library目录中,每个发布者都有一个目录。出于此答案的目的,我将debian用作我们的示例发布者。

您可以在debian此处查看发布到 Docker Hub 的 docker 镜像列表:

解决方案

假设我们想从Docker Hub 上stable-slim的发布者那里下载图像。debian在此示例中,我们还将使用全新安装的 Debian 10 作为 docker 主机。

##
# first, install docker
## 
root@disp2716:~# apt-get install docker.io
...
root@disp2716:~#

##
# confirm that there is no docker config dir yet
##

root@disp2716:~# ls -lah /root/.docker
ls: cannot access '/root/.docker': No such file or directory
root@disp2716:~# 

##
# add the debian publisher's root DCT key
##

root@disp2716:~# mkdir -p /root/.docker/trust/tuf/docker.io/library/debian/metadata
root@disp2716:~# chown -R root:root /root/.docker
root@disp2716:~# chmod -R 0700 /root/.docker
root@disp2716:~# echo '{"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2025-08-07T20:55:22.677722315-07:00","keys":{"5717dcd81d9fb5b73aa15f2d887a6a0de543829ab9b2d411acce9219c2f8ba3a":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsslGF2xHOYztrocb2OsRF2zth16v170QiLAyKdce1nQgOJ34FOk679ClPL9/RNnJukf2JfQXSlVV/qcsvxV2dQ=="}},"575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84":{"keytype":"ecdsa-x509","keyval":{"private":null,"public":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlVENDQVIrZ0F3SUJBZ0lRWExkUFFHTGJaOE84UXFlTzVuZlBRekFLQmdncWhrak9QUVFEQWpBak1TRXcKSHdZRFZRUURFeGhrYjJOclpYSXVhVzh2YkdsaWNtRnllUzlrWldKcFlXNHdIaGNOTVRVd09ERXhNRE0xTlRJeQpXaGNOTWpVd09EQTRNRE0xTlRJeVdqQWpNU0V3SHdZRFZRUURFeGhrYjJOclpYSXVhVzh2YkdsaWNtRnllUzlrClpXSnBZVzR3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVE1ZGkxcmxPQjBMQmRNS2N0VFQxYmwKUGd6aXYxOUJDdW9tNEFNL3BUdURtdjBnS0E5S1ptNUVjLy9VQmhSODVCYmR0cTk0cXhQM3IwUjhRc3FQV1Y4SQpvelV3TXpBT0JnTlZIUThCQWY4RUJBTUNBS0F3RXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdNd0RBWURWUjBUCkFRSC9CQUl3QURBS0JnZ3Foa2pPUFFRREFnTklBREJGQWlBOUFOZ3dPN2tBdUVIK3U2N25XNlFLWmlMdWd5UVcKaEQ3Vys5WjIza01mTndJaEFJa3RTaW1TdFdRQkFoOG9WOXhjaWNVWWVUN0pyUG82a0RqeHU1YitGZ3MxCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}},"728c96ff5e9f48d4e66d5a0c3ecabfdd90bee2b5f9f80b950ed9c668db264a70":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENtpBkDJ2oYaAAVdOkP0A6J0XwUkYGuFRk+q8N4WCPu2VnNIuBJkatPCWdEtHfQ9nNYLeanWgG62/UmJnx3E2Yg=="}},"d48327d85f0490827db7c931eedb58d293e1da5fc425ea0cde3e6c13b397ad69":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwfs26T/cpjvNTXVJpK7Wv8oDOnNKL78AT3Y1QD356OIAggwPupX2LQjZU6CVzCjm+pkJIO4clu9Q2n540gKuzQ=="}}},"roles":{"root":{"keyids":["575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84"],"threshold":1},"snapshot":{"keyids":["d48327d85f0490827db7c931eedb58d293e1da5fc425ea0cde3e6c13b397ad69"],"threshold":1},"targets":{"keyids":["5717dcd81d9fb5b73aa15f2d887a6a0de543829ab9b2d411acce9219c2f8ba3a"],"threshold":1},"timestamp":{"keyids":["728c96ff5e9f48d4e66d5a0c3ecabfdd90bee2b5f9f80b950ed9c668db264a70"],"threshold":1}},"version":1},"signatures":[{"keyid":"575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84","method":"ecdsa","sig":"3WbX1VXN9E8LRmSG+E4SQlBUNqBNchhwAStWnRWLLyAOoFNBq5xmIgSO3UYYuKyJvL7kbMoONRbn5Vk2p2Wqrg=="}]}' > /root/.docker/trust/tuf/docker.io/library/debian/metadata/root.json
root@disp2716:~# 
root@disp2716:~# chown root:root /root/.docker/trust/tuf/docker.io/library/debian/metadata/root.json
root@disp2716:~# chmod 0600 /root/.docker/trust/tuf/docker.io/library/debian/metadata/root.json
root@disp2716:~# 

##
# pull the docker image with DCT verification
##

root@disp2716:~# export DOCKER_CONTENT_TRUST=1
root@disp2716:~# docker pull debian:stable-slim
Pull (1 of 1): debian:stable-slim@sha256:850a7ee21c49c99b0e5e06df21f898a0e64335ae84eb37d6f71abc1bf28f5632
sha256:850a7ee21c49c99b0e5e06df21f898a0e64335ae84eb37d6f71abc1bf28f5632: Pulling from library/debian
6e640006d1cd: Pull complete 
Digest: sha256:850a7ee21c49c99b0e5e06df21f898a0e64335ae84eb37d6f71abc1bf28f5632
Status: Downloaded newer image for debian@sha256:850a7ee21c49c99b0e5e06df21f898a0e64335ae84eb37d6f71abc1bf28f5632
Tagging debian@sha256:850a7ee21c49c99b0e5e06df21f898a0e64335ae84eb37d6f71abc1bf28f5632 as debian:stable-slim
root@disp2716:~# 

证明

虽然没有办法告诉dockerTOFU 失败,但我们可以通过将公钥设为其他内容来确认上述密钥固定是否有效

##
# first, move the docker config dir out of the way
## 

mv /root/.docker /root/.docker.bak

##
# add the debian publisher's root DCT key (note I just overwrote the first 8
# characters of the actual key with "INVALID/")
##

root@disp2716:~# mkdir -p /root/.docker/trust/tuf/docker.io/library/debian/metadata
root@disp2716:~# chown -R root:root /root/.docker
root@disp2716:~# chmod -R 0700 /root/.docker
root@disp2716:~# echo '{"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2025-08-07T20:55:22.677722315-07:00","keys":{"5717dcd81d9fb5b73aa15f2d887a6a0de543829ab9b2d411acce9219c2f8ba3a":{"keytype":"ecdsa","keyval":{"private":null,"public":"INVALID/KoZIzj0CAQYIKoZIzj0DAQcDQgAEsslGF2xHOYztrocb2OsRF2zth16v170QiLAyKdce1nQgOJ34FOk679ClPL9/RNnJukf2JfQXSlVV/qcsvxV2dQ=="}},"575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84":{"keytype":"ecdsa-x509","keyval":{"private":null,"public":"INVALID/RUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlVENDQVIrZ0F3SUJBZ0lRWExkUFFHTGJaOE84UXFlTzVuZlBRekFLQmdncWhrak9QUVFEQWpBak1TRXcKSHdZRFZRUURFeGhrYjJOclpYSXVhVzh2YkdsaWNtRnllUzlrWldKcFlXNHdIaGNOTVRVd09ERXhNRE0xTlRJeQpXaGNOTWpVd09EQTRNRE0xTlRJeVdqQWpNU0V3SHdZRFZRUURFeGhrYjJOclpYSXVhVzh2YkdsaWNtRnllUzlrClpXSnBZVzR3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVE1ZGkxcmxPQjBMQmRNS2N0VFQxYmwKUGd6aXYxOUJDdW9tNEFNL3BUdURtdjBnS0E5S1ptNUVjLy9VQmhSODVCYmR0cTk0cXhQM3IwUjhRc3FQV1Y4SQpvelV3TXpBT0JnTlZIUThCQWY4RUJBTUNBS0F3RXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdNd0RBWURWUjBUCkFRSC9CQUl3QURBS0JnZ3Foa2pPUFFRREFnTklBREJGQWlBOUFOZ3dPN2tBdUVIK3U2N25XNlFLWmlMdWd5UVcKaEQ3Vys5WjIza01mTndJaEFJa3RTaW1TdFdRQkFoOG9WOXhjaWNVWWVUN0pyUG82a0RqeHU1YitGZ3MxCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}},"728c96ff5e9f48d4e66d5a0c3ecabfdd90bee2b5f9f80b950ed9c668db264a70":{"keytype":"ecdsa","keyval":{"private":null,"public":"INVALID/KoZIzj0CAQYIKoZIzj0DAQcDQgAENtpBkDJ2oYaAAVdOkP0A6J0XwUkYGuFRk+q8N4WCPu2VnNIuBJkatPCWdEtHfQ9nNYLeanWgG62/UmJnx3E2Yg=="}},"d48327d85f0490827db7c931eedb58d293e1da5fc425ea0cde3e6c13b397ad69":{"keytype":"ecdsa","keyval":{"private":null,"public":"INVALID/KoZIzj0CAQYIKoZIzj0DAQcDQgAEwfs26T/cpjvNTXVJpK7Wv8oDOnNKL78AT3Y1QD356OIAggwPupX2LQjZU6CVzCjm+pkJIO4clu9Q2n540gKuzQ=="}}},"roles":{"root":{"keyids":["575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84"],"threshold":1},"snapshot":{"keyids":["d48327d85f0490827db7c931eedb58d293e1da5fc425ea0cde3e6c13b397ad69"],"threshold":1},"targets":{"keyids":["5717dcd81d9fb5b73aa15f2d887a6a0de543829ab9b2d411acce9219c2f8ba3a"],"threshold":1},"timestamp":{"keyids":["728c96ff5e9f48d4e66d5a0c3ecabfdd90bee2b5f9f80b950ed9c668db264a70"],"threshold":1}},"version":1},"signatures":[{"keyid":"575d013f89e3cbbb19e0fb06aa33566c22718318e0c9ffb1ab5cc4291e07bf84","method":"ecdsa","sig":"3WbX1VXN9E8LRmSG+E4SQlBUNqBNchhwAStWnRWLLyAOoFNBq5xmIgSO3UYYuKyJvL7kbMoONRbn5Vk2p2Wqrg=="}]}' > /root/.docker/trust/tuf/docker.io/library/debian/metadata/root.json
root@disp2716:~# 
root@disp2716:~# chown root:root /root/.docker/trust/tuf/docker.io/library/debian/metadata/root.json
root@disp2716:~# chmod 0600 /root/.docker/trust/tuf/docker.io/library/debian/metadata/root.json
root@disp2716:~# 

##
# pull the docker image with DCT verification
##

root@disp2716:~# export DOCKER_CONTENT_TRUST=1
root@disp2716:~# docker pull debian:stable-slim
could not validate the path to a trusted root: unable to retrieve valid leaf certificates
root@disp2716:~# 
root@disp2716:~# echo $?
1
root@disp2716:~# 

请注意,docker exits 1 出现错误,拒绝debian:stable-slim从 Docker Hub 拉取 docker 映像,因为它无法信任其签名

于 2021-08-27T19:27:38.927 回答