このガイドでは、Google Kubernetes Engine(GKE)がコントロール プレーン VM に使用する Compute Engine 仮想マシン(VM)イメージの整合性を確認する方法について説明します。このガイドは、コントロール プレーン ログをモニタリングし、次のことを確認するセキュリティ チームを対象としています。
- コントロール プレーン VM は、セキュアブートおよび整合性モニタリングによって暗号的に検証された、本物のファームウェアやその他のブートソフトウェアで起動しました。
- コントロール プレーン VM が、正規の GKE OS イメージから起動された。
この検証は、ワーカーノードの OS イメージと起動の整合性に対しても実行できます。
このページでは、GKE のオプションのコントロール プレーン機能のセットについて説明します。この機能を使用すると、コントロール プレーンのセキュリティ対策の検証や、管理する鍵を使用してコントロール プレーンでの暗号化と認証情報の署名の構成などのタスクを実行できます。詳細については、GKE control plane authority についてをご覧ください。
デフォルトでは、Google Cloud はマネージド コントロール プレーンにさまざまなセキュリティ対策を適用します。このページでは、GKE コントロール プレーンの可視性と制御を強化するオプション機能について説明します。
VM の完全性検証について
デフォルトでは、すべての GKE コントロール プレーン インスタンスは Shielded VM です。これは、セキュアブート、メジャード ブート、仮想トラステッド プラットフォーム モジュール(vTPM)、UEFI ファームウェアなどのセキュリティ機能を使用した強化された VM です。また、すべての GKE ノードで整合性モニタリングが有効になり、各シールドされた VM のブート シーケンスがベースラインの「正常な」ブート シーケンスと照合されます。この検証は、各起動シーケンス フェーズで合格または不合格の結果を返します。これらの結果は Cloud Logging に追加されます。完全性モニタリングはすべての GKE クラスタでデフォルトで有効になっており、次のフェーズを検証します。
- 初期ブート シーケンス: UEFI ファームウェアの起動からブートローダーが制御を取得するまでの間。VM ログに
earlyBootReportEvent
として追加されます。 - 後期ブート シーケンス: ブートローダーが制御を取得してからオペレーティング システムのカーネルが制御を取得するまでの間。VM ログに
lateBootReportEvent
として追加されます。
また、GKE はコントロール プレーン VM の作成ログを Logging に追加します。これらのログには、マシンを識別するメタデータが含まれ、VM イメージとブート順序の詳細が含まれています。Google Cloud は、GKE コントロール プレーン VM イメージごとに、検証概要証明書(VSA)を GitHub の gke-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" jsonPayload.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 プロジェクト IDLOCATION
: クラスタのロケーション。CLUSTER_NAME
: クラスタの名前。
コントロール プレーン VM ログを検索して検査する
GKE クラスタに対応する Compute Engine VM 作成ログは、_Default
ログバケットに保存されます。クラスタ コントロール プレーン VM の作成ログを見つけてこのメタデータを取得する手順は次のとおりです。
Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。
[クエリ] フィールドに次のクエリを規定します。
resource.type="gce_instance" protoPayload.methodName="v1.compute.instances.insert" protoPayload.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 を見つけて確認するには、次の操作を行います。
gke-vsa
GitHub リポジトリを開きます。- 「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