Keyfactor EJBCA リファレンス実装

概要

このガイドでは、Keyfactor EJBCA Enterprise(外部アプライアンスとしてデプロイ)を Google Distributed Cloud(GDC)エアギャップのサードパーティ認証局(CA)として統合する方法について説明します。

Keyfactor EJBCA Enterprise は、スケーラビリティが高く、堅牢で、FIPS に準拠した認証局プラットフォームです。組織は、このプラットフォームを使用して、異種環境にわたる公開鍵基盤(PKI)を管理できます。

GDC エアギャップには、ホストされたクラウド境界内の鍵と証明書の自動管理のための組み込みの Certificate Authority Service が含まれています。ただし、GDC 外の既存のワークロード用に Keyfactor EJBCA で PKI インフラストラクチャを標準化している組織は、エアギャップ GDC 環境内で実行されるワークロードに同じ一貫性のある CA アーキテクチャと管理ポリシーを活用することを望む可能性があります。

このガイドでは、GDC ネットワーキング、内部 DNS、Kubernetes cert-manager を構成して、証明書のライフサイクル管理(ACME)を自動化し、登録機関(RA)パターンを使用して大量のプログラムによる発行をサポートする方法について説明します。

前提条件

このガイドに進む前に、次の前提条件が満たされていることを確認してください。

  • Keyfactor EJBCA はソフトウェア アプライアンスまたはハードウェア アプライアンスとしてデプロイされ、安定した IP アドレスがサービスに構成されます。
  • ルート、下位、管理の認証局(CA)が EJBCA インスタンスに作成されている。
  • エンド エンティティ(EE)プロファイルが構成されている(TLS サーバー証明書など)。
  • 管理 CA ユーザーの証明書がダウンロードされました。
  • EJBCA インスタンスで必要なプロトコル(ACME など)が有効になっている。
  • このガイドでは、RSA 署名アルゴリズムを使用します。署名アルゴリズムは、特定の要件または EJBCA インスタンスで構成されている内容に基づいて変更できます。

アーキテクチャ

このアーキテクチャは、外部認証局モデルに従っています。このモデルでは、EJBCA サーバーとそのバックエンドのハードウェア セキュリティ モジュール(HSM)が、物理的な GDC の境界外に外部でホストされますが、ネットワーク経由でアクセスできます。EJBCA サーバーは、ハードウェア アプライアンスまたはソフトウェア アプライアンスとして外部にデプロイできます。このガイドで説明するコア統合では、外部 EJBCA サーバーが安定した IP アドレスを使用して到達可能であることのみが求められます。

Keyfactor EJBCA のアーキテクチャ図。

このアーキテクチャの主なコンポーネントは次のとおりです。

  • EJBCA Enterprise Server: Keyfactor ハードウェア アプライアンスまたはソフトウェア アプライアンスとして外部にデプロイされ、CA(ルートと下位)を格納し、CC EAL4+ 認定の HSM 内ですべての CA 鍵マテリアルを生成します。
  • GDC Standard Kubernetes クラスタ: お客様のワークロード、cert-manager、統合プロキシを実行するコンピューティング環境。
  • GDC 内部 DNS: ACME DNS-01 チャレンジの解決に使用されるローカル プライベート DNS ゾーン(環境変数で構成された限定公開ドメイン名を使用)を管理します。
  • GDC 下り(外向き)ゲートウェイ: クラスタ Pod から外部 EJBCA サーバーの IP アドレスにアウトバウンド トラフィックを転送します。
  • Harbor プライベート レジストリ: エアギャップ デプロイ用にミラーリングされたコンテナ イメージ(EJBCA cert-manager 発行者など)をホストします。

始める前に

統合を開始する前に、GDC 環境が次の要件を満たしていることを確認してください。

  • まず、このガイド全体で生成されるすべてのリソースのホルダーとして機能するプロジェクトを作成します。
  • このガイド全体で参照される環境変数を構成します。必要に応じて、特定の環境に合わせてこれらの値を変更します。

    # GDC Environment Configuration
    export GDC_ORG="your-org-name"
    export GDC_ZONE="your-zone-name"
    export GDC_PROJECT_ID="your-project-id"
    export GDC_USER_NAME="your-gdc-user-email"
    export GDC_CLUSTER_NAME="your-cluster-name"
    
    # EJBCA Server Configuration
    export EJBCA_DNS_ZONE="example.internal"
    export EJBCA_HOSTNAME="ejbca.${EJBCA_DNS_ZONE}"
    export EJBCA_LB_IP="XX.XX.XX.XX" # Stable IP of your EJBCA Server
    export EJBCA_CA_NAME="GDC Subordinate CA"
    export EJBCA_NAMESPACE="ejbca-ee"
    export CERTIFICATE_PROFILE_NAME="GDC TLS SERVER PROFILE"
    export END_ENTITY_PROFILE_NAME="GDC TLS SERVER EE PROFILE"
    
    # Harbor Private Registry Configuration
    export HARBOR_INSTANCE_URL="your-harbor-url.internal"
    export HARBOR_PROJECT="your-harbor-project"
    export HARBOR_ROBOT_ACCOUNT="robot$your-robot-name"
    export HARBOR_ROBOT_SECRET="your-robot-secret"
    export HARBOR_PULL_SECRET_NAME="harbor-secret"
    
  • ネットワークに関する注: このガイドは、GDC エアギャップ API にアクセスでき、必要なマニフェストとコンテナ イメージをダウンロードするためにインターネットにもアクセスできる要塞ノードから実行されることを前提としています。インターネットにアクセスできないマシンからこれを実行する場合は、これらのアセットを別途取得し(たとえば、docker save を使用して接続されたマシンからイメージをエクスポートし、docker load を使用してインポートするなど)、続行する前に環境に安全にアップロードする必要があります。

kubectl エイリアスを構成する

このセクションでは、GDC のゾーン管理 API とグローバル API の便利なコマンドライン エイリアスを作成します。

  • ゾーン管理 API のエイリアスを作成します(MANAGEMENT_API_KUBECONFIG は、管理 API の kubeconfig のパスに置き換えます)。

    alias km="kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG"
    
  • グローバル API のエイリアスを作成します(GLOBAL_API_KUBECONFIG は、グローバル API の kubeconfig のパスに置き換えます)。

    alias kg="kubectl --kubeconfig GLOBAL_API_KUBECONFIG"
    

GDC Standard クラスタを作成する

このセクションでは、GDC 内に標準の Kubernetes クラスタをデプロイし、GDC 標準クラスタの管理者ロールとローカル Harbor コンテナ レジストリの認証情報を構成します。

1. 次のコマンドを実行して、使用可能な仮想マシン イメージタイプを特定します。

```shell
gdcloud compute machine-types list
```

2 クラスタ ワーカーノードに適したマシンタイプを選択します。

```shell
export MACHINE_TYPE="n3-standard-8-gdc"
```

3. ゾーン管理 API を使用して、2 つのワーカーノードを含む標準クラスタを作成します。

```shell
km create -f - <<EOF
apiVersion: cluster.gdc.goog/v1
kind: Cluster
metadata:
  name: ${GDC_CLUSTER_NAME}
  namespace: ${GDC_PROJECT_ID}
spec:
  nodePools:
  - machineTypeName: ${MACHINE_TYPE}
    nodeCount: 2
    name: ${GDC_CLUSTER_NAME}-node-pool
EOF
```

This creates a simple GDC cluster. Cluster creation
can take up to 60 minutes to complete. To check the status, use the
following command:

```shell
km get clusters/${GDC_CLUSTER_NAME} \
  -n ${GDC_PROJECT_ID} \
  --watch
```

After the cluster is ready, the output should show a STATE of `Running`.

4. クラスタの準備ができたら、認証情報を取得します。

```shell
KUBECONFIG=kubeconfig-${GDC_CLUSTER_NAME}.yaml gdcloud clusters \
  get-credentials ${GDC_CLUSTER_NAME} \
  --standard \
  --project ${GDC_PROJECT_ID} \
  --zone ${GDC_ZONE}
```

5. GDC ユーザーに GDC 標準クラスタ管理者ロールを割り当てます。

```shell
gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
  --member="user:${GDC_USER_NAME}" \
  --role=cluster-admin

gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
  --member="user:${GDC_USER_NAME}" \
  --role=standard-cluster-admin
```

6 GDC に Harbor インスタンスと Harbor プロジェクトを作成して、ミラーリングされたコンテナ イメージをホストします。

```shell
gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
  --member="user:${GDC_USER_NAME}" \
  --role=harbor-instance-admin
```

7 Harbor ロボット アカウントを作成し、そのユーザー名とシークレット キーを記録します。

8 Harbor インスタンスで認証します。

```shell
docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
  -u ${HARBOR_ROBOT_ACCOUNT} \
  -p ${HARBOR_ROBOT_SECRET}
```

This saves the robot account credentials to
`./docker-harbor/config.json` for subsequent Secret creation.

インフラストラクチャとネットワークの構成

このセクションでは、基盤となる GDC インフラストラクチャとネットワーク設定を構成します。これにより、Kubernetes ワークロードが外部 EJBCA ホスト ドメイン名を解決し、アウトバウンド API 呼び出しをその IP アドレスに正常に転送できます。

GDC エアギャップでのプライベート DNS の設定

ドメイン解決を確立するには、外部 EJBCA サーバーをローカル ドメイン名にマッピングする限定公開 DNS ゾーンとレコード セットをデプロイします。これにより、GDC 内のサービスは、未加工の IP アドレスではなく安定したホスト名を使用して接続できます。

  • ユーザーにマネージド DNS プロジェクト管理者のロールを割り当てます。

    gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
      --member=user:${GDC_USER_NAME} \
      --role=managed-dns-project-admin
    
  • グローバル ManagedDNSZone リソースをデプロイします。

    kubectl --kubeconfig GLOBAL_API_KUBECONFIG apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ManagedDNSZone
    metadata:
      name: private-example-internal
      namespace: ${GDC_PROJECT_ID}
    spec:
      dnsName: ${EJBCA_DNS_ZONE}
      visibility: PRIVATE
    EOF
    
  • EJBCA アプライアンスの IP アドレスを指す ResourceRecordSet をデプロイします。

    kubectl --kubeconfig GLOBAL_API_KUBECONFIG apply -f - <<EOF
    apiVersion: networking.global.gdc.goog/v1
    kind: ResourceRecordSet
    metadata:
      name: ${EJBCA_HOSTNAME}
      namespace: ${GDC_PROJECT_ID}
    spec:
      name: ${EJBCA_HOSTNAME}
      ttlSeconds: 600
      type: A
      rrData:
      - ${EJBCA_LB_IP}
      dnsZone: private-example-internal
    EOF
    

アウトバウンド NAT ゲートウェイの設定

次に、カスタム サブネットと NAT ゲートウェイを設定して GDC 下り(外向き)ネットワーキングを構成し、Kubernetes ワークロード(cert-manager や登録機関クライアントなど)がアウトバウンド トラフィックを EJBCA サーバーに安全にルーティングできるようにします。

  • プロジェクト レベルと組織レベルのネットワーク デベロッパー ロールを割り当てます。

    gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
      --member=user:${GDC_USER_NAME} \
      --role=cloud-nat-developer
    
    gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
      --member=user:${GDC_USER_NAME} \
      --role=subnet-project-admin
    
    gdcloud organizations add-iam-policy-binding ${GDC_ORG} \
      --member="user:${GDC_USER_NAME}" \
      --role=subnet-org-admin
    
  • 下り(外向き)サブネットを作成します。

    kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG apply -f - <<EOF
    apiVersion: ipam.gdc.goog/v1
    kind: Subnet
    metadata:
      name: ejbca-cluster-egress
      namespace: ${GDC_PROJECT_ID}
    spec:
      ipv4Request:
        prefixLength: 32
      parentReference:
        name: data-network-segment-${GDC_ZONE}-group
        namespace: platform
        type: SubnetGroup
      type: Leaf
    EOF
    
  • cert-manager 発行者セレクタに一致する CloudNATGateway を作成します。

    kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG apply -f - <<EOF
    apiVersion: networking.gdc.goog/v1
    kind: CloudNATGateway
    metadata:
      name: ejbca-egress-gateway
      namespace: ${GDC_PROJECT_ID}
    spec:
      subnetRefs:
      - ejbca-cluster-egress
      workloadSelector:
        labelSelector:
          clusters:
            matchLabels:
              kubernetes.io/metadata.name: ${GDC_CLUSTER_NAME}
          workloads:
            matchLabels:
              app.kubernetes.io/name: ejbca-cert-manager-issuer
    EOF
    

Kubernetes cert-manager の統合

このセクションでは、カスタム EJBCA cert-manager 発行元を GDC の cert-manager サービスと統合します。これにより、コンテナ化されたサービスの証明書の自動プロビジョニング、更新、ライフサイクル管理を確立できます。

EJBCA cert-manager 統合図。

カード発行会社向けに EJBCA を構成する

発行者を統合するには、必要なプロファイルを構成し、管理クライアント認証情報を登録して、EJBCA サーバー内でロール バインディングを設定します。これにより、cert-manager が EJBCA で認証を行い、証明書をリクエストできる安全な管理チャネルが確立されます。

管理者証明書プロファイルを作成する

まず、EJBCA 内に証明書プロファイルを作成して、管理者証明書の技術的プロパティと暗号制約(アルゴリズムや有効期間など)を定義します。

  • EJBCA 管理 UI を開き、[CA Functions] > [Certificate Profiles] に移動します。
  • ENDUSER プロファイルを複製し、GDC ADMIN PROFILE という名前を付けます。
  • GDC ADMIN PROFILE を編集して、次の設定を構成します。
    • 使用可能な鍵アルゴリズム: RSA
    • 利用可能なビット長: 2,048、3,072、4,096
    • Signature Algorithm: SHA512WithRSA
    • 有効性: 200d
    • Issuer Alternative Name: [Use] をオフにします。
    • CRL 配布ポイント: [使用] をオンにします。
    • CA 定義の CRL 配布ポイントを使用する: [使用する] をオンにします。
    • Authority Information Access: [Use] をオンにします。
    • CA 定義の OCSP ロケータを使用する: [使用する] をオンにします。
    • CA で定義された CA 発行元を使用する: [使用] をオンにします。
    • 利用可能な CA: GDC Subordinate CA を選択します。
  • [保存] をクリックします。

管理者エンド エンティティ プロファイルを作成する

次に、EJBCA でエンド エンティティ プロファイルを作成して、デフォルトのフィールドと CA の割り当てを定義します。これにより、管理証明書の登録と発行のプロセスが簡素化されます。

  • [RA Functions] > [End Entity Profiles] に移動します。
  • [Add End Entity Profile] で GDC ADMIN EE PROFILE を入力し、[Add Profile] をクリックします。
  • プロファイルを編集し、次の設定を構成します。
    • デフォルトの証明書プロファイル: GDC ADMIN PROFILE
    • 利用可能な証明書プロファイル: GDC ADMIN PROFILE
    • デフォルト CA: GDC Subordinate CA
    • 利用可能な CA: GDC Subordinate CA
  • [保存] をクリックします。

管理者証明書を登録する

プロファイルが確立されたら、EJBCA 登録機関(RA)インターフェースを使用して管理 ID を登録し、秘密鍵、公開証明書、信頼チェーンを抽出して、cert-manager の認証に必要な物理認証情報ファイルを生成します。

  • [RA Web](RA ウェブ)タブに移動します。
  • [Make New Request] をクリックして、次の項目を設定します。
    • 証明書のタイプ: GDC ADMIN EE PROFILE
    • 鍵ペアの生成: CA による
    • 鍵アルゴリズム: RSA 4,096 ビット
    • Common Name(CN): cert-manager
    • ユーザー名: cert-manager
    • 登録コード: abcd
  • [PEM をダウンロード] をクリックして、cert-manager.pem として保存します。
  • PEM ファイルを次の 3 つのファイルに分割します。

    • client.key(シークレット キー):

      openssl pkey -in cert-manager.pem -out client.key
      
    • client.crt(公開証明書):

      openssl x509 -in cert-manager.pem -out client.crt
      
    • ca.crt(下位 CA 証明書とルート CA 証明書を含む信頼チェーン):

      awk '/BEGIN CERTIFICATE/{i++} i>1' cert-manager.pem > ca.crt
      

ロールとアクセスルールを構成する

最後に、EJBCA で管理ロールを作成し、cert-manager 証明書のシリアル番号にバインドして、発行者が証明書の承認とリクエストに必要な最小限の権限のみを持つようにします。

  • EJBCA 管理 UI で、[RA Functions] > [Search End Entities] に移動します。
  • cert-manager エンド エンティティを検索し、その証明書のシリアル番号を記録します。
  • [System Functions] > [Roles and Access Rules] に移動し、[Add] をクリックします。
  • ロールに cert-manager という名前を付け、記録したシリアル番号を使用して新しいメンバーを追加します。
  • [アクセスルールの編集] をクリックして、次の権限を構成します。
    • ロール テンプレート: RA 管理者
    • 承認済み CA: GDC Subordinate CA
    • エンド エンティティのルール: エンド エンティティの承認、作成、編集
    • エンド エンティティ プロファイル: GDC TLS SERVER EE PROFILE
    • その他のルール: [監査ログを表示] をオフにします。
  • [保存] をクリックします。

GDC クラスタを準備する

GDC 環境を準備するには、標準の Kubernetes クラスタで認証を行い、抽出した EJBCA 管理認証情報を Kubernetes Secret に保存して、cert-manager 発行者 Pod から安全にアクセスできるようにします。

  • 標準クラスタの認証情報を取得します。

    gdcloud clusters get-credentials "${GDC_CLUSTER_NAME}" \
      --standard \
      --project "${GDC_PROJECT_ID}" \
      --zone "${GDC_ZONE}"
    
  • カスタム発行者のターゲット Namespace を作成します。

    kubectl create ns ejbca-issuer-system
    
  • TLS 認証シークレットをデプロイします。

    kubectl create secret tls ejbca-secret \
      -n ejbca-issuer-system \
      --cert=client.crt \
      --key=client.key
    
  • EJBCA 信頼チェーン シークレットをデプロイします。

    kubectl create secret generic ejbca-ca-secret \
      -n ejbca-issuer-system \
      --from-file=ca.crt
    

EJBCA 発行者をインストールする

デプロイを構成するには、EJBCA cert-manager 発行元コンテナ イメージを非公開の Harbor レジストリにミラーリングし、Helm チャートをデプロイします。これにより、Kubernetes 証明書リクエストを EJBCA API 呼び出しに変換するために必要なカスタム コントローラがインスタンス化されます。

  • 発行者の Namespace に Harbor イメージ pull Secret を作成します。

    # Authenticate with the private Harbor registry
    docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
      -u ${HARBOR_ROBOT_ACCOUNT} \
      -p ${HARBOR_ROBOT_SECRET}
    
    kubectl create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ejbca-issuer-system
    
  • 公式の EJBCA cert-manager 発行者イメージを Harbor にミラーリングします。

    docker pull keyfactor/ejbca-cert-manager-issuer:latest --platform linux/amd64
    
    docker tag keyfactor/ejbca-cert-manager-issuer:latest \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/ejbca-cert-manager-issuer:latest
    
    docker --config=./docker-harbor push \
      ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/ejbca-cert-manager-issuer:latest
    
  • Helm リポジトリを追加して、チャートをダウンロードします。

    helm repo add ejbca-issuer https://keyfactor.github.io/ejbca-cert-manager-issuer
    helm repo update
    helm pull ejbca-issuer/ejbca-cert-manager-issuer --untar
    
  • ミラーリングされたイメージ リポジトリを使用して Helm チャートをデプロイします。

    helm install ejbca-cert-manager-issuer ./ejbca-cert-manager-issuer \
      --namespace ejbca-issuer-system \
      --set image.repository=${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/ejbca-cert-manager-issuer \
      --set "imagePullSecrets[0].name=${HARBOR_PULL_SECRET_NAME}" \
      --set image.tag=latest
    

発行者リソースを作成する

次に、GDC RBAC 権限を確立し、グローバル ClusterIssuer リソースをデプロイします。これにより、EJBCA サーバーが Kubernetes cert-manager フレームワーク内の信頼できる署名元として登録されます。

  • GDC の cert-manager コントローラがカスタム EJBCA 発行者を使用できるように RBAC 権限を構成します。

    kubectl apply -f - <<EOF
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
    rules:
    - verbs:
      - approve
      apiGroups:
      - cert-manager.io
      resources:
      - signers
      resourceNames:
      - issuers.ejbca-issuer.keyfactor.com/*
      - clusterissuers.ejbca-issuer.keyfactor.com/*
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
    subjects:
    - kind: ServiceAccount
      name: cert-manager
      namespace: cert-manager
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cert-manager-controller-approve:issuers-ejbca-issuer-keyfactor-com
    EOF
    
  • グローバル ClusterIssuer リソースをデプロイします。

    kubectl apply -f - <<EOF
    apiVersion: ejbca-issuer.keyfactor.com/v1alpha1
    kind: ClusterIssuer
    metadata:
      name: clusterissuer-ejbca
    spec:
      hostname: "${EJBCA_HOSTNAME}"
      ejbcaSecretName: "ejbca-secret"
      caBundleSecretName: "ejbca-ca-secret"
      certificateAuthorityName: "${EJBCA_CA_NAME}"
      certificateProfileName: "${CERTIFICATE_PROFILE_NAME}"
      endEntityProfileName: "${END_ENTITY_PROFILE_NAME}"
      endEntityName: ""
    EOF
    
  • 発行者のステータスを確認します。

    kubectl get clusterissuer.ejbca-issuer.keyfactor.com/clusterissuer-ejbca \
      -o "custom-columns=NAME:.metadata.name,STATUS:.status.conditions[0].message"
    

    出力には次の内容が表示されます。

    NAME                  STATUS
    clusterissuer-ejbca   Success
    

証明書をリクエスト

統合を検証するには、標準の Kubernetes 証明書リソースをデプロイして、cert-manager のエンドツーエンドのフローをテストし、EJBCA がリクエストされた証明書に正常に署名してプロビジョニングすることを確認します。

統合が成功したことを確認するために、テスト Certificate リソースを作成します。

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: ejbca-test-certificate
  namespace: ${EJBCA_NAMESPACE}
spec:
  commonName: example.com
  secretName: ejbca-certificate
  issuerRef:
    name: clusterissuer-ejbca
    group: ejbca-issuer.keyfactor.com
    kind: ClusterIssuer
EOF

証明書が作成され、準備ができていることを確認します。

kubectl get certificates.cert-manager.io -n ${EJBCA_NAMESPACE}

出力には次の内容が表示されます。

NAME                     READY   SECRET              AGE
ejbca-test-certificate   True    ejbca-certificate   12s

DNS-01 チャレンジによる ACME の自動化

このセクションでは、EJBCA の ACME サービスを構成し、GDC 内部 DNS リソースを利用してドメイン検証済み証明書の発行を自動化します。これにより、標準の cert-manager または Certbot クライアントは、標準の自動 ACME プロトコルを使用して証明書をリクエストできます。

ACME 用に EJBCA を構成する

サーバーを準備するには、EJBCA 内で ACME サービスを有効にし、専用の DNS リゾルバを使用して ACME エイリアスを構成します。これにより、EJBCA サーバーは GDC 内で DNS-01 チャレンジ レスポンスを処理して検証する準備が整います。

  • EJBCA 管理 UI で、[System Configuration] > [ACME Configuration] に移動します。
  • [追加] をクリックして、次のように構成します。
    • 名前: default
    • エンド エンティティ プロファイル: GDC TLS SERVER EE PROFILE
    • ワイルドカード証明書の発行を許可: チェック
    • チャレンジ レスポンス MPIC 検証 DNS 識別子チャレンジ タイプ: dns-01 を選択します。
    • DNS リゾルバ: グローバル DNS の IP を入力します。
    • DNSSEC を検証する: クリア(ローカルのプライベート環境であるため)
  • [保存] をクリックします。

ACME 環境変数を作成する

このセクションでは、Certbot クライアントを構成するために次の環境変数を作成します。必要に応じて、次の値を変更します。

# ACME Alias created in the EJBCA configuration
export ACME_ALIAS="default"

# Arbitrary email address used for ACME registration
export ACME_EMAIL="your-email@example.com"

Certbot クライアントを登録する

次に、標準の Certbot クライアントをインストールし、EJBCA のプライベート ACME エンドポイントに登録します。これにより、証明書の自動オペレーションの実行に必要な信頼できるクライアント アカウントが確立されます。

  • ワークステーションに certbot をインストールします。たとえば、macOS の場合:

    brew install certbot
    
  • 構成とログ用のローカル フォルダを作成します。

    mkdir -p ./certbot/config ./certbot/work ./certbot/logs
    
  • クライアントを EJBCA ACME ディレクトリ エンドポイントに登録します。

    certbot register \
      --config-dir ./certbot/config \
      --work-dir ./certbot/work \
      --logs-dir ./certbot/logs \
      --server https://${EJBCA_HOSTNAME}/ejbca/acme/${ACME_ALIAS}/directory \
      --email ${ACME_EMAIL} \
      --agree-tos \
      --no-eff-email
    

DNS チャレンジを使用して証明書を発行する

最後に、手動の Certbot リクエストを実行し、一時的な GDC DNS TXT リソースをデプロイして DNS-01 チャレンジを解決します。これにより、ターゲット ドメインの所有権が検証され、証明書の自動発行がトリガーされます。

  • 手動チャレンジ コマンドを実行します。

    certbot certonly \
      --manual \
      --preferred-challenges dns \
      --key-type rsa \
      --rsa-key-size 2048 \
      --config-dir ./certbot/config \
      --work-dir ./certbot/work \
      --logs-dir ./certbot/logs \
      --server https://${EJBCA_HOSTNAME}/ejbca/acme/${ACME_ALIAS}/directory \
      -d test.${EJBCA_DNS_ZONE}
    

    ターミナルが停止し、チャレンジ値が表示されます。出力例:

    Please deploy a DNS TXT record under the name:
    
    _acme-challenge.test.example.internal.
    
    with the following value:
    
    q3pCmzXfIhsTpT4f4JAulHmHaAR3udC_9Wf1G498ER0
    
    Before continuing, verify the TXT record has been deployed.
    
  • Certbot から提供された文字列を使用して、TXT レコードをグローバル DNS にデプロイします。

  • DNS の伝播を約 30 秒待ってから、Certbot ターミナルに戻り、Enter キーを押します。

    出力例:

    Successfully received certificate.
    Certificate is saved at:./certbot/config/live/test.example.internal/fullchain.pem
    Key is saved at:./certbot/config/live/test.example.internal/privkey.pem
    This certificate expires on 2026-11-16.
    These files will be updated when the certificate renews.
    
  • 証明書が ./certbot/config/live/test.${EJBCA_DNS_ZONE}/ に正常に書き込まれたことを確認します。