创建从属证书授权机构

本页面介绍了创建从属证书授权机构 (Sub CA) 的步骤。

子 CA 负责直接向最终实体(例如用户、计算机和设备)颁发证书。它们由父 CA(通常是根 CA)以加密方式签名。信任根 CA 的系统会自动信任子 CA 及其颁发的证书。

CA 证书签名者可以是 CA Service 中创建的另一个 CA(例如根 CA),也可以是外部 CA。对于外部 CA,CA Service 会生成证书签名请求 (CSR),该请求必须由外部 CA 签名。

准备工作

如需获得创建子证书授权机构所需的权限,请让组织 IAM 管理员向您授予 Certificate Authority Service Admin (certificate-authority-service-admin) 角色。如需详细了解角色,请参阅角色定义

获取 kubeconfig 文件

如需针对管理 API 服务器运行命令,请确保您拥有以下资源:

  • 登录并生成管理 API 服务器的 kubeconfig 文件(如果您还没有)。

  • 使用管理 API 服务器的 kubeconfig 文件路径替换这些说明中的 MANAGEMENT_API_SERVER_KUBECONFIG

创建受管理的子 CA

对于受管理的从属 CA,CA 证书的签名者是在 CA Service 中创建的另一个 CA(根 CA)。

如需创建受管理的子 CA,请将自定义资源应用于 Distributed Cloud Appliance 实例。

  1. 创建 CertificateAuthority 资源并将其保存为名为 subca.yaml 的 YAML 文件:

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateAuthority
    metadata:
      Name: SUB_CA_NAME
      namespace: USER_PROJECT_NAMESPACE
    spec:
      caProfile:
        commonName: COMMON_NAME
        duration: DURATION
        renewBefore: RENEW_BEFORE
        organizations:
        - ORGANIZATIONS
        organizationalUnits:
        - ORGANIZATIONAL_UNITS
        countries:
        - COUNTRIES
        localities:
        - LOCALITIES
        provinces:
        - PROVINCES
        streetAddresses:
        - STREET_ADDRESSES
        postalCodes:
        - POSTAL_CODES
      caCertificate:
        managedSubCA:
          certificateAuthorityRef:
            name: ROOT_CA_NAME
            namespace: USER_PROJECT_NAMESPACE
      certificateProfile:
        keyUsage:
          - digitalSignature
          - keyCertSign
          - crlSign
        extendedKeyUsage:
          - EXTENDED_KEY_USAGE
      secretConfig:
        secretName: SECRET_NAME
        privateKeyConfig:
          algorithm: KEY_ALGORITHM
          size: KEY_SIZE
      acme:
        enabled: ACME_ENABLED
    

    执行以下变量替换操作:

    变量 说明
    SUB_CA_NAME 子 CA 的名称。
    USER_PROJECT_NAMESPACE 用户项目所在的命名空间的名称。
    COMMON_NAME CA 证书的通用名称。
    DURATION CA 证书的请求有效期。
    ROOT_CA_NAME 根 CA 的名称。
    SECRET_NAME 包含私钥和已签名的 CA 证书的 Kubernetes Secret 的名称。

    以下变量是可选值:

    变量 说明
    RENEW_BEFORE 在 CA 证书过期之前进行轮替的时间。
    ORGANIZATIONS 证书上要使用的组织。
    ORGANIZATIONAL_UNITS 证书上要使用的组织部门。
    COUNTRIES 证书上要使用的国家/地区。
    LOCALITIES 证书上要使用的城市。
    PROVINCES 证书上要使用的州或省/直辖市/自治区。
    STREET_ADDRESSES 证书上要使用的街道地址。
    POSTAL_CODES 证书上要使用的邮政编码。
    EXTENDED_KEY_USAGE 证书的扩展密钥用途。如果提供,允许的值为 serverAuthclientAuth
    KEY_ALGORITHYM 相应证书所用的私钥算法。允许的值为 RSA、Ed25519 或 ECDSA。如果未提供大小,则对于 ECDSA,默认值为 256;对于 RSA,默认值为 2048。对于 Ed25519,系统会忽略密钥大小。
    KEY_SIZE 相应证书的私钥大小(以位为单位)取决于算法。RSA 允许 2048、3072、4096 或 8192 位(默认 2048 位)。ECDSA 允许 256、384 或 521(默认 256)。Ed25519 会忽略大小。
    ACME_ENABLED 如果设置为 true,CA 将在 ACME 模式下运行,并输出 ACME 服务器网址。然后,您可以使用 ACME 客户端和协议来管理证书。
  2. 将自定义资源应用于 Distributed Cloud 实例:

    kubectl apply -f subca.yaml --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    

    MANAGEMENT_API_SERVER_KUBECONFIG 替换为管理 API 服务器的 kubeconfig 文件的路径。

  3. 验证子 CA 的就绪情况。CA 大约需要 40 分钟才能准备就绪:

    kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificateauthority.pki.security.gdc.goog/SUB_CA_NAME -ojson | jq -r ' 
    .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    输出类似于以下内容:

    {
      "lastTransitionTime": "2025-01-24T17:09:29Z",
      "message": "CA reconciled",
      "observedGeneration": 2,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    

从外部 CA 创建从属 CA

此子 CA 支持使用外部 CA 或用户管理的 CA 对叶证书进行签名。它会生成供用户签名的 CSR。

  1. 创建 CertificateAuthority 资源并将其保存为名为 subca-external.yaml 的 YAML 文件:

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateAuthority
    metadata:
      Name: SUB_CA_NAME
      namespace: USER_PROJECT_NAMESPACE
    spec:
      caProfile:
        commonName: COMMON_NAME
        duration: DURATION
        renewBefore: RENEW_BEFORE
        organizations:
        - ORGANIZATION
        organizationalUnits:
        - ORGANIZATIONAL_UNITS
        countries:
        - COUNTRIES
        localities:
        - LOCALITIES
        provinces:
        - PROVINCES
        streetAddresses:
        - STREET_ADDRESSES
        postalCodes:
        - POSTAL_CODES
      caCertificate:
        externalCA: {}
      certificateProfile:
        keyUsage:
          - digitalSignature
          - keyCertSign
          - crlSign
        extendedKeyUsage:
          - EXTENDED_KEY_USAGE
      secretConfig:
        secretName: SECRET_NAME
        privateKeyConfig:
          algorithm: KEY_ALGORITHM
          size: KEY_SIZE
      acme:
        enabled: ACME_ENABLED
    

    执行以下变量替换操作:

    变量 说明
    SUB_CA_NAME 子 CA 的名称。
    USER_PROJECT_NAMESPACE 要将映像导入到的项目的项目 ID。
    COMMON_NAME CA 证书的通用名称。
    DURATION CA 证书的请求有效期
    SECRET_NAME 包含私钥和已签名的 CA 证书的 Kubernetes Secret 的名称。

    以下变量是可选值:

    变量 说明
    RENEW_BEFORE 在 CA 证书过期之前进行轮替的时间。
    ORGANIZATION 证书上要使用的组织。
    ORGANIZATIONAL_UNITS 证书上要使用的组织部门。
    COUNTRIES 证书上要使用的国家/地区。
    LOCALITIES 证书上要使用的城市。
    PROVINCES 证书上要使用的州或省/直辖市/自治区。
    STREET_ADDRESSES 证书上要使用的街道地址。
    POSTAL_CODES 证书上要使用的邮政编码。
    EXTENDED_KEY_USAGE 证书的扩展密钥用途。如果提供,允许的值为 serverAuthclientAuth
    KEY_ALGORITHYM 相应证书所用的私钥算法。允许的值为 RSAEd25519ECDSA。如果未提供大小,则对于 ECDSA,大小默认为 256;对于 RSA,大小默认为 2048。对于 Ed25519,密钥大小会被忽略。
    KEY_SIZE 相应证书的私钥大小(以位为单位)取决于算法。RSA 允许 2048、3072、4096 或 8192(默认 2048)。 ECDSA 允许 256、384 或 521(默认值为 256)。Ed25519 会忽略大小。
    ACME_ENABLED 如果设置为 true,CA 将在 ACME 模式下运行,并输出 ACME 服务器网址。然后,您可以使用 ACME 客户端和协议来管理证书。
  2. 将自定义资源应用于 Distributed Cloud 实例:

    kubectl apply -f subca-external.yaml --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    
  3. 在 GDC 管理 API 服务器中生成子 CA 的 CSR。您必须下载 CSR 并对其进行签名。签名后,您可以将签名后的证书上传到 GDC Management API 服务器。

  4. 从 Distributed Cloud 环境中收集证书签名请求 (CSR):

    kubectl get certificateauthorities SUB_CA_NAME -n USER_PROJECT_NAMESPACE -ojson | jq -j '"echo ", .status.externalCA.csr, " | base64 -d > ","sub_ca.csr\n"' | bash
    

    该命令会在当前目录中生成一个名为 sub_ca.csr 的 CSR 文件。此文件包含 X.509 CA 证书的 CSR。

  5. 使用客户的根 CA 为 sub_ca.csr 文件请求已签名的 CA 证书。

  6. 对于已获批准的证书签名请求,您必须获取由客户的根 CA 签名的 CA 证书。将证书存储在当前目录中的 sub_ca.crt 文件中。

  7. 如果适用,请获取客户的根 CA 证书,并将其存储在当前目录的 ca.crt 文件中。

  8. 验证证书中的主题备用名称 (SAN) 扩展项:

    openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject Alternative Name"
    

    如果 CA 证书具有公用名 (CN) 而不是 SAN,请验证证书中的 CN:

    openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject: CN"
    
  9. 生成 spec 以修补 CertificateAuthority 资源:

    echo "spec:
      caCertificate:
        externalCA:
          signedCertificate:
            certificate: $(base64 -w0 SUB_CA_NAME.crt)
            ca: $(base64 -w0 ca.crt)" > patch.txt
    

    patch.txt 文件中的内容类似于以下内容:

    spec:
      caCertificate:
        externalCA:
          signedCertificate:
            certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ…
            ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
    
  10. 修改 CertificateAuthority 资源的 spec 字段:

    kubectl patch certificateauthority SUB_CA_NAME -n USER_PROJECT_NAMESPACE--patch-file patch.txt --type='merge'
    
  11. 验证自带 (BYO) 子 CA 的就绪情况。CA 通常需要大约 40 分钟才能准备就绪:

    kubectl -n USER_PROJECT_NAMESPACE get certificateauthority.pki.security.gdc.goog/SUB_CA_NAME -ojson | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    输出类似于以下内容:

    {
      "lastTransitionTime": "2024-04-30T22:10:50Z",
      "message": "Certificate authority is ready for use",
      "observedGeneration": 3,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    
  12. 验证已签名的 CA 证书的失效日期:

    kubectl -n USER_PROJECT_NAMESPACE get secret SECRET_NAME -ojson | jq -j '"echo ", .metadata.name, " $(echo ", .data["tls.crt"], "| base64 -d | openssl x509 -enddate -noout)\n"' | bash
    

列出 CA

如需列出 Distributed Cloud 空气隔离实例中的所有 Certificate Authority Service 资源,请执行以下操作:

使用 certificateauthorities 参数列出所有 CertificateAuthority 资源:

   kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificateauthorities

输出类似于以下内容:

   NAMESPACE    NAME              READY   REASON   AGE
   foo          root-ca           True    Ready    7h24m
   foo          sub-ca            True    Ready    7h24m