Google Distributed Cloud (GDC) 网闸隔离设备提供了一个公钥基础架构 (PKI) API 来获取 Web 证书。本文档提供了从一种 PKI 证书模式过渡到另一种模式的说明。如需详细了解 PKI 模式配置类型,请参阅 Web TLS 证书配置。
准备工作
在转换 PKI 模式之前,您必须拥有必要的权限并准备好环境。
申请 IAM 角色
如需创建、更新和删除证书授权机构和证书签发者,请与组织 IAM 管理员联系,请求在系统命名空间中获得 Infra PKI Admin (infra-pki-admin) 角色。
准备环境
如果您尚未下载并安装 gdcloud CLI,请执行此操作。
按照安装组件中的说明安装
kubectlCLI。生成 kubeconfig 文件以配置
kubectl访问权限。
改用自带子 CA 模式
本部分提供了一系列步骤,用于过渡到自带 (BYO) SubCA 证书模式。
创建自带子 CA
如需创建自带子 CA,请将自定义资源应用到 GDC 网闸隔离配置设备实例。
创建
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 证书的请求生命周期。以小时为单位指定时长(例如
1000h)。不支持天 (d) 或年 (y) 等单位。 - RENEW_BEFORE:CA 证书过期前的轮替时间。
- SECRET_NAME:将包含私钥和已签名的 CA 证书的 Kubernetes Secret 的名称。
将自定义资源应用到 GDC 网闸隔离配置设备实例。
kubectl apply -f byo-subca.yaml --kubeconfig MANAGEMENT_API_SERVER将 MANAGEMENT_API_SERVER 替换为 Management API 服务器 kubeconfig 文件。
为子 CA 生成 CSR 并等待您对其进行签名。如需签署 CSR,请按照签署自带的子 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 联系。验证 CA 证书的通用名称 (CN):
openssl x509 -noout -subject -in sub_ca.crt如果您的设置需要正文备用名称 (SAN) 扩展项,请验证证书中的 SAN 扩展项:
openssl x509 -text -noout -in sub_ca.crt | grep -A 1 "Subject Alternative Name"生成用于修补
CertificateAuthority资源的规范:echo "spec: caCertificate: externalCA: signedCertificate: certificate: $(base64 -w0 sub_ca.crt) ca: $(base64 -w0 ca.crt)" > patch.txtpatch.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 替换为自带子 CA 签发者的名称。
使用
kubectlCLI 将自定义资源应用到 Management API 服务器中的 GDC 网闸隔离配置设备实例: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))'
过渡到自带证书模式
本部分提供了一系列步骤,用于过渡到自带证书模式。
创建自带证书的 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 服务器中,将自定义资源应用于 GDC 网闸隔离配置设备实例:
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-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 中,随时可供使用。获取证书 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相匹配。在等待签署 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 状态为
证书重新签发
如需将默认发卡机构切换为新发卡机构,请参阅更改默认证书发卡机构
如需立即使用新的默认签发者重新签发证书,请参阅手动重新签发 PKI 网络证书。