Transizione a diverse modalità PKI

Google Distributed Cloud (GDC) con air gap fornisce un'API Public Key Infrastructure (PKI) per ottenere certificati web. Questa pagina fornisce istruzioni per la transizione da una modalità di certificato PKI a un'altra. Per ulteriori informazioni sui tipi di configurazione della modalità PKI, consulta Configurazione del certificato TLS web.

Prima di iniziare

Per ottenere le autorizzazioni necessarie per configurare l'emittente di certificati PKI predefinita, chiedi all'amministratore IAM dell'organizzazione di concederti il ruolo Amministratore PKI dell'infrastruttura (infra-pki-admin) nello spazio dei nomi di sistema.

Transizione alla modalità BYO subCA

Questa sezione fornisce una serie di passaggi per la transizione alla modalità di certificato SubCA BYO (Bring Your Own).

Crea una subCA BYO

Per creare una subCA BYO, applica una risorsa personalizzata alla zona Distributed Cloud.

  1. Crea una risorsa CertificateAuthority e salvala come file YAML. Nell'esempio seguente, vedi una risorsa CertificateAuthority di esempio

    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
    

    Sostituisci le seguenti variabili:

    • CA_NAME: il nome della subCA.
    • COMMON_NAME: il nome comune del certificato CA.
    • DURATION: la durata richiesta del certificato CA.
    • RENEW_BEFORE: il tempo di rotazione prima della scadenza del certificato CA.
    • SECRET_NAME: il nome del secret Kubernetes che conterrà la chiave privata e il certificato CA firmato.
  2. Applica la risorsa personalizzata alla zona Distributed Cloud.

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

    Sostituisci MANAGEMENT_API_SERVER con il file kubeconfig del server dell'API Management.

Una CSR per l'autorità di certificazione secondaria viene generata e attende la tua firma. Per firmare la CSR, segui le istruzioni riportate nella sezione Firma il certificato della CA secondaria BYO.

Firma il certificato della CA secondaria BYO

  1. Recupera le richieste di firma del certificato (CSR) dal tuo ambiente GDC:

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

    Il comando genera il file sub_ca.csr nella directory corrente. Questo file contiene una CSR per un certificato CA X.509.

  2. Utilizza il protocollo della CA radice del cliente per richiedere certificati CA firmati per il file sub_ca.csr.

  3. Per una richiesta di firma del certificato approvata, otterrai un certificato CA firmato dalla CA radice del cliente. Memorizza il certificato nel file sub_ca.crt nella directory attuale. Inoltre, ottieni il certificato CA radice del cliente e archivialo nel file ca.crt nella directory corrente. Contatta l'Ufficio di gestione del progetto per istruzioni esatte.

  4. Verifica quanto segue per garantire l'integrità e l'accuratezza dei certificati:

    1. Assicurati che sub_ca.crt rispetti il formato standard del certificato con codifica PEM:

      -----BEGIN CERTIFICATE-----
            <Certificate>
      -----END CERTIFICATE-----
      
    2. Verifica che sub_ca.crt sia un'autorità di certificazione (CA) valida nell'estensione "Vincoli di base":

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

      L'output deve includere CA:TRUE o sono necessari ulteriori accertamenti:

      X509v3 Basic Constraints: critical
          CA:TRUE
      
    3. Verifica le estensioni del nome alternativo del soggetto (SAN) nel certificato:

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

      Se il certificato CA ha il nome comune (CN) anziché il nome alternativo del soggetto (SAN), verifica CN nel certificato:

      openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject: CN"
      
  5. Genera la specifica per applicare la patch alla risorsa CertificateAuthority:

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

    I contenuti del file patch.txt sono simili al seguente snippet:

     spec:
      caCertificate:
       externalCA:
        signedCertificate:
         certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ…
         ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
    
  6. Modifica la specifica della risorsa CertificateAuthority:

    kubectl patch certificateauthority CA_NAME -n pki-system --patch-file patch.txt --type='merge'
    
  7. Verifica l'idoneità della CA secondaria BYO:

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

    Vedi un output simile al seguente:

    {
      "lastTransitionTime": "2024-04-30T22:10:50Z",
      "message": "Certificate authority is ready for use",
      "observedGeneration": 3,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    
  8. Verifica la scadenza dei certificati CA firmati:

    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 file YAML della risorsa CertificateIssuer e salvalo. Ad esempio, 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
    

    Sostituisci BYO_SUBCA_ISSUER con il nome dell'emittente della subCA BYO.

  10. Applica la risorsa personalizzata alla tua zona Distributed Cloud nel server API Management utilizzando la CLI kubectl:

    kubectl apply -f byo-subca-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  11. Verifica la disponibilità del nuovo emittente:

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

Transizione alla modalità BYO Certificate

Questa sezione fornisce una serie di passaggi per passare alla modalità BYO-cert.

Crea un BYO CertificateIssuer

  1. Crea una risorsa CertificateIssuer e salvala come file YAML, ad esempio byo-cert-issuer.yaml. Questo emittente di certificati BYO utilizza la CA gestita default-tls-ca come CA di riserva:

    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
    

    Sostituisci BYO_CERT_ISSUER_NAME con il nome dell'emittente del certificato BYO.

  2. Applica la risorsa personalizzata alla tua zona Distributed Cloud nel server API Management:

    kubectl apply -f byo-cert-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Verifica la disponibilità del nuovo emittente.

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

    L'output è simile al seguente:

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

Firma del certificato BYO

  1. Durante l'attesa della firma esterna della richiesta di firma del certificato, una CA di riserva specificata nell'emittente del certificato BYOC può emettere temporaneamente un certificato BYOC. Ottieni lo stato attuale di 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))'
    

    L'output è simile al seguente:

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

    Il motivo dello stato Pronto indica UsingFallbackCA per indicare che la CA di riserva emette il certificato. Viene quindi archiviato nel secret e pronto per l'uso.

  2. Recupera il nome del secret del certificato:

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

    L'output è simile al seguente:

    web-tls
    
  3. Controlla l'emittente del secret:

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

    L'output è simile al seguente:

    Issuer: CN = GDC Managed ORG TLS CA
    

    Un certificato BYO-cert (bring-your-own certificate) può utilizzare temporaneamente un certificato corrispondente in attesa della propria firma CSR. Un certificato example-service con dnsName come example-service.org-1.zone1.google.gdch.test corrisponde a default-wildcard-cert con DNSName *.org-1.zone1.google.gdch.test dello stesso emittente del certificato. Il certificato example-service può avere lo stato seguente in attesa della firma della 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. Recupera la CSR dallo stato del certificato:

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

    L'output è simile al seguente:

    {
      "conditions": [
        {
          "lastTransitionTime": "2024-05-03T18:14:19Z",
          "message": "",
          "observedGeneration": 1,
          "reason": "WaitingForSigning",
          "status": "False",
          "type": "Ready"
        }
      ],
      "csr": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSB..."
    }
    
  5. Esistono diversi metodi per firmare una CSR in base alla configurazione dell'autorità di certificazione esterna. Durante la firma, utilizza il SAN della CSR. Ad esempio:

    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 i seguenti dettagli:

    • Lo stato della CSR del certificato è 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"
       }
    ]
    
    • Il certificato è Ready con il 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))'
    

    L'output è simile al seguente:

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

    L'output è simile al seguente:

            Issuer: CN = external-ca
    

Transizione a un certificato BYO con modalità ACME

Questa sezione fornisce una serie di passaggi per la transizione a un certificato BYO con modalità ACME.

Crea un emittente di certificati con configurazione ACME

  1. Crea una risorsa CertificateIssuer con la configurazione ACME e salvala come file YAML, ad esempio 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
    

    Sostituisci le seguenti variabili:

    • ACME_ISSUER_NAME: il nome dell'emittente ACME.
    • ROOT_CA_CERTIFICATE: i dati della CA radice dei certificati emessi dal server ACME.
    • ACME_SERVER_URL: l'URL per accedere all'endpoint della directory del server ACME.
    • CA_BUNDLE: il bundle con codifica Base64 delle CA PEM che convalida la catena di certificati presentata dal server ACME.
    • PRIVATE_KEY_SECRET_NAME: il nome del secret che contiene la chiave privata dell'account ACME.

    Per utilizzare una chiave privata dell'account ACME esistente, assicurati che il secret che la contiene utilizzi il nome PRIVATE_KEY_SECRET_NAME nello stesso spazio dei nomi dell'emittente ACME. Se non fornisci questo secret, ne viene generato automaticamente uno nuovo con lo stesso nome per archiviare la chiave privata dell'account ACME.

  2. Applica la risorsa personalizzata alla zona Distributed Cloud:

    kubectl apply -f acme-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Verifica la disponibilità del nuovo emittente:

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

    Vedi un output simile al seguente:

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

Riemissione del certificato

Per passare all'emittente predefinita con la nuova emittente ACME, vedi Modificare l'emittente di certificati predefinita

Per riemettere immediatamente i certificati con il nuovo emittente predefinito, consulta Riemettere manualmente i certificati web PKI.