Transição para diferentes modos de PKI

O Google Distributed Cloud (GDC) com isolamento físico oferece uma API de infraestrutura de chave pública (PKI) para receber certificados da Web. Nesta página, fornecemos instruções para fazer a transição de um modo de certificado de PKI para outro. Para mais informações sobre os tipos de configuração do modo PKI, consulte Configuração de certificado TLS da Web.

Antes de começar

Para receber as permissões necessárias para configurar o emissor de certificado padrão da PKI, peça ao administrador do IAM da organização para conceder a você a função de administrador da PKI de infraestrutura (infra-pki-admin) no namespace do sistema.

Migrar para o modo de subautoridade de certificação BYO

Esta seção fornece uma série de etapas para fazer a transição para o modo de certificado BYO (traga sua própria subautoridade de certificação).

Criar uma subautoridade de certificação BYO

Para criar uma subautoridade certificadora BYO, aplique um recurso personalizado à sua zona do Distributed Cloud.

  1. Crie um recurso CertificateAuthority e salve-o como um arquivo YAML. No exemplo a seguir, você vê um recurso CertificateAuthority

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateAuthority
    metadata:
      name: CA_NAME
      namespace: pki-system
    spec:
      caProfile:
        commonName: COMMON_NAME
        duration: DURATION
        renewBefore: RENEW_BEFORE
      caCertificate:
        externalCA: {}
      certificateProfile:
        keyUsage:
        - digitalSignature
        - keyCertSign
        - crlSign
        extendedKeyUsage:
        - serverAuth
      secretConfig:
        secretName: SECRET_NAME
    

    Substitua as seguintes variáveis:

    • CA_NAME: o nome da subCA.
    • COMMON_NAME: o nome comum do certificado da CA.
    • DURATION: o tempo de vida solicitado do certificado da CA.
    • RENEW_BEFORE: o tempo de rotação antes da expiração do certificado de CA.
    • SECRET_NAME: o nome do secret do Kubernetes que vai conter a chave privada e o certificado da CA assinado.
  2. Aplique o recurso personalizado à sua zona do Distributed Cloud.

    kubectl apply -f byo-subca.yaml --kubeconfig MANAGEMENT_API_SERVER
    

    Substitua MANAGEMENT_API_SERVER pelo arquivo kubeconfig do servidor da API Management.

Uma CSR para a subautoridade certificadora é gerada e aguarda sua assinatura. Para assinar a CSR, siga as instruções na seção Assinar o certificado da subCA BYO.

Assinar o certificado da subCA BYO

  1. Receba as solicitações de assinatura de certificado (CSR) do seu ambiente do GDC:

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

    O comando gera o arquivo sub_ca.csr no diretório atual. Esse arquivo contém uma CSR para um certificado de CA X.509.

  2. Use o protocolo da CA raiz do cliente para solicitar certificados de CA assinados para o arquivo sub_ca.csr.

  3. Para uma solicitação de assinatura de certificado aprovada, você vai receber um certificado de CA assinado pela CA raiz do cliente. Armazene o certificado no arquivo sub_ca.crt no diretório atual. Além disso, obtenha o certificado da CA raiz do cliente e armazene-o no arquivo ca.crt no diretório atual. Entre em contato com o PMO para receber instruções exatas.

  4. Verifique o seguinte para garantir a integridade e a precisão dos certificados:

    1. Verifique se sub_ca.crt segue o formato padrão de certificado codificado em PEM:

      -----BEGIN CERTIFICATE-----
            <Certificate>
      -----END CERTIFICATE-----
      
    2. Verifique se sub_ca.crt é uma autoridade certificadora (CA) válida na extensão "Restrições básicas":

      openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Basic Constraints"
      

      A saída precisa incluir CA:TRUE ou mais investigações são necessárias:

      X509v3 Basic Constraints: critical
          CA:TRUE
      
    3. Verifique as extensões de nome alternativo do assunto (SAN) no certificado:

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

      Se o certificado da CA tiver um nome comum (CN) em vez de um SAN, verifique o CN no certificado:

      openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject: CN"
      
  5. Gere a especificação para corrigir o recurso CertificateAuthority:

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

    O conteúdo do arquivo patch.txt é semelhante ao snippet a seguir:

     spec:
      caCertificate:
       externalCA:
        signedCertificate:
         certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ…
         ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
    
  6. Edite a especificação do recurso CertificateAuthority:

    kubectl patch certificateauthority CA_NAME -n pki-system --patch-file patch.txt --type='merge'
    
  7. Verifique se a subCA BYO está pronta:

    kubectl get certificateauthority CA_NAME -n pki-system -ojson | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    Você verá uma saída semelhante a esta:

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

    kubectl -n pki-system get secret SECRET_NAME -ojson | jq -j '"echo ",
    .metadata.name, " $(echo ", .data["tls.crt"], "| base64 -d | openssl x509 -enddate -noout)\n"' | bash
    
  9. Crie um arquivo YAML de recurso CertificateIssuer e salve-o. Por exemplo, byo-subca-issuer.yaml:

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateIssuer
    metadata:
      name: BYO_SUBCA_ISSUER
      namespace: pki-system
    spec:
      caaasConfig:
        certificateAuthorityRef:
          namespace: pki-system
          name: CA_NAME
    

    Substitua BYO_SUBCA_ISSUER pelo nome do emissor da subCA BYO.

  10. Aplique o recurso personalizado à sua zona do Distributed Cloud no servidor da API Management usando a CLI kubectl:

    kubectl apply -f byo-subca-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  11. Verifique se o novo emissor está pronto:

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

Transição para o modo de certificado BYO

Esta seção apresenta uma série de etapas para fazer a transição para o modo BYO-cert.

Criar um CertificateIssuer BYO

  1. Crie um recurso CertificateIssuer e salve-o como um arquivo YAML. Por exemplo, byo-cert-issuer.yaml. Esse emissor de certificado BYO usa o default-tls-ca gerenciado como a CA substituta:

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateIssuer
    metadata:
      name: BYO_CERT_ISSUER_NAME
      namespace: pki-system
    spec:
      byoCertConfig:
        fallbackCertificateAuthority:
          name: default-tls-ca
          namespace: pki-system
    

    Substitua BYO_CERT_ISSUER_NAME pelo nome do emissor de certificado BYO.

  2. Aplique o recurso personalizado à sua zona do Distributed Cloud no servidor da API Management:

    kubectl apply -f byo-cert-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Verifique se o novo emissor está pronto.

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

    A saída será assim:

    {
      "lastTransitionTime": "2024-05-01T22:25:20Z",
      "message": "",
      "observedGeneration": 1,
      "reason": "FallbackCAReady",
      "status": "True",
      "type": "Ready"
    }
    

Assinar o certificado BYO

  1. Enquanto espera que a CSR seja assinada externamente, um certificado BYO pode ser emitido temporariamente por uma CA de substituição especificada no emissor do certificado BYO. Confira o status atual do BYO-cert default-wildcard-cert:

    kubectl get certificate.pki.security.gdc.goog/default-wildcard-cert -n istio-system -o json | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    A saída será assim:

    {
      "lastTransitionTime": "2024-05-03T08:42:10Z",
      "message": "Certificate is issued by a fallback CA",
      "observedGeneration": 1,
      "reason": "UsingFallbackCA",
      "status": "True",
      "type": "Ready"
    }
    

    O motivo pronto indica UsingFallbackCA para informar que a CA de substituição emitiu o certificado. Em seguida, ele é armazenado no secret e fica pronto para uso.

  2. Consiga o nome do secret do certificado:

    kubectl -n istio-system get certificate.pki.security.gdc.goog/default-wildcard-cert -ojson | jq -r '.spec.secretConfig.secretName'
    

    A saída será assim:

    web-tls
    
  3. Verifique o emissor do secret:

    kubectl get secret web-tls -n istio-system -o jsonpath='{.data.tls\.crt}' |
    base64 -d | openssl x509 -text -noout | grep Issuer
    

    A saída será assim:

    Issuer: CN = GDC Managed ORG TLS CA
    

    Um certificado BYO pode usar temporariamente um certificado correspondente enquanto aguarda a própria assinatura de CSR. Um certificado example-service com dnsName como example-service.org-1.zone1.google.gdch.test é correspondido pelo default-wildcard-certcom DNSName *.org-1.zone1.google.gdch.test do mesmo emissor de certificado. O certificado example-service pode ter o seguinte status enquanto aguarda a assinatura da CSR:

    {
      "lastTransitionTime": "2024-05-03T22:30:51Z",
      "message": "Using a matched issued Certificate: default-wildcard-cert/istio-system",
      "observedGeneration": 1,
      "reason": "UsingMatchedCert",
      "status": "True",
      "type": "Ready"
    }
    
  4. Extraia a CSR do status do certificado:

    kubectl -n istio-system get certificate.pki.security.gdc.goog/default-wildcard-cert -ojson | jq -r ' .status.byoCertStatus.csrStatus'
    

    A saída será assim:

    {
      "conditions": [
        {
          "lastTransitionTime": "2024-05-03T18:14:19Z",
          "message": "",
          "observedGeneration": 1,
          "reason": "WaitingForSigning",
          "status": "False",
          "type": "Ready"
        }
      ],
      "csr": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSB..."
    }
    
  5. Há diferentes métodos para assinar uma CSR com base na configuração da CA externa. Ao assinar, use o SAN da CSR. Exemplo:

    function signCert() {
       certName=$1
       ns=$2
    
       # Download the CSR from the certificate
       kubectl get certificate.pki.security.gdc.goog $certName -n $ns -o jsonpath='{.status.byoCertStatus.csrStatus.csr}' | base64 -d > $certName.csr
    
       # Get SAN from the csr
       san=$(openssl req -in $certName.csr -noout -text | grep 'DNS:' | sed -s 's/^[ ]*//')
    
       # Save SAN to extension config
       cat <<EOF >$certName-csr.ext
     keyUsage=digitalSignature,keyEncipherment
     extendedKeyUsage=serverAuth,clientAuth
     subjectAltName=${san}
     EOF
    
       # Sign the CSR with an external CA. You need to prepare the external CA cert and key
       openssl x509 -req -in $certName.csr -days 365 -CA ext-ca.crt -CAkey ext-ca.key -CAcreateserial -extfile $certName-csr.ext -out $certName-signed.crt
       openssl x509 -in $certName-signed.crt -text -noout
    
       # Upload the externally signed certificate by patching.
       echo "spec:
         byoCertificate:
            certificate: $(base64 -w0 $certName-signed.crt)
            ca: $(base64 -w0 ext-ca.crt)" > patch.txt
    
       kubectl patch certificate.pki.security.gdc.goog $certName -n $ns --patch-file patch.txt --type='merge'
     }
    
     # Use the function to sign the default-wildcard-cert in the istio-system namespace
     signCert default-wildcard-cert istio-system
    
  6. Verifique os seguintes detalhes:

    • O status da CSR do certificado é Ready
    kubectl -n istio-system get certificate.pki.security.gdc.goog/default-wildcard-cert -ojson | jq -r ' .status.byoCertStatus.csrStatus.conditions'
    
    [
       {
          "lastTransitionTime": "2024-05-03T21:56:25Z",
          "message": "",
          "observedGeneration": 2,
          "reason": "Signed",
          "status": "True",
          "type": "Ready"
       }
    ]
    
    • O certificado é Ready pelo motivo Issued
    kubectl get certificate.pki.security.gdc.goog/default-wildcard-cert -n istio-system -o json | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    A saída será assim:

    {
      "lastTransitionTime": "2024-05-03T08:42:10Z",
      "message": "Certificate is issued",
      "observedGeneration": 2,
      "reason": "Issued",
      "status": "True",
      "type": "Ready"
    }
    
    • O secret é atualizado:
    kubectl get secret web-tls -n istio-system -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout | grep Issuer
    

    A saída será assim:

            Issuer: CN = external-ca
    

Fazer a transição para um certificado BYO com o modo ACME

Esta seção apresenta uma série de etapas para fazer a transição para um BYO-cert com o modo ACME.

Criar um CertificateIssuer com configuração do ACME

  1. Crie um recurso CertificateIssuer com a configuração do ACME e salve-o como um arquivo YAML, como acme-issuer.yaml.

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateIssuer
    metadata:
      name: ACME_ISSUER_NAME
      namespace: pki-system
    spec:
         acmeConfig:
           rootCACertificate: ROOT_CA_CERTIFICATE
           acme:
             server: ACME_SERVER_URL
             caBundle: CA_BUNDLE
             privateKeySecretRef:
               name: PRIVATE_KEY_SECRET_NAME
    

    Substitua as seguintes variáveis:

    • ACME_ISSUER_NAME: o nome do emissor ACME.
    • ROOT_CA_CERTIFICATE: os dados da CA raiz dos certificados emitidos pelo servidor ACME.
    • ACME_SERVER_URL: o URL para acessar o endpoint de diretório do servidor ACME.
    • CA_BUNDLE: o pacote codificado em Base64 de CAs PEM que valida a cadeia de certificados apresentada pelo servidor ACME.
    • PRIVATE_KEY_SECRET_NAME: o nome do secret que contém a chave privada da conta ACME.

    Para usar uma chave privada de conta do ACME, verifique se o secret que a contém usa o nome PRIVATE_KEY_SECRET_NAME no mesmo namespace do emissor do ACME. Se você não fornecer esse secret, um novo com o mesmo nome será gerado automaticamente para armazenar a chave privada da conta ACME.

  2. Aplique o recurso personalizado à sua zona do Distributed Cloud:

    kubectl apply -f acme-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Verifique se o novo emissor está pronto:

    kubectl --kubeconfig MANAGEMENT_API_SERVER -n pki-system get certificateissuer.pki.security.gdc.goog/ACME_ISSUER_NAME -ojson | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    Você verá uma saída semelhante a esta:

    {
      "lastTransitionTime": "2024-05-01T18:32:17Z",
      "message": "",
      "observedGeneration": 1,
      "reason": "ACMEClientReady",
      "status": "True",
      "type": "Ready"
    }
    

Reemissão de certificado

Para mudar o emissor padrão para o novo emissor ACME, consulte Mudar o emissor de certificado padrão

Para reemitir imediatamente os certificados com o novo emissor padrão, consulte Reemitir manualmente certificados da Web da ICP.