Google Distributed Cloud (GDC) 氣隙隔離提供公開金鑰基礎架構 (PKI) API,可取得網頁憑證。本頁面提供從一個 PKI 憑證模式轉換至另一個模式的說明。如要進一步瞭解 PKI 模式設定類型,請參閱「Web TLS certificate configuration」(網頁 TLS 憑證設定)
事前準備
如要取得設定 PKI 預設憑證簽發機構所需的權限,請要求機構 IAM 管理員在系統命名空間中,授予您基礎架構 PKI 管理員 (infra-pki-admin
) 角色。
改用自備子 CA 模式
本節提供一系列步驟,說明如何改用自備 SubCA 憑證模式。
建立自備子 CA
如要建立自有次要 CA,請將自訂資源套用至 Distributed Cloud 區域。
建立
CertificateAuthority
資源,並儲存為 YAML 檔案。在下列範例中,您會看到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
請替換下列變數:
- CA_NAME:子 CA 的名稱。
- COMMON_NAME:CA 憑證的一般名稱。
- DURATION:要求的 CA 憑證生命週期。
- RENEW_BEFORE:CA 憑證到期前的輪替時間。
- SECRET_NAME:Kubernetes Secret 的名稱,用於保存私密金鑰和已簽署的 CA 憑證。
將自訂資源套用至 Distributed Cloud 區域。
kubectl apply -f byo-subca.yaml --kubeconfig MANAGEMENT_API_SERVER
將 MANAGEMENT_API_SERVER 替換為 Management API 伺服器 kubeconfig 檔案。
系統會產生子 CA 的 CSR,並等待您簽署。如要簽署 CSR,請按照「簽署 BYO 子 CA 憑證」一節中的指示操作。
簽署自備子 CA 憑證
從 GDC 環境取得憑證簽署要求 (CSR):
kubectl get certificateauthorities CA_NAME -n pki-system -ojson | jq -j '"echo ", .status.externalCA.csr, " | base64 -d > ","sub_ca.csr\n"' | bash
這個指令會在目前目錄中產生
sub_ca.csr
檔案。這個檔案包含 X.509 CA 憑證的 CSR。使用客戶根 CA 的通訊協定,為
sub_ca.csr
檔案要求簽署的 CA 憑證。如果憑證簽署要求獲得核准,您會取得由客戶根 CA 簽署的 CA 憑證。將憑證儲存至目前目錄中的
sub_ca.crt
檔案。此外,請取得客戶的根 CA 憑證,並儲存至目前目錄中的ca.crt
檔案。如需確切的操作說明,請與 PMO 聯絡。請驗證下列事項,確保憑證的完整性和準確性:
確認
sub_ca.crt
符合標準 PEM 編碼憑證格式:-----BEGIN CERTIFICATE----- <Certificate> -----END CERTIFICATE-----
確認
sub_ca.crt
是「基本限制」擴充功能中的有效憑證授權單位 (CA):openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Basic Constraints"
輸出內容必須包含
CA:TRUE
,否則需要進一步調查:X509v3 Basic Constraints: critical CA:TRUE
驗證憑證中的主體別名 (SAN) 擴充功能:
openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject Alternative Name"
如果 CA 憑證具有共用名稱 (CN) 而非 SAN,請驗證憑證中的
CN
:openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject: CN"
產生規格,以修補
CertificateAuthority
資源:echo "spec: caCertificate: externalCA: signedCertificate: certificate: $(base64 -w0 sub_ca.crt) ca: $(base64 -w0 ca.crt)" > patch.txt
patch.txt
檔案中的內容類似下列程式碼片段:spec: caCertificate: externalCA: signedCertificate: certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ… ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
編輯
CertificateAuthority
資源的規格:kubectl patch certificateauthority CA_NAME -n pki-system --patch-file patch.txt --type='merge'
確認自備子 CA 是否已準備就緒:
kubectl get certificateauthority CA_NAME -n pki-system -ojson | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id))'
畫面會顯示類似以下內容的輸出:
{ "lastTransitionTime": "2024-04-30T22:10:50Z", "message": "Certificate authority is ready for use", "observedGeneration": 3, "reason": "Ready", "status": "True", "type": "Ready" }
確認簽署的 CA 憑證是否過期:
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
建立
CertificateIssuer
資源 YAML 檔案,然後儲存檔案。例如: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
將 BYO_SUBCA_ISSUER 換成 BYO 子 CA 簽發者名稱。
使用
kubectl
CLI,將自訂資源套用至 Management API 伺服器中的 Distributed Cloud 區域:kubectl apply -f byo-subca-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
確認新核發機構是否已準備就緒:
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))'
改用自備憑證模式
本節提供一系列步驟,說明如何轉換至自備憑證模式。
建立 BYO CertificateIssuer
建立
CertificateIssuer
資源,並儲存為 YAML 檔案,例如byo-cert-issuer.yaml
。這個自備憑證核發者會使用代管的default-tls-ca
做為備用 CA: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
將 BYO_CERT_ISSUER_NAME 替換為自有憑證簽發者的名稱。
在 Management API 伺服器中,將自訂資源套用至 Distributed Cloud 區域:
kubectl apply -f byo-cert-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
確認新核發機構是否已準備就緒。
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))'
輸出看起來類似以下內容:
{ "lastTransitionTime": "2024-05-01T22:25:20Z", "message": "", "observedGeneration": 1, "reason": "FallbackCAReady", "status": "True", "type": "Ready" }
簽署自備憑證
等待外部簽署 CSR 時,BYO 憑證簽發者指定的備援 CA 可以暫時核發 BYO 憑證。取得目前的自備憑證狀態:
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))'
輸出看起來類似以下內容:
{ "lastTransitionTime": "2024-05-03T08:42:10Z", "message": "Certificate is issued by a fallback CA", "observedGeneration": 1, "reason": "UsingFallbackCA", "status": "True", "type": "Ready" }
準備就緒原因會顯示
UsingFallbackCA
,表示備援 CA 核發了憑證。然後儲存在密鑰中,隨時可供使用。取得憑證密鑰名稱:
kubectl -n istio-system get certificate.pki.security.gdc.goog/default-wildcard-cert -ojson | jq -r '.spec.secretConfig.secretName'
輸出看起來類似以下內容:
web-tls
檢查密鑰的簽發者:
kubectl get secret web-tls -n istio-system -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout | grep Issuer
輸出看起來類似以下內容:
Issuer: CN = GDC Managed ORG TLS CA
自備憑證 (BYO-cert) 在等待自己的 CSR 簽章時,可以暫時使用相符的憑證。如果範例服務憑證的 dnsName 為
example-service.org-1.zone1.google.gdch.test
,則來自同一憑證核發機構的default-wildcard-cert
(DNSName 為*.org-1.zone1.google.gdch.test
) 會與該憑證相符。等待簽署 CSR 時,example-service 憑證可能處於下列狀態:{ "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:
kubectl -n istio-system get certificate.pki.security.gdc.goog/default-wildcard-cert -ojson | jq -r ' .status.byoCertStatus.csrStatus'
輸出看起來類似以下內容:
{ "conditions": [ { "lastTransitionTime": "2024-05-03T18:14:19Z", "message": "", "observedGeneration": 1, "reason": "WaitingForSigning", "status": "False", "type": "Ready" } ], "csr": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSB..." }
根據外部 CA 設定,簽署 CSR 的方法有所不同。簽署時,請使用 CSR 中的 SAN。例如:
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
請確認下列詳細資料:
- 憑證的 CSR 狀態為「
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" } ]
- 憑證已
Ready
,原因為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))'
輸出看起來類似以下內容:
{ "lastTransitionTime": "2024-05-03T08:42:10Z", "message": "Certificate is issued", "observedGeneration": 2, "reason": "Issued", "status": "True", "type": "Ready" }
- 密鑰已更新:
kubectl get secret web-tls -n istio-system -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout | grep Issuer
輸出看起來類似以下內容:
Issuer: CN = external-ca
- 憑證的 CSR 狀態為「
改用 ACME 模式的自備憑證
本節提供一系列步驟,說明如何使用 ACME 模式轉換為自備憑證。
使用 ACME 設定建立 CertificateIssuer
使用 ACME 設定建立
CertificateIssuer
資源,並儲存為 YAML 檔案,例如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
請替換下列變數:
- ACME_ISSUER_NAME:ACME 核發機構的名稱。
- ROOT_CA_CERTIFICATE:ACME 伺服器核發憑證的根 CA 資料。
- ACME_SERVER_URL:用來存取 ACME 伺服器目錄端點的網址。
- CA_BUNDLE:以 Base64 編碼的 PEM CA 套裝組合,用於驗證 ACME 伺服器提供的憑證鏈結。
- PRIVATE_KEY_SECRET_NAME:包含 ACME 帳戶私密金鑰的密碼名稱。
如要使用現有的 ACME 帳戶私密金鑰,請確認保存該金鑰的密鑰使用與 ACME 簽發者相同的命名空間,且名稱為 PRIVATE_KEY_SECRET_NAME。如果您未提供這個密碼,系統會自動產生同名的新密碼,用於儲存 ACME 帳戶私密金鑰。
將自訂資源套用至 Distributed Cloud 區域:
kubectl apply -f acme-issuer.yaml --kubeconfig MANAGEMENT_API_SERVER
確認新核發機構是否已準備就緒:
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))'
畫面會顯示類似以下內容的輸出:
{ "lastTransitionTime": "2024-05-01T18:32:17Z", "message": "", "observedGeneration": 1, "reason": "ACMEClientReady", "status": "True", "type": "Ready" }
重新核發憑證
如要將預設簽發機構切換為新的 ACME 簽發機構,請參閱「變更預設憑證簽發機構」一文。
如要立即使用新的預設簽發者重新核發憑證,請參閱「手動重新核發 PKI 網頁憑證」。