7 セキュリティに関する推奨事項
セキュリティに関する推奨事項とガイドラインに従って、インフラストラクチャとコンテナ化されたアプリケーションが安全であることを確認します。ここで提供する情報に加えて、https://docs.docker.com/engine/security/で提供されているようなアップストリームのセキュリティのガイドラインも確認することをお薦めします。
Dockerコンポーネントのベスト・プラクティス
重要となるのは、悪用を減らすために環境のインフラストラクチャ内のすべてのレベルでセキュリティ・ガイドラインに従うことです。環境内で使用されるコンポーネントごとにベスト・プラクティス・ガイドラインに従う必要があります。
コンテナ化では、同じホスト上で実行されているアプリケーション間でリソースを分離できますが、分離が完了していないと、コンテナから切り離されたり、同じホストで実行されている他のコンテナに影響を与えるような方法でコンテナが悪用される可能性があります。組織内に様々なテナンシがある場合や、様々な顧客が同じインフラストラクチャを使用している場合は、より完全な分離を実現し、重大なデータ侵害の発生を防ぐために、様々なホストまたは様々な仮想マシンでコンテナを実行することが不可欠です。
ホスト
-
ホスト・カーネルとオペレーティング・システム・ソフトウェアの定期的な更新
問題が解決されると、Oracleはカーネルとオペレーティング・システム・ソフトウェアのセキュリティ・パッチとバグ修正を定期的にリリースします。最新のソフトウェア更新でオペレーティング・システムを最新の状態に保つことをお薦めします。システムで最新のソフトウェア・チャネルまたはリポジトリをサブスクライブし、通常のyum更新操作を実行します。また、Kspliceを使用してシステム・ソフトウェアを最新の状態に保つことを検討してください。
-
最小限のオペレーティング・システムを使用しセキュリティのベスト・プラクティスに従っていることの確認
可能な場合は、最小限のオペレーティング・システム・インストールを使用し、Oracle Linux 7: セキュリティ・ガイドで説明されているセキュリティのベスト・プラクティスに従っていることを確認します。最も重要なことは、同じシステムで実行されているサービスの数を減らすことです。理想的には、常駐する他のすべてのサービスをDockerが管理するコンテナ内に移動するか、完全に他のシステムに移動します。これは、コンテナが破損した場合に損害を抑えるのに役立ちます。
-
オペレーティング・システムとカーネルの安全性の定期的な精査
安全性と潜在的な脆弱性についてオペレーティング・システムを定期的に精査することを怠らないでください。
-
最適なセキュリティ機能セットを提供する成熟したカーネルの使用
Oracleでは、UEK R5以降とOracle Container Runtime for Dockerを併用する必要があります。これにより、カーネル・ネームスペース、プライベート・ネットワーク、コントロール・グループなどのカーネルベースの機能が、厳しいテストを受けた信頼性の高い成熟したものになります。LXC (Linux Containers)など他のツールや機能をサポートするためにはDockerに必要なカーネル機能のいずれも等しく必要であるため、必要なカーネル機能はすべて、サポートされているUEKリリース内で定期的にテストされます。
Dockerエンジン
-
Dockerエンジンを使用してコンテナを作成および管理できるユーザーの制限
通常、Dockerエンジンはホスト・システム上で、root権限で実行されます。したがって、システムで新規にコンテナを作成できるユーザーや、Docker Engineにアクセスしてコンテナを開始できるユーザーを制限する必要があります。イメージのロードやプルなどの一部の操作は、他の入力によって悪用される可能性があります。Docker Engineを使用してアクションを実行するためのアクセス権を持つユーザーはすべて信頼できるユーザーにしてください。
-
Dockerエンジン・ソフトウェアの定期的な更新
オペレーティング・システム上のすべてのソフトウェアと同様に、最新のセキュリティ・パッチが適用されたバイナリを確実に実行するには、定期的な更新が重要です。
-
現在の推奨ドライバの使用
レガシーのLXCドライバは使用しないでください。本番環境ではbtrfsベースの記憶域を使用することをお薦めします。OverlayFSはテスト目的で使用できますが、まだ未成熟の部分があるため、開発者は既知の問題があることに注意してください。デフォルトのデバイス・マッパー・オプションは、非常に低速でコンテナ内の領域が不足する可能性があるため、お薦めしません。
-
Dockerエンジンのクライアント・ポートの最小化
可能な場合は、単一のデフォルトUNIXソケット・ポートだけを使用して、Dockerデーモンを実行します。他のソケットを使用する必要がある場合は、TLS用に構成します。
-
Dockerコンテナとイメージ用の十分なストレージ容量の確保
Dockerでは、コンテナとイメージ・データがディレクトリ(デフォルトでは
/var/lib/docker
)に格納されます。この容量がすぐにいっぱいになることがあるので、Docker、コンテナおよびDockerホストのサービス拒否を防ぐために、十分なストレージ容量を確保してください。Dockerファイルを格納するための別個のパーティション(論理ボリューム)を作成します。
-
Dockerサービスと構成ファイルの保護
サービスと構成ファイルに適切な権限と所有権を設定して、不正アクセスを防止します。通常、デフォルト値は適切ですが、次のガイドラインが実行および監査に役立ちます。
次のDocker Engineシステム・ファイルにセキュアな権限が設定されていることを確認します(所有者/グループは
root:root
で、権限は644以上に制限されています)。-
/usr/lib/systemd/system/docker.service
-
/usr/lib/systemd/system/docker-registry.service
-
/usr/lib/systemd/system/docker.socket
-
/etc/sysconfig/docker
-
/etc/default/docker
-
/etc/sysconfig/docker-network
-
/etc/sysconfig/docker-registry
-
/etc/sysconfig/docker-storage
次のDocker Engineシステム・ファイルにセキュアな権限が設定されていることを確認します(所有者/グループは
root:root
で、権限は755以上に制限されています)。-
/etc/docker
次のDocker Engineシステム・ファイルにセキュアな権限が設定されていることを確認します(所有者/グループは
root:root
で、権限は444以上に制限されています)。-
/etc/docker/certs.d/<registry-name>/*
-
TLS CA証明書ファイル(
--tlscacert
パラメータで指定されたファイル) -
Dockerサーバー証明書ファイル(
--tlscert
パラメータで指定されたファイル)
次のDocker Engineシステム・ファイルにセキュアな権限が設定されていることを確認します(所有者/グループは
root:root
で、権限は400以上に制限されています)。-
Dockerサーバー証明書キー・ファイル(
--tlskey
パラメータで指定されたファイル)
次のDocker Engineシステム・ファイルにセキュアな権限が設定されていることを確認します(所有者/グループは
root:docker
で、権限は460以上に制限されています)。-
/var/run/docker.sock
-
-
Dockerシステム・ファイルの監視および監査
auditdなどのシステム・ロギング機能を使用し、すべてのDockerエンジン・アクティビティを監査します。サービス・ロギング・レベルはinfo (デフォルト)にする必要があります。監査ログの容量が大きくなっても十分な記憶域が使用可能であることを確認します。次のファイルおよびディレクトリをモニターします。
-
/var/lib/docker
-
/etc/docker
-
/usr/lib/systemd/system/docker-registry.service
-
/usr/lib/systemd/system/docker.service
-
/var/run/docker.sock
-
/etc/sysconfig/docker
-
/etc/sysconfig/docker-network
-
/etc/sysconfig/docker-registry
-
/etc/sysconfig/docker-storage
-
/etc/default/docker
-
Dockerイメージ
-
イメージが検証済の信頼できるソースから得られることの確認
Dockerイメージが、信頼できるレピュテーションがあり認証されたソースから受信され、未変更のままデプロイされることを確認します。
リモート・ソースからイメージをプルする場合は、接続が保護されており、プル・リクエストにHTTPSを使用していることを確認してください。セキュアでなく、TLSで保護されていないイメージ・レジストリは使用しないでください。
理想的には、タグではなく事前検証済ハッシュによってイメージをプルし、可能であれば、これらのイメージをエクスポートして、よりセキュアなメディア・サーバーに独自の制御の下でホストしてください。
可能な場合は、Dockerイメージは厳選された信頼できるイメージ・サプライヤの集まりを生成元とし、ベースにする必要があります。
-
確実に再現可能なイメージの作成
Dockerfilesを使用して新しいイメージを構築する場合は、セキュリティのためにベース・イメージとインストール済ソフトウェアを確認します。セキュリティの脆弱性を正確に確認したベース・イメージとソフトウェアが新しいイメージで使用されるようにするには、次のようにします。
-
イメージDockerfileのベース・イメージに固定バージョンを指定します。
-
イメージDockerfileのビルド・ステップでパッケージのプルに固定バージョンを指定します(依存性の依存関係は依然として信頼性の問題である可能性があることに注意してください)。
-
ビルド・ステップでのパッケージのプルに信頼できる検証済のソースが使用されていることを確認します
-
-
イメージにインストール済のパッケージの最小化
新しいイメージ・ビルドには不要なパッケージをインストールしないでください。Dockerfileをレビューして、不要なインストール・ステップを削除し、イメージが機能に制限されるようにします。
-
Linuxセキュリティ・モジュールの使用
イメージ内では、可能なかぎり適切なセキュリティ・モジュールを使用します。
-
Red HatディストリビューションでSELinuxを実行します
-
DebianおよびUbuntuディストリビューションでAppArmorを実行します
-
-
イメージの定期的な更新
コンテナを定期的にスキャンして、古いソフトウェアやパッチが適用されていないソフトウェアを検出する必要があります。コンテナは不変である必要があるため、ソフトウェアにパッチを適用できません。かわりに、新しくビルドしたイメージに置き換える必要があります。サードパーティ・イメージの更新に依存しているものの待っていることができない場合は、パッチを適用した独自の新しいイメージを展開することを検討してください。
ベンダーは、現在の開発ストリームに焦点を当てる傾向があります。コンテナとイメージにパッチを適用するかわりに、イメージを最初から再ビルドし、新しいビルドから新しいコンテナをインスタンス化します。
Dockerコンテナ
-
root以外のユーザーでのコンテナの実行
特に指定がないかぎり、Dockerは各コンテナをrootとして実行します。UIDがホスト間で共有されるため、コンテナ内のrootユーザーはホスト上のrootユーザーです。可能な場合は、
--user
フラグを使用して、コンテナがroot以外のユーザーとして起動されるようにします。コンテナを起動して現在のユーザーとして実行するには、idコマンドを使用します。たとえば、コンテナの起動時に--user $(id -u):$(id -g)
を使用します。 -
コンテナ・メモリーとCPU使用率の制限
メモリーおよびスワップ・メモリーに
-m
および--memory-swap
オプションを使用し、CPUに-c
オプションを使用して、コンテナ・メモリーとCPU境界が制限されたコンテナを作成し、起動します。 -
コンテナの再起動の制限
制御できないコンテナに起因する潜在的なサービス拒否を防ぐには、コンテナの作成時または起動時に、
--restart=on-failure:N
オプションを使用してコンテナの再起動を制限します。 -
コンテナのリソース使用率の監視
Dockerはメモリー消費量、CPU時間、I/O、ネットワーク使用率などのコンテナ・リソースの使用状況を監視する機能を備えています。コンテナのリソース使用率を調べてパフォーマンス、エラー検出および異常な動作を確認します。リソースの使用、疑わしいトラフィック、予期しないユーザー・アクティビティなど、異常なアクティビティがないかリアルタイムにリソース使用状況をモニターできるツールの使用を検討してください。
-
コンテナ・ファイル・アクセスの制限
コンテナの作成および起動時には、
--read-only
フラグまたは-v <host dir>:<container dir>:ro
オプションを使用して、コンテナ・ファイル・アクセスを制限します。コンテナ・アプリケーションが書き込むためのボリュームを明示的に作成し、これらのボリューム内のファイルへの変更をモニターします。コンテナの書込みアクセス専用のボリュームにスプロールがないか確認し、定期的にクリーン・アップするようにします。コンテナ実行時に機密のホスト・システム・ディレクトリをマウントしないでください。
-
/
-
/boot
-
/dev
-
/etc
-
/lib
-
/proc
-
/sys
-
/usr
-
-
コンテナの安全性の定期的な確認
コンテナの安全性チェックの自動化や、コンテナ内の変更の監視に役立つツールの使用を検討してください。たとえば、Docker Bench for Security (CIS)とDocker Diffはこの目的に役立ちます。詳細は、https://github.com/docker/docker-bench-securityおよびhttps://docs.docker.com/engine/reference/commandline/diff/を参照してください。
ホスト・システムから不要なイメージやコンテナを体系的に削除して、イメージやコンテナのスプロールを回避し、セキュリティ精査を回避する可能性がある古い未使用のイメージやコンテナが誤って使用されるのを防ぎます。
-
コンテナ内のカーネル機能の制限
コンテナの作成および起動時には、
--cap-add
および--cap-drop
オプションを使用して、カーネル機能を制限します。これらのオプションのいずれかの値をall
に設定できることに注意してください。コンテナ化されたアプリケーションに必要な最小限のカーネル機能セットを適用してください。デフォルトでは、次のカーネル機能がコンテナに付与されます。
-
CHOWN
-
DAC_OVERRIDE
-
FSETID
-
FOWNER
-
MKNOD
-
NET_RAW
-
SETGID
-
SETUID
-
SETFCAP
-
SETPCAP
-
NET_BIND_SERVICE
-
SYS_CHROOT
-
KILL
-
AUDIT_WRITE
.
デフォルトでは、次の重要なカーネル機能がコンテナから削除されます。
-
SYS_TIME
-
NET_ADMIN
-
SYS_MODULE
-
SYS_NICE
-
SYS_ADMIN
コンテナの起動時に
--privileged
オプションを使用しないでください。 -
-
コンテナ内のカーネル・ファイル・ハンドルとプロセス・リソースの制限
コンテナの作成および起動時には、
--ulimit
オプションを使用してカーネル・リソースを制限するか、Dockerサービスの起動時に--default-ulimit
を使用してコンテナのデフォルトを設定します。 -
コンテナ・ネットワーキングの制限
コンテナがまったく通信する必要がない場合は、Dockerエンジンの起動時に
--icc=false
オプションを使用して、コンテナ・ネットワークを完全に制限します。コンテナ間通信を無効にすると、コンテナ間ではネットワーク・トラフィックが許可されませんが、引き続きホストにポートを公開できます。ホストにポートを公開する場合は、コンテナがリスニングするネットワーク・インタフェースに攻撃サーフェスが縮小されるように、ポートにバインドするインタフェースのIPアドレスを指定します。
-p
または--publish
オプションの使用時にIPアドレスを指定しないと、Dockerはデフォルトですべてのインタフェース(0.0.0.0)に公開されます。コンテナ内でSSHを実行しないでください。
コンテナ内で特権ポート(1024未満)をマップしないでください。
コンテナの起動時または実行時に、コンテナに
--net=host
モード・オプションを使用しないでください。 -
ホスト・ネームスペースとコンテナの共有の禁止
コンテナの起動時または実行時に、PIDやIPCネームスペースなどのホスト・ネームスペースを共有しないでください。
-
コンテナへのホスト・デバイスの公開の禁止
コンテナの起動時または実行時に、ホスト・デバイスをコンテナに公開しないでください。
コンテナ化されたアプリケーション
-
コンテナ化されたアプリケーション内でのカーネル・コールの最小化
カーネルはコンテナ間で共有されるため、カーネル・コールはホスト・システム上で実行されている他のコンテナに対するリスクを増大させます。コンテナ化されたアプライアンス内では可能なかぎりカーネル・コールを回避します。
-
root以外のユーザーでのコンテナ・アプリケーションの実行
特に指定がないかぎり、Dockerは各コンテナをrootとして実行します。コンテナ化されたアプリケーションがroot以外のユーザーとして実行されるようにします。UIDがホスト間で共有されるため、コンテナ内のrootユーザーはホスト上のrootユーザーです。
ユーザーを変更する必要がある場合は、sudoではなくgosuの使用を検討してください。sudoでは2つのプロセスが作成されますが、gosuでは単一のプロセスが作成されるためです。これにより、コンテナ信号が転送される際の問題を回避できます。詳細は、https://github.com/tianon/gosuを参照してください。
-
コンテナ化されたアプリケーションでのsetuidおよびsetgidの使用の削除または最小化
ほとんどのアプリケーションにsetuidバイナリやsetgidバイナリは必要ありません。できれば、そのようなバイナリは無効にするか削除してください。そうすることで、権限エスカレーション攻撃に使用される可能性がなくなります。setuidまたはsetgid権限フラグを持つバイナリを検出した場合は、それらを完全に削除するか、権限フラグを削除して、バイナリ上のこれらの権限に関連付けられているリスクを排除します。
-
コンテナ化されたアプリケーションを非永続的なものにする設計
可能なかぎり、アプリケーションはステートレスでロール可能、可能であれば即時移行できるマイクロサービス・コンテナ・アプリケーションになるように設計します。自身の設計でないアプリケーションを使用する場合は、コンテナ内で実行するソフトウェアを選択する際に、このアプローチを考慮してください。この品質を保つと、システムの侵害や不慮の事態が発生している間やその後にサービスを管理する場合に役立ちます。