fbpx

コンテナイメージを一意に識別するための課題 #aqua #コンテナ #セキュリティ

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

本ブログは「Aqua Security」社の技術ブログで2021年4月22日に公開された「 The Challenges of Uniquely Identifying Your Images 」の日本語翻訳です。

コンテナイメージを一意に識別するための課題


コンテナセキュリティの課題の1つは、ダウンロードしたコンテナイメージが期待通りのものであることを確認することです。セキュリティと一貫性の観点から、期待通りのイメージがダウンロードされることの保証が重要です。Docker のイメージタグは便利ですが、常に一貫した特定のイメージを指すとは限らないので、一般的なアドバイスとしては、SHA-256 ハッシュを使ってイメージを識別することです。しかし、それは思ったほど容易ではありません。

Docker Hubとローカルのハッシュを比較

Docker Hub でサンプルイメージを見てみると、一見容易な作業であるように思えます。例として、人気の高い Jenkins/Jenkins イメージの「centos7」タグをたどると、以下のように表示されます。

そして、そこにはハッシュ(8d28034275002fb438766e90b95e9c0f99a7568b8c56459c1ba25045ed63ce)が表示されており、これを使って特定のコンテナイメージを引き出すことができます。

以下はコンテナイメージをダウンロードした際に出力されるハッシュの例です。

docker pull jenkins/jenkins@sha256:8d28034275002fb438766e90b95e9c0f99a7568b8c5645949c1ba25045ed63ce

どこに問題があるのかが見えてきました。例えば、Docker インストールでローカルに取得したイメージが、Docker Hub で確認したものと同じかどうかを確認したいとします。論理的には、ハッシュが取得したものと同じであることを確認することになります。しかし、出力されるのは次のようなものです。

docker images jenkins/jenkins

REPOSITORY       TAG       IMAGE ID       CREATED     SIZE

jenkins/jenkins   <none>   bac2f5fed373   6 days ago   693MB

イメージ ID を見ると、取り出した ID とは全く違うことがわかります。また、Docker Hub のイメージハッシュを使ってコンテナを起動しようとすると、それもうまくいかないことがわかります。

docker run -it 8d28034275002fb438766e90b95e9c0f99a7568b8c5645949c1ba25045ed63ce /bin/sh

docker: Error response from daemon: No such image: sha256:8d28034275002fb438766e90b95e9c0f99a7568b8c5645949c1ba25045ed63ce

その舞台裏

では、なぜこのような食い違いが生じるのでしょうか。コンテナの世界では(多くの世界がそうであるように)、答えを探すのに最適な場所はおそらく GitHub issue です。この Docker Hub issue には、Docker Hub に表示されるハッシュとローカルに表示されるハッシュとの不一致についての歴史が記載されています。この post about local images ID not matching registry manifest digest には、Docker 側の考えをもう少し詳しく説明しています。

この問題の本質は、Docker レジストリで使用されるハッシュがマニフェストダイジェストであり、これがローカルのイメージ ID ダイジェストと同じ情報で動作していないため、両者が一致しないということです。

ローカルイメージ ID がどこから来ているかは、サンプルイメージの内容を見ればわかります。

このコマンドを使って、確認したい特定のイメージ ID の tar ファイルを作成できます。

docker save bac2f5fed373 -o jenkins.tar

ファイルのリストを見ると、bac2f5fed3730d7c6857f47f773e52ac3bada754e2a769f1c088c92e04015a4d.json というファイルがあり、これはイメージ ID の完全な SHA-256 ハッシュです。やや自己言及的なスタイルですが、このファイル名は実際はファイル内容のハッシュであり、sha256sum コマンドで確認できます。

sha256sum bac2f5fed3730d7c6857f47f773e52ac3bada754e2a769f1c088c92e04015a4d.json

bac2f5fed3730d7c6857f47f773e52ac3bada754e2a769f1c088c92e04015a4d bac2f5fed3730d7c6857f47f773e52ac3bada754e2a769f1c088c92e04015a4d.json

課題への対応

さて、問題がわかったところでどうすればいいのでしょうか。実践的なレベルでは、ローカルの Docker イメージをチェックしてレジストリハッシュを確認する方法があります。以下のコマンドを実行します。

docker inspect [IMAGE_NAME] --format=''

上記のように入力すると、そのイメージ ID に対応するリポジトリのハッシュが返されます。

このアプローチは便利な手法ではありますが、一般的にイメージ ID をチェックするだけでは、イメージの整合性や出所を管理する理想的な方法ではありません。なぜならイメージが作成された後、ローカルの Docker インスタンスへ最初に pull する前に、イメージが改ざんされるリスクに対処できないからです。そのためには、別のアプローチが必要です。

イメージ署名

コンテナイメージに暗号化された署名をつけることは、イメージの証明と完全性を証明するという問題に対処するための、高いレベルでの優れたアプローチです。Notary による Docker イメージの署名は以前からサポートされていましたが、実装の容易さや一般的なデプロイメントシナリオでの使用に課題があったため、その普及はかなり限定的でした。そのため、Notary バージョン 2 のプロジェクトが開始され、最初のプロジェクトから学んだことを考慮したアプローチで新しいバージョンを提供することになりました。

また、この問題に対処するための有用なオプションとして、急速に発展している新しいイメージ署名ツールもあります。cosign プロジェクト(sigstore イニシアチブの一環)は、コンテナイメージやその他のアーティファクトへ署名するために使用されています。このプロジェクトはまだ始まったばかりですが、使いやすい署名ツールを提供しており、一般的なコンテナイメージレジストリにも対応しています。

まとめ


イメージハッシュは、コンテナランタイムの便利な機能であり、イメージを一意に識別するのに役立ちますが、使用する際にはいくつかの微妙な違いに注意する必要があります。イメージの出所を強力に管理する必要がある場合は、コンテナイメージの署名がお勧めです。また、Aqua を利用しているのであれば、イメージフィンガープリントと開発から本番への整合性保証が製品に組み込まれています。

New call-to-action

新規CTA