Cambiar a otros modos de PKI

Google Distributed Cloud (GDC) con air gap proporciona una API de infraestructura de clave pública (PKI) para obtener certificados web. En esta página se explica cómo cambiar de un modo de certificado de PKI a otro. Para obtener más información sobre los tipos de configuración del modo PKI, consulta Configuración de certificados TLS web.

Antes de empezar

Para obtener los permisos que necesitas para configurar la entidad emisora de certificados predeterminada de la PKI, pide al administrador de gestión de identidades y accesos de tu organización que te asigne el rol de administrador de PKI de infraestructura (infra-pki-admin) en el espacio de nombres del sistema.

Cambiar al modo de subautoridad de certificación propia

En esta sección se describen los pasos que debe seguir para cambiar al modo de certificado de subautoridad de certificación propio (BYO).

Crear una subautoridad de certificación propia

Para crear una subautoridad de certificación propia, aplica un recurso personalizado a tu zona de Distributed Cloud.

  1. Crea un recurso CertificateAuthority y guárdalo como archivo YAML. En el siguiente ejemplo, se muestra un recurso CertificateAuthority de muestra:

    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
    

    Sustituye las siguientes variables:

    • CA_NAME: el nombre de la subautoridad certificadora.
    • COMMON_NAME: el nombre común del certificado de la AC.
    • DURATION: el tiempo de validez solicitado del certificado de la AC.
    • RENEW_BEFORE: el tiempo de rotación antes de que caduque el certificado de la AC.
    • SECRET_NAME: el nombre del secreto de Kubernetes que contendrá la clave privada y el certificado de CA firmado.
  2. Aplica el recurso personalizado a tu zona de Distributed Cloud.

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

    Sustituye MANAGEMENT_API_SERVER por el archivo kubeconfig del servidor de la API Management.

Se genera una CSR para la subautoridad de certificación y espera a que la firmes. Para firmar la CSR, sigue las instrucciones de la sección Firma el certificado de subautoridad de certificación propio.

Firmar el certificado de subautoridad de certificación BYO

  1. Obtén las solicitudes de firma de certificado (CSR) de tu entorno de GDC:

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

    El comando genera el archivo sub_ca.csr en el directorio actual. Este archivo contiene una CSR para un certificado de AC X.509.

  2. Usa el protocolo de la AC raíz del cliente para solicitar certificados de AC firmados para el archivo sub_ca.csr.

  3. Si se aprueba la solicitud de firma de certificado, obtendrá un certificado de AC firmado por la AC raíz del cliente. Guarda el certificado en el archivo sub_ca.crt del directorio actual. Además, obtén el certificado de la AC raíz del cliente y guárdalo en el archivo ca.crt del directorio actual. Ponte en contacto con la oficina de gestión de proyectos para obtener instrucciones exactas.

  4. Verifica lo siguiente para asegurarte de que los certificados son íntegros y precisos:

    1. Asegúrate de que sub_ca.crt cumpla el formato estándar de certificado codificado en PEM:

      -----BEGIN CERTIFICATE-----
            <Certificate>
      -----END CERTIFICATE-----
      
    2. Verifica que sub_ca.crt sea una autoridad de certificación (CA) válida en la extensión "Restricciones básicas":

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

      El resultado debe incluir CA:TRUE o se debe investigar más a fondo:

      X509v3 Basic Constraints: critical
          CA:TRUE
      
    3. Verifica las extensiones de nombre alternativo de la entidad (SAN) del certificado:

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

      Si el certificado de CA tiene un nombre común (CN) en lugar de un SAN, comprueba el CN del certificado:

      openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject: CN"
      
  5. Genera el archivo de especificaciones para parchear el recurso CertificateAuthority:

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

    El contenido del archivo patch.txt tiene un aspecto similar al siguiente fragmento:

     spec:
      caCertificate:
       externalCA:
        signedCertificate:
         certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ…
         ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
    
  6. Edita la especificación del recurso CertificateAuthority:

    kubectl patch certificateauthority CA_NAME -n pki-system --patch-file patch.txt --type='merge'
    
  7. Verifica que la subautoridad de certificación de BYO esté lista:

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

    Verá un resultado similar al siguiente:

    {
      "lastTransitionTime": "2024-04-30T22:10:50Z",
      "message": "Certificate authority is ready for use",
      "observedGeneration": 3,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    
  8. Verifica la caducidad de los certificados de AC firmados:

    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. Crea un archivo YAML de recursos CertificateIssuer y guárdalo. Por ejemplo: 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
    

    Sustituye BYO_SUBCA_ISSUER por el nombre de la subautoridad de certificación emisora de la clave.

  10. Aplica el recurso personalizado a tu zona de Distributed Cloud en el servidor de la API de gestión mediante la CLI de kubectl:

    kubectl apply -f byo-subca-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  11. Verifica que el nuevo emisor esté listo:

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

Cambiar al modo de certificado propio

En esta sección se proporcionan una serie de pasos para cambiar al modo BYO-cert.

Crear un CertificateIssuer BYO

  1. Crea un recurso CertificateIssuer y guárdalo como un archivo YAML. Por ejemplo, byo-cert-issuer.yaml. Esta entidad emisora de certificados BYO usa la default-tls-ca gestionada como autoridad de certificación alternativa:

    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
    

    Sustituye BYO_CERT_ISSUER_NAME por el nombre de la entidad emisora del certificado BYO.

  2. Aplica el recurso personalizado a tu zona de Distributed Cloud en el servidor de la API Management:

    kubectl apply -f byo-cert-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Verifica que el nuevo emisor esté listo.

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

    El resultado es similar al siguiente:

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

Firmar el certificado BYO

  1. Mientras se espera a que se firme externamente la CSR, una AC de respaldo especificada en el emisor del certificado BYO puede emitir temporalmente un certificado BYO. Obtener el estado actual de default-wildcard-cert BYO-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))'
    

    El resultado es similar al siguiente:

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

    El motivo de disponibilidad indica UsingFallbackCA para indicar que la CA de respaldo emite el certificado. Después, se almacena en el secreto y está listo para usarse.

  2. Obtén el nombre del secreto del certificado:

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

    El resultado es similar al siguiente:

    web-tls
    
  3. Comprueba la entidad emisora del secreto:

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

    El resultado es similar al siguiente:

    Issuer: CN = GDC Managed ORG TLS CA
    

    Un certificado propio (BYO-cert) puede usar temporalmente un certificado coincidente mientras espera su propia firma de CSR. Un certificado de ejemplo de servicio con dnsName example-service.org-1.zone1.google.gdch.test coincide con el certificado default-wildcard-cert con DNSName *.org-1.zone1.google.gdch.test del mismo emisor de certificados. El certificado example-service puede tener el siguiente estado mientras espera a que se firme su 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. Obtén la CSR del estado del certificado:

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

    El resultado es similar al siguiente:

    {
      "conditions": [
        {
          "lastTransitionTime": "2024-05-03T18:14:19Z",
          "message": "",
          "observedGeneration": 1,
          "reason": "WaitingForSigning",
          "status": "False",
          "type": "Ready"
        }
      ],
      "csr": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSB..."
    }
    
  5. Hay diferentes métodos para firmar una CSR en función de la configuración de la CA externa. Al firmar, usa el SAN de la CSR. Por ejemplo:

    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. Verifica los siguientes detalles:

    • El estado de la CSR del certificado es 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"
       }
    ]
    
    • El certificado es Ready por el 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))'
    

    El resultado es similar al siguiente:

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

    El resultado es similar al siguiente:

            Issuer: CN = external-ca
    

Cambiar a un certificado propio con el modo ACME

En esta sección se describen los pasos que debes seguir para cambiar a un certificado propio con el modo ACME.

Crear un CertificateIssuer con configuración ACME

  1. Crea un recurso CertificateIssuer con la configuración de ACME y guárdalo como archivo YAML, por ejemplo, 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
    

    Sustituye las siguientes variables:

    • ACME_ISSUER_NAME: el nombre de la entidad emisora de ACME.
    • ROOT_CA_CERTIFICATE: los datos de la AC raíz de los certificados emitidos por el servidor ACME.
    • ACME_SERVER_URL: URL para acceder al endpoint del directorio del servidor ACME.
    • CA_BUNDLE: el paquete de CAs PEM codificado en Base64 que valida la cadena de certificados presentada por el servidor ACME.
    • PRIVATE_KEY_SECRET_NAME: el nombre del secreto que contiene la clave privada de la cuenta de ACME.

    Para usar una clave privada de una cuenta de ACME, asegúrate de que el secreto que la contiene use el nombre PRIVATE_KEY_SECRET_NAME en el mismo espacio de nombres que el emisor de ACME. Si no proporcionas este secreto, se generará automáticamente uno nuevo con el mismo nombre para almacenar la clave privada de la cuenta ACME.

  2. Aplica el recurso personalizado a tu zona de Distributed Cloud:

    kubectl apply -f acme-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Verifica que el nuevo emisor esté listo:

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

    Verá un resultado similar al siguiente:

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

Reemisión de certificados

Para cambiar la entidad emisora predeterminada a la nueva entidad emisora ACME, consulta el artículo Cambiar la entidad emisora de certificados predeterminada.

Para volver a emitir inmediatamente los certificados con la nueva entidad emisora predeterminada, consulta Volver a emitir manualmente certificados web de PKI.