하위 인증 기관 만들기

이 문서에서는 하위 인증 기관(하위 CA)을 만드는 단계를 설명합니다.

하위 CA는 사용자, 컴퓨터, 기기 등의 종단 개체에 직접 인증서를 발급합니다. 하위 CA는 대개 루트 CA인 상위 CA에 의해 암호화 방식으로 서명됩니다. 루트 CA를 신뢰하는 시스템은 하위 CA와 하위 CA가 발급하는 인증서를 자동으로 신뢰합니다.

CA 인증서 서명자는 CA 서비스에서 생성된 다른 CA(예: 루트 CA)이거나 외부 CA일 수 있습니다. 외부 CA를 사용하면 CA 서비스는 외부 CA에서 서명해야 하는 인증서 서명 요청 (CSR)을 생성합니다.

이 문서는 프로젝트 내에서 인증서 수명 주기를 관리하는 애플리케이션 개발자 또는 데이터 과학자와 같은 애플리케이션 운영자 그룹 내의 사용자를 대상으로 합니다. 자세한 내용은 GDC 에어 갭 문서의 대상 그룹을 참고하세요.

시작하기 전에

하위 CA를 만들려면 먼저 필요한 권한을 요청하고 환경을 준비해야 합니다.

IAM 역할 요청

인증 기관 리소스를 만들고, 업데이트하고, 삭제하려면 조직 IAM 관리자에게 문의하여 인증 기관의 프로젝트 네임스페이스에서 Certificate Authority Service 관리자(certificate-authority-service-admin) 역할을 요청하세요.

개발 환경 준비

관리형 하위 CA 만들기

관리형 하위 CA의 경우 CA 인증서의 서명자는 CA 서비스에서 생성된 다른 CA (루트 CA)입니다.

관리형 하위 CA를 만들려면 커스텀 리소스를 Distributed Cloud Appliance 인스턴스에 적용합니다.

  1. CertificateAuthority 리소스를 만들고 subca.yaml이라는 YAML 파일로 저장합니다.

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateAuthority
    metadata:
      Name: SUB_CA_NAME
      namespace: USER_PROJECT_NAMESPACE
    spec:
      caProfile:
        commonName: COMMON_NAME
        duration: DURATION
        renewBefore: RENEW_BEFORE
        organizations:
        - ORGANIZATIONS
        organizationalUnits:
        - ORGANIZATIONAL_UNITS
        countries:
        - COUNTRIES
        localities:
        - LOCALITIES
        provinces:
        - PROVINCES
        streetAddresses:
        - STREET_ADDRESSES
        postalCodes:
        - POSTAL_CODES
      caCertificate:
        managedSubCA:
          certificateAuthorityRef:
            name: ROOT_CA_NAME
            namespace: USER_PROJECT_NAMESPACE
      certificateProfile:
        keyUsage:
          - digitalSignature
          - keyCertSign
          - crlSign
        extendedKeyUsage:
          - EXTENDED_KEY_USAGE
      secretConfig:
        secretName: SECRET_NAME
        privateKeyConfig:
          algorithm: KEY_ALGORITHM
          size: KEY_SIZE
      acme:
        enabled: ACME_ENABLED
    

    다음 변수를 바꿉니다.

    변수 설명
    SUB_CA_NAME 하위 CA의 이름입니다.
    USER_PROJECT_NAMESPACE 사용자 프로젝트가 있는 네임스페이스의 이름입니다.
    COMMON_NAME CA 인증서의 일반 이름입니다.
    DURATION 요청된 CA 인증서의 수명입니다. 시간 단위로 기간을 지정합니다 (예: 1000h). 일 (d) 또는 연도 (y)와 같은 단위는 지원되지 않습니다.
    ROOT_CA_NAME 루트 CA의 이름입니다.
    SECRET_NAME 비공개 키와 서명된 CA 인증서를 보유하는 Kubernetes 보안 비밀의 이름입니다.

    다음 변수는 선택적 값입니다.

    변수 설명
    RENEW_BEFORE CA 인증서가 만료되기 전의 순환 시간입니다.
    ORGANIZATIONS 인증서에 사용할 조직입니다.
    ORGANIZATIONAL_UNITS 인증서에 사용할 조직 단위입니다.
    COUNTRIES 인증서에 사용할 국가입니다.
    LOCALITIES 인증서에 사용할 도시입니다.
    PROVINCES 인증서에 사용할 주 또는 도입니다.
    STREET_ADDRESSES 인증서에 사용할 도로 주소입니다.
    POSTAL_CODES 인증서에 사용할 우편번호입니다.
    EXTENDED_KEY_USAGE 인증서의 확장 키 사용입니다. 제공된 경우 허용되는 값은 serverAuthclientAuth입니다.
    KEY_ALGORITHYM 이 인증서에 사용되는 비공개 키 알고리즘입니다. 허용되는 값 은 RSA, Ed25519 또는 ECDSA입니다. 크기가 제공되지 않으면 기본값은 ECDSA의 경우 256이고 RSA의 경우 2048입니다. Ed25519의 경우 키 크기가 무시됩니다.
    KEY_SIZE 이 인증서의 비공개 키 크기(비트)는 알고리즘에 따라 다릅니다. RSA는 2048, 3072, 4096 또는 8192 (기본값 2048)를 허용합니다. ECDSA 는 256, 384 또는 521 (기본값 256)을 허용합니다. Ed25519는 크기를 무시합니다.
    ACME_ENABLED true로 설정하면 CA가 ACME 모드로 실행되고 ACME 서버 URL을 출력합니다. 그런 다음 ACME 클라이언트 및 프로토콜을 사용하여 인증서를 관리할 수 있습니다.
  2. 커스텀 리소스를 Distributed Cloud 인스턴스에 적용합니다.

    kubectl apply -f subca.yaml --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    

    MANAGEMENT_API_SERVER_KUBECONFIG를 Management API 서버의 kubeconfig 파일 경로로 바꿉니다.

  3. 하위 CA의 준비 상태를 확인합니다. CA가 준비되는 데 약 40분이 걸립니다.

    kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificateauthority.pki.security.gdc.goog/SUB_CA_NAME -ojson | jq -r ' 
    .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    결과는 다음과 유사합니다.

    {
      "lastTransitionTime": "2025-01-24T17:09:29Z",
      "message": "CA reconciled",
      "observedGeneration": 2,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    

외부 CA에서 하위 CA 만들기

이 하위 CA는 외부 또는 사용자 관리 CA로 리프 인증서 서명을 지원합니다. 사용자가 서명할 CSR을 생성합니다.

  1. CertificateAuthority 리소스를 만들고 subca-external.yaml이라는 YAML 파일로 저장합니다.

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateAuthority
    metadata:
      Name: SUB_CA_NAME
      namespace: USER_PROJECT_NAMESPACE
    spec:
      caProfile:
        commonName: COMMON_NAME
        duration: DURATION
        renewBefore: RENEW_BEFORE
        organizations:
        - ORGANIZATION
        organizationalUnits:
        - ORGANIZATIONAL_UNITS
        countries:
        - COUNTRIES
        localities:
        - LOCALITIES
        provinces:
        - PROVINCES
        streetAddresses:
        - STREET_ADDRESSES
        postalCodes:
        - POSTAL_CODES
      caCertificate:
        externalCA: {}
      certificateProfile:
        keyUsage:
          - digitalSignature
          - keyCertSign
          - crlSign
        extendedKeyUsage:
          - EXTENDED_KEY_USAGE
      secretConfig:
        secretName: SECRET_NAME
        privateKeyConfig:
          algorithm: KEY_ALGORITHM
          size: KEY_SIZE
      acme:
        enabled: ACME_ENABLED
    

    다음 변수를 바꿉니다.

    변수 설명
    SUB_CA_NAME subCA의 이름입니다.
    USER_PROJECT_NAMESPACE 이미지를 가져올 프로젝트의 프로젝트 ID입니다.
    COMMON_NAME CA 인증서의 일반 이름입니다.
    DURATION 요청된 CA 인증서의 수명입니다. 시간 단위로 기간을 지정합니다 (예: 1000h). 일 (d) 또는 연도 (y)와 같은 단위는 지원되지 않습니다.
    SECRET_NAME 비공개 키와 서명된 CA 인증서를 보유하는 Kubernetes 보안 비밀의 이름입니다.

    다음 변수는 선택적 값입니다.

    변수 설명
    RENEW_BEFORE CA 인증서가 만료되기 전의 순환 시간입니다.
    ORGANIZATION 인증서에 사용할 조직입니다.
    ORGANIZATIONAL_UNITS 인증서에 사용할 조직 단위입니다.
    COUNTRIES 인증서에 사용할 국가입니다.
    LOCALITIES 인증서에 사용할 도시입니다.
    PROVINCES 인증서에 사용할 주 또는 도입니다.
    STREET_ADDRESSES 인증서에 사용할 도로 주소입니다.
    POSTAL_CODES 인증서에 사용할 우편번호입니다.
    EXTENDED_KEY_USAGE 인증서의 확장 키 사용입니다. 제공된 경우 허용되는 값은 serverAuthclientAuth입니다.
    KEY_ALGORITHYM 이 인증서에 사용되는 비공개 키 알고리즘입니다. 허용되는 값 은 RSA, Ed25519 또는 ECDSA입니다. 크기가 제공되지 않으면 ECDSA의 경우 기본값은 256이고 2048 의 경우 RSA입니다. Ed25519의 경우 키 크기가 무시됩니다.
    KEY_SIZE 이 인증서의 비공개 키 크기(비트)는 알고리즘에 따라 다릅니다. RSA는 2048, 3072, 4096 또는 8192 (기본값 2048)를 허용합니다. ECDSA는 256, 384 또는 521 (기본값 256)을 허용합니다. Ed25519 는 크기를 무시합니다.
    ACME_ENABLED true로 설정하면 CA가 ACME 모드로 실행되고 ACME 서버 URL을 출력합니다. 그런 다음 ACME 클라이언트 및 프로토콜을 사용하여 인증서를 관리할 수 있습니다.
  2. 커스텀 리소스를 Distributed Cloud 인스턴스에 적용합니다.

    kubectl apply -f subca-external.yaml --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    
  3. 하위 CA의 CSR은 GDC Management API 서버 내에서 생성됩니다. CSR을 다운로드하고 서명해야 합니다. 서명한 후 서명된 인증서를 GDC Management API 서버에 업로드할 수 있습니다.

  4. Distributed Cloud 환경에서 인증서 서명 요청 (CSR)을 수집합니다.

    kubectl get certificateauthorities SUB_CA_NAME -n USER_PROJECT_NAMESPACE -ojson | jq -j '"echo ", .status.externalCA.csr, " | base64 -d > ","sub_ca.csr\n"' | bash
    

    이 명령어는 현재 디렉터리에 sub_ca.csr이라는 CSR 파일을 생성합니다. 이 파일에는 X.509 CA 인증서의 CSR이 포함되어 있습니다.

  5. 고객의 루트 CA를 사용하여 sub_ca.csr 파일의 서명된 CA 인증서를 요청합니다.

  6. 승인된 인증서 서명 요청의 경우 고객의 루트 CA에서 서명한 CA 인증서를 가져와야 합니다. 현재 디렉터리의 sub_ca.crt 파일에 인증서를 저장합니다.

  7. 해당하는 경우 고객의 루트 CA 인증서를 가져와서 현재 디렉터리의 ca.crt 파일에 저장합니다.

  8. 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"
    
  9. CertificateAuthority 리소스를 패치할 spec을 생성합니다.

    echo "spec:
      caCertificate:
        externalCA:
          signedCertificate:
            certificate: $(base64 -w0 SUB_CA_NAME.crt)
            ca: $(base64 -w0 ca.crt)" > patch.txt
    

    patch.txt 파일의 콘텐츠는 다음과 유사합니다.

    spec:
      caCertificate:
        externalCA:
          signedCertificate:
            certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURSekNDQ…
            ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRVENDQ…
    
  10. CertificateAuthority 리소스의 spec 필드를 수정합니다.

    kubectl patch certificateauthority SUB_CA_NAME -n USER_PROJECT_NAMESPACE--patch-file patch.txt --type='merge'
    
  11. BYO (Bring Your Own) 하위 CA의 준비 상태를 확인합니다. 일반적으로 CA가 준비되는 데 약 40분이 걸립니다.

    kubectl -n USER_PROJECT_NAMESPACE get certificateauthority.pki.security.gdc.goog/SUB_CA_NAME -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"
    }
    
  12. 서명된 CA 인증서의 만료일을 확인합니다.

    kubectl -n USER_PROJECT_NAMESPACE get secret SECRET_NAME -ojson | jq -j '"echo ", .metadata.name, " $(echo ", .data["tls.crt"], "| base64 -d | openssl x509 -enddate -noout)\n"' | bash
    

CA 나열

Distributed Cloud 에어 갭 인스턴스에서 모든 Certificate Authority Service 리소스를 나열하려면 다음 단계를 따르세요.

certificateauthorities 매개변수를 사용하여 모든 CertificateAuthority 리소스를 나열합니다.

   kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificateauthorities

결과는 다음과 유사합니다.

   NAMESPACE    NAME              READY   REASON   AGE
   foo          root-ca           True    Ready    7h24m
   foo          sub-ca            True    Ready    7h24m