驗證 GKE 控制層 VM 完整性


本指南說明如何驗證 Compute Engine 虛擬機器 (VM) 映像檔的完整性。Google Kubernetes Engine (GKE) 會將此映像檔用於控制平面 VM。本指南適用於監控控制平面記錄的安全性團隊,可協助驗證下列事項:

  • 控制平面 VM 會使用安全啟動和完整性監控功能,以經過加密驗證的韌體和其他啟動軟體啟動。
  • 控制層 VM 是從正版 GKE OS 映像檔啟動。

您也可以對工作站節點的 OS 映像檔和啟動完整性執行這項驗證。

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

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

關於 VM 完整性驗證

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

  • 早期啟動順序:從 UEFI 韌體啟動開始,到系統啟動載入程式取得控制權為止。新增至 VM 記錄檔,顯示為 earlyBootReportEvent
  • 後期啟動順序:從系統啟動載入程式取得控制權,到作業系統核心取得控制權為止。已新增至 VM 記錄檔,如 lateBootReportEvent

GKE 也會在 Cloud Logging 中新增控制層 VM 建立記錄。這些記錄檔包含可識別機器的中繼資料,以及 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,取得最新版本。
  • Enable the Cloud Logging API.

    Enable the API

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

必要的角色

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

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

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

檢查啟動順序階段是否失敗

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

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

    前往「Logs Explorer」頁面

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

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

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

    前往「Logs Explorer」頁面

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

    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
  • 擁有 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,請按照下列步驟操作:

  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
    

後續步驟