Dockerセキュリティ:Docker Content Trust (DCT) で不正なイメージを遮断する

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

そのダウンロードしたイメージ、本当に安全ですか?

私たちは日々、無意識に docker pull を実行しています。しかし、今ダウンロードした nginx:latestubuntu:22.04 は本当に「クリーン」でしょうか?あるいは、ハッカーによってバックドアが仕込まれ、紛らわしい名前で Docker Hub に公開されたものではないでしょうか?

2年前、あるFintechプロジェクトで50ノードのクラスターを管理していた時のことです。インターン生がテストのために個人リポジトリから誤ってイメージをプルしてしまいました。わずか15分後、監視システムが赤色のアラートを出し続け、サーバーのCPU使用率は隠れて行われていた仮想通貨のマイニングによって100%に達しました。そのミスのおかげで、チーム全員がインフラ全体の調査で2晩徹夜することになりました。

このような惨事を防ぐために、Docker Content Trust (DCT) は必須のソリューションです。これにより、信頼できる送信者によって署名されたイメージのみをシステムで実行できるようになります。

30秒でDCTを有効化する

デフォルトでは、Docker はすべてのイメージに対して制限を設けていません。セキュリティを強化するには、Linux マシンで環境変数を1つ設定するだけです。

ステップ1:一時的にDCTを有効にする

export DOCKER_CONTENT_TRUST=1

ステップ2:効果を確認する

署名されていないイメージ(例:知名度の低い個人のイメージなど)をプルしてみてください:

docker pull bitnami/not-signed-image:latest

Docker は即座にこのコマンドをブロックし、“Error: remote trust data does not exist” というメッセージを表示します。この状態では、library/nginx のような署名済みの公式イメージのみがダウンロード可能になります。

DCTの仕組み

DCTを「デジタル公証人」と考えてください。これは Notary システムを使用して、公開鍵と秘密鍵のペアを管理します。イメージをプッシュすると、Docker は秘密鍵を使用して署名します。他の誰かがプルするとき、Docker は公開鍵を使用してその署名を照合します。

イメージがたとえ1ビットでも改ざんされていれば、署名が一致せず、プル操作は失敗します。特に注意すべき2種類の鍵があります:

  • Root Key: すべての権限を管理する最高位の鍵。この鍵を紛失すると、信頼できるデータに対するすべての制御権を失うことになります。
  • Tagging Key: イメージの各バージョン(タグ)に直接署名するために使用される鍵。

独自のイメージに署名する

企業環境では、Docker Hub のイメージを使うだけでは不十分です。内部の安全性を確保するために、チームでビルドしたイメージにも署名する必要があります。

1. 署名鍵 (Signing Key) の作成

まず、ローカルマシンで鍵ペアを生成します:

docker trust key generate my-signer-key

Docker からパスフレーズの入力を求められます。鍵ファイルは ~/.docker/trust/ に保存されるため、大切に保管してください。

2. リポジトリの署名者を宣言する

リポジトリ myregistry.com/my-app を使用していると仮定します。ユーザーに署名権限を付与します:

docker trust signer add --key my-signer-key.pub my-signer-name myregistry.com/my-app

3. 署名済みイメージをシステムにプッシュする

DOCKER_CONTENT_TRUST=1 が有効な場合、プッシュコマンドには自動的に署名が含まれます:

docker push myregistry.com/my-app:v1.0

今後、DCTを有効にしているすべてのサーバーは、この v1.0 バージョンを完全に信頼するようになります。

本番環境へのDCTの導入

手動で export コマンドを打つのは忘れがちです。プロフェッショナルな運用のために、以下の2つの方法を推奨します:

ユーザーごとの永続的な設定: .bashrc ファイルに export DOCKER_CONTENT_TRUST=1 を追加します。これにより、そのユーザーが行うすべての Docker 操作が常に保護されます。

CI/CD パイプラインへの適用: デプロイスクリプト(GitHub Actions や GitLab CI など)で、ビルドやプッシュの前にこの環境変数を設定します。もし CI/CD サーバーが侵害され、攻撃者がイメージを書き換えようとしても、デプロイプロセスは即座に失敗します。

実戦経験:備えあれば憂いなし

これまでの経験から、Docker Trust を使用する際の3つの重要な注意点を挙げます:

  • Root Key をすぐにバックアップする: 以前、マシンの再インストール時に Root Key を紛失し、古いイメージの署名を更新できなくなったことがあります。~/.docker/trust ディレクトリをオフラインのUSBメモリや安全な Vault に保管してください。
  • レジストリのサポートを確認する: すべてのレジストリが Notary と互換性があるわけではありません。Docker Hub、Harbor、Azure Container Registry (ACR) は現在、良好にサポートしています。
  • ベースイメージの管理: 常に署名済みのイメージから FROM を指定してください。ベースレイヤーが安全でなければ、イメージ全体にリスクが残ります。

まとめ

Docker Content Trust を有効にすると、パスワード入力の手間などでワークフローが数秒遅れるかもしれません。しかし、その代償は、システムがランサムウェアに感染したり、顧客データが流出したりするリスクに比べれば非常に小さいものです。重要なシステムを管理しているなら、今すぐ DCT を有効にしましょう。

Share: