相互傳輸層安全性總覽

相互傳輸層安全性 (mTLS) 是業界標準通訊協定,用於用戶端和伺服器之間的相互驗證。它會驗證各方是否持有由信任的憑證授權單位 (CA) 核發的有效憑證,確保用戶端和伺服器都能相互驗證。與只驗證伺服器的標準 TLS 不同,mTLS 要求用戶端和伺服器都出示憑證,在建立通訊之前確認雙方的身分。

在所有應用程式負載平衡器的目標 HTTPS Proxy 資源上設定 mTLS:

  • 全域外部應用程式負載平衡器
  • 傳統版應用程式負載平衡器
  • 區域性外部應用程式負載平衡器
  • 區域性內部應用程式負載平衡器
  • 跨區域內部應用程式負載平衡器

mTLS 會使用公開金鑰基礎架構 (PKI) 驗證透過網路通訊實體的身分。基礎架構包含三個元件:用戶端、伺服器和憑證授權單位 (CA)。負載平衡器的 mTLS 支援下列功能:

  • 驗證提交憑證的用戶端是否擁有私密金鑰。

  • 在下列兩種模式中驗證用戶端憑證:

    • 拒絕無效憑證:如果無法驗證用戶端憑證鏈結,系統會拒絕要求,以便強制執行嚴格驗證。

    • 允許無效或缺少的憑證:將所有要求傳遞至後端,即使用戶端憑證缺少或無效,也能提供彈性。

  • 針對已上傳的 PKI 錨點 (根憑證) 驗證用戶端憑證,並提供個別新增多個錨點的選項,以便在不造成停機的情況下,從舊 PKI 無縫遷移至新 PKI。

  • 提供其他中繼憑證,協助根據指定的 PKI 錨點 (根憑證) 建構用戶端憑證驗證路徑。這些中繼憑證可讓 mTLS 與未提供完整憑證鏈的用戶端搭配運作。

  • 產生憑證指紋,並將其傳遞至後端,做為自訂要求標頭。

  • 使用自訂標頭,將從憑證中擷取的所選欄位傳遞至後端。

  • 使用自訂標頭,將驗證結果和任何驗證錯誤傳遞至後端。

憑證規定

設定 mTLS 憑證時,請確保憑證符合下列規定:

  • mTLS 驗證的基礎是現代密碼編譯工具。憑證必須使用 RSA 或 ECDSA 演算法進行金鑰交換。雜湊演算法必須使用 SHA-256 或更強的加密編譯雜湊函式。系統不支援 MD4、MD5 和 SHA-1 等雜湊演算法。
  • 用戶端 (葉節點) 憑證:
  • 根憑證和中繼憑證:

mTLS 部署作業的架構

透過 mTLS,您可以設定信任設定資源,其中包含信任儲存庫。信任儲存庫封裝了信任錨點 (根憑證),以及一或多個中繼憑證 (屬於選用性質)。負載平衡器收到用戶端憑證後,會建立從用戶端憑證回溯至已設定信任錨點的信任鏈結,藉此驗證憑證。

以下簡要概述您需要設定的不同資源,以便為負載平衡器設定 mTLS:

  • 信任設定。包含單一信任儲存庫資源,該資源會封裝信任錨點 (根憑證),以及一或多個中繼憑證 (屬於選用性質)。信任設定用於在用戶端憑證和信任錨點之間建立信任鏈結。詳情請參閱「信任設定」。

    您可以選擇使用自行簽署、已過期或其他無效的憑證,或是您無法存取根憑證和中繼憑證,您可以將該憑證新增至 allowlistedCertificates 欄位的信任設定。您不需要信任存放區,即可將憑證新增至許可清單。

    將憑證新增至許可清單,表示只要憑證可剖析、私密金鑰擁有權已建立,且憑證的 SAN 欄位限制已滿足,系統一律會將憑證視為有效。

  • 信任存放區:包含信任錨點和中繼憑證授權單位 (CA) 憑證,用於建立信任鏈結並驗證用戶端憑證。CA 會用來為用戶端核發信任憑證。CA 會透過負載平衡器的信任錨點 (根憑證) 或中介 CA 憑證來識別。

    您可以將下列類型的根憑證和中繼憑證上傳至信任存放區:

  • 用戶端驗證 (也稱為 ServerTLSPolicy)。指定用戶端驗證模式,以及驗證用戶端憑證時要使用的信任設定資源。如果用戶端向負載平衡器提供無效憑證或未提供憑證,用戶端驗證模式會指定如何處理用戶端連線。您可以在伺服器 TLS 政策中指定所有 mTLS 驗證相關參數。用戶端驗證 (ServerTLSPolicy) 資源已附加至目標 HTTPS Proxy 資源。

下圖顯示全球和區域應用程式負載平衡器的目標 HTTPS 代理程式資源所附加的不同 mTLS 元件。

全球

下圖顯示外部應用程式負載平衡器部署作業的元件。這項架構也適用於跨區域內部應用程式負載平衡器,也就是使用全域元件的內部應用程式負載平衡器。

全域外部應用程式負載平衡器元件的 mTLS。
雙向傳輸層安全標準 (TLS) 與全域外部應用程式負載平衡器元件 (按一下可放大)。

區域

下圖顯示區域內部應用程式負載平衡器部署作業的元件。這項架構也適用於區域性外部應用程式負載平衡器,也就是使用區域性元件的外部應用程式負載平衡器。

區域內部應用程式負載平衡器元件的相互 TLS。
雙向傳輸層安全標準 (TLS) 與區域性內部應用程式負載平衡器元件 (按一下可放大)。

用戶端驗證模式

如果用戶端向負載平衡器提供無效憑證或未提供憑證,用戶端驗證 (ServerTLSPolicy) 資源的 clientValidationMode 屬性會指定負載平衡器處理用戶端連線的方式。

用戶端驗證模式的值如下:

  • ALLOW_INVALID_OR_MISSING_CLIENT_CERT:即使用戶端憑證驗證失敗或未提供用戶端憑證,也允許用戶端連線。在這個模式中,負載平衡器會允許來自用戶端的連線,並將所有要求傳遞至後端,不論是否能建立信任鏈。

    在提交用戶端憑證時,系統一律會檢查私密金鑰的證明。如果用戶端無法證明擁有私密金鑰,即使用戶端驗證模式允許無效或缺少的用戶端憑證,TLS 握手也會終止。

  • REJECT_INVALID. 如果用戶端未提供憑證,或憑證驗證失敗,則拒絕連線。在這個模式中,如果負載平衡器無法從用戶端憑證建立信任鏈結,並連回信任錨點,就會終止來自用戶端的連線。

在負載平衡器上設定 mTLS

以下概略說明在負載平衡器上設定 mTLS 時,需要遵循的重要步驟:

  1. 建立信任設定資源,其中包含信任錨點 (根憑證) 和用於信任根的次要憑證。

  2. 將信任設定連結至用戶端驗證 (ServerTLSPolicy) 資源,該資源會定義 ALLOW_INVALID_OR_MISSING_CLIENT_CERTREJECT_INVALID 的用戶端驗證模式。

  3. 將用戶端驗證 (ServerTLSPolicy) 資源附加至負載平衡器的目標 HTTPS Proxy 資源。

  4. 選用:您可以使用自訂 mTLS 標頭,將 mTLS 連線的相關資訊傳遞至後端服務或網址對應。

如要進一步瞭解這項設定,請參閱下列指南:

用戶端憑證驗證步驟

驗證用戶端憑證時,負載平衡器會執行下列操作:

  1. 確認用戶端是否擁有私密金鑰

    在握手程序中產生簽名後,用戶端會證明自己擁有與憑證中公開金鑰相關聯的私密金鑰。負載平衡器會使用用戶端的公開金鑰驗證這個簽名。如果簽署驗證失敗,表示用戶端不是憑證的擁有者,在這種情況下,即使設定允許無效或缺少用戶端憑證,TLS 握手也會終止。全域外部應用程式負載平衡器不會記錄任何錯誤,但區域外部應用程式負載平衡器和內部應用程式負載平衡器會在 proxyStatus 欄位中記錄 TLS 錯誤。

  2. 驗證信任鏈

    負載平衡器會驗證用戶端憑證與已設定的信任設定之間的信任鏈結。驗證檢查項目包括:

    • 用戶端、中繼和根憑證符合憑證規定
    • 父項憑證的主旨欄位與子項憑證的核發者欄位相符。這項驗證可確保父項憑證的身分 (主體) 與子項憑證中列為核發者的身分相同。
    • 父項憑證的主體金鑰 ID (SKID) 與子項憑證中的授權單位金鑰 ID (AKID) 相符。這項比對結果證實子憑證是由正確的根憑證授權單位核發,且可信任,因為 AKID 會參照根憑證的公開金鑰,用於驗證憑證的有效性。
    • 子項憑證的主體別名 (SAN) 不會違反父項憑證中的 NameConstraints 欄位。
  3. 將要求轉送至後端

    如果用戶端憑證驗證成功,系統會使用自訂 mTLS 標頭將要求轉送至後端。

    不過,如果驗證失敗,採取的動作會視用戶端驗證模式的值而定:

    • ALLOW_INVALID_OR_MISSING_CLIENT_CERT:系統會傳送要求,並附上自訂 mTLS 標頭,指出驗證失敗的原因。如要瞭解跨區域內部應用程式負載平衡器、區域性外部應用程式負載平衡器和區域內部應用程式負載平衡器,除了自訂 mTLS 標頭,您還可以設定 mTLS 選用欄位,查看失敗的原因。

    • REJECT_INVALID:連線終止,且錯誤記錄至 Cloud Logging

傳遞至後端的自訂 mTLS 標頭

下表列出可在用戶端憑證通過驗證和失敗時傳遞至後端的自訂 mTLS 標頭變數。如果用戶端憑證驗證失敗,只有在用戶端驗證模式設為 ALLOW_INVALID_OR_MISSING_CLIENT_CERT 時,要求才會傳送至後端。

您也可以在網址對應中設定這些變數。

用戶端憑證狀態 用戶端驗證模式 自訂標頭

用戶端憑證鏈結過長 (用戶端憑證包含超過 10 個中繼憑證)。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_chain_exceeded_limit

client_cert_sha256_fingerprint: <cert hash>

用戶端或中繼憑證的 RSA 金鑰大小無效。

不會執行驗證。

RSA 金鑰的長度可介於 2048 至 4096 位元之間。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_invalid_rsa_key_size

client_cert_sha256_fingerprint: <cert hash>

用戶端或中繼憑證使用不支援的橢圓曲線。

不會執行驗證。

有效的橢圓曲線為 P-256 和 P-384。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_unsupported_elliptic_curve_key

client_cert_sha256_fingerprint: <cert hash>

用戶端或中繼憑證使用非 RSA 和非 ECDSA 演算法。

不會執行驗證。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_unsupported_key_algorithm

client_cert_sha256_fingerprint: <cert hash>

用於驗證的 PKI 包含超過十張中繼憑證,這些憑證共用相同的主體和主體公開金鑰資訊。

不會執行驗證。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_pki_too_large

client_cert_sha256_fingerprint: <cert hash>

用於驗證的中繼憑證有超過 10 個名稱限制。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_chain_max_name_constraints_exceeded

client_cert_sha256_fingerprint: <cert hash>

用戶端憑證沒有包含 clientAuthExtended Key Usage (EKU) 擴充功能。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_chain_invalid_eku

client_cert_sha256_fingerprint: <cert hash>

嘗試驗證憑證鏈結時超過時間限制。 ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_validation_timed_out

client_cert_sha256_fingerprint: <cert hash>

嘗試驗證憑證鏈結時,已達到深度或迭代限制。

憑證鏈的深度上限為十層,包括根憑證和用戶端憑證。最大重複次數為 100 次 (檢查憑證以驗證用戶端憑證鏈結)。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_validation_search_limit_exceeded

client_cert_sha256_fingerprint: <cert hash>

您未設定 TrustConfig 資源,就設定了 mTLS。

無法執行驗證,但憑證雜湊會轉送至後端。

ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_validation_not_performed

client_cert_sha256_fingerprint: <cert hash>

沒有用戶端憑證。 ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: false

client_cert_chain_verified: false

client_cert_error: client_cert_not_provided

client_cert_sha256_fingerprint: <empty>

用戶端憑證無法驗證 TrustConfig 資源。 ALLOW_INVALID_OR_MISSING_CLIENT_CERT

client_cert_present: true

client_cert_chain_verified: false

client_cert_error: client_cert_validation_failed

client_cert_sha256_fingerprint: <cert hash>

用戶端憑證通過憑證驗證工具的驗證。 不適用

client_cert_present: true

client_cert_chain_verified: true

client_cert_error: <empty>

client_cert_sha256_fingerprint: <cert hash>

client_cert_serial_number: <serial_number>

client_cert_valid_not_before: <date>

client_cert_valid_not_after: <date>

client_cert_uri_sans: <list>

client_cert_dnsname_sans: <list>

client_cert_issuer_dn: <issuer>

client_cert_subject_dn: <subject>

client_cert_leaf: <certificate>

client_cert_chain: <list>

剖析傳遞至後端的自訂標頭變數值

部分自訂 mTLS 標頭變數值是二進位唯一編碼規則 (DER) 憑證資料的 Base64 編碼字串表示法。您可以使用所選工具或軟體程式庫解碼 Base64 編碼字串。例如:

  • macOS 和 Linux 系統可使用指令列 base64 工具,這是這兩個作業系統內含的核心公用程式。如要使用 base64 公用程式解碼 Base64 編碼字串,請將已編碼的字串做為標準輸入內容傳遞至 base64 指令,然後使用 -d 標記解碼字串,如下所示:

    echo BASE_64_ENCODED_STRING | base64 -d
    
  • Python 包含 base64 模組,可用於解碼 Base64 編碼字串,如下所示:

    import base64
    encoded_string=BASE_64_ENCODED_STRING
    decoded_string=base64.b64decode(encoded_string).decode()
    print(decoded_string) # Note that a newline character (\n) is added to the end of the string.
    

錯誤處理和記錄

應用程式負載平衡器提供詳細的記錄功能,可讓您監控用戶端憑證驗證、找出潛在問題,以及排解連線問題。本節將概略說明 mTLS 驗證期間可能發生的不同類型錯誤,以及如何記錄這些錯誤。

REJECT_INVALID 模式中記錄的錯誤

如果用戶端憑證驗證失敗,且用戶端驗證模式設為 REJECT_INVALID,連線就會終止,並將錯誤記錄到 Cloud Logging。下表說明這些錯誤。

用戶端憑證狀態 記錄的錯誤
用戶端憑證鏈結過長 (用戶端憑證包含超過 10 個中繼憑證)。 client_cert_chain_exceeded_limit

用戶端或中繼憑證的 RSA 金鑰大小無效。

不會執行驗證。

RSA 金鑰的長度可介於 2048 至 4096 位元之間。

client_cert_invalid_rsa_key_size

用戶端或中繼憑證使用不支援的橢圓曲線。

不會執行驗證。

有效的曲線為 P-256 和 P-384。

client_cert_unsupported_elliptic_curve_key

用戶端或中繼憑證使用非 RSA 或非 ECDSA 演算法。

不會執行驗證。

client_cert_unsupported_key_algorithm

用於驗證的 PKI 包含超過十張共用相同主體和主體公開金鑰資訊的中繼憑證。

不會執行驗證。

client_cert_pki_too_large

用於驗證的中繼憑證有超過 10 個名稱限制。

client_cert_chain_max_name_constraints_exceeded

用戶端憑證沒有包含 clientAuthExtended Key Usage (EKU) 副檔名。

client_cert_chain_invalid_eku

嘗試驗證憑證鏈結時超過時間限制。 client_cert_validation_timed_out

嘗試驗證憑證鏈結時,已達到深度或迭代限制。

憑證鏈的深度上限為十層,包括根憑證和用戶端憑證。迭代次數上限為 100 (檢查憑證以驗證用戶端憑證鏈結)。

client_cert_validation_search_limit_exceeded
您未設定 TrustConfig 資源,就設定了 mTLS。 client_cert_validation_not_performed
在握手期間,用戶端未提供要求的憑證。 client_cert_not_provided
用戶端憑證無法通過 TrustConfig 資源的驗證。 client_cert_validation_failed

關閉連線的記錄錯誤

如果用戶端驗證模式設為 ALLOW_INVALID_OR_MISSING_CLIENT_CERTREJECT_INVALID,某些錯誤會導致連線關閉,並記錄至 Cloud Logging。下表說明這些錯誤。

用戶端憑證狀態 要求 記錄的錯誤
用戶端憑證在握手期間無法通過簽名比對。 終止安全資料傳輸層 (SSL) 握手
服務無法執行憑證鏈結驗證。 終止連線 client_cert_validation_unavailable
驗證憑證鏈結時發生內部錯誤。 終止連線 client_cert_validation_internal_error
找不到相符的 TrustConfig 終止連線 client_cert_trust_config_not_found
用戶端憑證酬載 (包括任何中介憑證) 過大 (超過 16 KB)。 終止連線 client_cert_exceeded_size_limit

如果後端服務已啟用記錄功能,您可以查看 mTLS 用戶端憑證驗證期間關閉連線的記錄錯誤

限制

  • 負載平衡器不會對用戶端憑證執行撤銷檢查。

  • 應用程式負載平衡器可讓您上傳信任設定,其中包含單一信任儲存庫,最多可包含:信任錨點和中繼憑證的總數 (中繼憑證數量上限為 100),以及加入許可清單的 500 個憑證。所有中繼憑證不得超過三張,且必須共用相同的主體和主體公開金鑰資訊。詳情請參閱「配額和限制」。

  • 憑證鏈的深度上限為十,包括根憑證和用戶端憑證。嘗試建立信任鏈時,中繼憑證的評估次數上限為 100 次。詳情請參閱「配額與限制」。

  • 從用戶端上傳及傳遞的憑證金鑰僅限於以下項目:

    • RSA 金鑰的長度可介於 2048 至 4096 位元之間。詳情請參閱配額與限制一文。
    • ECDSA 金鑰可使用 P-256 或 P-384 曲線。
  • 從用戶端收到的已接受憑證鏈結大小上限為 16 KB,且憑證數量上限為 10 個。詳情請參閱「配額與限制」。

  • 用於驗證的根憑證最多只能包含 10 個名稱限制。詳情請參閱「配額與限制」。

  • 第 1 層 Google Front End (GFE) 會強制執行 10 秒的非可設定逾時時間,讓用戶端在 TLS 握手期間出示憑證。在負載高峰期,這個逾時值可能會縮短。用戶端必須在這個時間範圍內完成憑證提交作業,才能順利建立 mTLS 連線。

後續步驟