セキュリティのベストプラクティス

いくつかの手順を経ますと、コンテナのセキュリティを改善できます。手順には以下が含まれます。

  1. 信頼できる場所から 正しいベースイメージの選択 をし、小ささを維持

  2. マルチステージ ビルドを使う

  3. イメージの再構築

  4. イメージの脆弱性を確認するには

正しいベースイメージの選択

安全なイメージを確保するための第一歩は、正しいベースイメージの選択です。イメージを選択するときは、信頼できる場所で構築されたものかを確認し、小ささを維持し続けます。

Docker Hub には 830 万以上のリポジトリがあります。これらのいくつかは 公式イメージ(Official Images) と呼ばれ、Docker のオープンソースと手軽に導入できるソリューションのリポジトリが、 Docker によって選抜された集まりとして公開されているものです。また、 Docker は 認定パブリッシャー(Verified Publishers) によって作成されているイメージも提供しています。これらは高品質なイメージとして公開されており、Docker のパートナー組織によってメンテナンスされ、各リポジトリ内容の信頼性を Docker が検証しています。ベースイメージの選択時には、 Official ImageVerified Publisher バッジを探してください。

Docker Hub 公式イメージ

Dockerfile から自分のイメージを構築するときは、要件に一致する最小のベースイメージを選択します。より小さなベースイメージはポータビリティ(移植性)や素早いダウンロードをもたらさないかもしれませんが、イメージの容量を減らし、依存関係をと通してもたらされる数々の脆弱性を最小化します。

また、2種類のベースイメージを利用するのを検討した方が良いでしょう。1つ目のイメージは開発やユニットテスト用で、2つ目は開発の最終段階やプロダクション用です。開発の後半段階では、コンパイラ、構築システム、あるいはデバッギング・ツールなどの構築ツールが不要になるでしょう。依存関係が最小の小さなイメージにより、攻撃となりうる対象を大幅に減少できます。

マルチステージ ビルドを使う

読みやすく保守しやすいように最適化された Dockerfile を作成するために、マルチステージ ビルド(multi-stage builds) は設計されています。マルチステージ ビルドがあれば、複数のイメージを使って、ある特定のイメージから必要なアーティファクト(成果物)だけを選択してコピーできます。

Dockerfile 内で複数の FROM を記述できるため、 FROM ごとに異なるベースイメージを利用できます。また、あるステージから別のステージにアーティファクトを選んでコピーできるため、最終イメージでは不要なものを除去できます。この結果、最終イメージは簡素にできます。

この手法で作られた小さなイメージは、複雑さを著しく減らすだけではありません。イメージ内に、脆弱性がある部分を組み込む流れも変わります。つまり、あるイメージから構築されたイメージを元にして、更にイメージを構築するという方法にかわり、マルチステージビルドであればベースイメージ上の脆弱性を継承することなく、必要なアーティファクトを選択して取り込めます。

マルチステージビルドの設定方法についての詳しい情報は マルチステージビルド を御覧ください。

イメージの再構築

Docker イメージは Dockerfile から構築します。Dockerfile に含まれるのは命令の集まりであり、これにより、通常の(手動で)イメージを作成する手順を自動化できるようになります。さらに、ライブラリの組み込みや、任意のソフトウェアのインストールが可能になります。これらが Dockerfile 内での命令として表されます。

自分用に構築するイメージとは、対象となるイメージの、該当時点におけるスナップショットです。タグを使わないベースイメージに依存する場合は、再構築時に毎回異なるベースイメージを入手します。また、パッケージのインストーラを使ってパッケージをインストールする場合は、再構築によってイメージが大幅に変わる可能性があります。例えば、以下にある内容の Dockerfile では、毎回再構築するたびに異なるバイナリを得る可能性があります。

# syntax=docker/dockerfile:1
FROM ubuntu:latest
RUN apt-get -y update && apt-get install -y python

対応された既知の脆弱性を防ぐため、定期的な Docker イメージの再構築を推奨します。再構築時には、確実に新しいものをダウンロードし、キャッシュの適用を無効化するために --no-cache オプションを使います。

例:

$ docker build --no-cache -t myImage:myTag myPath/

イメージの再構築時、以下のベストプラクティスに従うのを考えます。

  • 各コンテナは、1つの役割のみ持たせるべき。

  • コンテナはイミュータブル(不変)、軽量、速くあるべき。

  • コンテナ内にデータを保管しない。代わりに共有データストアを使う。

  • コンテナは簡単に破棄と再構築できるべき。

  • (Alpine Linux のような)小さなベースイメージを使う。小さなイメージは配布も簡単。

  • 不要なパッケージのインストールを避ける。これにより、イメージをクリーンかつ安全に保つ。

  • 構築時はキャッシュのヒットを避ける。

  • 脆弱性のあるコンテナをプロダクションに送信するのを避けるため、デプロイ前にイメージの自動スキャンをする。

  • 開発中とプロダクションの両方で、日々イメージの脆弱性を分析する。その上で、必要があればイメージ再構築を自動化する。

効率的なイメージの構築関するベストプラクティスや手法の詳細は Dockerfile ベストプラクティス を御覧ください。

イメージの脆弱性を確認するには

このページでこれまで取り上げたイメージ構築のベストプラクティスに加え、脆弱性検出ツールを使い、イメージのセキュリティ状況の継続的な分析と評価も重要です。

Docker ツールには、イメージの構築や使用にあたり、日々脆弱性について更新し続けるために役立つ機能があります。

  • Docker Hub は自動的な 脆弱性スキャン 機能をサポートしています。これを有効にすると、Docker Hub リポジトリへイメージの送信時に自動的にスキャンします。 Docker サブスクリプション が必要です。

  • 早期アクセスの 高度なイメージ解析(advanced image analysis) 機能もサポートしています。これは「コア」となる脆弱性検査ソリューションを拡張したもので、能力の拡張や、より詳しく実用的な洞察を行います。

  • CLI 用としては docker scout CLI プラグイン があります。これはターミナルを使ってイメージの脆弱性を探せます。

  • Docker Desktop はローカルに保存しているイメージの詳細を表示し、既知の脆弱性による影響をうけるイメージ情報を視覚的に全て表示します。

これらの機能はすべて Docker Scout(ドッカー スカウト) の技術を備えています。これら機能により、セキュリティに関する供給網(サプライチェーン)の全体像を表示するのに役立つでしょう。また、各脆弱性に対応できるようにするため、対処可能な提案も提供します。

まとめ

安全なイメージの構築とは、継続的なプロセスです。このガイドにおける推奨やベストプラクティスを、計画、効率的な構築、スケーラブル、安全なイメージのために検討ください。

このガイドで扱った話題を要約すると:

  • 信頼できるベースイメージから始めます。ベースイメージの選択時、公式イメージ(Official image)と認定パブリッシャー(Verified Publisher)バッジに注目します。

  • コードと依存関係を安全に保ちます。

  • 最小限必要なパッケージがある最小のベースイメージのみ選択します。

  • イメージを最適化するため、マルチステージビルドを使います。

  • イメージにツールや依存関係を追加するときは、確実に注意深く観察・管理します。

  • イメージに対する脆弱性を定期的に確認します。

参考

Security best practices | Docker Documentation

https://docs.docker.com/develop/security-best-practices/