セキュリティの概要

このページでは、暗号化やノード構成など、GKE on AWS のセキュリティ アーキテクチャについて説明します。

GKE クラスタには、コンテナ イメージのコンテンツ、コンテナのランタイム、クラスタ ネットワーク、クラスタ API サーバーへのアクセスなど、ワークロードの保護に役立つ機能があります。

GKE クラスタを使用すると、クラスタの特定の責任を担うことに同意したことになります。詳細については、GKE クラスタの責任の共有をご覧ください。

AWS KMS 暗号化

GKE on AWS は、次のデータの暗号化に、顧客管理の AWS 鍵管理サービス(KMS)対称鍵を使用します。

本番環境では、構成とボリュームの暗号化に異なる鍵を使用することをおすすめします。鍵が不正使用された場合のリスクを最小限に抑えるために、次のようにそれぞれに異なる鍵を作成することもできます。

セキュリティをさらに強化するために、必要最小限の権限セットのみを割り当てる AWS KMS 鍵ポリシーを作成できます。詳細については、特定の権限を持つ KMS 鍵を作成するをご覧ください。

保存中のデータの暗号化

保存中のデータの暗号化は、転送中のデータとは異なり、保存されたデータの暗号化です。GKE on AWS は、デフォルトで AWS プラットフォーム マネージド鍵を使用して、etcd およびストレージ ボリューム内の保存データを暗号化します。

GKE on AWS クラスタでは、AWS Elastic ブロック ストレージ(EBS)ボリュームにデータが保存されます。これらの EBS ボリュームは、AWS 鍵管理システム(AWS KMS)の鍵で常に保存時に暗号化されます。クラスタとノードプールを作成するときに、顧客管理の KMS 鍵(CMK)を指定して、基盤となる EBS ボリュームを暗号化できます。鍵を指定しない場合、AWS ではクラスタが実行される AWS リージョン内のデフォルトの AWS 管理鍵が使用されます。

また、すべての GKE クラスタでは、etcd に保存されている Kubernetes Secret オブジェクトなどの機密データ用にアプリケーション レイヤでの Secret の暗号化が有効になっています。etcd データが保存されている基盤となるボリュームに攻撃者がアクセスしたとしても、これらのデータは暗号化されます。

クラスタを作成する際には、AWS KMS 鍵を --database-encryption-kms-key-arn フィールドに渡す必要があります。この鍵は、アプリケーション データのエンベロープ暗号化に使用されます。このリソース フィールドは不変で、クラスタの作成後は変更できないため、KMS 鍵のエイリアスを使用することをおすすめします。鍵のエイリアスを使用すると、保存ライフサイクルの暗号化に使用する鍵をクラスタのライフサイクル全体でローテーションできます。

アプリケーション レベルの暗号化の仕組み

Kubernetes では、「エンベロープ暗号化」と呼ばれる手法でアプリケーション レベルの暗号化が行われます。ローカル鍵(一般にデータ暗号鍵(DEK)と呼ばれます)は、Secret を暗号化するために使用されます。次に、DEK 自体が鍵暗号鍵(KEK)と呼ばれる第二の鍵で暗号化されます。KEK は Kubernetes に保存されません。 新しい Kubernetes Secret を作成すると、クラスタでは次の処理が行われます。

  1. Kubernetes API サーバーは乱数生成ツールを使用して、Secret のための一意の DEK を生成します。

  2. Kubernetes API サーバーが、DEK を使用して Secret をローカルに暗号化します。

  3. Kubernetes API サーバーが、DEK を暗号化のために AWS KMS に送信します。

  4. AWS KMS が、事前生成された KEK を使用して DEK を暗号化し、暗号化した DEK を Kubernetes API サーバーの AWS KMS プラグインに返します。

  5. Kubernetes API サーバーは暗号化された Secret と暗号化された DEK を etcd に保存します。平文の DEK はディスクに保存されません。

  6. Kubernetes API サーバーが、メモリ内のキャッシュ エントリを作成し、暗号化された DEK を平文の DEK にマッピングします。これにより、API サーバーは、AWS KMS にクエリを行わずに、最近アクセスされた Secret を復号できます。

クライアントが Kubernetes API サーバーから Secret をリクエストすると、次の処理が実行されます。

  1. Kubernetes API サーバーは、暗号化された Secret と暗号化された DEK を etcd から取得します。

  2. Kubernetes API サーバーはキャッシュに既存のマップエントリがあるかチェックし、見つかった場合はそれで Secret を復号します。

  3. 一致するキャッシュ エントリがない場合、API サーバーは KEK を使用して復号するため DEK を AWS KMS に送信します。復号された DEK を使用して Secret が復号されます。

  4. Kubernetes API サーバーは、復号された Secret をクライアントに返します。

鍵のローテーション

証明書のローテーションとは対照的に、鍵のローテーションは、鍵暗号鍵(KEK)に含まれる基盤となる暗号マテリアルを変更する動作です。このオペレーションは、スケジュール設定されたローテーションの一環として自動的にトリガーできます。また、通常は鍵が不正使用された可能性があるセキュリティ インシデントの後に手動で行うこともできます。鍵のローテーションによって、暗号鍵と復号鍵の元データを含む鍵の単一のフィールドのみが置き換えられます。

KMS 鍵のローテーション

AWS KMS は、KMS 鍵の自動ローテーションをサポートしています。有効にすると、AWS は年に 1 回、鍵の新しい暗号鍵マテリアルを自動的に生成します。手動での操作は必要ありません。

詳細については、鍵のローテーションをご覧ください。

クラスタの信頼性

すべてのクラスタ通信では、Transport Layer Security(TLS)が使用されます。各クラスタには、次の主要な自己署名ルート認証局(CA)がプロビジョニングされています。

  • クラスタルート CA は、API サーバーに送信されたリクエストの検証に使用されます。
  • etcd ルート CA は、etcd レプリカに送信されたリクエストの検証に使用されます。

各クラスタには一意のルート CA があります。あるクラスタの CA の信頼が損なわれても、他のクラスタの CA は影響を受けません。すべてのルート CA の有効期間は 30 年です。

ノードのセキュリティ

GKE on AWS では、AWS EC2 インスタンスのノードプールにワークロードをデプロイします。次のセクションでは、ノードのセキュリティ機能について説明します。

Ubuntu

ノードは、Kubernetes コントロール プレーンとノードを実行するために、最適化されたバージョンの Ubuntu OS を実行します。詳細については、Ubuntu のドキュメントのセキュリティ機能をご覧ください。

GKE クラスタは、次のようないくつかのセキュリティ機能を実装しています。

Ubuntu には、次のような別のセキュリティ ガイドも用意されています。

ワークロードを保護する

Kubernetes では、コンテナベースのワークロードのプロビジョニング、スケーリング、更新を迅速に行うことができます。このセクションでは、クラスタと Google Cloud サービスでコンテナを実行する場合の副作用を制限する方法について説明します。

Pod コンテナのプロセス権限を制限する

コンテナ化されたプロセスの権限を制限することは、クラスタのセキュリティにとって重要です。セキュリティ関連のオプションは、セキュリティ コンテキストを使用して設定できます。これらの設定により、次のようなプロセスのセキュリティ設定を変更できます。

  • プロセスを実行しているユーザーとグループ。
  • 利用可能な Linux 機能
  • 権限昇格

GKE on AWS ノードのデフォルトのオペレーティング システムである Ubuntu は、すべてのコンテナに対してデフォルトの Docker AppArmor セキュリティ ポリシーを使用します。プロファイルのテンプレートは GitHub で確認できます。特に、このプロファイルではコンテナの以下の機能が拒否されます。

  • プロセス ID ディレクトリ(/proc/)で直接ファイルに書き込む。
  • /proc/ にないファイルへに書き込む。
  • /proc/sys 内に存在する /proc/sys/kernel/shm* 以外のファイルに書き込む。
  • ファイル システムをマウントする

ワークロードの自己変更機能を制限する

特定の Kubernetes ワークロード(特にシステム ワークロード)には、自己変更の権限があります。たとえば、一部のワークロードは垂直方向に自動スケーリングされます。これは便利ですが、すでにノードを不正使用した攻撃者がクラスタ内でさらにエスカレーションする可能性があります。たとえば、攻撃者がノード上のワークロード自体を変更して、同じ Namespace 内に存在する、より権限の高いサービス アカウントとして実行するおそれがあります。

理想的には、ワークロードにはそもそも自己変更機能を付与するべきではありません。自己変更が必要な場合は、クラスタに Policy Controller または Gatekeeper をインストールして、オープンソースの Gatekeeper ライブラリのいくつかの有用なセキュリティ ポリシーを提供する NoUpdateServiceAccount などの制約を適用することで、権限を制限できます。

ポリシーをデプロイする場合、通常はクラスタのライフサイクルを管理するコントローラがポリシーをバイパスできるようにする必要があります。これは、コントローラがクラスタに変更を加える(クラスタのアップグレードを適用するなど)ことができるようにするために必要です。たとえば、GKE on AWS に NoUpdateServiceAccount ポリシーをデプロイする場合は、Constraint で次のパラメータを設定する必要があります。

parameters:
  allowedGroups: []
  allowedUsers:
  - service-PROJECT_NUMBER@gcp-sa-gkemulticloud.iam.gserviceaccount.com

PROJECT_NUMBER は、クラスタをホストするプロジェクトの番号(ID ではありません)に置き換えます。

Binary Authorization を使用する

ワークロードを保護するもう 1 つの方法は、Binary Authorization を有効にすることです。Binary Authorization は、信頼できるコンテナ イメージのみが GKE クラスタにデプロイされるようにするセキュリティ機能です。

この仕組みは次のとおりです:

  1. 管理者が、イメージのデプロイ要件を定義するポリシーを作成します。これには、イメージに署名できる信頼され認可されたエンティティ(認証者)を指定することも含まれます。また、イメージのデプロイが安全であるとみなされるために満たす必要がある他の基準を含めることもできます。

  2. 認証者(デベロッパーや自動システムなど)が、暗号アルゴリズムを使用して鍵ペア(秘密鍵と公開鍵)を生成します。

  3. 秘密鍵は、イメージのデジタル署名(一意の文字セット)を生成するために使用されます。この署名は、イメージが必要なすべてのチェックと検証に合格したことを示す、承認のシールとして機能します。

  4. デジタル署名がイメージに「付加」されます。つまり、署名はイメージのメタデータ(通常はイメージ レジストリ)に保存されます。

  5. 次に、公開鍵は Binary Authorization システムに登録され、システムが署名検証に公開鍵を使用できるようになります。

  6. コンテナのデプロイ リクエストが行われると、Binary Authorization システムがレジストリ内のイメージに付加されているデジタル署名を取得します。

  7. Binary Authorization システムは、登録された公開鍵を使用して、イメージに付加されているデジタル署名を検証します。また、イメージがポリシーで定義されている他のすべての条件を満たしているかどうかも確認します。公開鍵とイメージデータを使用してデジタル署名が正常に検証され、イメージがポリシーで定義されている他のすべての条件を満たしている場合、Binary Authorization システムはコンテナのデプロイを許可します。公開鍵とイメージデータを使用してデジタル署名を正常に検証できない場合や、イメージがポリシーで定義された他の基準を満たしていない場合、Binary Authorization システムはコンテナのデプロイを拒否します。

Binary Authorization の仕組みについては、Binary Authorization の概要をご覧ください。

既存のクラスタで Binary Authorization を有効にする、またはクラスタを作成する際に Binary Authorization を有効にするには、Binary Authorization を有効にする方法をご覧ください。

次のステップ