Implementación de referencia de Keyfactor EJBCA

Descripción general

En esta guía, se explica la integración de Keyfactor EJBCA Enterprise (implementado como un dispositivo externo) como una entidad de certificación (CA) externa para Google Distributed Cloud (GDC) aislado.

Keyfactor EJBCA Enterprise es una plataforma de entidad certificadora altamente escalable, sólida y que cumple con FIPS, que permite a las organizaciones administrar la infraestructura de clave pública (PKI) en entornos heterogéneos.

GDC aislado incluye un servicio de autoridad certificadora integrado para la administración automatizada de claves y certificados dentro del límite de la nube alojada. Sin embargo, las organizaciones que estandarizaron su infraestructura de PKI en Keyfactor EJBCA para las cargas de trabajo existentes fuera de GDC podrían preferir aprovechar la misma arquitectura de AC y políticas de administración coherentes para las cargas de trabajo que se ejecutan en sus entornos de GDC aislados.

En esta guía, se muestra cómo configurar las redes de GDC, el DNS interno y cert-manager de Kubernetes para automatizar la administración del ciclo de vida de los certificados (ACME) y admitir la emisión programática de gran volumen con un patrón de autoridad de registro (RA).

Suposiciones

Antes de continuar con esta guía, asegúrate de que se cumplan las siguientes suposiciones:

  • Keyfactor EJBCA se implementa como un dispositivo de software o hardware, y se configura una dirección IP estable para el servicio.
  • Se crearon autoridades certificadoras (AC) raíz, subordinadas y de administración en la instancia de EJBCA.
  • Se configuraron perfiles de entidad final (EE) (p.ej., para certificados de servidor TLS).
  • Se descargaron los certificados para los usuarios de la AC administrativa.
  • Los protocolos obligatorios (como ACME) están habilitados en la instancia de EJBCA.
  • En esta guía, se usan algoritmos de firma RSA. Puedes cambiar el algoritmo de firma según tus requisitos específicos o lo que esté configurado en tu instancia de EJBCA.

Arquitectura

La arquitectura sigue el modelo de autoridad de certificación externa, en el que el servidor de EJBCA y su módulo de seguridad de hardware (HSM) de respaldo se alojan de forma externa fuera de los límites físicos del GDC, pero son accesibles a través de la red. El servidor de EJBCA se puede implementar de forma externa como un dispositivo de hardware o software. La integración principal que se describe en esta guía solo requiere que se pueda acceder al servidor externo de EJBCA con una dirección IP estable.

Diagrama de arquitectura de Keyfactor EJBCA.

Los componentes clave de esta arquitectura incluyen los siguientes:

  • EJBCA Enterprise Server: Se implementa de forma externa como un dispositivo de hardware o software de Keyfactor, que alberga las AC (raíz y subordinada) y genera todo el material de claves de la AC dentro de un HSM certificado por CC EAL4+.
  • Clúster de Kubernetes estándar de GDC: Es el entorno de procesamiento que ejecuta las cargas de trabajo del cliente, cert-manager y los proxies de integración.
  • DNS interno de GDC: Administra las zonas de DNS privadas locales (con el nombre de dominio privado configurado en las variables de entorno) que se usan para resolver los desafíos DNS-01 de ACME.
  • Puerta de enlace de salida de GDC: Dirige el tráfico saliente de los Pods del clúster a la dirección IP externa del servidor de EJBCA.
  • Registro privado de Harbor: Aloja imágenes de contenedor duplicadas (como el emisor de cert-manager de EJBCA) para la implementación aislada.

Antes de comenzar

Antes de comenzar la integración, asegúrate de que tu entorno de GDC cumpla con los siguientes requisitos:

  • Primero, crea un proyecto que servirá como contenedor de todos los recursos generados a lo largo de esta guía.
  • Configura las variables de entorno a las que se hará referencia a lo largo de esta guía. Modifica estos valores según sea necesario para que coincidan con tu entorno específico:

    # 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"
    
  • Nota de red: En esta guía, se supone que se ejecuta desde un nodo bastión que tiene acceso a las APIs aisladas de GDC y también a Internet para descargar los manifiestos y las imágenes de contenedores necesarios. Si ejecutas este comando desde una máquina sin acceso a Internet, debes obtener estos recursos por separado (por ejemplo, usando docker save para exportar imágenes desde una máquina conectada y docker load para importarlas) y subirlos de forma segura a tu entorno antes de continuar.

Configura alias de kubectl

En esta sección, crearás alias convenientes de la línea de comandos para las APIs globales y de administración zonal de GDC:

  • Crea un alias para la API de administración zonal (reemplaza MANAGEMENT_API_KUBECONFIG por la ruta de acceso a kubeconfig para la API de administración):

    alias km="kubectl --kubeconfig MANAGEMENT_API_KUBECONFIG"
    
  • Crea un alias para la API global (reemplaza GLOBAL_API_KUBECONFIG por la ruta de acceso a kubeconfig para la API global):

    alias kg="kubectl --kubeconfig GLOBAL_API_KUBECONFIG"
    

Crea el clúster estándar de GDC

En esta sección, implementarás un clúster de Kubernetes estándar dentro de GDC y configurarás los roles de administrador del clúster estándar de GDC y las credenciales locales del registro de contenedores de Harbor:

1 Para identificar los tipos de imágenes de máquina virtual disponibles, ejecuta el siguiente comando:

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

2 Selecciona un tipo de máquina adecuado para los nodos de trabajador de tu clúster:

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

3 Crea un clúster estándar con dos nodos de trabajador usando la API de administración zonal:

```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 Una vez que el clúster esté listo, recupera sus credenciales:

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

5 Asigna roles de administrador de clúster estándar de GDC a tu usuario de 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 Crea una instancia y un proyecto de Harbor en GDC para alojar las imágenes de contenedor duplicadas:

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

7 Crea una cuenta de robot de Harbor y registra su nombre de usuario y clave secreta.

8 Autentícate con tu instancia de 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.

Configuración de la infraestructura y la red

En esta sección, configurarás la infraestructura y la configuración de red subyacentes de GDC. Esto garantiza que tus cargas de trabajo de Kubernetes puedan resolver el nombre de dominio externo del host de EJBCA y enrutar correctamente las llamadas a la API salientes a su dirección IP.

Configuración del DNS privado en GDC aislado

Para establecer la resolución de dominio, implementa una zona de DNS privada y un conjunto de registros para asignar el servidor externo de EJBCA a un nombre de dominio local, lo que permite que los servicios dentro de GDC se conecten con un nombre de host estable en lugar de una dirección IP sin procesar:

  • Asigna el rol de administrador del proyecto de DNS administrado a tu usuario:

    gdcloud projects add-iam-policy-binding ${GDC_PROJECT_ID} \
      --member=user:${GDC_USER_NAME} \
      --role=managed-dns-project-admin
    
  • Implementa el recurso ManagedDNSZone global:

    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
    
  • Implementa el ResourceRecordSet que apunta a la dirección IP de tu dispositivo EJBCA:

    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
    

Configuración de la puerta de enlace NAT saliente

A continuación, configura las redes de salida de GDC configurando una subred personalizada y una puerta de enlace de NAT para permitir que las cargas de trabajo de Kubernetes (como cert-manager y los clientes de la autoridad de registro) enruten de forma segura el tráfico saliente al servidor de EJBCA:

  • Asigna roles de desarrollador de redes a nivel de la organización y del proyecto:

    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
    
  • Crea la subred de salida:

    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
    
  • Crea el CloudNATGateway que coincida con el selector de la entidad emisora de cert-manager:

    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
    

Integración de cert-manager de Kubernetes

En esta sección, integrarás la entidad emisora personalizada de cert-manager de EJBCA con el servicio de cert-manager de GDC. Esto te permite establecer el aprovisionamiento, la renovación y la administración del ciclo de vida de certificados automatizados para tus servicios en contenedores.

Diagrama de integración de EJBCA cert-manager.

Configura EJBCA para la entidad emisora

Para integrar la entidad emisora, debes configurar los perfiles necesarios, inscribir la credencial del cliente de administración y configurar las vinculaciones de roles dentro del servidor de EJBCA. Esto establece un canal administrativo seguro que permite que cert-manager se autentique con EJBCA y solicite certificados de esta.

Crea un perfil de certificado de administrador

Para comenzar, establece un perfil de certificado dentro de EJBCA para definir las propiedades técnicas y las restricciones criptográficas (como algoritmos y períodos de validez) del certificado administrativo:

  • Abre la IU de administración de EJBCA y navega a CA Functions > Certificate Profiles.
  • Clona el perfil ENDUSER y asígnale el nombre GDC ADMIN PROFILE.
  • Edita GDC ADMIN PROFILE y establece los siguientes parámetros de configuración:
    • Algoritmos de clave disponibles: RSA
    • Longitudes de bits disponibles: 2048, 3072, 4096
    • Algoritmo de firma: SHA512WithRSA
    • Validez: 200d
    • Nombre alternativo de la entidad emisora: Borrar Usar
    • Puntos de distribución de CRL: Marca la casilla de verificación Usar.
    • Usar el punto de distribución de CRL definido por la CA: Marca Usar.
    • Authority Information Access: Marca Use.
    • Usar el localizador de OCSP definido por la CA: Marca Usar.
    • Use CA defined CA issuer: Marca Use.
    • CAs disponibles: Selecciona GDC Subordinate CA.
  • Haz clic en Guardar.

Crea un perfil de entidad final de administrador

A continuación, crearás un perfil de entidad final en EJBCA para definir los campos predeterminados y las asignaciones de AC, lo que simplifica el proceso de inscripción y emisión del certificado administrativo:

  • Navega a RA Functions > End Entity Profiles.
  • En Add End Entity Profile, ingresa GDC ADMIN EE PROFILE y haz clic en Add Profile.
  • Edita el perfil y establece los siguientes parámetros de configuración:
    • Perfil de certificado predeterminado: GDC ADMIN PROFILE
    • Perfiles de certificados disponibles: GDC ADMIN PROFILE
    • CA predeterminada: GDC Subordinate CA
    • CA disponibles: GDC Subordinate CA
  • Haz clic en Guardar.

Inscribe el certificado de administrador

Con los perfiles establecidos, inscribe la identidad administrativa con la interfaz de la autoridad de registro (RA) de EJBCA y extrae la clave privada, el certificado público y la cadena de confianza para generar los archivos de credenciales físicas necesarios para autenticar cert-manager:

  • Navega a la pestaña RA Web.
  • Haz clic en Make New Request y configura lo siguiente:
    • Tipo de certificado: GDC ADMIN EE PROFILE
    • Generación de pares de claves: Por parte de la CA
    • Algoritmo de clave: RSA de 4,096 bits
    • Nombre común (CN): cert-manager
    • Nombre de usuario: cert-manager
    • Código de inscripción: abcd
  • Haz clic en Descargar PEM y guárdalo como cert-manager.pem.
  • Divide los archivos PEM en tres archivos:

    • client.key (la clave secreta):

      openssl pkey -in cert-manager.pem -out client.key
      
    • client.crt (el certificado público):

      openssl x509 -in cert-manager.pem -out client.crt
      
    • ca.crt (la cadena de confianza con los certificados de la CA subordinada y raíz):

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

Configura roles y reglas de acceso

Por último, crea un rol administrativo en EJBCA y lo vincula al número de serie del certificado de cert-manager para garantizar que la entidad emisora solo tenga el conjunto mínimo de permisos necesarios para aprobar y solicitar certificados:

  • En la IU de administración de EJBCA, navega a RA Functions > Search End Entities.
  • Busca la entidad final cert-manager y registra su número de serie del certificado.
  • Navega a Funciones del sistema > Roles y reglas de acceso y haz clic en Agregar.
  • Asigna el nombre cert-manager al rol y agrega un miembro nuevo con el número de serie que registraste.
  • Haz clic en Editar reglas de acceso y configura los siguientes privilegios:
    • Plantilla de rol: Administradores de RA
    • CA autorizadas: GDC Subordinate CA
    • Reglas de entidades finales: Aprobar, crear y editar entidades finales
    • Perfiles de entidades finales: GDC TLS SERVER EE PROFILE
    • Otras reglas: Borrar Ver registro de auditoría
  • Haz clic en Guardar.

Prepara el clúster de GDC

Para preparar el entorno de GDC, te autenticas con tu clúster estándar de Kubernetes y almacenas las credenciales administrativas de EJBCA extraídas dentro de los Secrets de Kubernetes, lo que hace que sean accesibles de forma segura para los Pods del emisor de cert-manager:

  • Recupera las credenciales del clúster estándar:

    gdcloud clusters get-credentials "${GDC_CLUSTER_NAME}" \
      --standard \
      --project "${GDC_PROJECT_ID}" \
      --zone "${GDC_ZONE}"
    
  • Crea el espacio de nombres de destino para la entidad emisora personalizada:

    kubectl create ns ejbca-issuer-system
    
  • Implementa el secreto de autenticación de TLS:

    kubectl create secret tls ejbca-secret \
      -n ejbca-issuer-system \
      --cert=client.crt \
      --key=client.key
    
  • Implementa el secreto de la cadena de confianza de EJBCA:

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

Instala la entidad emisora de EJBCA

Para configurar la implementación, duplicas la imagen del contenedor del emisor de cert-manager de EJBCA en tu registro privado de Harbor y, luego, implementas el gráfico de Helm. Esto crea una instancia del controlador personalizado necesario para traducir las solicitudes de certificados de Kubernetes en llamadas a la API de EJBCA:

  • Crea un Secret de extracción de imágenes de Harbor en el espacio de nombres del emisor:

    # 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
    
  • Duplica la imagen oficial del emisor de cert-manager de EJBCA en 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
    
  • Agrega el repositorio de Helm y descarga el gráfico:

    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
    
  • Implementa el gráfico de Helm con el repositorio de imágenes duplicado:

    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
    

Crea el recurso de la entidad emisora

A continuación, establecerás permisos de RBAC de GDC y, luego, implementarás un recurso ClusterIssuer global, que registrará el servidor de EJBCA como una fuente de firma de confianza dentro del framework de cert-manager de Kubernetes:

  • Configura los permisos de RBAC para permitir que el controlador cert-manager de GDC use la entidad emisora de EJBCA personalizada:

    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
    
  • Implementa el recurso ClusterIssuer global:

    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
    
  • Verifica el estado del emisor:

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

    El resultado debería mostrar lo siguiente:

    NAME                  STATUS
    clusterissuer-ejbca   Success
    

Solicitar un certificado

Para verificar la integración, implementa un recurso de certificado de Kubernetes estándar para probar el flujo de cert-manager de extremo a extremo y confirmar que EJBCA firma y aprovisiona correctamente el certificado solicitado:

Crea un recurso Certificate de prueba para verificar que la integración se haya realizado correctamente:

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

Verifica que el certificado se haya creado y esté listo:

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

El resultado debería mostrar lo siguiente:

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

ACME automatizado con desafíos DNS-01

En esta sección, configurarás el servicio ACME de EJBCA y utilizarás los recursos de DNS internos de GDC para automatizar la emisión de certificados validados por dominio. Esto permite que los clientes estándar de cert-manager o Certbot soliciten certificados con protocolos ACME automatizados estándar.

Configura EJBCA para ACME

Para preparar el servidor, habilita el servicio ACME dentro de EJBCA y configura un alias de ACME con un solucionador de DNS dedicado. Esto prepara el servidor de EJBCA para procesar y validar las respuestas de desafío DNS-01 dentro de GDC:

  • En la IU de administración de EJBCA, navega a System Configuration > ACME Configuration.
  • Haz clic en Agregar y configura lo siguiente:
    • Nombre: default
    • Perfil de la entidad final: GDC TLS SERVER EE PROFILE
    • Wildcard Certificate Issuance Allowed: Marcado
    • Tipos de desafío de identificador de DNS de validación de MPIC de respuesta a desafío: Selecciona dns-01.
    • Agente de resolución de DNS: Ingresa la IP de tu DNS global.
    • Validar DNSSEC: Borrar (ya que se trata de un entorno privado local)
  • Haz clic en Guardar.

Crea variables de entorno de ACME

En esta sección, crearás las siguientes variables de entorno para configurar tu cliente de Certbot. Modifica estos valores según sea necesario:

# 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"

Registra el cliente de Certbot

A continuación, instala el cliente estándar de Certbot y regístralo con el extremo privado de ACME de EJBCA. Esto establece la cuenta de cliente de confianza necesaria para realizar operaciones de certificados automatizadas:

  • Instala certbot en tu estación de trabajo. Por ejemplo, para macOS:

    brew install certbot
    
  • Crea carpetas locales para la configuración y los registros:

    mkdir -p ./certbot/config ./certbot/work ./certbot/logs
    
  • Registra el cliente con el extremo del directorio de ACME de EJBCA:

    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
    

Emite un certificado con el desafío de DNS

Por último, ejecutarás una solicitud manual de Certbot y, luego, implementarás un recurso TXT de DNS de GDC temporal para resolver el desafío DNS-01. Esto valida tu propiedad del dominio de destino y activa la emisión automática del certificado:

  • Ejecuta el comando de desafío manual:

    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}
    

    La terminal se detendrá y mostrará un valor de desafío. Resultado de ejemplo:

    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.
    
  • Implementa el registro TXT en tu DNS global con la cadena proporcionada por Certbot.

  • Espera aproximadamente 30 segundos para que se propague el DNS, vuelve a la terminal de Certbot y presiona Intro.

    Resultado de ejemplo:

    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.
    
  • Verifica que el certificado se haya escrito correctamente en ./certbot/config/live/test.${EJBCA_DNS_ZONE}/.