更新 VM 上的安全啟動憑證

本文說明如何在 Google Distributed Cloud (GDC) 氣隙環境中,更新虛擬機器 (VM) 的整合可延伸韌體介面 (UEFI) 安全啟動憑證。

UEFI 安全啟動是一項安全功能,可驗證所有啟動元件的數位簽章,確保 VM 系統執行的軟體均真實可信。如果驗證失敗,安全啟動功能會停止 VM 啟動程序。

Microsoft 使用安全憑證,在各種作業系統中支援安全啟動。部分安全啟動憑證即將到期。為避免系統中斷,請務必續約這些憑證。

本文適用於平台管理員或應用程式運算子群組的開發人員,這些人員會在 Distributed Cloud 環境中設定 VM 的安全啟動功能。詳情請參閱 GDC 氣隙環境適用的目標對象說明文件

事前準備

Distributed Cloud 的所有指令都使用 gdcloudkubectl CLI,且需要作業系統 (OS) 環境。請務必下載、安裝及設定 gdcloud CLI

取得 kubeconfig 檔案

如要對管理 API 伺服器執行指令,請確認您具備下列資源:

  1. 如果沒有管理 API 伺服器的 kubeconfig 檔案,請登入並產生該檔案。

  2. 請使用管理 API 伺服器的 kubeconfig 檔案路徑,替換這些操作說明中的 MANAGEMENT_API_SERVER

要求 IAM 角色

如要在 VM 上更新安全啟動憑證,請聯絡專案 IAM 管理員,要求「Virtual Machine Project Admin」(虛擬機器專案管理員) (project-vm-admin) 角色。

所有 VM 角色都必須繫結至 VM 所在的專案命名空間。 按照步驟驗證存取權。

安全啟動憑證

所有安全啟動憑證都有有效期限。憑證過期的 VM 會正常啟動,直到您安裝 Windows Boot Manager 或 Linux shim 的第一個安全性更新為止。更新後,您必須更新過期的憑證,VM 才能開機。

即將到期的憑證

下表說明舊版安全啟動憑證的最終到期日:

憑證名稱 憑證到期日
Microsoft Corporation KEK CA 2011 2026 年 6 月 26 日
Microsoft UEFI CA 2011 2026 年 6 月 26 日
Microsoft Windows Production PCA 2011 2026 年 10 月 19 日

新憑證

下表說明新版安全啟動憑證的最終到期日:

憑證名稱 憑證到期日
Microsoft UEFI CA 2023 2038 年 6 月 13 日
Microsoft Corporation KEK 2K CA 2023 2038 年 3 月 2 日
Microsoft Option ROM UEFI CA 2023 2038 年 10 月 26 日
Windows UEFI CA 2023 2035 年 6 月 13 日

憑證續購程序

如要在 VM 上更新安全啟動憑證,您必須使用註解和受控更新選擇加入。更新後,使用新舊映像檔建立的所有新 VM 都會安裝這兩項憑證,並順利啟動。

找出 VM 並套用註解

找出命名空間或專案中受影響的 VM。找出受影響的 VM 執行個體後,請套用更新註解。

  1. 使用 kubectl 檢查 enableSecureBoot 狀態:

    kubectl --kubeconfig MANAGEMENT_API_SERVER get vms --all-namespaces -o \
        custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,SECURE_BOOT:.spec.shieldConfig.enableSecureBoot"
    
  2. 將註解套用至 VM 自訂資源,將 VM 標示為可供更新。這會在下次重新啟動 VM 時註冊憑證:

    kubectl --kubeconfig MANAGEMENT_API_SERVER annotate virtualmachine VM_NAME -n VM_NAMESPACE virtualmachine.gdc.goog/enable-microsoft-2023-sbcert="true" --overwrite
    

    請替換下列變數:

    • VM_NAME:VM 執行個體的名稱。
    • VM_NAMESPACE:VM 所在的命名空間名稱。
  3. 將註解大量套用至專案中的所有 VM:

    kubectl --kubeconfig MANAGEMENT_API_SERVER annotate virtualmachine --all -n VM_NAMESPACE virtualmachine.gdc.goog/enable-microsoft-2023-sbcert="true" --overwrite
    

    只要未使用磁碟加密,您就可以在機構中的所有 VM 大量套用註解標籤。

    在專案層級,專案擁有者可以個別將標籤套用至符合資格的 VM。

  4. 如要套用變更,請重新啟動 VM:

    kubectl --kubeconfig MANAGEMENT_API_SERVER patch VirtualMachine VM_NAME -n VM_NAMESPACE -p '{"spec":{"runningState":"Stopped"}}' --type=merge
    
    kubectl --kubeconfig MANAGEMENT_API_SERVER patch VirtualMachine VM_NAME -n VM_NAMESPACE -p '{"spec":{"runningState":"Running"}}' --type=merge
    

特殊處理方式:BitLocker 和 FDE

您必須執行下列工作:

  1. 暫時停用 BitLocker、LUKS 或任何類似的加密解決方案。
  2. 請確保您隨時可取得救援金鑰,並備份最新資料。
  3. 套用「憑證續約程序」一節步驟 2 中提及的 Secure Boot 更新註解。
  4. 重新啟動 VM,註冊憑證。
  5. 確認更新後,請重新啟用 BitLocker、LUKS 或 FDE。

停用 BitLocker

套用 "virtualmachine.gdc.goog/enable-microsoft-2023-sbcert" 註解前,請務必先停用 VM 上的 BitLocker。這需要解密磁碟。請等待解密程序完成,再套用註解。

請使用下列指令碼停用 BitLocker:

disable_bitlocker.ps1

   # Log start time
   Add-Content -Path C:\disable_bitlocker_log.txt -Value "Script started at $(Get-Date)"

   # Get all BitLocker volumes
   $BitLockerVolumes = Get-BitLockerVolume

   if ($BitLockerVolumes) {
       foreach ($Volume in $BitLockerVolumes) {
           Add-Content -Path C:\disable_bitlocker_log.txt -Value "Processing volume: $($Volume.MountPoint)"
           if ($Volume.ProtectionStatus -eq 'On') {
               Add-Content -Path C:\disable_bitlocker_log.txt -Value "Disabling BitLocker on $($Volume.MountPoint)"
               try {
                   Disable-BitLocker -MountPoint $Volume.MountPoint -ErrorAction Stop
                   Add-Content -Path C:\disable_bitlocker_log.txt -Value "Successfully initiated BitLocker disable on $($Volume.MountPoint). Decryption may take time."
               } catch {
                   Add-Content -Path C:\disable_bitlocker_log.txt -Value "ERROR disabling BitLocker on $($Volume.MountPoint): $($_.Exception.Message)"
               }
           } else {
               Add-Content -Path C:\disable_bitlocker_log.txt -Value "BitLocker is already Off or Unprotected on $($Volume.MountPoint)"
           }
       }
   } else {
       Add-Content -Path C:\disable_bitlocker_log.txt -Value "No BitLocker volumes found."
   }

   # Log end time
   Add-Content -Path C:\disable_bitlocker_log.txt -Value "Script finished at $(Get-Date)"

disable_bitlocker.ps1 指令碼新增至 VM 開機指令碼

如要在 VM 重新啟動時停用 BitLocker,您可以在執行中的 VM 執行這個指令碼,或是將指令碼新增至開機指令碼。請按照下列步驟,將這個指令碼做為開機指令碼使用。

  1. 將指令碼進行 Base64 編碼,然後建立 Kubernetes 密鑰:

    # Encode the script
    B64_SCRIPT=$(base64 -w 0 disable_bitlocker.ps1)
    
    # Create Secret YAML
    cat <<EOF > disable_bitlocker_secret.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: disable-bitlocker-script
      namespace: VM_NAMESPACE
    type: Opaque
    data:
      script: $B64_SCRIPT
    EOF
    
    # Apply the Secret to the GDCer
    kubectl --kubeconfig MANAGEMENT_API_SERVER -f disable_bitlocker_secret.yaml
    
  2. 修補 VM CR,將 disable-bitlocker.ps1 指令碼新增至開機指令碼spec 欄位:

    spec:
      # ... other existing spec fields ...
      osType: Windows
      startupScripts:
        - name: disable-bitlocker-ps1 # Note the -ps1 suffix
          scriptSecretRef:
            name: disable-bitlocker-script
    
  3. 重新啟動 VM:

    • 停止 VM:

      kubectl --kubeconfig MANAGEMENT_API_SERVER patch VirtualMachine VM_NAME -n VM_NAMESPACE -p '{"spec":{"runningState":"Stopped"}}' --type=merge
      
    • 啟動 VM:

      kubectl --kubeconfig MANAGEMENT_API_SERVER patch VirtualMachine <vm-name> -n VM_NAMESPACE -p '{"spec":{"runningState":"Running"}}' --type=merge
      

檢查 BitLocker 狀態

如要確認磁碟區已完全解密,請使用下列任一 PowerShell 指令檢查 BitLocker 狀態:

  • 檢查所有硬碟的狀態:

    Get-BitLockerVolume
    
  • 查看特定硬碟的狀態:

    Get-BitLockerVolume -MountPoint "C:"
    

或者,您也可以使用 manage-bde 指令檢查所有硬碟的狀態:

manage-bde -status

停用 BitLocker 後的輸出內容如下圖所示:

執行 manage-bde -status 後,PowerShell CLI 畫面顯示 BitLocker 狀態為 False

選用:驗證

如要驗證 VM 上的憑證,請按照對應作業系統的步驟操作:

Linux

  1. 使用 mokutil 確認電腦已啟用安全啟動功能:

    user@vm1:~$ mokutil --sb-state
    

    如果已啟用安全啟動,輸出內容會類似如下:

    SecureBoot enabled
    
  2. 請使用 mokutil 指令搭配適當的旗標,並使用 grep 將搜尋範圍縮小至特定認證年度。

    2023 年認證

    user@vm1:~$ mokutil --kek | grep 2023
    

    輸出結果會與下列內容相似:

        Not Before: Mar  2 20:21:35 2023 GMT
        Subject: C=US, O=Microsoft Corporation, CN=Microsoft Corporation KEK 2K CA 2023
    
    user@vm1:~$ mokutil --db | grep 2023
    

    輸出結果會與下列內容相似:

        Not Before: Jun 13 19:21:47 2023 GMT
        Subject: C=US, O=Microsoft Corporation, CN=Microsoft UEFI CA 2023
        Not Before: Jun 13 18:58:29 2023 GMT
        Subject: C=US, O=Microsoft Corporation, CN=Windows UEFI CA 2023
    

    2011 年認證

    user@vm1:~$ mokutil --kek | grep 2011
    

    輸出結果會與下列內容相似:

        Not Before: Jun 24 20:41:29 2011 GMT
        Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Corporation KEK CA 2011
    
    user@vm1:~$ mokutil --db | grep 2011
    

    輸出結果會與下列內容相似:

        Not Before: Oct 19 18:41:42 2011 GMT
        Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Windows Production PCA 2011
        Not Before: Jun 27 21:22:45 2011 GMT
        Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Corporation UEFI CA 2011
    

Windows

  1. 確認系統是否具備安全啟動憑證:

    PS C:\Windows\system32> Confirm-SecureBootUEFI
    

    如果電腦上有憑證,輸出內容會是 True

  2. 使用 -match 旗標,將適用憑證年份的指令附加至指令:

    PS C:\Windows\system32> [System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI KEK).bytes) -match "2023"
    PS C:\Windows\system32> [System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI KEK).bytes) -match "2011"
    PS C:\Windows\system32> [System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI db).bytes) -match "2011"
    PS C:\Windows\system32> [System.Text.Encoding]::ASCII.GetString((Get-SecureBootUEFI db).bytes) -match "2023"
    

排解續訂問題

如果現有 VM 發生續約問題,請在 VM CR 中新增註解,以復原變更。VM 會使用先前的舊憑證開機。

復原變更

  1. 將下列註解新增至 VM 自訂資源:

    註解

    kubectl --kubeconfig MANAGEMENT_API_SERVER annotate virtualmachine VM_NAME -n VM_NAMESPACE virtualmachine.gdc.goog/recover-efi-backup="true" --overwrite
    
  2. 重新啟動 VM,即可復原舊版憑證:

    • 停止 VM:

      kubectl --kubeconfig MANAGEMENT_API_SERVER patch VirtualMachine VM_NAME -n VM_NAMESPACE -p '{"spec":{"runningState":"Stopped"}}' --type=merge
      
    • 啟動 VM:

      kubectl --kubeconfig MANAGEMENT_API_SERVER patch VirtualMachine VM_NAME -n VM_NAMESPACE -p '{"spec":{"runningState":"Running"}}' --type=merge