驗證 GKE 控制層 VM 完整性

您可以驗證 Google Kubernetes Engine (GKE) 用於控制層 VM 的 Compute Engine 虛擬機器 (VM) 映像檔完整性。本頁面提供操作說明,協助安全團隊監控控制層記錄,驗證下列事項:

  • 控制層 VM 使用真實韌體和其他啟動軟體啟動,這些軟體已透過安全啟動和完整性監控進行加密驗證。
  • 控制層 VM 是從正版 GKE OS 映像檔啟動。

您也可以對節點的 OS 映像檔和開機完整性執行這項驗證。

本頁面說明 GKE 中一組選用控制層功能,可讓您執行驗證控制層安全狀態,或使用您管理的金鑰在控制層中設定加密和憑證簽署等工作。詳情請參閱「關於 GKE 控制層授權」。

根據預設, Google Cloud 會對代管控制層套用多項安全措施。本頁說明選用功能,可讓您進一步瞭解或控管 GKE 控制層。

關於 VM 完整性驗證

根據預設,所有 GKE 控制層執行個體都是Shielded VM,也就是經過強化的 VM,會使用安全和測量啟動、虛擬信任平台模組 (vTPM) 和 UEFI 韌體等安全性功能。所有 GKE 節點也會啟用完整性監控,根據基準「良好」啟動序列驗證每個 Shielded VM 的啟動序列。這項驗證會針對每個開機程序階段傳回通過或失敗結果,並將這些結果新增至 Cloud Logging。所有 GKE 叢集預設都會啟用完整性監控功能,並驗證下列階段:

  • 提早啟動序列:從 UEFI 韌體啟動到系統啟動載入程式接管控制權。以 earlyBootReportEvent 的形式新增至 VM 記錄。
  • 延後啟動:從系統啟動載入程式接管控制權,到作業系統核心接管控制權為止。以 lateBootReportEvent 的形式新增至 VM 記錄。

GKE 也會將控制層 VM 建立記錄新增至 Cloud Logging。這些記錄包含中繼資料,可識別機器,並提供 VM 映像檔和啟動序列的詳細資料。Google Cloud 會針對 GitHub 上的 gke-vsa 存放區中每個 GKE 控制層 VM 映像檔,發布驗證摘要證明 (VSA)。VSA 使用 in-toto 架構進行認證。您可以根據對應的 VSA 驗證叢集的控制層 VM 記錄,確認控制層節點是否如預期啟動。

執行這些驗證有助於達成下列目標:

  • 確保控制層上的軟體受到安全啟動和完整性監控機制保護,與預期原始碼相符,且與其他 Google Cloud 客戶使用的映像檔完全相同。
  • 進一步瞭解 GKE 如何保護控制層安全。

定價

這項功能在 GKE 中不需額外付費即可使用。

事前準備

開始之前,請確認您已執行下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 如果尚未啟用,請啟用 Cloud Logging API。

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過擁有者角色 (roles/owner) 取得這項權限。否則,您可以透過服務使用情形管理員角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。

    啟用 API

  • 確認您已擁有執行 1.29 以上版本的 GKE Autopilot 模式或標準模式叢集。

必要的角色

如要取得驗證控制層 VM 完整性所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

檢查是否有失敗的開機程序階段

如果控制層 VM 失敗或順利完成啟動順序的階段,完整性監控功能會在 Logging 中新增記錄。如要查看開機失敗事件,請執行下列指令:

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面:

    前往「Logs Explorer」頁面

  2. 在「查詢」欄位中,指定下列查詢:

    jsonPayload.@type="type.googleapis.com/cloud_integrity.IntegrityEvent"
    jsonPayload.earlyBootReportEvent.policyEvaluationPassed="false" OR jsonPayload.lateBootReportEvent.policyEvaluationPassed="false"
    jsonPayload.metadata.isKubernetesControlPlaneVM="true"
    

    您也可以在這個查詢中將 false 替換為 true,藉此檢查開機事件是否成功。

  3. 按一下「Run query」(執行查詢)。如果沒有看到結果,表示控制層 VM 已通過所有完整性監控檢查。如果看到輸出內容,請繼續下一個步驟,找出對應的叢集。

  4. 在開機完整性記錄檔中,複製 resource.labels.instance_id 欄位中的值。

  5. 在「Query」(查詢) 欄位中,指定下列查詢:

    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 欄位的值。

  6. 按一下「Run query」(執行查詢)。protoPayload.metadata.parentResource.parentResourceId 欄位中的值是 GKE 叢集 ID。

  7. 找出 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 記錄檔 bucket。如要找出叢集控制層 VM 的建立記錄並擷取這項中繼資料,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面:

    前往「Logs Explorer」頁面

  2. 在「查詢」欄位中,指定下列查詢:

    resource.type="gce_instance"
    protoPayload.methodName="v1.compute.instances.insert"
    protoPayload.metadata.isKubernetesControlPlaneVM="true"
    
  3. 按一下「Run query」(執行查詢)。如果沒有看到結果,請確認您符合「事前準備」一節中的所有規定。

  4. 在查詢結果中,檢查 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 映像檔的網址。這個欄位的值語法為 https://www.googleapis.com/compute/v1/projects/PROJECT_NUMBER/global/images/IMAGE_NAME,其中 PROJECT_NUMBER 是代管控制層 VM 的Google Cloud擁有專案數量,IMAGE_NAME 則是用於啟動 VM 的映像檔名稱。
    • isBootDisk:布林值 ID,指出這個磁碟是否用做 VM 的開機磁碟。

尋找並驗證控制層 VM 映像檔的 VSA

在本節中,您會在 GitHub 的 gke-vsa 存放區中,找到與控制層 VM 映像檔對應的 VSA。然後使用軟體構件供應鏈級別 (SLSA) 架構提供的 slsa-verifier 工具,驗證 VSA。您需要控制平面 VM 建立記錄中的下列資料:

  • VM 映像檔 ID
  • Google Cloud代管 VM 的專案編號
  • 用於啟動 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,請按照下列步驟操作:

  1. 開啟 gke-vsa GitHub 存放區。
  2. 在「gke-master-images」目錄中,找出對應 VM 映像檔的檔案。例如: https://github.com/GoogleCloudPlatform/gke-vsa/blob/main/gke-master-images:78064567238/IMAGE_NAME:IMAGE_ID.intoto.jsonl
  3. 下載 VSA 檔案。
  4. 安裝 slsa-verifier 工具。
  5. 將用於驗證 VSA 的公開金鑰儲存至名為 vsa_signing_public_key 的檔案:

    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeGa6ZCZn0q6WpaUwJrSk+PPYEsca
    3Xkk3UrxvbQtoZzTmq0zIYq+4QQl0YBedSyy+XcwAMaUWTouTrB05WhYtg==
    -----END PUBLIC KEY-----
    

  6. 驗證 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
    

後續步驟