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.com en 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:

  1. Certbot contacta al servidor ACME y solicita autorización para *.example.com.
  2. El servidor ACME emite un token e instruye a publicar un registro TXT en _acme-challenge.example.com con un valor específico derivado del token.
  3. Certbot (o su plugin DNS) crea el registro TXT mediante la API de tu proveedor DNS.
  4. El servidor ACME consulta los resolutores DNS para verificar que el registro TXT existe.
  5. Una vez validado, el certificado es firmado y devuelto.
  6. 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.

PluginProveedorComando de instalación
certbot-dns-cloudflareCloudflaresudo snap install certbot-dns-cloudflare
certbot-dns-route53AWS Route 53sudo snap install certbot-dns-route53
certbot-dns-googleGoogle Cloud DNSsudo snap install certbot-dns-google
certbot-dns-digitaloceanDigitalOceansudo snap install certbot-dns-digitalocean
certbot-dns-linodeLinode/Akamaisudo snap install certbot-dns-linode
certbot-dns-hetznerHetzner DNSpip 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 PerfilTokens APICrear Token.

Usa la plantilla “Editar DNS de zona” y configura:

  • Permisos: ZonaDNSEditar
  • Recursos de Zona: IncluirZona específica → selecciona tu dominio (o Todas las zonas si 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:

ArchivoRutaPropósito
Cadena completa/etc/letsencrypt/live/example.com/fullchain.pemCertificado + CA intermedia (usar en Nginx/Apache)
Clave privada/etc/letsencrypt/live/example.com/privkey.pemClave privada — proteger cuidadosamente
Solo cadena/etc/letsencrypt/live/example.com/chain.pemSolo cadena CA intermedia
Solo certificado/etc/letsencrypt/live/example.com/cert.pemCertificado 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ímiteValorVentana
Certificados por dominio registrado507 días
Certificados duplicados57 días
Validaciones fallidas51 hora
Nuevas órdenes3003 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

HerramientaWildcardDNS AutoLet’s EncryptOtras CAsNotas
CertbotSí (plugins)Por pluginLimitadoCliente oficial EFF, ecosistema más amplio
acme.shIntegrado (150+)Solo Bash, sin dependencias, muy portable
CaddySí (nativo)AutomáticoSin configuración; módulo DNS debe compilarse
TraefikSí (nativo)AutomáticoLimitadoIdeal para entornos de contenedores
CA ComercialNo (manual)No$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 ser chmod 600.
  • Los archivos del certificado están en /etc/letsencrypt/live/ — siempre usa fullchain.pem en 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 --staging para pruebas y --dry-run para validar la renovación.
  • Los registros CAA deben incluir letsencrypt.org con issuewild para autorización wildcard.

Artículos Relacionados