Google Distributed Cloud (GDC) 에어 갭은 웹 인증서를 가져오는 공개 키 인프라 (PKI) API를 제공합니다. 이 페이지에서는 한 PKI 인증서 모드에서 다른 모드로 전환하는 방법을 설명합니다. PKI 모드 구성 유형에 관한 자세한 내용은 웹 TLS 인증서 구성을 참고하세요.
시작하기 전에
PKI 기본 인증서 발급자를 구성하는 데 필요한 권한을 얻으려면 조직 IAM 관리자에게 시스템 네임스페이스의 인프라 PKI 관리자(infra-pki-admin
) 역할을 부여해 달라고 요청하세요.
BYO 하위 CA 모드로 전환
이 섹션에서는 자체 하위 CA 인증서 모드로 전환하는 일련의 단계를 설명합니다.
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 보안 비밀의 이름입니다.
커스텀 리소스를 Distributed Cloud 영역에 적용합니다.
kubectl apply -f byo-subca.yaml --kubeconfig MANAGEMENT_API_SERVER
MANAGEMENT_API_SERVER를 관리 API 서버 kubeconfig 파일로 바꿉니다.
하위 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-----
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 하위 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를 사용하여 관리 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 인증서 발급자는 관리형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을 BYO 인증서 발급자의 이름으로 바꿉니다.
관리 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 인증서 발급기관에 지정된 대체 CA에서 BYO 인증서를 일시적으로 발급할 수 있습니다. 현재 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" }
준비 이유에는 대체 CA가 인증서를 발급했음을 나타내는
UsingFallbackCA
가 표시됩니다. 그러면 보안 비밀에 저장되어 사용할 준비가 됩니다.인증서 보안 비밀 이름을 가져옵니다.
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
인 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 상태가
ACME 모드로 BYO 인증서로 전환
이 섹션에서는 ACME 모드로 BYO 인증서로 전환하는 일련의 단계를 제공합니다.
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 서버에서 제공하는 인증서 체인을 검증하는 Base64로 인코딩된 PEM CA 번들입니다.
- 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 웹 인증서 수동 재발급을 참고하세요.