TL;DR — Resumen Rápido
Certificados SSL wildcard con Certbot y DNS-01. Cubre plugins DNS, configuración de Cloudflare, renovación automática, límites de tasa y solución de problemas.
Los certificados SSL wildcard permiten que un único certificado proteja cada subdominio bajo tu dominio — *.example.com cubre api.example.com, app.example.com, staging.example.com y cualquier otro subdominio que crees. En lugar de emitir certificados individuales para cada servicio, obtienes uno solo y lo despliegas en toda tu infraestructura. Let’s Encrypt proporciona certificados wildcard de forma gratuita, pero requiere el desafío DNS-01 para la validación — un requisito que los desafíos basados en HTTP no pueden satisfacer.
Esta guía cubre todos los aspectos de la obtención y mantenimiento de certificados wildcard con Certbot: desde entender por qué DNS-01 es obligatorio, la validación manual, los plugins DNS automatizados, la configuración detallada de Cloudflare, la renovación automática con systemd, los SANs multi-dominio, los límites de tasa y la solución de problemas.
Requisitos Previos
Antes de comenzar, ten lo siguiente preparado:
- Ubuntu 22.04 LTS o 24.04 LTS (o cualquier Linux basado en Debian) con acceso sudo.
- Un dominio registrado con DNS gestionado por un proveedor compatible (Cloudflare, AWS Route 53, DigitalOcean, Google Cloud DNS, o acceso manual a tu zona).
- Certbot instalado — o lo instalarás a continuación.
- Un token API para tu proveedor DNS con permiso para crear y eliminar registros DNS.
- El puerto 80 NO necesita estar abierto para los desafíos DNS-01 wildcard (a diferencia de los desafíos HTTP-01).
¿Por Qué Certificados Wildcard?
Un certificado estándar cubre uno o más nombres de host específicos: example.com, www.example.com, api.example.com. Si añades un nuevo subdominio — metrics.example.com — debes o bien añadirlo a la lista SAN y reemitir el certificado, u obtener uno nuevo.
Un certificado wildcard (*.example.com) elimina este problema:
- Un certificado, subdominios ilimitados — Cualquier nombre de host que coincida con
*.example.comen un solo nivel queda cubierto automáticamente. - Gestión simplificada de certificados — Un proceso de renovación, una clave privada, un hook de despliegue.
- Funciona con servicios internos — Los subdominios sin servidores web públicos (APIs internas, interfaces de gestión) quedan cubiertos sin necesidad de acceso HTTP.
- Eficiencia de costes — Let’s Encrypt los emite gratis. Los certificados wildcard comerciales de CAs tradicionales cuestan típicamente $100–$300/año.
La única limitación: los wildcards cubren exactamente un nivel de subdominio. *.example.com cubre api.example.com pero no v1.api.example.com. Para subdominios anidados, añade un segundo wildcard: *.api.example.com.
Entendiendo ACME y el Desafío DNS-01
Let’s Encrypt usa el protocolo ACME (RFC 8555) para automatizar la emisión de certificados. Debes demostrar el control de tu dominio completando un desafío.
Por Qué HTTP-01 No Puede Validar Wildcards
El desafío HTTP-01 coloca un archivo token en http://example.com/.well-known/acme-challenge/<TOKEN>. Esto funciona para nombres de host específicos con un servidor web accesible. Pero *.example.com representa un conjunto infinito de nombres de host — la mayoría de los cuales pueden no tener ningún servidor HTTP. El servidor ACME no tiene forma de sondear cada subdominio posible, por lo que HTTP-01 está explícitamente prohibido para certificados wildcard por la especificación ACME.
Cómo Funciona DNS-01
DNS-01 valida el control del dominio probando que puedes escribir en la zona DNS:
- Certbot contacta al servidor ACME y solicita autorización para
*.example.com. - El servidor ACME emite un token e instruye a publicar un registro TXT en
_acme-challenge.example.comcon un valor específico derivado del token. - Certbot (o su plugin DNS) crea el registro TXT mediante la API de tu proveedor DNS.
- El servidor ACME consulta los resolutores DNS para verificar que el registro TXT existe.
- Una vez validado, el certificado es firmado y devuelto.
- Certbot (o su plugin) elimina el registro TXT.
DNS-01 funciona incluso cuando no existe ningún servidor web, cuando el puerto 80 está bloqueado por un cortafuegos y cuando el subdominio no tiene registro A.
Instalación de Certbot
El paquete snap es el método de instalación oficialmente mantenido y garantiza que siempre tengas la versión más reciente.
# Eliminar cualquier certbot empaquetado por el SO para evitar conflictos
sudo apt remove certbot -y 2>/dev/null || true
# Instalar Certbot mediante snap
sudo snap install --classic certbot
# Crear enlace simbólico para que certbot esté en el PATH
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# Verificar
certbot --version
Si tu distribución no soporta snaps, usa pip en un entorno virtual:
sudo apt install python3-pip python3-venv -y
python3 -m venv /opt/certbot
/opt/certbot/bin/pip install certbot
sudo ln -s /opt/certbot/bin/certbot /usr/local/bin/certbot
Validación DNS Manual
Para un certificado único o al hacer pruebas, la validación DNS manual no requiere tokens API. Creas el registro TXT tú mismo.
sudo certbot certonly \
--manual \
--preferred-challenges dns \
-d "*.example.com" \
-d example.com
Certbot mostrará algo como:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com
with the following value:
gfj9Xq8R3mT2nKp1vLwY5sAqZdBcF7eH
Once deployed, press Enter to continue...
Inicia sesión en tu proveedor DNS, añade el registro TXT, luego verifica la propagación antes de presionar Enter:
dig +short TXT _acme-challenge.example.com
# Debería devolver: "gfj9Xq8R3mT2nKp1vLwY5sAqZdBcF7eH"
# O consulta un resolutor público
dig @8.8.8.8 +short TXT _acme-challenge.example.com
Nota: La validación manual no admite la renovación automática. Certbot te pedirá que recreés el registro TXT manualmente cada 60–89 días. Para uso en producción, configura un plugin DNS automatizado.
Plugins DNS Automatizados
Los plugins DNS eliminan los pasos manuales llamando a la API de tu proveedor DNS para crear y eliminar el registro TXT _acme-challenge automáticamente durante la emisión inicial y cada renovación posterior.
| Plugin | Proveedor | Comando de instalación |
|---|---|---|
certbot-dns-cloudflare | Cloudflare | sudo snap install certbot-dns-cloudflare |
certbot-dns-route53 | AWS Route 53 | sudo snap install certbot-dns-route53 |
certbot-dns-google | Google Cloud DNS | sudo snap install certbot-dns-google |
certbot-dns-digitalocean | DigitalOcean | sudo snap install certbot-dns-digitalocean |
certbot-dns-linode | Linode/Akamai | sudo snap install certbot-dns-linode |
certbot-dns-hetzner | Hetzner DNS | pip install certbot-dns-hetzner |
Cada plugin sigue el mismo patrón: instalar el plugin, crear un archivo de credenciales con tu token API, establecer los permisos del archivo a 600 y ejecutar certbot certonly con la bandera --dns-<proveedor> del plugin.
Configuración Detallada del Plugin Cloudflare
Cloudflare es uno de los proveedores DNS más comunes y tiene excelente integración con Certbot. Aquí está el proceso completo.
Paso 1: Crear un Token API de Cloudflare
Inicia sesión en el panel de Cloudflare → Mi Perfil → Tokens API → Crear Token.
Usa la plantilla “Editar DNS de zona” y configura:
- Permisos:
Zona→DNS→Editar - Recursos de Zona:
Incluir→Zona específica→ selecciona tu dominio (oTodas las zonassi gestionas múltiples dominios) - Filtrado de dirección IP: Opcionalmente restringe a la IP de tu servidor para mayor seguridad
- TTL: Establece una fecha de expiración si deseas rotación forzada del token
Copia el valor del token — solo se muestra una vez.
Paso 2: Crear el Archivo de Credenciales
sudo mkdir -p /etc/letsencrypt/cloudflare
sudo tee /etc/letsencrypt/cloudflare/credentials.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = TU_TOKEN_API_DE_CLOUDFLARE_AQUI
EOF
# Restringir solo a lectura de root
sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
sudo chown root:root /etc/letsencrypt/cloudflare/credentials.ini
Nota de seguridad: Nunca uses el método heredado de
dns_cloudflare_email+dns_cloudflare_api_key(Clave API Global). El token API con alcance limitado reduce el riesgo si el archivo de credenciales queda expuesto.
Paso 3: Instalar el Plugin
sudo snap install certbot-dns-cloudflare
# Conectar el plugin snap al snap de certbot
sudo snap set certbot trust-plugin-with-root=ok
sudo snap connect certbot:plugin certbot-dns-cloudflare
Paso 4: Obtener el Certificado
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
--dns-cloudflare-propagation-seconds 60 \
-d example.com \
-d "*.example.com" \
--email admin@example.com \
--agree-tos \
--non-interactive
La bandera --dns-cloudflare-propagation-seconds 60 indica a Certbot que espere 60 segundos después de crear el registro TXT antes de pedir a Let’s Encrypt que lo valide.
Paso 5: Verificar el Certificado
sudo certbot certificates
Ubicaciones de los Archivos del Certificado
Tras la emisión, los archivos del certificado se almacenan en /etc/letsencrypt/. El directorio live/ contiene enlaces simbólicos a las versiones más recientes:
| Archivo | Ruta | Propósito |
|---|---|---|
| Cadena completa | /etc/letsencrypt/live/example.com/fullchain.pem | Certificado + CA intermedia (usar en Nginx/Apache) |
| Clave privada | /etc/letsencrypt/live/example.com/privkey.pem | Clave privada — proteger cuidadosamente |
| Solo cadena | /etc/letsencrypt/live/example.com/chain.pem | Solo cadena CA intermedia |
| Solo certificado | /etc/letsencrypt/live/example.com/cert.pem | Certificado del dominio sin cadena |
Configura Nginx para usar el certificado wildcard:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name *.example.com 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_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
Renovación Automática con systemd
Certbot instala automáticamente un temporizador systemd al instalarse mediante snap o apt. El temporizador se activa dos veces al día y solo solicita un nuevo certificado cuando el existente tiene 30 días o menos de validez restante.
Verificar el Temporizador
sudo systemctl status certbot.timer
sudo systemctl list-timers certbot.timer
Añadir un Hook de Despliegue para Nginx
# Hook de despliegue permanente
sudo bash -c 'cat >> /etc/letsencrypt/renewal/example.com.conf <<EOF
[renewalparams]
deploy_hook = systemctl reload nginx
EOF'
Probar la Renovación
sudo certbot renew --dry-run
Wildcards Multi-Dominio
Un único certificado puede incluir múltiples SANs wildcard:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
-d example.com \
-d "*.example.com" \
-d staging.example.net \
-d "*.staging.example.net"
Para subdominios anidados, añade wildcards explícitos:
-d "*.api.example.com" \
-d "*.internal.example.com"
*.example.com NO cubre *.api.example.com. Cada nivel requiere una entrada wildcard separada.
Límites de Tasa
Let’s Encrypt aplica límites de tasa para prevenir abusos:
| Límite | Valor | Ventana |
|---|---|---|
| Certificados por dominio registrado | 50 | 7 días |
| Certificados duplicados | 5 | 7 días |
| Validaciones fallidas | 5 | 1 hora |
| Nuevas órdenes | 300 | 3 horas |
El límite más frecuentemente alcanzado durante el desarrollo es el de 5 certificados duplicados por semana.
Pruebas con el Entorno de Staging
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
--staging \
-d example.com \
-d "*.example.com"
Una vez que tu configuración funcione correctamente, elimina el certificado de staging y obtén uno de producción:
sudo certbot delete --cert-name example.com
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
-d example.com \
-d "*.example.com"
Certbot vs Alternativas
| Herramienta | Wildcard | DNS Auto | Let’s Encrypt | Otras CAs | Notas |
|---|---|---|---|---|---|
| Certbot | Sí (plugins) | Por plugin | Sí | Limitado | Cliente oficial EFF, ecosistema más amplio |
| acme.sh | Sí | Integrado (150+) | Sí | Sí | Solo Bash, sin dependencias, muy portable |
| Caddy | Sí (nativo) | Automático | Sí | Sí | Sin configuración; módulo DNS debe compilarse |
| Traefik | Sí (nativo) | Automático | Sí | Limitado | Ideal para entornos de contenedores |
| CA Comercial | Sí | No (manual) | No | Sí | $100–$300/año, opciones OV/EV |
Solución de Problemas Comunes
Registro CAA Bloquea la Emisión
Síntoma: Error: CAA record for example.com prevents issuance
Verifica tus registros CAA:
dig +short CAA example.com
Si no existe una entrada para Let’s Encrypt, añádela:
example.com. CAA 0 issue "letsencrypt.org"
example.com. CAA 0 issuewild "letsencrypt.org"
La etiqueta issuewild es específicamente necesaria para la autorización de certificados wildcard.
Retrasos en la Propagación DNS
Síntoma: DNS problem: NXDOMAIN looking up TXT for _acme-challenge.example.com
Aumenta el tiempo de espera de propagación:
--dns-cloudflare-propagation-seconds 120
Verifica que el registro TXT sea visible desde un resolutor público antes de que Certbot valide:
dig @8.8.8.8 +short TXT _acme-challenge.example.com
dig @1.1.1.1 +short TXT _acme-challenge.example.com
Límite de Tasa Alcanzado
Síntoma: Error creating new order :: too many certificates already issued
Has emitido 5 certificados duplicados para el mismo conjunto de dominios en 7 días. Opciones: esperar a que expire la ventana de límite, añadir o quitar un dominio de la lista SAN, o usar --staging para más pruebas.
Error de Permisos en el Archivo de Credenciales
Síntoma: Unsafe permissions on credentials configuration file
sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
sudo chown root:root /etc/letsencrypt/cloudflare/credentials.ini
Resumen
Los certificados SSL wildcard de Let’s Encrypt te dan la flexibilidad de proteger subdominios ilimitados con un solo certificado de forma gratuita. Los puntos clave a recordar:
- Los wildcards requieren el desafío DNS-01 — HTTP-01 no puede validar
*.example.com. - La validación DNS manual funciona para emisión única pero no admite renovación automática.
- Los plugins DNS (certbot-dns-cloudflare, certbot-dns-route53, etc.) permiten la renovación totalmente automatizada.
- El token API de Cloudflare debe tener permiso
Zona:DNS:Editar; el archivo de credenciales debe serchmod 600. - Los archivos del certificado están en
/etc/letsencrypt/live/— siempre usafullchain.pemen tu servidor web. - Los hooks de despliegue recargan Nginx, HAProxy u otros servicios tras cada renovación.
- Los límites de tasa son estrictos — usa
--stagingpara pruebas y--dry-runpara validar la renovación. - Los registros CAA deben incluir
letsencrypt.orgconissuewildpara autorización wildcard.