クラスタ メタデータの保護

概要

GKE はインスタンス メタデータを使用してノード VM を構成しますが、このメタデータの一部は潜在的に機密性が高く、クラスタ上で実行されているワークロードから保護する必要があります。

始める前に

このタスクの準備として、次の手順を行います。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Enable Google Kubernetes Engine API を有効にする
  • Cloud SDK がインストール済みであることを確認します。
  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project [PROJECT_ID]
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone [COMPUTE_ZONE]
  • リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud を最新バージョンに更新します。
    gcloud components update

ノードのサービス アカウントの構成

各ノードのサービス アカウント認証情報は引き続きワークロードに公開されるため、必要最小限の権限でサービス アカウントが構成されていることを確認してください。次に、このサービス アカウントをノードに接続して、攻撃者が Compute Engine API を使用してノード インスタンスに直接アクセスすることで GKE のメタデータ保護を回避することができないようにします。

compute.instances.get 権限、Compute インスタンス管理者の役割、またはその他の同様の権限を持つサービス アカウントを使用しないでください。これは、潜在的な攻撃者がこれらの権限を利用して、Compute Engine API 経由でインスタンス メタデータを取得可能になるためです。アクセス スコープではなく、サービス アカウント権限を使用して、ノード VM の権限を制限することをおすすめします。詳細については、Compute Engine のサービス アカウントのドキュメントをご覧ください。

ノードサービス アカウントを持っていない場合は、次のコマンドを使用してノードサービス アカウントを作成できます。

export NODE_SA_NAME=gke-node-sa
gcloud iam service-accounts create $NODE_SA_NAME \
  --display-name "Node Service Account"
export NODE_SA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
  --filter='displayName:Node Service Account')

必要な役割と権限でサービス アカウントを構成するには、次のコマンドを実行します。PROJECT は自分のプロジェクト ID です。

export PROJECT=$(gcloud config get-value project)

gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/monitoring.metricWriter
gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/monitoring.viewer
gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/logging.logWriter

さらに、クラスタが Container Registry から非公開イメージを pull する場合は、storage.objectViewer 役割を追加します。

gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/storage.objectViewer

以前のメタデータ API を無効にする

Compute Engine のインスタンス メタデータ サーバーが公開する以前の /0.1//v1beta1/ エンドポイントは、メタデータ クエリヘッダーを適用しません。これは /v1/ API の機能であり、これにより潜在的な攻撃者はインスタンス メタデータを取得することがより困難になります。特に必要とされる場合を除き、こうした以前の API を無効にすることをおすすめします。

注: 現在、従来のメタデータ API を無効にできるのは、新しいクラスタの作成時や、既存のクラスタに新しいノードプールを追加する場合にのみ使用できます。

以前のメタデータ API を無効にして新しいノードプールを作成する

サービス アカウントの作成後、gcloud コマンドライン ツールで以前のメタデータ API を無効にして、新しいノードプール(または新しいクラスタのデフォルトのノードプール)を作成できます。

以前のメタデータ API を無効にして新しいノードプールを作成するには、--metadata disable-legacy-endpoints=true フラグを使用します。例:

gcloud container node-pools create [POOL_NAME] \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true

以前のメタデータ API を無効にした状態で新しいクラスタをデフォルトのノードプールに作成するには、同じフラグを使用します。例:

gcloud container clusters create [CLUSTER_NAME] \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true

既存のクラスタを更新して以前のメタデータ API を無効にする

以前のメタデータ API を無効にした状態で新しいノードプールを作成した後に、既存のクラスタを更新してそのノードプールを使用するには、ノードプールの移行ガイドに従ってください。

以前のメタデータ API が無効であることを確認する

以前のインスタンス メタデータ API が無効になっていると、/0.1/ および /v1beta1/ メタデータ サーバー エンドポイントに対するリクエストで 403 Forbidden が返されます。

以前のメタデータ API が無効になっていることを確認するには、ポッド内から curl コマンドを実行します。

root@pod-name# curl -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/attributes/disable-legacy-endpoints'
true
root@pod-name# curl 'http://metadata.google.internal/computeMetadata/v1beta1/instance/id'
... Error 403 (Forbidden) ... Legacy metadata endpoint accessed: /computeMetadata/v1beta1/instance/id Legacy metadata endpoints are disabled. Please use the /v1/ endpoint. ...

メタデータ隠蔽

GKE のメタデータ隠蔽は、一部の潜在的に機密性が高いシステム メタデータを、クラスタ上で実行されているユーザー ワークロードから保護します。

Kubernetes v1.9.3 以降では、メタデータ隠蔽を有効にして、ユーザーのポッドがクラスタのノードの特定の VM メタデータ(Kubelet 認証情報や VM インスタンス情報など)にアクセスすることを防止できます。 具体的には、メタデータ隠蔽は、kube-env(Kubelet 認証情報を含む)と VM のインスタンス ID トークンへのアクセスを保護します。

メタデータ隠蔽は、ユーザーポッド(HostNetwork 上で実行されていないポッド)からクラスタ メタデータ サーバーへのトラフィックをファイアウォール制御し、安全なクエリのみを許可します。ファイアウォールは、ユーザーポッドが、特権エスカレーション攻撃に Kubelet 認証情報を使用するのを防ぎます。また、インスタンス エスカレーション攻撃に VM ID を使用するのも防ぎます。

制限事項

  • メタデータ隠蔽は、kube-env とノードのインスタンス ID トークンへのアクセスだけを保護します。
  • メタデータ隠蔽は、ノードのサービス アカウントへのアクセスを制限しません。
  • メタデータ隠蔽は、他の関連するインスタンス メタデータへのアクセスを制限しません。
  • メタデータ隠蔽は、その他の以前のメタデータ API へのアクセスを制限しません。

メタデータ隠蔽を使用した新しいクラスタまたはノードプールの作成

サービス アカウントの作成後、gcloud コマンドライン ツールを使用して新しいクラスタを作成し、メタデータ隠蔽を有効にできます。

メタデータ隠蔽が有効になっているクラスタを作成するには、シェルまたはターミナル ウィンドウで次のコマンドを実行します。

gcloud beta container clusters create [CLUSTER_NAME] \
  --workload-metadata-from-node=SECURE \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true \
  [additional parameters and flags omitted]

ここで

  • [CLUSTER_NAME] は、作成するクラスタの名前です。
  • --workload-metadata-from-node は、SECURE に設定されています。フラグを EXPOSED または UNSPECIFIED に設定すると、メタデータ隠蔽が無効になります。

ID トークン メタデータがクラスタのワークロードから隠蔽されていることを確認する

メタデータを隠蔽するときは、ノードのインスタンス ID トークンを介して署名をリクエストできないようにする必要があります。リクエストが隠蔽されているメタデータをユーザーに明示的に通知することを確認するには、ポッド内から次の curl コマンドを実行します。

root@pod-name# curl -H "Metadata-Flavor: Google" \
'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://www.example.com'
This metadata endpoint is concealed.
このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Kubernetes Engine のドキュメント