Keyfactor EJBCA 参考实现

概览

本指南将逐步介绍如何将 Keyfactor EJBCA Enterprise(部署为外部设备)集成为 Google Distributed Cloud (GDC) 网闸隔离配置的第三方证书授权机构 (CA)。

Keyfactor EJBCA Enterprise 是一个高度可伸缩、强大且符合 FIPS 标准的证书授权机构平台,可让组织跨异构环境管理公钥基础架构 (PKI)。

GDC 网闸隔离配置包含内置证书授权机构服务,用于在托管云边界内自动管理密钥和证书。不过,如果组织已针对 GDC 之外的现有工作负载在 Keyfactor EJBCA 上将其 PKI 基础设施标准化,则可能更愿意为在其经过网闸隔离的 GDC 环境中运行的工作负载利用相同的一致 CA 架构和管理政策。

本指南演示了如何配置 GDC 网络、内部 DNS 和 Kubernetes cert-manager,以实现证书生命周期管理 (ACME) 自动化,并使用数字证书注册中心 (RA) 模式支持大批量程序化签发。

前提

在继续阅读本指南之前,请确保满足以下假设条件:

  • Keyfactor EJBCA 部署为软件设备或硬件设备,并为该服务配置了稳定的 IP 地址。
  • 已在 EJBCA 实例中创建根证书授权机构、从属证书授权机构和管理证书授权机构 (CA)。
  • 已配置终端实体 (EE) 配置文件(例如,针对 TLS 服务器证书)。
  • 已下载管理 CA 用户的证书。
  • 在 EJBCA 实例上启用了必需的协议(例如 ACME)。
  • 本指南中使用 RSA 签名算法。您可以根据具体要求或 EJBCA 实例中的配置更改签名算法。

架构

该架构遵循外部证书授权机构模型,其中 EJBCA 服务器及其支持的硬件安全模块 (HSM) 托管在物理 GDC 边界之外,但可通过网络访问。EJBCA 服务器可以作为硬件或软件设备部署在外部。本指南中介绍的核心集成仅要求可以使用稳定的 IP 地址访问外部 EJBCA 服务器。

Keyfactor EJBCA 架构图。

此架构的关键组件包括:

  • EJBCA Enterprise Server:作为 Keyfactor 硬件设备或软件设备部署在外部,用于托管 CA(根 CA 和从属 CA),并在通过 CC EAL4+ 认证的 HSM 中生成所有 CA 密钥材料。
  • GDC 标准 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 创建便捷的命令行别名:

  • 为可用区级 Management API 创建别名(将 MANAGEMENT_API_KUBECONFIG 替换为 Management API 的 kubeconfig 路径):

    alias km="kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG"
    
  • 为全局 API 创建别名(将 GLOBAL_API_KUBECONFIG 替换为全局 API 的 kubeconfig 路径):

    alias kg="kubectl --kubeconfig GLOBAL_API_KUBECONFIG"
    

创建 GDC 标准集群

在本部分中,您将在 GDC 中部署标准 Kubernetes 集群,并配置 GDC 标准集群管理员角色和本地 Harbor Container Registry 凭证:

1 通过运行以下命令来确定可用的虚拟机映像类型:

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

2 为集群工作器节点选择合适的机器类型:

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

3 使用可用区级管理 API 创建一个包含两个工作器节点的标准集群:

```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 设置

如需建立网域解析,您需要部署一个专用 DNS 区域和记录集,以将外部 EJBCA 服务器映射到本地域名,从而允许 GDC 内部的服务使用稳定的主机名(而非原始 IP 地址)进行连接:

  • 为您的用户分配 Managed DNS Project Admin 角色:

    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 网关设置

接下来,您需要配置 GDC 出站流量网络,方法是设置自定义子网和 NAT 网关,以允许 Kubernetes 工作负载(例如 cert-manager 和注册机构客户端)安全地将出站流量路由到 EJBCA 服务器:

  • 分配项目级和组织级 Network Developer 角色:

    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 管理界面,然后依次前往 CA Functions > Certificate Profiles。
  • 克隆 ENDUSER 配置文件,并将其命名为 GDC ADMIN PROFILE。
  • 修改 GDC ADMIN PROFILE 并配置以下设置:
    • 可用的密钥算法:RSA
    • 可用的位长度:2048、3072、4096
    • 签名算法:SHA512WithRSA
    • 有效期:200d
    • 颁发者备用名称:清除使用
    • CRL 分发点:勾选使用
    • 使用 CA 定义的 CRL 分发点:勾选使用
    • 授权信息访问:勾选使用
    • 使用 CA 定义的 OCSP 定位器:勾选使用
    • 使用 CA 定义的 CA 颁发者:勾选使用
    • Available CAs(可用 CA):选择 GDC Subordinate CA
  • 点击保存。

创建管理员最终实体配置文件

接下来,您需要在 EJBCA 中创建最终实体配置文件,以定义默认字段和 CA 分配,从而简化注册和颁发管理证书的过程:

  • 依次前往 RA Functions > End Entity Profiles。
  • 在添加最终实体配置文件下,输入 GDC ADMIN EE PROFILE,然后点击添加配置文件。
  • 修改配置文件并配置以下设置:
    • 默认证书配置文件:GDC ADMIN PROFILE
    • 可用的证书配置文件:GDC ADMIN PROFILE
    • 默认 CA:GDC Subordinate CA
    • 可用的 CA:GDC Subordinate CA
  • 点击保存。

注册管理员证书

建立配置文件后,您可以使用 EJBCA 注册机构 (RA) 界面注册管理身份,并提取私钥、公共证书和信任链,以生成对 cert-manager 进行身份验证所需的物理凭据文件:

  • 前往 RA Web 标签页。
  • 点击发出新请求并进行配置:
    • 证书类型:GDC ADMIN EE PROFILE
    • 密钥对生成:由 CA 生成
    • 密钥算法:RSA 4096 位
    • 通用名称 (CN):cert-manager
    • 用户名:cert-manager
    • 注册代码:abcd
  • 点击下载 PEM,并将其另存为 cert-manager.pem。
  • 将 PEM 文件拆分为三个文件:

    • 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 管理界面中,前往 RA Functions > Search End Entities。
  • 搜索 cert-manager 终端实体并记录其证书序列号。
  • 依次前往系统功能 > 角色和访问规则,然后点击添加。
  • 将该角色命名为 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}"
    
  • 为自定义颁发者创建目标命名空间:

    kubectl create ns ejbca-issuer-system
    
  • 部署 TLS 身份验证 Secret:

    kubectl create secret tls ejbca-secret \
      -n ejbca-issuer-system \
      --cert=client.crt \
      --key=client.key
    
  • 部署 EJBCA 信任链 Secret:

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

安装 EJBCA 颁发者

如需配置部署,您需要将 EJBCA cert-manager 颁发者容器映像镜像到您的私有 Harbor 注册表,并部署 Helm 图表。这会实例化将 Kubernetes 证书请求转换为 EJBCA API 调用所需的自定义控制器:

  • 在颁发者的命名空间中创建 Harbor 映像拉取 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 框架内的可信签名来源:

  • 配置 RBAC 权限,以允许 GDC 的 cert-manager 控制器使用自定义 EJBCA 颁发者:

    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 管理界面中,依次前往系统配置 > ACME 配置。
  • 点击添加并配置以下内容:
    • 名称:default
    • 结束实体配置文件:GDC TLS SERVER EE PROFILE
    • 允许颁发通配符证书:勾选
    • Challenge Response MPIC Validation DNS identifier challenge types(质询响应 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。

  • 等待大约 30 秒以完成 DNS 传播,返回 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}/。