容器镜像签名

概述

Notary 是一个用于建立内容之间信任的平台。在容器镜像中可以对镜像进行加密签名用来保证镜像件来源和镜像内容防篡改。
软件版本

软件 版本
Harbor 1.10.1
Docker 18.09.9

Harbor打开Notary

Harbor部署时可以选择启用notray,需要Harbor使用Https模式

1
./install --with-notary

部署完后会在harbor中启用
notary-server-photon和notary-signer-photon组件,服务监听4443端口

新建个notary项目配置内容信任,阻止没有签名的镜像下载

上传镜像
默认不启用docker的内容信任参数上传镜像

1
docker push 172.16.1.31/notary/hyperkube:v1.15.5-rancher1

此时在Harbor中看见镜像是未签名状态

因为项目开启了仅允许通过认证的镜像下载,所以未签名的镜像无法pull下来。

docker开启镜像签名

使用以下两个环境变量

1
2
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER="https://172.16.1.31:4443"

DOCKER_CONTENT_TRUST=1:表示开启Docker内容信任模式
DOCKER_CONTENT_TRUST_SERVER:指定认证服务器,其实就是对应harbor notary服务的地址和端口

若Harbor使用自签名证书,则需要将对应的ca证书放置到
主机的~/.docker/tls/172.16.1.31:4443/目录,证书名为ca.crt。

172.16.1.31:443为你的notary节点ip和端口

原理就是使用目录下ca证书进行镜像的签发密钥和验证。

继续push镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
docker push 172.16.1.31/notary/hyperkube:v1.15.5-rancher1
The push refers to repository [172.16.1.31/notary/hyperkube]
2ea80d1d4b24: Layer already exists
3892a0baf222: Layer already exists
39b3ac6d96e9: Layer already exists
7bbae4dddb88: Layer already exists
a00defcfe869: Layer already exists
2ab0ae805c74: Layer already exists
43a8fe7d2382: Layer already exists
3f6a6f542637: Layer already exists
5ba3be777c2d: Layer already exists
v1.15.5-rancher1: digest: sha256:19c919ef37b634919bd08429ee1fde0f3d8ed83c7e75929f7e259ba35f88d9b7 size: 2211
Signing and pushing trust metadata
You are about to create a new root signing key passphrase. This passphrase
will be used to protect the most sensitive key in your signing system. Please
choose a long, complex passphrase and be careful to keep the password and the
key file itself secure and backed up. It is highly recommended that you use a
password manager to generate the passphrase and keep it safe. There will be no
way to recover this key. You can find the key in your config directory.
Enter passphrase for new root key with ID cd80889:

输入密码对镜像进行签名,后续镜像上传都是使用此密码进行镜像签署。
根密钥的密码
在 ~/.docker/trust 目录中生成一个根密钥
镜像签署密钥的密码
在 ~/.docker/trust 目录中生成一个镜像签署密钥

上传成功后在harbor中查看

查看镜像的签名

1
docker trust inspect 172.16.1.31/notary/hyperkube:v1.15.5-rancher1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
docker trust inspect 172.16.1.31/notary/hyperkube:v1.15.5-rancher1
[
{
"Name": "172.16.1.31/notary/hyperkube:v1.15.5-rancher1",
"SignedTags": [
{
"SignedTag": "v1.15.5-rancher1",
"Digest": "19c919ef37b634919bd08429ee1fde0f3d8ed83c7e75929f7e259ba35f88d9b7",
"Signers": [
"Repo Admin"
]
}
],
"Signers": [],
"AdministrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "4d8fcd2d60d87115dff15e43a649ff0c95fa26f7fd9cf1756ce4775c1a0f94c8"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "7254ee1ad59f87b21cd1af6ec847f95a41b84702cd745e8eb9c47abadb5145e5"
}
]
}
]
}
]

镜像拉取

1、若节点docker配置了docker内容信任

1
2
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER="https://172.16.1.31:4443"

拉取镜像需要进行证书签名比对,若harbor使用的是自签名证书,此时需要节点~/.docker/tls/上放置了CA证书

若节点没有配置docker内容信任,则拉取镜像时不需要做签名验证。

2、Harbor项目开启了只允许信任镜像下载,则未签名的镜像无法下载

镜像删除

签名了的镜像无法直接通过Harbor进行删除,需要在notary中将镜像签名去除

1
notary -s https://172.16.1.31:4443 -d ~/.docker/trust --tlscacert /root/.docker/tls/172.16.1.31\:4443/ca.crt remove -p 172.16.1.31/notary/hyperkube v1.15.5-rancher1 signed

注意点:
1、tag和镜像是用空格分开的
2、notary命令可以通过https://github.com/theupdateframework/notary/releases下载