Saltar al contenido principal

Integración con ACME / Let's Encrypt

Descripción general

El protocolo ACME (utilizado por Let's Encrypt y otras autoridades de certificación) admite el desafío DNS-01 para la validación de dominios. DNS-01 es el único tipo de desafío que admite certificados wildcard (*.example.com), y no requiere un servidor HTTP en la máquina de destino.

NexDNS ofrece integraciones nativas con los clientes ACME más populares, además de un hook de CLI genérico para cualquier cliente que admita hooks DNS manuales.

Todas las integraciones ACME requieren un token API, disponible en los planes Pro y superiores. Cada cliente busca la zona antes de escribir el desafío, así que el token necesita zones.read además de records.read y records.write. Crea uno en nexdns.tech/settings/api-keys.

Cómo se valida un wildcard

El desafío es un registro TXT en _acme-challenge bajo el nombre que se está validando. Un certificado que cubre tanto example.com como *.example.com produce dos valores de desafío distintos en el mismo nombre, y ambos tienen que estar presentes a la vez – todas las integraciones de abajo lo gestionan, y por eso nunca debes eliminar el conjunto de registros entre las dos validaciones.

Deja margen para la propagación

Un registro de desafío tarda unos 30 segundos en llegar a los servidores de nombres, así que esperar 30 segundos no deja ningún margen: hemos visto fallar una validación con NXDOMAIN. Concede a la autoridad de certificación al menos 60 segundos: el plugin de certbot y lego esperan 60 por defecto, y en acme.sh y el hook de CLI la espera la defines tú.

acme.sh

acme.sh es un cliente ACME escrito íntegramente en shell. Nuestro hook de DNS todavía no forma parte de una versión de acme.sh, así que colócalo en ~/.acme.sh/dnsapi/ antes de la primera ejecución: curl -fsSL https://get.nexdns.tech/acme/dns_nexdns.sh -o ~/.acme.sh/dnsapi/dns_nexdns.sh. El mismo archivo está en el repositorio de la CLI por si prefieres leerlo antes.

Emitir un certificado

export NEXDNS_Token="nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
acme.sh --issue --server letsencrypt --dns dns_nexdns \
    --dnssleep 60 \
    -d example.com -d '*.example.com'

El token se guarda en ~/.acme.sh/account.conf después de la primera ejecución, por lo que no necesitas exportarlo nuevamente para las renovaciones.

Renovar

Las renovaciones se realizan automáticamente mediante cron. Para forzar una renovación manual:

acme.sh --renew -d example.com

lego y Traefik

lego es un cliente ACME basado en Go que también está detrás de la gestión automática de certificados de Traefik. El proveedor se incluye en lego a partir de la versión 5.4.0.

Uso independiente

NEXDNS_API_TOKEN=nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
NEXDNS_PROPAGATION_TIMEOUT=300 \
lego --dns nexdns \
    --domains example.com \
    --domains '*.example.com' \
    --email admin@example.com \
    --accept-tos \
    run

lego lee sus tiempos de espera como un número simple de segundos: NEXDNS_PROPAGATION_TIMEOUT=300 funciona, mientras que 300s no se puede interpretar y se sustituye en silencio por el valor por defecto de 60 segundos.

Configuración de Traefik

Traefik incorpora la tabla de proveedores de lego al compilar y todavía usa una versión anterior, así que aquí hace falta una compilación de Traefik con lego 5.4.0. Añade el resolutor de desafío DNS de NexDNS a tu configuración de Traefik: el siguiente docker-compose.yml muestra una instalación típica:

services:
  traefik:
    image: traefik:v3  # lego >= v5.4.0
    command:
      - "--certificatesresolvers.nexdns.acme.dnschallenge=true"
      - "--certificatesresolvers.nexdns.acme.dnschallenge.provider=nexdns"
      - "--certificatesresolvers.nexdns.acme.email=admin@example.com"
      - "--certificatesresolvers.nexdns.acme.storage=/letsencrypt/acme.json"
    environment:
      NEXDNS_API_TOKEN: "nxd_xxxxxxxxxxxxxxxxxxxx"
    volumes:
      - letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - "443:443"

volumes:
  letsencrypt:

Luego usa el resolver en las etiquetas de tu servicio:

labels:
  - "traefik.http.routers.myapp.tls.certresolver=nexdns"
  - "traefik.http.routers.myapp.tls.domains[0].main=example.com"
  - "traefik.http.routers.myapp.tls.domains[0].sans=*.example.com"

cliente certbot

certbot es el cliente oficial de Let's Encrypt. Usa el plugin de autenticación DNS de NexDNS para la validación DNS-01 automatizada.

Instalar el plugin

Instala el plugin desde PyPI o usa la imagen de Docker de abajo, que ya lo incluye.

pip install certbot-dns-nexdns

Crear archivo de credenciales

Crea el archivo ~/.nexdns/certbot-credentials.ini con tu token API:

dns_nexdns_token = nxd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Restringe los permisos del archivo:

chmod 600 ~/.nexdns/certbot-credentials.ini

Emitir un certificado

certbot certonly \
    --authenticator dns-nexdns \
    --dns-nexdns-credentials ~/.nexdns/certbot-credentials.ini \
    -d example.com \
    -d '*.example.com'

Uso con Docker

docker run --rm \
    -v /etc/letsencrypt:/etc/letsencrypt \
    -v ~/.nexdns/certbot-credentials.ini:/credentials.ini:ro \
    nexdns/certbot certonly \
        --non-interactive --agree-tos --email admin@example.com \
        --authenticator dns-nexdns \
        --dns-nexdns-credentials /credentials.ini \
        -d example.com \
        -d '*.example.com'

Hook de CLI

Si tu cliente ACME admite hooks DNS manuales, puedes usar el CLI de NexDNS como script de hook. Esto funciona con cualquier cliente que proporcione las opciones --manual-auth-hook y --manual-cleanup-hook (p. ej., certbot en modo manual).

certbot con hook de CLI

certbot certonly --manual --preferred-challenges dns \
    --manual-auth-hook "nexdns acme hook --action create && sleep 60" \
    --manual-cleanup-hook "nexdns acme hook --action delete" \
    -d example.com \
    -d '*.example.com'

El hook lee las variables de entorno CERTBOT_DOMAIN y CERTBOT_VALIDATION establecidas por certbot y crea o elimina el registro TXT _acme-challenge automáticamente.

El CLI debe estar autenticado antes de usar hooks. Ejecuta nexdns auth token nxd_xxx o establece la variable de entorno NEXDNS_TOKEN.

Utilizamos cookies para garantizar el correcto funcionamiento de este sitio web y mejorar su experiencia. Algunas cookies son estrictamente necesarias para el funcionamiento del sitio, mientras que otras son opcionales.

Puede aceptar todas las cookies o limitar su elección a las estrictamente necesarias. Para más información, consulte nuestra Política de privacidad y nuestra Política de cookies.