概要と環境
今回はskopeoを使って自身のコンテナイメージへの署名を行う。skopeoとはコンテナイメージやイメージリポジトリに対して様々な操作を実行できるCLIツール(公式GitHub)。今回コンテナイメージへの署名を行う環境は以下。
OS | mac OS Monterey |
CPU | Apple M1 Pro |
Container Runtime | Podman 4.1.1 |
Container signing tools | skopeo 1.8.0 |
Signature Method | PGP Signatures |
PGP Tool | GnuPG 2.3.6 |
Container Registry | IBM Cloud Container Registry |
署名手順
前提として以下ソフトウェアはインストール済みの想定で進めていく。
- Podman
- skopeo
- GnuPG
1. PGPキーペアの作成
> gpg --gen-key
この時メールアドレス、フルネーム、パスワードを要求される。メールアドレスはこの後のキーペア識別のプロセスで使用される。
確認
> gpg --list-keys
gpg: 信用データベースの検査
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: 深さ: 0 有効性: 1 署名: 0 信用: 0-, 0q, 0n, 0m, 0f, 1u
gpg: 次回の信用データベース検査は、2024-06-29です
/Users/username/.gnupg/pubring.kbx
----------------------------------------
pub ed25519 2022-06-30 [SC] [有効期限: 2024-06-29]
****************************************
uid [ 究極 ] username <user@domain>
sub cv25519 2022-06-30 [E] [有効期限: 2024-06-29]
2. コンテナイメージへの署名
> skopeo copy --sign-by user@domain docker://jp.icr.io/namespace/sample:no-signed docker://jp.icr.io/namespace/sample:signed
引数とオプションについて説明する
--sign-by オプション | 署名する際のkey ID。PGPキーペアの作成時のメールアドレスを指定 |
第一引数 | 未署名のコンテナイメージ。既存の未署名コンテナイメージを指定 |
第二引数 | 署名したコンテナイメージ。署名後に保存する場所と名前を指定 |
skopeo copy
コマンドの詳細については公式GitHubを参照
以上でコンテナイメージへの署名ができる。
署名の確認
今回はローカルのPodmanに署名の検証を行う設定を、実際に署名済みのコンテナイメージをpullする。
1. 署名したメールアドレスのキーを配置する
> gpg --output /tmp/key.gpg --armor --export user@domain
2. Podmanのポリシーファイルを変更する
現在実行しているPodmanのmachineにsshする。
> podman machine ssh {machinename}
ssh完了後、ポリシーが記述されているファイルを変更する。
> sudo vi /etc/containers/policy.json
今回はjp.icr.io
ドメインのコンテナレジストリにイメージを保管しているので、jp.icr.io
からPullする際に署名の検証を行うように変更。
keyPath
は配置したキーのパスを指定。(今回はskopeoをホストマシンで動かしているのでpodmanのmachineに対してvoumeをmountしており、そのパスを指定している)
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports": {
"docker": {
"registry.access.redhat.com": [
{
"type": "signedBy",
"keyType": "GPGKeys",
"keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
}
],
"registry.redhat.io": [
{
"type": "signedBy",
"keyType": "GPGKeys",
"keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
}
],
+ "jp.icr.io": [
+ {
+ "type": "signedBy",
+ "keyType": "GPGKeys",
+ "keyPath": "/mnt/Users/Documents/keys/key.gpg"
+ }
+ ]
},
"docker-daemon": {
"": [
{
"type": "insecureAcceptAnything"
}
]
}
}
}
3. 署名したcontainer imageのpull
正しいメールアドレスで署名したコンテナイメージの場合
> podman pull jp.icr.io/namespace/sample:singed
Trying to pull jp.icr.io/namespace/sample:singed...
Getting image source signatures
Checking if image destination supports signatures
Copying blob sha256:b2bba1b0d55c2bc59eff70dab9c3b780df30e642cf9a258abc77685b661b2591
Copying blob sha256:da62b97c2205cc3f43f9f9cb706083bc67f0c3a9ad6f549d926dda4bb7e6c5ee
Copying blob sha256:26a16869ff11ebd2eb902b15ce29e2b9f801e2b88cbfee212c153cdea8eafcfb
Copying blob sha256:25b4cabbd0308d844e766c2b31700653ddc6cb2650d54765374f1ddc2809058c
Copying blob sha256:e96f7b1dd1b96ad97646bbb6388be03e145b40c487eb849039ba8d9b975a575d
Copying blob sha256:2dd1cbe30bcd1a4b890eadbb94d7786961e9b6c84cd969c8db8f6767f127d849
Copying config sha256:8cfcd0fa92f4d4cd287c98ccc89729c7979c95b351e9f6594086ee14f0f93815
Writing manifest to image destination
Storing signatures
8cfcd0fa92f4d4cd287c98ccc89729c7979c95b351e9f6594086ee14f0f93815
間違ったメールアドレスで署名したコンテナイメージや未署名のコンテナイメージの場合
> podman pull jp.icr.io/namespace/sample:no-signed
Trying to pull jp.icr.io/namespace/sample:no-signed...
Error: Source image rejected: Signature for identity jp.icr.io/namespace/sample:singed is not accepted