Übergang zu anderen PKI-Modi

Google Distributed Cloud (GDC) mit Air Gap bietet eine PKI-API (Public-Key-Infrastruktur) zum Abrufen von Webzertifikaten. Auf dieser Seite finden Sie eine Anleitung für den Übergang von einem PKI-Zertifikatsmodus zu einem anderen. Weitere Informationen zu Konfigurationstypen für den PKI-Modus finden Sie unter Web-TLS-Zertifikatskonfiguration.

Hinweise

Bitten Sie Ihren IAM-Administrator der Organisation, Ihnen die Rolle „Infra PKI Admin“ (infra-pki-admin) im System-Namespace zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Konfigurieren des Standardausstellers von PKI-Zertifikaten benötigen.

Auf den Modus „Eigene untergeordnete CA verwenden“ umstellen

In diesem Abschnitt finden Sie eine Reihe von Schritten für die Umstellung auf den Modus „Bring your own (BYO) SubCA cert“.

BYO-Unter-CA erstellen

Wenn Sie eine eigene untergeordnete CA erstellen möchten, wenden Sie eine benutzerdefinierte Ressource auf Ihre Distributed Cloud-Zone an.

  1. Erstellen Sie eine CertificateAuthority-Ressource und speichern Sie sie als YAML-Datei. Im folgenden Beispiel sehen Sie eine Beispielressource 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
    

    Ersetzen Sie die folgenden Variablen:

    • CA_NAME: der Name der untergeordneten CA.
    • COMMON_NAME: der Name des CA-Zertifikats.
    • DURATION: die angeforderte Gültigkeitsdauer des CA-Zertifikats.
    • RENEW_BEFORE: die Rotationszeit, bevor das CA-Zertifikat abläuft.
    • SECRET_NAME: der Name des Kubernetes-Secrets, das den privaten Schlüssel und das signierte CA-Zertifikat enthält.
  2. Wenden Sie die benutzerdefinierte Ressource auf Ihre Distributed Cloud-Zone an.

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

    Ersetzen Sie MANAGEMENT_API_SERVER durch die kubeconfig-Datei des Management API-Servers.

Eine CSR für die untergeordnete CA wird generiert und wartet darauf, dass Sie sie signieren. Folgen Sie der Anleitung im Abschnitt BYO-Unter-CA-Zertifikat signieren, um den CSR zu signieren.

BYO-Unter-CA-Zertifikat signieren

  1. Rufen Sie die Anfragen zur Zertifikatssignierung (Certificate Signing Request, CSR) aus Ihrer GDC-Umgebung ab:

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

    Mit dem Befehl wird die Datei sub_ca.csr im aktuellen Verzeichnis generiert. Diese Datei enthält einen CSR für ein X.509-CA-Zertifikat.

  2. Verwenden Sie das Protokoll der Stammzertifizierungsstelle des Kunden, um signierte CA-Zertifikate für die Datei sub_ca.csr anzufordern.

  3. Für eine genehmigte Anfrage für die Signierung des Zertifikats erhalten Sie ein CA-Zertifikat, das von der Stammzertifizierungsstelle des Kunden signiert wurde. Speichern Sie das Zertifikat in der Datei sub_ca.crt im aktuellen Verzeichnis. Außerdem müssen Sie das Root-CA-Zertifikat des Kunden abrufen und in der Datei ca.crt im aktuellen Verzeichnis speichern. Wenden Sie sich an das PMO, um genaue Anweisungen zu erhalten.

  4. Prüfen Sie Folgendes, um die Integrität und Richtigkeit der Zertifikate sicherzustellen:

    1. Prüfen Sie, ob sub_ca.crt dem Standardformat für PEM-codierte Zertifikate entspricht:

      -----BEGIN CERTIFICATE-----
            <Certificate>
      -----END CERTIFICATE-----
      
    2. Prüfen Sie, ob sub_ca.crt eine gültige Zertifizierungsstelle in der Erweiterung „Basic Constraints“ ist:

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

      Die Ausgabe muss CA:TRUE enthalten. Andernfalls sind weitere Untersuchungen erforderlich:

      X509v3 Basic Constraints: critical
          CA:TRUE
      
    3. Prüfen Sie die Erweiterungen für alternative Antragstellernamen (Subject Alternative Name, SAN) im Zertifikat:

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

      Wenn das CA-Zertifikat einen Common Name (CN) anstelle von SAN hat, prüfen Sie die CN im Zertifikat:

      openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject: CN"
      
  5. Generieren Sie die Spezifikation zum Patchen der CertificateAuthority-Ressource:

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

    Der Inhalt der Datei patch.txt sieht in etwa so aus:

     spec:
      caCertificate:
       externalCA:
        signedCertificate:
         certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ…
         ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
    
  6. Bearbeiten Sie die Spezifikation der CertificateAuthority-Ressource:

    kubectl patch certificateauthority CA_NAME -n pki-system --patch-file patch.txt --type='merge'
    
  7. Prüfen Sie, ob die BYO-Unter-CA bereit ist:

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

    Die Ausgabe sollte in etwa so aussehen:

    {
      "lastTransitionTime": "2024-04-30T22:10:50Z",
      "message": "Certificate authority is ready for use",
      "observedGeneration": 3,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    
  8. Prüfen Sie, ob die signierten CA-Zertifikate abgelaufen sind:

    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. Erstellen Sie eine YAML-Datei für die CertificateIssuer-Ressource und speichern Sie die Datei. Beispiel: 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
    

    Ersetzen Sie BYO_SUBCA_ISSUER durch den Namen des Ausstellers der untergeordneten BYO-CA.

  10. Wenden Sie die benutzerdefinierte Ressource mit der kubectl-CLI auf Ihre Distributed Cloud-Zone auf dem Management API-Server an:

    kubectl apply -f byo-subca-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  11. Prüfen Sie, ob der neue Aussteller bereit ist:

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

Umstellung auf den Modus „Eigenes Zertifikat verwenden“

In diesem Abschnitt finden Sie eine Reihe von Schritten für den Übergang zum BYO-Cert-Modus.

BYO-CertificateIssuer erstellen

  1. Erstellen Sie eine CertificateIssuer-Ressource und speichern Sie sie als YAML-Datei, z. B. byo-cert-issuer.yaml. Dieser BYO-Zertifikataussteller verwendet die verwaltete default-tls-ca als Fallback-Zertifizierungsstelle:

    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
    

    Ersetzen Sie BYO_CERT_ISSUER_NAME durch den Namen des BYO-Zertifikatausstellers.

  2. Wenden Sie die benutzerdefinierte Ressource auf Ihre Distributed Cloud-Zone auf dem Management API-Server an:

    kubectl apply -f byo-cert-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Prüfen Sie, ob der neue Aussteller bereit ist.

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

    Die Ausgabe sieht dann ungefähr so aus:

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

BYO-Zertifikat signieren

  1. Während darauf gewartet wird, dass die CSR extern signiert wird, kann ein BYO-Zertifikat vorübergehend von einer Fallback-Zertifizierungsstelle ausgestellt werden, die im BYO-Zertifikataussteller angegeben ist. Aktuellen Status von default-wildcard-cert-Zertifikaten abrufen:

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

    Die Ausgabe sieht dann ungefähr so aus:

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

    Der Grund für die Bereitschaft gibt UsingFallbackCA an, um darauf hinzuweisen, dass die Fallback-Zertifizierungsstelle das Zertifikat ausstellt. Es wird dann im Secret gespeichert und kann verwendet werden.

  2. Rufen Sie den Namen des Zertifikat-Secrets ab:

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

    Die Ausgabe sieht dann ungefähr so aus:

    web-tls
    
  3. Prüfen Sie den Aussteller des Secrets:

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

    Die Ausgabe sieht dann ungefähr so aus:

    Issuer: CN = GDC Managed ORG TLS CA
    

    Ein BYO-Zertifikat kann vorübergehend ein passendes Zertifikat verwenden, während auf die Signatur der eigenen CSR gewartet wird. Ein Beispielzertifikat für einen Dienst mit dem dnsName example-service.org-1.zone1.google.gdch.test wird mit dem default-wildcard-cert mit dem DNSName *.org-1.zone1.google.gdch.test vom selben Zertifikataussteller abgeglichen. Das Zertifikat des Beispiel-Dienstes kann die folgenden Status haben, während es darauf wartet, dass die CSR signiert wird:

    {
      "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. CSR über den Zertifikatsstatus abrufen:

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

    Die Ausgabe sieht dann ungefähr so aus:

    {
      "conditions": [
        {
          "lastTransitionTime": "2024-05-03T18:14:19Z",
          "message": "",
          "observedGeneration": 1,
          "reason": "WaitingForSigning",
          "status": "False",
          "type": "Ready"
        }
      ],
      "csr": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSB..."
    }
    
  5. Je nach Konfiguration der externen Zertifizierungsstelle gibt es verschiedene Methoden zum Signieren eines CSR. Verwenden Sie beim Signieren den SAN aus der CSR. Beispiel:

    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. Prüfen Sie die folgenden Details:

    • Der CSR-Status des Zertifikats ist 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"
       }
    ]
    
    • Das Zertifikat ist Ready mit dem Grund 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))'
    

    Die Ausgabe sieht dann ungefähr so aus:

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

    Die Ausgabe sieht dann ungefähr so aus:

            Issuer: CN = external-ca
    

Auf ein BYO-Zertifikat mit ACME-Modus umstellen

In diesem Abschnitt finden Sie eine Reihe von Schritten für die Umstellung auf ein BYO-Zertifikat mit ACME-Modus.

CertificateIssuer mit ACME-Konfiguration erstellen

  1. Erstellen Sie eine CertificateIssuer-Ressource mit der ACME-Konfiguration und speichern Sie sie als YAML-Datei, z. B. 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
    

    Ersetzen Sie die folgenden Variablen:

    • ACME_ISSUER_NAME: der Name des ACME-Ausstellers.
    • ROOT_CA_CERTIFICATE: Die Root-CA-Daten von Zertifikaten, die vom ACME-Server ausgestellt wurden.
    • ACME_SERVER_URL: die URL für den Zugriff auf den Verzeichnisendpunkt des ACME-Servers.
    • CA_BUNDLE: Das base64-codierte Bundle von PEM-Zertifizierungsstellen, mit dem die vom ACME-Server präsentierte Zertifikatkette validiert wird.
    • PRIVATE_KEY_SECRET_NAME: Der Name des Secrets, das den privaten Schlüssel des ACME-Kontos enthält.

    Wenn Sie einen vorhandenen privaten Schlüssel für ein ACME-Konto verwenden möchten, muss das Secret, in dem er gespeichert ist, den Namen PRIVATE_KEY_SECRET_NAME im selben Namespace wie der ACME-Aussteller verwenden. Wenn Sie dieses Secret nicht angeben, wird automatisch ein neues mit demselben Namen generiert, um den privaten Schlüssel des ACME-Kontos zu speichern.

  2. Wenden Sie die benutzerdefinierte Ressource auf Ihre Distributed Cloud-Zone an:

    kubectl apply -f acme-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
    
  3. Prüfen Sie, ob der neue Aussteller bereit ist:

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

    Die Ausgabe sollte in etwa so aussehen:

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

Neuausstellung von Zertifikaten

Informationen zum Wechseln des Standardausstellers zum neuen ACME-Aussteller finden Sie unter Standardzertifikataussteller ändern.

Wenn Sie Zertifikate sofort mit dem neuen Standardaussteller neu ausstellen möchten, lesen Sie den Abschnitt PKI-Webzertifikate manuell neu ausstellen.