Google Distributed Cloud(GDC)エアギャップは、ウェブ証明書を取得するための公開鍵基盤(PKI)API を提供します。このページでは、ある PKI 証明書モードから別の PKI 証明書モードに移行する手順について説明します。PKI モードの構成タイプの詳細については、ウェブ TLS 証明書の構成をご覧ください。
始める前に
PKI のデフォルト証明書発行者を構成するために必要な権限を取得するには、組織の IAM 管理者に、システム Namespace の Infra PKI 管理者(infra-pki-admin
)ロールの付与を依頼してください。
BYO サブ CA モードに移行する
このセクションでは、お客様所有(BYO)SubCA 証明書モードに移行する一連の手順について説明します。
BYO サブ CA を作成する
BYO サブ 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: 秘密鍵と署名付き CA 証明書を保持する Kubernetes Secret の名前。
カスタム リソースを Distributed Cloud ゾーンに適用します。
kubectl apply -f byo-subca.yaml --kubeconfig MANAGEMENT_API_SERVER
MANAGEMENT_API_SERVER は、Management API サーバーの kubeconfig ファイルに置き換えます。
Sub CA の CSR が生成され、署名されるのを待ちます。CSR に署名するには、BYO サブ CA 証明書に署名するの手順に沿って操作します。
BYO サブ 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-----
「Basic Constraints」拡張機能で
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 証明書に SAN ではなく共通名(CN)がある場合は、証明書の
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'
BYO subCA の準備状況を確認します。
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 証明書モードへの移行
このセクションでは、BYO-cert モードに移行する一連の手順について説明します。
BYO CertificateIssuer を作成する
CertificateIssuer
リソースを作成し、YAML ファイル(byo-cert-issuer.yaml
など)として保存します。この BYO 証明書発行者は、フォールバック CA としてマネージドdefault-tls-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 は、BYO-cert 発行者の名前に置き換えます。
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" }
BYO 証明書に署名する
CSR が外部で署名されるのを待機している間、BYO-cert 発行者で指定されたフォールバック CA によって BYO-cert が一時的に発行されることがあります。現在の 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))'
出力は次のようになります。
{ "lastTransitionTime": "2024-05-03T08:42:10Z", "message": "Certificate is issued by a fallback CA", "observedGeneration": 1, "reason": "UsingFallbackCA", "status": "True", "type": "Ready" }
準備完了の理由に
UsingFallbackCA
と表示され、フォールバック CA が証明書を発行したことが示されます。その後、シークレットに保存され、使用できるようになります。証明書の Secret 名を取得します。
kubectl -n istio-system get certificate.pki.security.gdc.goog/default-wildcard-cert -ojson | jq -r '.spec.secretConfig.secretName'
出力は次のようになります。
web-tls
Secret から発行者を確認します。
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
の example-service 証明書は、同じ証明書発行元の DNSName*.org-1.zone1.google.gdch.test
のdefault-wildcard-cert
と一致します。example-service 証明書は、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" }
証明書のステータスから 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 モードで BYO 証明書に移行する
このセクションでは、ACME モードで BYO-cert に移行する一連の手順について説明します。
ACME 構成で CertificateIssuer を作成する
ACME 構成で
CertificateIssuer
リソースを作成し、acme-issuer.yaml
などの 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 サーバーのディレクトリ エンドポイントにアクセスするための URL。
- CA_BUNDLE: ACME サーバーによって提示された証明書チェーンを検証する PEM CA の Base64 でエンコードされたバンドル。
- PRIVATE_KEY_SECRET_NAME: ACME アカウントの秘密鍵を含む Secret の名前。
既存の 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 ウェブ証明書を手動で再発行するをご覧ください。