このガイドでは、Google Kubernetes Engine(GKE)がコントロール プレーン VM に使用する Compute Engine 仮想マシン(VM)イメージの整合性を検証する方法について説明します。このガイドは、コントロール プレーン ログをモニタリングし、次のことを検証するセキュリティ チームを対象としています。
- コントロール プレーン VM が、セキュアブートと整合性モニタリングによって暗号的に検証された、本物のファームウェアやその他のブート ソフトウェアで起動したこと。
- コントロール プレーン VM が、本物の GKE OS イメージから起動したこと。
この検証は、OS イメージや、ワーカーノードの起動時の整合性に対しても行うことができます。
このページでは、GKE におけるオプションのコントロール プレーン機能について説明します。これらの機能を使用すると、コントロール プレーンのセキュリティ ポスチャーを確認する、ユーザーが管理する鍵を使用してコントロール プレーンでの暗号化と認証情報の署名を構成するといったタスクを行えます。詳細については、GKE control plane authority についてをご覧ください。
デフォルトでは、Google Cloud はマネージド コントロール プレーンにさまざまなセキュリティ対策を適用します。このページでは、コントロール プレーンの可視性と制御性をさらに高めるオプション機能について説明します。
VM の整合性検証について
デフォルトでは、GKE コントロール プレーン インスタンスはすべて Shielded VM です。これは強化された VM であり、セキュアブート、メジャード ブート、仮想トラステッド プラットフォーム モジュール(vTPM)、UEFI ファームウェアなどのセキュリティ機能を使用します。また、すべての GKE ノードで整合性モニタリングが有効になり、ベースラインの「正常な」ブート シーケンスに照らして各 Shielded VM のブート シーケンスが検証されます。この検証では、ブート シーケンス フェーズごとに合格または不合格の結果が返され、Cloud Logging に結果が追加されます。整合性モニタリングはすべての GKE クラスタでデフォルトで有効になっています。検証の対象となるフェーズは次のとおりです。
- アーリーブート シーケンス: UEFI ファームウェアが起動してから、ブートローダーが制御を取得するまでの間。VM ログに
earlyBootReportEvent
として追加されます。 - レイトブート シーケンス: ブートローダーが制御を取得してから、オペレーティング システムのカーネルが制御を取得するまでの間。VM ログに
lateBootReportEvent
として追加されます。
また、GKE はコントロール プレーン VM の作成ログを Logging に追加します。このログには、マシンを識別するメタデータや、VM イメージとブート シーケンスの詳細が含まれています。Google Cloud は、GitHub の gke-vsa リポジトリに各 GKE コントロール プレーン VM イメージの検証概要証明書(VSA)を公開しています。VSA は証明書に in-toto フレームワークを使用します。クラスタのコントロール プレーン VM ログを対応する VSA に照らして検証し、コントロール プレーン ノードが想定どおりに起動したことを確認できます。
これらの検証は、次の目標を達成するうえで役立ちます。
- コントロール プレーンのソフトウェアがセキュアブートと整合性モニタリングで保護されていて、対象のソースコードと一致しており、他の Google Cloud のお客様が使用するイメージとまったく同じであることを確認する。
- GKE でコントロール プレーンを保護する方法の信頼性を高める。
料金
この機能は、GKE で追加料金なしで提供されます。
始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
-
Enable the Cloud Logging API.
- バージョン 1.29 以降を実行している GKE Autopilot モードまたは Standard モードのクラスタがすでに存在していることを確認する。
必要なロール
コントロール プレーン VM の整合性を検証するために必要な権限を取得するには、管理者に依頼して、プロジェクトに対する次の IAM ロールを付与してもらってください。
-
クラスタを作成して操作する: Kubernetes Engine クラスタ管理者(
roles/container.clusterAdmin
) -
ログにアクセスして処理する: ログ閲覧者(
roles/logging.viewer
)
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
失敗したブート シーケンス フェーズを確認する
整合性モニタリングは、コントロール プレーン VM がブート シーケンスのフェーズを完了できなかった場合、またはフェーズを正常に完了した場合に、Logging にログを追加します。失敗したブートイベントを表示するには、次のコマンドを実行します。
Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。
[クエリ] フィールドに次のクエリを規定します。
jsonPayload.@type="type.googleapis.com/cloud_integrity.IntegrityEvent" jsonPayload.earlyBootReportEvent.policyEvaluationPassed="false" OR jsonPayload.lateBootReportEvent.policyEvaluationPassed="false" metadata.isKubernetesControlPlaneVM = true
このクエリの
false
をtrue
に置き換えることで、正常な起動イベントを確認することもできます。[クエリを実行] をクリックします。結果が表示されない場合、コントロール プレーン VM はすべての整合性モニタリング チェックに合格しています。結果が表示された場合は、次のステップに進んで該当のクラスタを特定します。
失敗した起動の整合性ログで、
resource.labels.instance_id
フィールドの値をコピーします。[クエリ] フィールドに次のクエリを規定します。
protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog" protoPayload.metadata.isKubernetesControlPlaneVM="true" resource.labels.instance_id="INSTANCE_ID" protoPayload.methodName="v1.compute.instances.insert"
INSTANCE_ID
は、前のステップでコピーしたinstance_id
フィールドの値に置き換えます。[クエリを実行] をクリックします。
protoPayload.metadata.parentResource.parentResourceId
フィールドの値は GKE クラスタ ID です。GKE クラスタの名前を確認します。
gcloud asset query \ --organization=ORGANIZATION_ID \ --statement="SELECT name FROM container_googleapis_com_Cluster WHERE resource.data.id='CLUSTER_ID';"
次のように置き換えます。
ORGANIZATION_ID
: Google Cloud 組織の数値 ID。CLUSTER_ID
: 前のステップで取得したprotoPayload.metadata.parentResource.parentResourceId
フィールドの値。
出力は次のようになります。
# lines omitted for clarity //container.googleapis.com/projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME
この出力のフィールドは次のとおりです。
PROJECT_ID
: Google Cloud プロジェクト ID。LOCATION
: クラスタのロケーション。CLUSTER_NAME
: クラスタの名前。
コントロール プレーン VM のログを見つけて調べる
GKE クラスタに対応する Compute Engine VM の作成ログは、_Default
ログバケットに保存されます。クラスタ コントロール プレーン VM の作成ログを見つけてこのメタデータを取得する手順は、次のとおりです。
Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。
[クエリ] フィールドに次のクエリを規定します。
resource.type="gce_instance" protoPayload.methodName="v1.compute.instances.insert" jsonPayload.metadata.isKubernetesControlPlaneVM="true"
[クエリを実行] をクリックします。結果が表示されない場合は、始める前にの要件をすべて満たしていることを確認してください。
クエリ結果で
metadata
フィールドを確認します。出力は次のようになります。# fields omitted for clarity "metadata": { "usedResources": { "attachedDisks": [ { "sourceImageId": "9046093115864736653", "sourceImage": "https://www.googleapis.com/compute/v1/projects/1234567890/global/images/gke-1302-gke1627000-cos-113-18244-85-49-c-pre", "isBootDisk": true } # fields omitted for clarity
metadata
フィールドには次の情報が含まれています。usedResources
: VM の作成に使用されるリソースのリスト。attachedDisks
: VM のブートディスク。sourceImageId
: VM イメージの一意の ID。sourceImage
: ソース VM イメージの URL。このフィールドの値の構文はhttps://www.googleapis.com/compute/v1/projects/PROJECT_NUMBER/global/images/IMAGE_NAME
です。ここで、PROJECT_NUMBER
はコントロール プレーン VM をホストする Google Cloud 所有のプロジェクトの番号、IMAGE_NAME
は VM の起動に使用されたイメージの名前です。isBootDisk
: このディスクが VM のブートディスクとして使用されたかどうかを示す識別子(ブール値)。
コントロール プレーン VM イメージの VSA を見つけて検証する
このセクションでは、GitHub の gke-vsa リポジトリで、コントロール プレーン VM イメージに対応する VSA を見つけます。次に、ソフトウェア アーティファクトのためのサプライ チェーン レベル(SLSA)フレームワークで提供されている slsa-verifier
というツールを使用して、VSA を検証します。コントロール プレーン VM の作成ログから次のデータを取得する必要があります。
- VM イメージ ID
- VM をホストする Google Cloud 所有プロジェクトのプロジェクト番号
- VM の起動に使用された OS イメージの名前
コントロール プレーン VM に対応するファイルのファイル名形式は次のようになります。
IMAGE_NAME:IMAGE_ID.intoto.jsonl
次のように置き換えます。
IMAGE_NAME
: VM イメージ名。前のセクションで説明した VM 監査ログに含まれるattachedDisks.sourceImage
フィールドの、/images/
の後に続く文字列です。例:gke-1302-gke1627000-cos-113-18244-85-49-c-pre
IMAGE_ID
: VM イメージ ID。前のセクションで説明した VM 監査ログに含まれるattachedDisks.sourceImageId
フィールドの値です。例:9046093115864736653
VSA ファイルのファイル名がわかったら、次の手順を実施して VSA を見つけて検証します。
- GitHub の
gke-vsa
リポジトリを開きます。 - 「gke-master-images」ディレクトリで、VM イメージに対応するファイルを見つけます。例:
https://github.com/GoogleCloudPlatform/gke-vsa/blob/main/gke-master-images:78064567238/IMAGE_NAME:IMAGE_ID.intoto.jsonl
- VSA ファイルをダウンロードします。
slsa-verifier
ツールをインストールします。VSA を検証するための公開鍵を
vsa_signing_public_key
というファイルに保存します。VSA を検証します。
slsa-verifier verify-vsa \ --attestation-path=PATH_TO_VSA_FILE \ --resource-uri=gce_image://gke-master-images:IMAGE_NAME \ --subject-digest=gce_image_id:IMAGE_ID\ --verifier-id=https://bcid.corp.google.com/verifier/bcid_package_enforcer/v0.1 \ --verified-level=BCID_L1 \ --verified-level=SLSA_BUILD_LEVEL_2 \ --public-key-path=PATH_TO_PUBLIC_KEY_FILE \ --public-key-id=keystore://76574:prod:vsa_signing_public_key
次のように置き換えます。
PATH_TO_VSA_FILE
: ダウンロードした VSA ファイルのパス。IMAGE_NAME
: VM イメージの名前(gke-1302-gke1627000-cos-113-18244-85-49-c-pre
など)。IMAGE_ID
: VM イメージ ID(9046093115864736653
など)。
VSA が検証チェックに合格すると、出力は次のようになります。
Verifying VSA: PASSED PASSED: SLSA verification passed