双向 TLS 身份验证

通常,在与 HTTPS 通信时,身份验证仅使用一种方式:客户端验证服务器的身份。

如果应用要求负载均衡器对连接到应用的客户端身份进行身份,请使用双向 TLS (mTLS)。

如果使用 mTLS,负载均衡器会请求客户端在与负载均衡器进行 TLS 握手期间发送证书以进行身份验证。您可以配置负载均衡器用来验证客户端证书信任链的信任库。

以下应用负载均衡器支持 mTLS:

  • 全球外部应用负载均衡器
  • 传统应用负载均衡器
  • 区域级外部应用负载均衡器(预览版)
  • 区域级内部应用负载均衡器(预览版)
  • 跨区域内部应用负载均衡器

架构

负载均衡器需要以下资源才能支持 mTLS 身份验证部署:

  • 服务器 TLS 政策 (ServerTLSPolicy) 资源。允许您指定在验证客户端证书时使用的服务器端 TLS 模式和 TrustConfig 资源。服务器 TLS 政策支持 mTLS 身份验证。服务器 TLS 政策可以关联到目标 HTTPS 代理资源。

  • 一项 TrustConfig 资源。 Certificate Manager 资源。TrustConfig 包含一个用于验证客户端证书的受信任证书存储区资源。如需了解详情,请参阅管理信任配置

    您可以将已列入许可名单的证书上传到 TrustConfig。只要证书可解析、已建立私钥所有权证明并满足针对证书 SAN 字段的限制条件,已列入许可名单的证书就会始终被视为有效。过期的证书在列入许可名单时也会被视为有效。

  • 受信任证书存储区。包含用于验证客户端证书链的信任锚和中间证书授权机构 (CA) 证书。CA 用于为客户端颁发可信证书。CA 由负载均衡器的信任锚根证书或中间 CA 证书进行标识。

    您可以将以下类型的客户端证书上传到受信任证书存储区:

下图显示了 mTLS 组件:

全局

下图展示了外部应用负载均衡器部署的组件。此架构也适用于跨区域内部应用负载均衡器,即使用全球组件的内部应用负载均衡器。

使用全球外部应用负载均衡器组件的双向 TLS。
图 1. 使用全球外部应用负载均衡器组件的双向 TLS(点击可放大)。

区域级

下图展示了区域级内部应用负载均衡器部署的组件。此架构也适用于区域级外部应用负载均衡器,即使用区域级组件的外部应用负载均衡器。

使用区域级内部应用负载均衡器组件的双向 TLS。
图 1. 使用区域级内部应用负载均衡器组件的双向 TLS(点击可放大)。

如需详细了解应用负载均衡器部署的组件,请参阅以下部分:

特性

借助适用于负载均衡器的 mTLS 支持的功能,您可以执行以下操作:

  • 验证客户端提供的证书私钥所有权的证明。

  • 采用以下两种模式之一验证客户端证书:

    • 如果我们无法根据受信任证书存储区验证客户端证书链,请拒绝请求。
    • 将所有请求都传递到后端,即使它们未提供客户端证书也是如此。
  • 对上传的 PKI 锚标记执行客户端证书验证。支持单独添加多个 PKI 锚,以方便从旧的 PKI 迁移到新的 PKI,且没有停机时间。

  • 提供其他中间证书,用于根据指定的 PKI 锚标记验证路径。中间证书可让您对未通过完整证书链的客户端使用 mTLS。

  • 生成证书指纹并将其作为自定义请求标头传递给后端。

  • 使用自定义请求标头将从证书中提取的选定字段传递给后端。

  • 使用自定义请求标头,将验证结果和任何验证错误传递给后端。

如需查看验证流程的详细说明,请参阅本页面后面的客户端证书验证步骤部分。

MTLS 客户端验证模式

当客户端向负载均衡器提供无效证书或没有证书时,clientValidationMode 会说明如何处理客户端连接。

clientValidationMode 值如下所示:

  • 即使客户端证书的证书链验证失败或未提供客户端证书,ALLOW_INVALID_OR_MISSING_CLIENT_CERT 也会允许从客户端进行连接。提供客户端证书时,系统始终会检查私钥的所有权证明。

    您可以使用此模式的自定义标头变量向后端指示客户端是否提供了证书、证书验证是否成功以及从证书中提取的其他信息。

  • 如果客户端未提供证书或者证书验证失败,REJECT_INVALID 会拒绝连接。

在后端服务上启用日志记录后,您可以查看 mTLS 客户端证书验证的日志

传递给后端的自定义标头值

下表显示了始终传递给后端的所有双向 TLS 自定义标头变量值(请求类型“将请求传递给后端”)。如果 clientValidationMode 设置为 ALLOW_INVALID_OR_MISSING_CLIENT_CERT 或客户端证书通过证书验证,则自定义标头将传递给后端。

客户端证书状态 clientValidationMode 自定义标头

客户端证书链太长(超过 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 具有 10 个以上的中间证书,它们共享相同的主体和主体公钥信息。

不执行验证。

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>

在尝试验证证书链时达到深度或迭代限制。

证书链的深度上限为 10,包括根证书和客户端证书。迭代次数上限为 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>

关闭连接时记录的错误

clientValidationMode 设置为 ALLOW_INVALID_OR_MISSING_CLIENT_CERTREJECT_INVALID 时,以下错误会导致客户端连接关闭。如需了解详情,请参阅 statusDetails HTTP 失败消息。这些错误会记录到 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

REJECT_INVALID 验证记录的错误

clientValidationMode 设置为 REJECT_INVALID 时,以下错误会导致连接关闭(请求类型“终止连接”)。如需了解详情,请参阅 statusDetails HTTP 失败消息。这些错误会记录到 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 具有 10 个以上的中间证书,它们共享相同的主体和主体公钥信息。

不执行验证。

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

在尝试验证证书链时达到深度或迭代限制。

证书链的深度上限为 10,包括根证书和客户端证书。迭代次数上限为 100(为验证客户端证书链所检查的证书)。

client_cert_validation_search_limit_exceeded
您在未设置 TrustConfig 资源的情况下配置了 mTLS。 client_cert_validation_not_performed
客户端在握手期间未提供请求的证书。 client_cert_not_provided
客户端证书未通过 TrustConfig 资源验证。 client_cert_validation_failed

客户端证书验证步骤

验证客户端证书时,负载均衡器会执行以下步骤:

  1. 负载均衡器会验证客户端的签名,以证明客户端拥有客户端证书的私钥。 如果此步骤失败,则负载均衡器始终无法完成 TLS 握手(即使您的配置允许客户端证书无效或缺失),并且不会记录任何信息。
  2. 如果配置包含 TrustAnchor,则负载均衡器会验证客户端证书和配置的 TrustAnchor 之间的信任链。具体而言,负载均衡器会验证以下内容:
    • 客户端证书、中间证书和根证书符合证书要求
    • 父证书中的主体字段与子证书中的问题字段匹配。
    • 父证书的主体密钥标识符 (SKID) 与子证书中的授权机构密钥标识符 (AKID) 匹配。
    • 子证书的 SAN 未违反父证书中的 NameConstraints 字段。
  3. 如果验证信任链成功,则请求会通过为端点配置的任何 mTLS 自定义标头转发到后端。
  4. 如果信任链验证失败,请执行以下操作:
    • 如果 ClientValidationMode 设置为 REJECT_INVALID,则负载均衡器会终止连接并将原因记录到 Cloud Logging
    • 如果 ClientValidationMode 设置为 ALLOW_INVALID_OR_MISSING_CLIENT_CERTIFICATE,则负载均衡器仍会将请求转发到后端。您可以使用自定义请求标头向后端指示验证失败以及失败原因。对于跨区域内部应用负载均衡器、区域级外部应用负载均衡器或区域级内部应用负载均衡器,除了自定义请求标头之外,您还可以配置 mTLS 可选字段来检查失败的原因。

证书要求

  • 证书必须使用 RSA 或 ECDSA 加密方式。
  • 对于客户端(叶)证书:
  • 对于根证书和中间证书:
    • 基本限制条件扩展程序必须包含 CA=true
    • 密钥用途扩展程序必须设置为 keyCertSign
    • 扩展密钥用途扩展程序应包含 clientAuth 字段。这对于颁发客户端证书的证书是必需的。
    • 该证书不得过期。

限制

  • 负载均衡器不会对客户端证书执行撤消检查。

  • 借助应用负载均衡器,您可以上传其单个受信任证书存储区最多包含 100 个信任锚和 100 个中间证书以及 500 个已列入许可名单的证书的信任配置。所有中间证书不得超过三个共享相同主体和主体公钥信息的证书。如需了解详情,请参阅配额和限制

  • 证书链的深度上限为 10,包括根证书和客户端证书。在尝试构建信任链时,评估中间证书的次数上限为 100。如需了解详情,请参阅配额和限制

  • 从客户端上传和传递的证书的密钥仅限于以下项:

    • RSA 密钥可为 2048 位到 4096 位。如需了解详情,请参阅配额和限制
    • ECDSA 密钥可以使用 P-256 或 P-384 曲线。
  • 从客户端收到的接受证书链限制为最多 16 KB 和 10 个证书。如需了解详情,请参阅配额和限制

  • 用于验证的根证书不得超过 10 个名称限制条件。如需了解详情,请参阅配额和限制

  • 负载均衡器始终将自签名客户端证书视为无效。

后续步骤