コンテナー イメージの署名と共同署名ツールによる検証
nerdctl >= 0.15 | |
---|---|
cosign は、コンテナイメージに署名して検証できるツールです。 公開鍵と秘密鍵のペア、または公開鍵を使わないキーレスサポートがあります。
Keylessは、自動的にエフェメラルキーとfulcio ルート CAの証明書を使用します。署名は、署名日の証明を自動的に提供できるRekor Transparency Logに格納されます。
Cosignは、署名
中にプロンプトを使用して以下のステートメントを確認します。Nerdctlは、Cosignコマンドに--yes
を追加して、追加のプロンプトを抑止します。
Cosign による署名で Nerdctl push を使用すると、ユーザーはステートメントに同意したことになります。
この署名された成果物には、個人を特定できる情報が含まれている可能性があることに注意してください。
認証に使用するアカウントに関連付けられたメールアドレスが含まれる場合があります。
情報は成果物に署名するために使用され、公開されている透明性ログに保存され、後で削除することはできません。
「y」と入力すると、この情報を透明性ログに永続的に保存することに同意したことになります。
コンテナーの署名と検証機能は、cosign
を使用して nerdctl
のpush
コマンドとpull
コマンドで有効にできます
内部的には、 コンテナイメージをプッシュする際に--sign
フラグを指定し、 コンテナー イメージをプルする際に--verify
フラグを指定しています。
- cosignの実行可能ファイルが
$PATH
に あることを確認します。- cosign は、次のページからインストールできます https://docs.sigstore.dev/cosign/installation。
環境準備
# Create a sample Dockerfile
$ cat <<EOF | tee Dockerfile.dummy
FROM alpine:latest
CMD [ "echo", "Hello World" ]
EOF
ベースイメージ (この場合は
alpine:latest
) は、ビルドされたコンテナーイメージの検証は行われません。 コンテナー イメージ自体は、署名後にのみ検証します。
# Build the image
$ nerdctl build -t devopps/hello-world -f Dockerfile.dummy .
# Generate a key-pair: cosign.key and cosign.pub
$ cosign generate-key-pair
# Export your COSIGN_PASSWORD to prevent CLI prompting
$ export COSIGN_PASSWORD=$COSIGN_PASSWORD
プッシュ中にコンテナー イメージに署名します。
# Sign the image with Keyless mode
$ nerdctl push --sign=cosign devopps/hello-world
# Sign the image and store the signature in the registry
$ nerdctl push --sign=cosign --cosign-key cosign.key devopps/hello-world
プル中にコンテナー イメージを確認します。
注意:-
-verify
フラグを渡した場合、一致する署名がない場合、イメージはプルされません。注意:v キーレスフローを機能させるには、--cosign-certificate-identity または --cosign-certificate-identity-regexp のいずれかと、--cosign-certificate-oidc-issuer または --cosign-certificate-oidc-issuer-regexp を設定する必要があります。--verify=cosign で有効に扱かわれる、Fulcio 証明書で想定される OIDC 発行者 (例: https://token.actions.githubusercontent.com または https://oauth2.sigstore.dev/auth)。
# Verify the image with Keyless mode
$ nerdctl pull --verify=cosign --certificate-identity=name@example.com --certificate-oidc-issuer=https://accounts.example.com devopps/hello-world
INFO[0004] cosign:
INFO[0004] cosign: [{"critical":{"identity":...}]
docker.io/devopps/nginx-new:latest: resolved |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:0910d404e58dd320c3c0c7ea31bf5fbfe7544b26905c5eccaf87c3af7bcf9b88: done |++++++++++++++++++++++++++++++++++++++|
config-sha256:1de1c4fb5122ac8650e349e018fba189c51300cf8800d619e92e595d6ddda40e: done |++++++++++++++++++++++++++++++++++++++|
elapsed: 1.4 s total: 1.3 Ki (928.0 B/s)
# You can not verify the image if it is not signed
$ nerdctl pull --verify=cosign --cosign-key cosign.pub devopps/hello-world-bad
INFO[0003] cosign: Error: no matching signatures:
INFO[0003] cosign: failed to verify signature
INFO[0003] cosign: main.go:46: error during command execution: no matching signatures:
INFO[0003] cosign: failed to verify signature
Compose で署名
Compose での Cosign のサポートも実験的であり、Compose の拡張機能に基づいて実装されています。
CoSign は、nerdctl compose up|run|push|pull
でサポートされています。Compose yaml に次のフィールドを追加することで、Compose で cosign を使用できます。これらのフィールドは_サービスごと_であり、検証
のみ、署名のみ (
またはその両方) を有効にすることができます。
# 署名/検証するサービスの下にのみ cosign 関連フィールドを配置します。
services:
svc0:
build: .
image: ${REGISTRY}/svc0_image # replace with your registry
#「x-nerdctl-verify」と「x-nerdctl-cosign-public-key」は検証用です
# 'nerdctl compose up|run|pull' に必要
x-nerdctl-verify: cosign
x-nerdctl-cosign-public-key: /path/to/cosign.pub
#「x-nerdctl-sign」と「x-nerdctl-cosign-private-key」は署名用です
#「nerdctl compose push」に必要
x-nerdctl-sign: cosign
x-nerdctl-cosign-private-key: /path/to/cosign.key
ポート:
- 8080:80
svc1:
build: .
image: ${REGISTRY}/svc1_image # replace with your registry
ポート:
- 8081:80
Following the cosign tutorial above, first set up environment and prepare cosign key pair:
# Generate a key-pair: cosign.key and cosign.pub
$ cosign generate-key-pair
# Export your COSIGN_PASSWORD to prevent CLI prompting
$ export COSIGN_PASSWORD=$COSIGN_PASSWORD
We'll use the following Dockerfile
and docker-compose.yaml
:
$ cat Dockerfile
FROM nginx:1.19-alpine
RUN uname -m > /usr/share/nginx/html/index.html
$ cat docker-compose.yml
services:
svc0:
build: .
image: ${REGISTRY}/svc1_image # replace with your registry
x-nerdctl-verify: cosign
x-nerdctl-cosign-public-key: ./cosign.pub
x-nerdctl-sign: cosign
x-nerdctl-cosign-private-key: ./cosign.key
ポート:
- 8080:80
svc1:
build: .
image: ${REGISTRY}/svc1_image # replace with your registry
ポート:
- 8081:80
キーレス モードの場合、docker-compose.yaml
は次のようになります。
$ cat docker-compose.yml
services:
svc0:
build: .
image: ${REGISTRY}/svc1_image # replace with your registry
x-nerdctl-verify: cosign
x-nerdctl-sign: cosign
x-nerdctl-cosign-certificate-identity: name@example.com # or x-nerdctl-cosign-certificate-identity-regexp
x-nerdctl-cosign-certificate-oidc-issuer: https://accounts.example.com # or x-nerdctl-cosign-certificate-oidc-issuer-regexp
ポート:
- 8080:80
svc1:
build: .
image: ${REGISTRY}/svc1_image # replace with your registry
ポート:
- 8081:80
The
env "COSIGN_PASSWORD="$COSIGN_PASSWORD""
part in the below commands is a walkaround to use rootful nerdctl and make the env variable visible to root (in sudo). (1)rootlessを使用している場合、または(2)COSIGN_PASSWORD
がrootに表示される場合は、この部分は必要ありません。
まず、2つのサービスをbuild
してpush
しましょう。
$ sudo nerdctl compose build
INFO[0000] Building image xxxxx/svc0_image
...
INFO[0000] Building image xxxxx/svc1_image
[+] Building 0.2s (6/6) FINISHED
$ sudo env "COSIGN_PASSWORD="$COSIGN_PASSWORD"" nerdctl compose --experimental=true push
INFO[0000] Pushing image xxxxx/svc1_image
...
INFO[0000] Pushing image xxxxx/svc0_image
INFO[0000] pushing as a reduced-platform image (application/vnd.docker.distribution.manifest.v2+json, sha256:4329abc3143b1545835de17e1302c8313a9417798b836022f4c8c8dc8b10a3e9)
INFO[0000] cosign: WARNING: Image reference xxxxx/svc0_image uses a tag, not a digest, to identify the image to sign.
INFO[0000] cosign:
INFO[0000] cosign: This can lead you to sign a different image than the intended one. Please use a
INFO[0000] cosign: digest (example.com/ubuntu@sha256:abc123...) rather than tag
INFO[0000] cosign: (example.com/ubuntu:latest) for the input to cosign. The ability to refer to
INFO[0000] cosign: images by tag will be removed in a future release.
INFO[0000] cosign: Pushing signature to: xxxxx/svc0_image
次に、サービスをpull
してup
できます(run
はupと似ています)。
# ensure built images are removed and pull is performed.
$ sudo nerdctl compose down
$ sudo env "COSIGN_PASSWORD="$COSIGN_PASSWORD"" nerdctl compose --experimental=true pull
$ sudo env "COSIGN_PASSWORD="$COSIGN_PASSWORD"" nerdctl compose --experimental=true up
$ sudo env "COSIGN_PASSWORD="$COSIGN_PASSWORD"" nerdctl compose --experimental=true run svc0 -- echo "hello"
# clean up compose resources.
$ sudo nerdctl compose down
ログをチェックして、svc0 が cosign によって検証され (cosign ログがある)、svc1 が検証されていないことを確認します。また、docker-compose.yaml
の公開キーをランダムな値に変更して、検証の失敗によってコンテナーの pull|up|run
が停止されることを確認することもできます。