Kubernetes などのコンテナーとオーケストレーターは、マイクロサービス アーキテクチャと継続的な開発と配信をサポートする、アプリケーション開発手法の新時代の到来をもたらします。最新の State of Containers and Kubernetes Security Report によると、Docker は圧倒的に支配的なコンテナ ランタイム エンジンであり、普及率は 91% です。
コンテナ化には多くの利点があるため、広く採用されています。Gartner によると、2020 年までに世界の組織の 50% 以上が実稼働環境でコンテナ化されたアプリケーションを実行するようになるでしょう。ただし、Docker コンテナを使用してアプリケーションを構築すると、セキュリティに関する新たな課題とリスクも生じます。単一の Docker コンテナが侵害されると、基盤となるホストだけでなく他のすべてのコンテナも脅威にさらされる可能性があり、Docker セキュリティの重要性が強調されています。
Docker のセキュリティ保護は、コンテナーのリークがホストのリークにつながらないようにホストを保護して強化することと、Docker コンテナーを保護することの 2 つの側面に大別できます。この記事ではコンテナのセキュリティに焦点を当て、Docker コンテナのセキュリティのリスクと課題に焦点を当て、ビルドおよびデプロイのフェーズで環境を強化し、実行時に Docker コンテナを保護するためのベスト プラクティスを提供します。
Kubernetes の広範な導入とコンテナのオーケストレーションにおける重要な役割を考慮して、Kubernetes をセキュリティで保護するためのベスト プラクティスも共有します。最後に、コンテナ セキュリティ プラットフォームが回答できるべき 11 の重要なセキュリティの質問を示し、本番環境でコンテナと Kubernetes を安全に実行するために必要な洞察と保護を提供します。
Docker が解決しなければならないコンテナ セキュリティの 8 つの課題
企業は長い間、アプリケーションを仮想マシン (VM) またはベア メタル サーバーに展開してきました。このタイプのインフラストラクチャのセキュリティには、アプリケーションとそれが実行されるホストを保護し、アプリケーションの実行中にそれらを保護することが含まれます。コンテナ化により、対処する必要がある新たな課題が生じます。
-
コンテナーによりマイクロサービスが可能になり、データ トラフィックだけでなくネットワークやアクセス制御も複雑になります。
-
コンテナーは基本イメージに依存しているため、イメージのソースが安全かどうかを判断するのは困難な場合があります。イメージには、そのイメージを使用するすべてのコンテナに伝播される可能性のある脆弱性が含まれる場合もあります。
-
コンテナーのライフサイクルは短いため、特に実行中のコンテナーの監視は困難な場合があります。もう 1 つのセキュリティ リスクは、変化するコンテナ環境の可視性の欠如によって発生します。
-
VM とは異なり、コンテナーは必ずしも相互に分離されているわけではありません。1 つの規格外の容器が他の容器に損傷を与える可能性があります。
-
コンテナ化された環境には、Kubernetes などの従来の VM よりも多くのコンポーネントがあり、独自のセキュリティ課題が存在します。どの展開またはクラスターが重大度の高い脆弱性の影響を受けるかわかりますか? インターネットに公開されましたか? 特定の脆弱性が悪用された場合、爆発範囲はどれくらいですか? コンテナは実稼働環境で実行されていますか? それとも開発/テスト環境で実行されていますか?
-
コンテナの構成もセキュリティ リスクを引き起こす領域です。コンテナは必要以上に高い権限で実行されていますか? イメージは攻撃対象領域を増やす不要なサービスを起動しますか? 画像には秘密が保存されていますか?
-
最大のセキュリティ推進要因の 1 つであるコンプライアンスは、コンテナ環境の急速な成長を考慮すると特別な課題となる可能性があります。ファイアウォール ルールなど、コンプライアンスの実証に役立つ多くの従来のコンポーネントは、Docker 環境ではまったく異なる形式になります。
-
最後に、既存のサーバー ワークロード セキュリティ ソリューションでは、コンテナのセキュリティの課題やリスクに対処するには不十分です。
26 Docker セキュリティのベスト プラクティス
以下は、Docker コンテナとイメージを安全に構成するための業界標準と StackRox 顧客によるベスト プラクティスのリストです。
-
常に最新バージョンの Docker を使用してください。たとえば、今年初めの runC の脆弱性は、Docker バージョン 18.09.2 のリリース後すぐにパッチされました。
-
信頼できるユーザーのみが Docker グループのメンバーであることを確認して、信頼できるユーザーのみが Docker デーモンの制御を許可されるようにします。Docker デーモンの攻撃対象領域を減らす方法について詳しくは、この記事をご覧ください。
-
適切なルールが監査証跡を提供できることを確認します。
-
ドッカーデーモン
-
Docker ファイルとディレクトリ:
-
/var/lib/docker
-
/etc/docker
-
Docker.service
-
Docker.ソケット
-
/etc/default/docker
-
/etc/docker/daemon.json
-
/etc/sysconfig/docker
-
/usr/bin/containerd
-
/usr/sbin/runc
-
-
-
すべての Docker ファイルとディレクトリを適切なユーザー (通常は root) が所有し、ファイルのアクセス許可が制限された値に設定されていることを確認して、それらを保護します (Docker デーモン構成ファイルの「CIS ベースライン」セクションを参照)。
-
有効なレジストリ証明書を持つレジストリ、または TLS を使用するレジストリを使用して、トラフィック傍受のリスクを最小限に抑えます。
-
イメージ内で明示的なコンテナ ユーザーが定義されていないコンテナを使用している場合は、ユーザー名前空間のサポートを有効にする必要があります。これにより、コンテナ ユーザーをホスト ユーザーに再マップできるようになります。
-
コンテナーによる新しいアクセス許可の取得を無効にします (デフォルトでは、コンテナーは新しいアクセス許可を取得できます)。そのため、この構成は明示的に設定する必要があります。権限昇格攻撃を軽減するために実行できるもう 1 つの手順は、イメージから setuid および setgid 権限を削除することです。
-
ベスト プラクティスとして、コンテナーは非 root ユーザー (0 以外の UID) として実行する必要があります。(デフォルトでは、コンテナはコンテナ内で root として実行されます。)
-
コンテナーを構築するときは、信頼できる基本イメージのみを使用してください。このヒントは明白に思えるかもしれませんが、多くの場合、サードパーティのレジストリには、そこに保存されているイメージに対するガバナンス ポリシーがありません。Docker ホストでどのイメージが使用できるかを知り、それらがどこから来たのかを理解し、その中に何が入っているかを確認することが重要です。また、イメージ検証のために Docker のコンテンツ信頼を有効にし、検証済みのパッケージのみをイメージにインストールする必要があります。
-
攻撃対象領域の拡大につながる可能性のある不要なパッケージを含まない最小限の基本イメージを使用してください。コンテナ内のコンポーネントが少ないと、利用可能な攻撃ベクトルの数が減ります。また、イメージを最小にすると、ディスク上のバイト数が減り、イメージをコピーするためのネットワーク トラフィックが減るため、パフォーマンスも向上します。BusyBox と Appline は、最小限の基本イメージを構築するための 2 つのオプションです。
-
頻繁なイメージ スキャンを強制する強力なガバナンス ポリシーを実装します。ビルドフェーズに入る前に、古いイメージを拒否するか、最近スキャンされていないイメージを再スキャンする必要があります。
-
古いイメージや未使用のイメージやコンテナを定期的に特定し、ホストから削除するワークフローを構築します。
-
シークレットをイメージ/Dockerfile に保存しないでください。デフォルトでは、シークレットを Dockerfile に保存できますが、シークレットをイメージに保存すると、そのイメージのすべてのユーザーがシークレットにアクセスできるようになります。暗号文が必要な場合は、暗号文管理ツールをご利用ください。
-
コンテナーを実行するときは、コンテナーの実行に必要な機能をすべて削除します。Docker の CAP DROP 機能を使用して、特定のコンテナーから機能 (Linux 機能とも呼ばれます) を削除し、CAP ADD を使用して、コンテナーが適切に機能するために必要な機能のみを追加できます。
-
--privileged フラグを指定してコンテナを実行しないでください。このタイプのコンテナには、基盤となるホストで使用できるほとんどの機能が含まれます。このフラグは、CAP DROP または CAP ADD を使用して設定したルールもオーバーライドします。
-
特に書き込み可能モードでは、機密性の高いホスト システム ディレクトリをコンテナにマウントしないでください。マウントすると、ホストが侵害される可能性のある悪意のある変更にさらされる可能性があります。
-
コンテナ内で sshd を実行しないでください。ssh デーモンはデフォルトではコンテナ内で実行されないため、SSH サーバーのセキュリティ管理を簡素化するためにインストールしないでください。
-
1024 より小さいポートは特権ポートとみなされ、機密データが送信されるため、コンテナ内でマップしないでください。デフォルトでは、Docker はコンテナーのポートを 49153 ~ 65525 の範囲のポートにマッピングしますが、コンテナーを特権ポートにマッピングすることもできます。一般的な経験則として、コンテナ上で必要なポートのみが開いていることを確認してください。
-
Docker コンテナと基盤となるホスト間の適切な分離を確保するために必要な場合を除き、ホストのネットワーク名前空間、プロセス名前空間、IPC 名前空間、ユーザー名前空間、または UTS 名前空間を共有しないでください。
-
任意の量に依存するのではなく、コンテナーが設計どおりに実行するために必要なメモリと CPU の量を指定します。デフォルトでは、Docker コンテナはリソースを制限なく平等に共有します。
-
コンテナのルート ファイルシステムを読み取り専用に設定します。コンテナーを実行すると、ルート ファイルシステムを変更する必要はありません。ルート ファイル システムに加えられた変更は悪意のある目的で行われる可能性があります。コンテナーの不変の性質 (新しいコンテナーにはパッチが適用されず、新しいイメージから再作成される) を維持するには、ルート ファイルシステムを書き込み可能にしないでください。
-
PID 制限を適用します。コンテナーの利点の 1 つは、厳密なプロセス識別子 (PID) 制御です。カーネル内の各プロセスには一意の PID があり、コンテナーは Linux PID 名前空間を利用して、各コンテナーに PID 階層の個別のビューを提供します。PID を制限すると、各コンテナーで実行されるプロセスの数が効果的に制限されます。コンテナ内のプロセスの数を制限すると、新しいプロセスの過剰な生成や潜在的に悪意のある横方向の移動が防止されます。PID 制限を課すことにより、フォーク ボム (継続的に自己複製するプロセス) や異常なプロセスも防止されます。ほとんどの場合、サービスが常に特定の数のプロセスを実行する場合、PID 制限をその正確な数に設定すると、リバース シェルやリモート コード インジェクションなどの多くの悪意のある動作を軽減できます。
-
共有のマウント伝播ルールを構成しないでください。共有マウントの伝播とは、マウントに加えられた変更がそのマウントのすべてのインスタンスに伝播されることを意味します。ボリュームへの必要な変更が、変更を必要としないコンテナと共有 (または伝播) しないように、マウントの伝播をスレーブ モードまたはプライベート モードに設定する必要があります。
-
この設定により、拡張された Linux 機能がコンテナーに提供される可能性があるため、特権または user=root オプションを指定して docker exec コマンドを使用しないでください。
-
デフォルトのブリッジ「docker0」は使用しないでください。デフォルトのブリッジを使用すると、ARP スプーフィングや MAC フラッディング攻撃にさらされる可能性があります。代わりに、コンテナはデフォルトの「docker0」ブリッジではなく、ユーザー定義のネットワーク上にある必要があります。
-
コンテナー内に Docker ソケットをマウントしないでください。この方法では、コンテナー内のプロセスがコマンドを実行できるようになり、ホストを完全に制御できるようになります。
Kubernetes セキュリティの 7 つのベスト プラクティス
Kubernetes はコンテナ オーケストレーションの事実上の標準として、アプリケーションのセキュリティを確保する上で重要な役割を果たしています。コンテナ化されたアプリケーションを効果的に保護するには、Kubernetes とそのネイティブのポリシー適用機能からのコンテキスト情報を活用する必要があります。たとえば、Kubernetes には、Kubernetes RBAC、ネットワーク ポリシー、アドミッション コントローラーなど、ライフサイクル全体を通じてコンテナ セキュリティの運用を容易にするいくつかのセキュリティ機能が組み込まれています。Kubernetes のこれらの固有のコントロールの力を活用して、コンテナ化された環境を保護します。
ここでは、ライフサイクル全体を通じてコンテナーを保護するために役立つ Kubernetes セキュリティのベスト プラクティスをいくつか紹介します。
-
RBAC の場合、クラスター管理者権限を任意のユーザーまたはグループに付与するのではなく、特定のユーザーまたはグループにロールと ClusterRole を割り当てます。
-
Kubernetes RBAC を使用する場合は、操作上の問題が発生する可能性があるため、権限を重複させないでください。
-
セキュリティ インシデントのトラブルシューティングや調査を行う際に、アクティブなロールに重点を置くために、未使用または非アクティブな RBAC ロールを削除します。
-
Kubernetes ネットワーク ポリシーを使用してポッドを分離し、アプリケーションの実行に必要な通信パスのみを明示的に許可します。そうしないと、横方向および南北方向の脅威に直面することになります。
-
ポッドがインターネット アクセス (イングレスまたはエグレス) を必要とする場合は、適切なネットワーク ポリシーを作成して正しいネットワーク セグメンテーション/ファイアウォール ルールを適用し、次にそのネットワーク ポリシーの対象となるラベルを作成し、最後にポッドをそのラベルに関連付けます。
-
PodSecurityPolicy アドミッション コントローラーを使用して、適切なガバナンス ポリシーが確実に適用されるようにします。PodSecurityPolicy コントローラーは、コンテナーが root として実行されるのを防止したり、コンテナーの root ファイルシステムが読み取り専用でマウントされるようにしたりすることができます (これらの提案は、以前の Docker 対策のリストに両方とも含まれていたため、聞き覚えがあるはずです)。
-
Kubernetes Admission Controller を使用してイメージ レジストリ ガバナンス ポリシーを適用し、信頼できないレジストリから取得したすべてのイメージを自動的に拒否します。
最後に – Docker コンテナ環境に関するセキュリティに関する 11 の質問に必ず答えてください。
セキュリティ体制を迅速に評価できるように、クラウド ネイティブ スタックが適切なセキュリティ対策で構築されている場合に、セキュリティ、DevSecOps、または DevOps チームが簡単に回答できる質問のリストをまとめました。
-
最終スキャン日が 60 日以上前のホストにはイメージがいくつありますか?
-
重大度の高い脆弱性を持つイメージ/コンテナはいくつありますか?
-
これらの重大度の高い脆弱なコンテナの影響を受けるのはどのデプロイメントですか?
-
影響を受けるデプロイメント内のコンテナーにはシークレットが保存されていますか?
-
脆弱なコンテナはルートまたは特権フラグで実行されていますか?
-
ポッド内にネットワーク ポリシーが関連付けられていない (つまり、すべての通信が許可されている) 脆弱なコンテナはありますか?
-
実稼働環境で実行されているコンテナはこの脆弱性の影響を受けますか?
-
私たちが使用している画像はどこから来たのでしょうか?
-
信頼できないレジストリから取得したイメージをブロックするにはどうすればよいですか?
-
コンテナーの実行中にどのプロセスが実行されているかを確認できますか?
-
Docker および Kubernetes の CIS ベンチマークに準拠していないクラスター、名前空間、およびノードはどれですか?
このリストにまとめられたベスト プラクティスに従うことで、Docker および Kubernetes 環境を適切に強化し、ビジネス クリティカルなアプリケーションを保護するための最も重要な手順を実行できるようになります。