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.
Erstellen Sie eine
CertificateAuthority
-Ressource und speichern Sie sie als YAML-Datei. Im folgenden Beispiel sehen Sie eine BeispielressourceCertificateAuthority
.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.
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
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.Verwenden Sie das Protokoll der Stammzertifizierungsstelle des Kunden, um signierte CA-Zertifikate für die Datei
sub_ca.csr
anzufordern.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 Dateica.crt
im aktuellen Verzeichnis speichern. Wenden Sie sich an das PMO, um genaue Anweisungen zu erhalten.Prüfen Sie Folgendes, um die Integrität und Richtigkeit der Zertifikate sicherzustellen:
Prüfen Sie, ob
sub_ca.crt
dem Standardformat für PEM-codierte Zertifikate entspricht:-----BEGIN CERTIFICATE----- <Certificate> -----END CERTIFICATE-----
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
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"
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…
Bearbeiten Sie die Spezifikation der
CertificateAuthority
-Ressource:kubectl patch certificateauthority CA_NAME -n pki-system --patch-file patch.txt --type='merge'
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" }
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
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.
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
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
Erstellen Sie eine
CertificateIssuer
-Ressource und speichern Sie sie als YAML-Datei, z. B.byo-cert-issuer.yaml
. Dieser BYO-Zertifikataussteller verwendet die verwaltetedefault-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.
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
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
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.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
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 demdefault-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" }
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..." }
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
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 GrundIssued
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
- Der CSR-Status des Zertifikats ist
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
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.
Wenden Sie die benutzerdefinierte Ressource auf Ihre Distributed Cloud-Zone an:
kubectl apply -f acme-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
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.