Crie uma autoridade de certificação subordinada

Este documento descreve os passos para criar uma autoridade de certificação subordinada (Sub CA).

As Sub CAs são responsáveis pela emissão de certificados diretamente para entidades finais, como utilizadores, computadores e dispositivos. São assinadas criptograficamente por uma CA principal, muitas vezes a CA de raiz. Os sistemas que confiam na CA de raiz confiam automaticamente nas Sub CAs e nos certificados que emitem.

O signatário do certificado da CA pode ser outra CA criada no serviço de AC, por exemplo, a CA de raiz, ou uma CA externa. Com as CAs externas, o serviço de AC gera um pedido de assinatura de certificado (CSR) que a CA externa tem de assinar.

Este documento destina-se a públicos-alvo no grupo de operadores de aplicações, como programadores de aplicações ou cientistas de dados, que gerem os ciclos de vida dos certificados nos respetivos projetos. Para mais informações, consulte o artigo Públicos-alvo da documentação isolada do GDC.

Antes de começar

Antes de poder criar uma Sub CA, tem de pedir as autorizações necessárias e preparar o seu ambiente.

Peça as funções do IAM

Para criar, atualizar e eliminar recursos da autoridade de certificação, contacte o administrador do IAM da organização para pedir a função de administrador do serviço de autoridade de certificação (certificate-authority-service-admin) no espaço de nomes do projeto da autoridade de certificação.

Prepare o seu ambiente

Crie uma Sub CA gerida

Para uma Sub CA gerida, o signatário do certificado da CA é outra CA (CA de raiz) criada no serviço de AC.

Para criar uma Sub CA gerida, aplique um recurso personalizado à sua instância do Distributed Cloud Appliance.

  1. Crie um recurso CertificateAuthority e guarde-o como um ficheiro YAML denominado subca.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
    

    Substitua as seguintes variáveis:

    Variável Descrição
    SUB_CA_NAME O nome da Sub CA.
    USER_PROJECT_NAMESPACE O nome do espaço de nomes onde reside o projeto do utilizador.
    COMMON_NAME O nome comum do certificado da CA.
    DURATION O tempo de vida útil pedido do certificado da CA. Especifique como uma duração em horas (por exemplo, 1000h). As unidades, como dias (d) ou anos (y), não são compatíveis.
    ROOT_CA_NAME O nome da CA de raiz.
    SECRET_NAME O nome do segredo do Kubernetes que contém a chave privada e o certificado da CA assinado.

    As seguintes variáveis são valores opcionais:

    Variável Descrição
    RENEW_BEFORE O tempo de rotação antes de o certificado da CA expirar.
    ORGANIZATIONS Organizações a usar no certificado.
    ORGANIZATIONAL_UNITS Unidades organizacionais a usar no certificado.
    COUNTRIES Países a usar no certificado.
    LOCALITIES Cidades a usar no certificado.
    PROVINCES Estados ou províncias a usar no certificado.
    STREET_ADDRESSES Moradas a usar no certificado.
    POSTAL_CODES Códigos postais a usar no certificado.
    EXTENDED_KEY_USAGE A utilização alargada da chave para o certificado. Se for fornecido, os valores permitidos são serverAuth e clientAuth.
    KEY_ALGORITHYM O algoritmo de chave privada usado para este certificado. Os valores permitidos são RSA, Ed25519 ou ECDSA. Se o tamanho não for fornecido, a predefinição é 256 para ECDSA e 2048 para RSA. O tamanho da chave é ignorado para Ed25519.
    KEY_SIZE O tamanho, em bits, da chave privada para este certificado depende de o algoritmo. O RSA permite 2048, 3072, 4096 ou 8192 (predefinição 2048). O ECDSA permite 256, 384 ou 521 (predefinição 256). O Ed25519 ignora o tamanho.
    ACME_ENABLED Se estiver definido como true, a CA é executada no modo ACME e apresenta o URL do servidor ACME. Em seguida, pode usar o cliente e o protocolo ACME para gerir certificados.
  2. Aplique o recurso personalizado à sua instância do Distributed Cloud:

    kubectl apply -f subca.yaml --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    

    Substitua MANAGEMENT_API_SERVER_KUBECONFIG pelo caminho para o ficheiro kubeconfig do servidor da API de gestão.

  3. Valide a preparação da Sub CA. A CA demora cerca de 40 minutos a ficar pronta:

    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))'
    

    O resultado é semelhante ao seguinte:

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

Crie uma Sub CA a partir de uma CA externa

Esta Sub CA é compatível com a assinatura de certificados de folha com CAs externas ou geridas pelo utilizador. Gera um CSR para os utilizadores assinarem.

  1. Crie um recurso CertificateAuthority e guarde-o como um ficheiro YAML denominado subca-external.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
    

    Substitua as seguintes variáveis:

    Variável Descrição
    SUB_CA_NAME O nome da subCA.
    USER_PROJECT_NAMESPACE O ID do projeto para o projeto onde quer importar a imagem.
    COMMON_NAME O nome comum do certificado da CA.
    DURATION O tempo de vida útil pedido do certificado da CA. Especifique como uma duração em horas (por exemplo, 1000h). As unidades, como dias (d) ou anos (y), não são compatíveis.
    SECRET_NAME O nome do segredo do Kubernetes que contém a chave privada e o certificado da CA assinado.

    As seguintes variáveis são valores opcionais:

    Variável Descrição
    RENEW_BEFORE O tempo de rotação antes de o certificado da CA expirar.
    ORGANIZATION Organização a usar no certificado.
    ORGANIZATIONAL_UNITS Unidades organizacionais a usar no certificado.
    COUNTRIES Países a usar no certificado.
    LOCALITIES Cidades a usar no certificado.
    PROVINCES Estados ou províncias a usar no certificado.
    STREET_ADDRESSES Moradas a usar no certificado.
    POSTAL_CODES Códigos postais a usar no certificado.
    EXTENDED_KEY_USAGE A utilização alargada da chave para o certificado. Se for fornecido, os valores permitidos são serverAuth e clientAuth.
    KEY_ALGORITHYM O algoritmo de chave privada usado para este certificado. Os valores permitidos são RSA, Ed25519 ou ECDSA. Se o tamanho não for fornecido, a predefinição é 256 para ECDSA e 2048 para RSA. O tamanho da chave é ignorado para Ed25519.
    KEY_SIZE O tamanho, em bits, da chave privada para este certificado depende de o algoritmo. O RSA permite 2048, 3072, 4096 ou 8192 (predefinição 2048). O ECDSA permite 256, 384 ou 521 (predefinição 256). Ed25519 ignora o tamanho.
    ACME_ENABLED Se estiver definido como true, a CA é executada no modo ACME e apresenta o URL do servidor ACME. Em seguida, pode usar o cliente e o protocolo ACME para gerir certificados.
  2. Aplique o recurso personalizado à sua instância do Distributed Cloud:

    kubectl apply -f subca-external.yaml --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    
  3. É gerado um CSR para a Sub CA no servidor da API de gestão do GDC. Tem de transferir o CSR e assiná-lo. Depois de assinado, pode carregar o certificado assinado para o servidor da API de gestão do GDC.

  4. Recolha os pedidos de assinatura de certificado (CSRs) do seu ambiente do Distributed Cloud:

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

    O comando gera um ficheiro CSR denominado sub_ca.csr no diretório atual. Este ficheiro contém um CSR para um certificado da CA X.509.

  5. Use a CA de raiz do cliente para pedir certificados da CA assinados para o ficheiro sub_ca.csr.

  6. Para um pedido de assinatura de certificado aprovado, tem de obter um certificado da CA assinado pela CA de raiz do cliente. Armazene o certificado no ficheiro sub_ca.crt no diretório atual.

  7. Se aplicável, obtenha o certificado da CA de raiz do cliente e armazene-o no ficheiro ca.crt no diretório atual.

  8. Valide o nome comum (CN) do certificado da CA:

    openssl x509 -noout -subject -in sub_ca.crt
    

    Se a sua configuração exigir extensões de nome alternativo do assunto (SAN), valide as extensões SAN no certificado:

    openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject Alternative Name"
    
  9. Gere a spec para aplicar uma correção ao recurso CertificateAuthority:

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

    O conteúdo no ficheiro patch.txt é semelhante ao seguinte:

    spec:
      caCertificate:
        externalCA:
          signedCertificate:
            certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ…
            ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
    
  10. Edite o campo spec do recurso CertificateAuthority:

    kubectl patch certificateauthority SUB_CA_NAME -n USER_PROJECT_NAMESPACE--patch-file patch.txt --type='merge'
    
  11. Valide a preparação da Sub CA do tipo "traga a sua própria" (BYO). Normalmente, a CA demora cerca de 40 minutos a ficar pronta:

    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))'
    

    O resultado é semelhante ao seguinte:

    {
      "lastTransitionTime": "2024-04-30T22:10:50Z",
      "message": "Certificate authority is ready for use",
      "observedGeneration": 3,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    
  12. Valide a data de validade dos certificados da CA assinados:

    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
    

Liste as CAs

Para listar todos os recursos do serviço de autoridade de certificação na sua instância isolada do Distributed Cloud, faça o seguinte:

Use o parâmetro certificateauthorities para listar todos os recursos CertificateAuthority:

   kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificateauthorities

O resultado é semelhante ao seguinte:

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