Certificados SSL a través de DNS: automatización de la emisión de Let’s Encrypt
Publicado el 04.10.2025
Introducción
Let’s Encrypt — el estándar para obtener certificados TLS gratuitos. La mayoría de las veces los certificados se emiten mediante el método HTTP-01, que requiere un servidor web accesible en el puerto 80. Sin embargo, para servicios internos o certificados wildcard (por ejemplo, *.example.com) es más cómodo usar DNS-01, que valida la propiedad del dominio mediante registros TXT en DNS y no requiere puertos abiertos.
En el artículo se tratan:
- Emisión de certificados a través de la API de Cloudflare,
- Emisión de certificados a través de Amazon Route 53 (AWS),
- Integración con los servidores web Nginx, HAProxy y Traefik,
- Automatización de la renovación de certificados.
Nota: Las instrucciones son válidas para Certbot 2.x, acme.sh 3.x, Nginx 1.18+, HAProxy 2.4+, Traefik 2.x en Linux (Ubuntu/Debian). Para otros SO o versiones de las herramientas pueden ser necesarios ajustes.
Cloudflare
1. Creación del token API
- Inicie sesión en Cloudflare → API Tokens → Create Token.
- Use la plantilla Edit zone DNS con los permisos:
Zone.DNS:EditZone.Zone:Read
- Limite el token a una zona concreta.
- Guarde el token en un lugar seguro (secretos de CI/CD, variables de entorno).
⚠️ La fuga del token otorga control total sobre la zona DNS.
2. Instalación de Certbot y el plugin
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-dns-cloudflare
CentOS/Fedora:
sudo dnf install -y certbot python3-certbot-dns-cloudflare
A través de snap:
sudo snap install --classic certbot
sudo snap install certbot-dns-cloudflare
3. Configuración del token
Archivo /etc/letsencrypt/cloudflare.ini:
dns_cloudflare_api_token = YOUR_CF_API_TOKEN
Permisos:
sudo chown root:root /etc/letsencrypt/cloudflare.ini
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
4. Emisión del certificado
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d example.com -d '*.example.com' \
--non-interactive
AWS Route 53
1. Configuración de permisos IAM
Cree una política con permisos mínimos para una zona concreta:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:ListHostedZones",
"route53:ListResourceRecordSets"
],
"Resource": "arn:aws:route53:::hostedzone/<YOUR_HOSTED_ZONE_ID>"
}
]
}
Configure el perfil de AWS CLI:
aws configure --profile certbot
Proporcione AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY y la región (por ejemplo, us-east-1).
2. Instalación del plugin
Ubuntu/Debian:
sudo apt-get install -y certbot python3-certbot-dns-route53
CentOS/Fedora:
sudo dnf install -y certbot python3-certbot-dns-route53
3. Emisión del certificado
AWS_PROFILE=certbot \
sudo certbot certonly \
--dns-route53 \
-d example.com -d '*.example.com' \
--non-interactive
Nota: se pueden usar variables de entorno en lugar del perfil (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY).
Integración con servidores web
Nginx
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
Hook para recargar /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh:
#!/bin/sh
if nginx -t; then
systemctl reload nginx
else
echo "Nginx configuration test failed"
exit 1
fi
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
HAProxy
Concatenación del certificado y la clave:
cat /etc/letsencrypt/live/example.com/fullchain.pem \
/etc/letsencrypt/live/example.com/privkey.pem \
| tee /etc/haproxy/certs/example.com.pem >/dev/null
Fragmento de la configuración:
frontend https-in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
default_backend web-backend
Traefik
Archivo /etc/traefik/dynamic.yml:
tls:
certificates:
- certFile: /etc/letsencrypt/live/example.com/fullchain.pem
keyFile: /etc/letsencrypt/live/example.com/privkey.pem
traefik.yml:
providers:
file:
filename: /etc/traefik/dynamic.yml
Si Traefik se ejecuta en Docker:
-v /etc/letsencrypt:/etc/letsencrypt:ro
Automatización de la renovación
Certbot
Tarea cron:
sudo crontab -e
0 0,12 * * * certbot renew --quiet --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Registros de errores: /var/log/letsencrypt/letsencrypt.log.
acme.sh
Al instalar acme.sh, este añade su propia tarea cron. Verificación:
crontab -l | grep acme.sh
Alternativa: acme.sh
Instalación:
curl https://get.acme.sh | sh
Cloudflare:
export CF_Token="YOUR_CF_API_TOKEN"
~/.acme.sh/acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
AWS Route 53:
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_REGION="us-east-1"
~/.acme.sh/acme.sh --issue --dns dns_aws -d example.com -d '*.example.com'
Instalación del certificado:
~/.acme.sh/acme.sh --install-cert -d example.com \
--key-file /etc/ssl/example.com/privkey.pem \
--fullchain-file /etc/ssl/example.com/fullchain.pem \
--reloadcmd "systemctl reload nginx"
Certbot vs acme.sh
| Criterio | Certbot | acme.sh | |
|---|---|---|---|
| Lenguaje | Python | POSIX sh | |
| Instalación | Paquetes del SO o snap | Un script `curl | sh` |
| Soporte DNS | Plugins oficiales | ~40 proveedores incorporados | |
| Actualizaciones | A través del gestor de paquetes | Actualización automática integrada | |
| Hooks y despliegue | Hooks limitados | Convenientes --reloadcmd, --deploy | |
| Dependencias | Python, paquetes certbot-* | curl, socat, openssl | |
| Recursos | Más pesado (Python) | Más ligero, minimalista | |
| Popularidad | Estándar de facto, más documentación | Más conveniente para CI/CD |
Cuando elegir Certbot:
- si se necesita soporte oficial de Let’s Encrypt,
- si es cómodo instalar paquetes mediante
apt/yum, - si la prioridad es un ecosistema estándar.
Cuando elegir acme.sh:
- si se dispone de un entorno mínimo sin Python,
- si la emisión debe integrarse en un pipeline de CI/CD,
- si el proveedor DNS está soportado directamente en acme.sh.
Limitaciones y riesgos
- La fuga de un token API = control total sobre la zona DNS.
- Límites de Let’s Encrypt: hasta 50 certificados por semana por dominio.
- Propagación DNS: retrasos de segundos a minutos.
- Errores en la renovación: hooks incorrectos pueden llevar a la expiración.
Consejo: añada monitorización (Zabbix, Prometheus, Nagios) para controlar la validez de los certificados.
Conclusión
La validación DNS permite:
- automatizar la emisión y renovación de SSL,
- usar certificados wildcard,
- no depender de puertos abiertos.
Cloudflare y AWS Route 53 ofrecen APIs para automatizar por completo. La integración con Nginx, HAProxy y Traefik requiere solo unas pocas líneas de configuración. La renovación automática y la monitorización son pasos obligatorios para una explotación fiable.
Reseñas relacionadas
Gracias a Mijaíl por su disposición. Hablamos por teléfono; me explicó cómo hacerlo yo mismo. Es la segunda vez que recurro a él: todo genial y muy rápido.
kireevk · Consulta sobre nginx proxy manager y portainer
Comprador acostumbrado25.02.2025 · ⭐ 5/5
Gracias a Михаил por su amabilidad. Hablamos por teléfono, me explicó cómo hacerlo por mi cuenta. Es la segunda vez que recurro, todo genial y rápido.
Quiero expresar mi enorme agradecimiento al especialista que me configuró las URLs amigables en OpenCart. Fue fácil y sencillo, y me alegra haber encontrado finalmente a un profesional que lo hizo todo con calidad y sin complicaciones. Antes cambié a cuatro especialistas y cada vez surgían problemas con la configuración, pero esta persona resolvió la tarea a la perfección.
apande · Configuración de Nginx y OpenCart
Un comprador muy poderoso07.09.2024 · ⭐ 5/5
Quiero expresar mi enorme agradecimiento al especialista que me configuró las URLs amigables en OpenCart. Configurar las URLs amigables resultó fácil y sencillo, y me alegra haber finalmente encontrado a un profesional que lo hizo todo con calidad y sin complicaciones innecesarias. Antes de esto cambié a cuatro especialistas, y cada vez surgían problemas con la configuración, pero esta persona resolvió la tarea a la perfección.
Excelente trabajo, no es la primera vez que recurro; encuentra soluciones a problemas complejos. Lo recomiendo.
Evgeni8j · Nginx rate limit
Comprador profesional-experto10.05.2024 · ⭐ 5/5
Excelente trabajo, recurro no por primera vez, encuentra soluciones a problemas complejos. Recomiendo.
¡Excelente trabajo! Cumplió con la tarea a tiempo y sin errores. Fue un placer colaborar, lo recomiendo.
Evgeni8j · Configuración de Nginx
Comprador profesional-experto03.05.2024 · ⭐ 5/5
¡Excelente trabajo! Completó la tarea encomendada a tiempo y sin errores. Fue un placer colaborar, lo recomiendo.
Excelente especialista, se adentró en el problema, lo entendió y lo solucionó. Lo recomiendo.
Evgeni8j · Corrección de la expresión regular en location de nginx
Comprador profesional-experto21.03.2024 · ⭐ 5/5
Excelente especialista, se involucró en el problema, lo entendió y lo solucionó. Recomiendo.
Había que resolver un problema con el certificado SSL en el servidor, que había sido emitido mediante Ngnix Proxy manager. Mijaíl aclaró todos los detalles de cómo tengo todo configurado, pidió accesos para evaluar la viabilidad de la solución, ya que antes no se había enfrentado a un servicio similar. Se familiarizó rápidamente y resolvió mi problema. Colaboración perfecta)
kireevk · Diagnóstico de Nginx Proxy Manager en un contenedor Docker y solución del problema
Comprador acostumbrado15.03.2024 · ⭐ 5/5
Necesitaba resolver un problema con el certificado SSL en el servidor, que fue emitido a través de Ngnix Proxy manager. Mikhail aclaró todos los detalles sobre cómo tengo todo organizado, pidió accesos para evaluar la viabilidad de resolver la tarea, ya que antes no se había enfrentado a un servicio similar. Se ocupó rápidamente y resolvió mi problema. Cooperación perfecta)