概要と環境
今回はbuildahを使って自身のコンテナイメージを暗号化する。
buildahとはコンテナのイメージビルドとレジストリへのプッシュを行うことができるツール(公式GitHub)。今回コンテナイメージの暗号化を行う環境は以下。
※ホストOSであるmac OS
上でUbuntu 22.04
のコンテナを動かし、コンテナ内でbuildah、skopeoを使用している。
OS | mac OS Monterey |
CPU | Apple M1 Pro |
Host OS Container Runtime | Podman 4.1.1 |
Container signing tools | skopeo 1.8.0 |
Container build tools | buildah 1.23.1 |
Encryption Method | 公開鍵暗号方式 |
Container Registry | IBM Cloud Container Registry |
暗号化手順
前提として以下ソフトウェアはインストール済みの想定で進めていく。
- buildah
- skopeo
- openssl
1. 秘密鍵と公開鍵のペアを生成
任意の場所に生成
↓秘密鍵
> openssl genrsa --out private.pem
↓公開鍵
> openssl rsa -in private.pem -pubout -out public.pem
2. コンテナイメージを暗号化してpush
> buildah push --encryption-key jwe:./public.pem jp.icr.io/namespace/sample:encrypted
--encryption-key
オプションにはjwe:{公開鍵のファイルパス}
を指定する
暗号化確認
復号化せずにpullすると怒られることが確認できる
> buildah pull jp.icr.io/namespace/sample:encrypted
Trying to pull jp.icr.io/namespace/sample:encrypted...
Getting image source signatures
Copying blob 56c2ae88d5cb [--------------------------------------] 0.0b / 460.0b
Copying blob 1ab766dfd54a [--------------------------------------] 0.0b / 2.4MiB
Copying blob a41872b65c84 [--------------------------------------] 0.0b / 24.7MiB
Copying blob 760faab46f0d [--------------------------------------] 0.0b / 2.8MiB
Copying blob 5159bf515ee0 [--------------------------------------] 0.0b / 90.4MiB
decrypting layer sha256:760faab46f0d775c1baa956919b59844a08736d108c1a5afc0660ed33aca81eb: missing private key needed for decryption
復号化を行うにはpullコマンドに--decryption-key
オプションを付与する。--decryption-key
オプションには暗号化した公開鍵と対になる秘密鍵のファイルパスを指定する
> buildah pull --decryption-key ./private.pem jp.icr.io/namespace/sample:encrypted
Trying to pull jp.icr.io/namespace/sample:encrypted...
Getting image source signatures
Copying blob 56c2ae88d5cb done
Copying blob 5159bf515ee0 done
Copying blob 760faab46f0d done
Copying blob a41872b65c84 done
Copying blob 1ab766dfd54a [======================================] 2.4MiB / 2.4MiB
Copying config df8ad46840 done
Writing manifest to image destination
Storing signatures
df8ad46840163cb65d63bdf09999cbbfd55f356012f12803448783d99e42bd81
コンテナイメージへの署名と併用するには
コンテナイメージの安全な運用方法の手段として暗号化の他に署名も挙げられる。この署名と暗号化を併用するには 先に暗号化を行う必要がある。 実際の動作を確認していく。
署名→暗号化
1. 非暗号化かつ未署名のコンテナイメージを用意する
> buildah push jp.icr.io/namespace/sample:no-enp
2. 署名を行う
署名にはskopeoを使用する。具体的な手順はこちらの記事を参照
> skopeo copy --sign-by user@domain docker://jp.icr.io/namespace/sample:no-enp docker://jp.icr.io/namespace/sample:no-enp-signed
Getting image source signatures
Copying blob f43264d372e8 skipped: already exists
Copying blob 76fecb13890c skipped: already exists
Copying blob 26adfc839732 skipped: already exists
Copying blob 8ecab674fb13 skipped: already exists
Copying blob d064b39eb698 skipped: already exists
Copying config 52353c9401 done
Writing manifest to image destination
Signing manifest
Storing signatures
3. 署名済みのイメージを暗号化する
まず署名済みのイメージをpullする
> buildah pull jp.icr.io/namespace/sample:no-enp-signed
pullしたイメージを暗号化し再度pushする
> buildah push --encryption-key jwe:./public.pem jp.icr.io/namespace/sample:no-enp-signed
Getting image source signatures
Checking if image destination supports signatures
error pushing image "jp.icr.io/namespace/sample:no-enp-signed" to "docker://jp.icr.io/namespace/sample:no-enp-signed": Copying this image requires changing layer representation, which is not possible (image is signed or the destination specifies a digest)
Copying this image requires changing layer representation, which is not possible (image is signed or the destination specifies a digest)
のように怒られてしまう。
暗号化→署名
先程作成した暗号化コンテナイメージを使用する
1. 署名を行う
skopeo copy --sign-by user@domain docker://jp.icr.io/namespace/sample:encrypted docker://jp.icr.io/namespace/sample:encrypted-signed
Getting image source signatures
Copying blob 760faab46f0d skipped: already exists
Copying blob 1ab766dfd54a skipped: already exists
Copying blob 56c2ae88d5cb skipped: already exists
Copying blob a41872b65c84 skipped: already exists
Copying blob 5159bf515ee0 skipped: already exists
Copying config df8ad46840 done
Writing manifest to image destination
Signing manifest
Storing signatures
こちらは正常に署名が完了する。
余談
イメージpullの際に--remove-signatures
を指定することで一度署名したコンテナイメージの署名を剥がすことができる。
buildah pull --remove-signatures jp.icr.io/namespace/sample:no-enp-signed
上記を行うことで暗号化が可能となる