使用用户提供的证书设置双向 TLS

本页面介绍了如何创建根证书和已签名的中间证书,然后如何将这些证书上传到 Certificate Manager TrustConfig 资源。如果您要上传现有证书,请跳过创建新证书的步骤。

您还将创建为应用负载均衡器配置双向 TLS (mTLS) 所需的网络安全资源。本页面中的说明使用 OpenSSL 创建根证书和中间证书。

准备工作

权限

如需获得完成本指南所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:

  • Compute Load Balancer Admin (roles/compute.loadBalancerAdmin)(如需创建负载均衡器资源,例如 TargetHTTPSProxy
  • Certificate Manager Owner (roles/certificatemanager.owner)(如需使用证书管理器资源)
  • Compute Network Admin (roles/compute.networkAdmin) 和 Compute Security Admin (roles/compute.securityAdmin)(如需创建安全和网络组件)
  • Project Creator (roles/resourcemanager.projectCreator)(如需创建项目)(可选)

如需详细了解如何授予角色,请参阅管理访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

生成密钥和签名证书

本部分使用 openssl 命令创建根证书和中间证书。

使用以下命令生成具有有效 keyUsageextendedKeyUsage 字段的根证书和已签名的中间证书。

  1. 创建示例 example.cnf 文件,其中包含创建有效签名证书所需的最低配置。如果您要在这些证书上设置任何其他字段,可以修改此文件。

    cat > example.cnf << EOF
    [req]
    distinguished_name = empty_distinguished_name
    [empty_distinguished_name]
    # Kept empty to allow setting via -subj command line arg.
    [ca_exts]
    basicConstraints=critical,CA:TRUE
    keyUsage=keyCertSign
    extendedKeyUsage=clientAuth
    EOF
    
  2. 创建根证书。

    openssl req -x509 \
        -new -sha256 -newkey rsa:2048 -nodes \
        -days 3650 -subj '/CN=root' \
        -config example.cnf \
        -extensions ca_exts \
        -keyout root.key -out root.cert
    
  3. 为中间证书创建签名请求。

    openssl req \
        -new -sha256 -newkey rsa:2048 -nodes \
        -subj '/CN=int' \
        -config example.cnf \
        -extensions ca_exts \
        -keyout int.key -out int.req
    
  4. 创建中间证书。

    openssl x509 -req \
        -CAkey root.key -CA root.cert \
        -set_serial 1 \
        -days 3650 \
        -extfile example.cnf \
        -extensions ca_exts \
        -in int.req -out int.cert
    

生成已列入许可名单的证书

本部分使用 openssl 命令创建已列入许可名单的示例证书。

请使用以下命令生成已列入许可名单的证书。

   openssl req -x509 \
       -new -sha256 -newkey rsa:2048 -nodes \
       -days 3650 -subj '/CN=localhost' \
       -keyout allowlisted.key -out allowlisted.cert

设置证书格式

如需在 TrustStore 中包括新证书或现有证书,请将证书格式设置为单行并将它们存储在环境变量中,以便证书可以读入 YAML 文件中。请使用以下命令设置证书格式并将其存储在环境变量中:

export ROOT_CERT=$(cat root.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')
export INTERMEDIATE_CERT=$(cat int.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')

如需在信任配置中包括已列入许可名单的新证书或现有证书,请将证书格式设置为单行并将它们存储在环境变量中,以便证书可以读入 YAML 文件中。请使用以下命令设置已列入许可名单的证书的格式并将它们存储在环境变量中:

export ALLOWLISTED_CERT=$(cat allowlisted.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')

创建 TrustConfig 资源

创建代表 PKI 的证书管理器 TrustConfig 资源。此示例 TrustConfig 资源包含一个受信任证书存储区,其中有两个信任锚和两个中间 CA 证书。它会从上一步设置证书格式中创建的环境变量读取证书内容。

如需创建包含其他信任锚或中间 CA 证书的信任库,请在相应的部分中添加 pemCertificate 行。如果信任锚或中间 CA 证书较少,请移除不需要的行。

此示例 TrustConfig 资源包含已列入许可名单的证书。您可以使用 pemCertificate 字段的多个实例指定多个已列入许可名单的证书。

在以下步骤中,将 TRUST_CONFIG_NAME 替换为 TrustConfig 资源的名称:

  1. 如需创建包含受信任证书存储区的 trust_config.yaml 文件,请使用以下命令:

    cat << EOF > trust_config.yaml
    trustStores:
    - trustAnchors:
      - pemCertificate: "${ROOT_CERT?}"
      - pemCertificate: "${ROOT_CERT_2?}"
      intermediateCas:
      - pemCertificate: "${INTERMEDIATE_CERT?}"
      - pemCertificate: "${INTERMEDIATE_CERT_2?}"
    EOF
    
  2. 可选:如需创建包含已列入许可名单的证书的 trust_config.yaml 文件,请使用以下命令:

    cat << EOF > trust_config.yaml
     allowlistedCertificates:
     - pemCertificate: "${ALLOWLISTED_CERT?}"
    EOF
    
  3. 如需创建 Certificate Manager TrustConfig 资源,请使用 gcloud certificate-manager trust-configs import 命令

    全局

    对于外部应用负载均衡器和跨区域内部应用负载均衡器,请使用以下命令:

    gcloud certificate-manager trust-configs import TRUST_CONFIG_NAME  \
       --source=trust_config.yaml
    

    区域级

    对于区域级外部应用负载均衡器和区域级内部应用负载均衡器,请使用以下命令:

    gcloud certificate-manager trust-configs import TRUST_CONFIG_NAME  \
       --source=trust_config.yaml \
       --location=REGION
    

创建网络安全资源

借助服务器 TLS 政策(ServerTLSPolicy 网络安全资源),您可以指定在验证客户端证书时使用的服务器端 TLS 模式和 TrustConfig 资源。当客户端向负载均衡器提供无效证书或没有证书时,clientValidationMode 指定客户端连接的处理方式。

  • clientValidationMode 设置为 ALLOW_INVALID_OR_MISSING_CLIENT_CERT 时,即使验证失败或缺少客户端证书,所有请求都会传递给后端。
  • clientValidationMode 设置为 REJECT_INVALID 时,只有提供能够针对 TrustConfig 资源进行验证的客户端证书的请求才会传递给后端。

如需创建 ServerTLSPolicy 资源,请完成以下步骤:

  1. 根据您希望处理连接的方式,选择以下选项之一。

    在以下步骤中,将 SERVER_TLS_POLICY_NAME 替换为服务器 TLS 政策的名称,并将 PROJECT_ID 替换为您的 Google Cloud 项目的 ID。

    • 方法 1clientValidationMode 设置为 ALLOW_INVALID_OR_MISSING_CLIENT_CERT

      要创建 server_tls_policy.yaml 文件,请使用以下命令:

      全局

      对于外部应用负载均衡器和跨区域内部应用负载均衡器,请使用以下命令:

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT
        clientValidationTrustConfig: projects/PROJECT_ID/locations/global/trustConfigs/TRUST_CONFIG_NAME
      EOF
      

      区域级

      对于区域级外部应用负载均衡器和区域级内部应用负载均衡器,请使用以下命令:

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT
        clientValidationTrustConfig: projects/PROJECT_ID/locations/REGION/trustConfigs/TRUST_CONFIG_NAME
      EOF
      
    • 方法 2:将 clientValidationMode 设置为 REJECT_INVALID

      要创建 server_tls_policy.yaml 文件,请使用以下命令:

      全局

      对于外部应用负载均衡器和跨区域内部应用负载均衡器,请使用以下命令:

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: REJECT_INVALID
        clientValidationTrustConfig: projects/PROJECT_ID/locations/global/trustConfigs/TRUST_CONFIG_NAME
      EOF
      

      区域级

      对于区域级外部应用负载均衡器和区域级内部应用负载均衡器,请使用以下命令:

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: REJECT_INVALID
        clientValidationTrustConfig: projects/PROJECT_ID/locations/REGION/trustConfigs/TRUST_CONFIG_NAME
      EOF
      
  2. 如需创建 ServerTlsPolicy 资源,请使用 gcloud network-security server-tls-policies import 命令

    全局

    对于外部应用负载均衡器和跨区域内部应用负载均衡器,请使用以下命令:

    gcloud network-security server-tls-policies import SERVER_TLS_POLICY_NAME \
      --source=server_tls_policy.yaml \
      --location=global
    

    区域级

    对于区域级外部应用负载均衡器和区域级内部应用负载均衡器,请使用以下命令:

    gcloud network-security server-tls-policies import SERVER_TLS_POLICY_NAME \
      --source=server_tls_policy.yaml \
      --location=REGION
    

如需了解详情,请参阅 MTLS 客户端验证模式

使用中间证书对客户端密钥进行签名

本部分提供了用于生成叶证书的其他配置选项。如果您已使用中间证书(int.certint.key创建了 TrustConfig 资源,请按照以下说明进行操作:

  1. 创建客户端密钥配置文件。

    cat > client.config << EOF
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    
    [extension_requirements]
    basicConstraints          = critical, CA:FALSE
    keyUsage                  = critical, nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage          = clientAuth
    
    [dn_requirements]
    countryName               = US
    stateOrProvinceName       = California
    localityName              = San Francisco
    0.organizationName        = example
    organizationalUnitName    = test
    commonName                = test.example.com
    emailAddress              = test@example.com
    
    EOF
    

    如果您要附加 SPIFFE 身份:

    • [extension_requirements] 部分添加 subjectAltName,如下所示:

      subjectAltName            = @sans_list
      
    • client.config 文件底部添加一个新部分,其中包含以下内容:

      [sans_list]
      URI.1                     = spiffe://example.com/test-identity
      
  2. 对密钥进行签名。

    openssl req -new -keyout client.key -out client.csr -config client.config
    
    openssl x509 -req -in client.csr -out client.cert -extfile client.config -extensions extension_requirements -days 365 -CA int.cert -CAkey int.key
    
  3. 如需进行测试,请向负载均衡器的 IP 地址发送 curl 请求。

    curl -v -k --key client.key --cert client.cert https://IP_ADDRESS
    

    IP_ADDRESS 替换为负载均衡器的 IP 地址。

后续步骤