Gestionar certificados SSL individuales para cada subdominio se vuelve tedioso rápidamente. Un certificado SSL wildcard de Let’s Encrypt cubre todos los subdominios bajo un solo dominio — *.example.com — con un único certificado. Esta guía explica cómo obtener un certificado wildcard gratuito usando Certbot con el DNS-01 challenge y configurar Nginx para servir HTTPS en todos tus subdominios.
Requisitos Previos
- Un servidor Linux (Ubuntu 22.04/24.04 o Debian 12) con acceso root o sudo
- Nginx instalado y en ejecución
- Un nombre de dominio registrado con acceso DNS (capacidad para crear registros TXT o acceso API)
- Puerto 443 abierto en tu firewall
- Familiaridad básica con comandos de terminal y configuración de Nginx
Entendiendo los Certificados Wildcard
Un certificado wildcard protege todos los subdominios de primer nivel de un dominio. Un certificado para *.example.com cubre www.example.com, api.example.com, staging.example.com y cualquier otro subdominio — pero no el dominio base example.com en sí, y tampoco subdominios de múltiples niveles como dev.api.example.com.
Let’s Encrypt requiere el DNS-01 challenge para certificados wildcard. A diferencia del HTTP-01 challenge (que coloca un archivo en tu servidor web), DNS-01 requiere que crees un registro TXT en _acme-challenge.example.com para demostrar la propiedad del dominio. Esto tiene sentido: un wildcard cubre todo el dominio, así que necesitas demostrar control sobre el DNS del dominio, no solo sobre un servidor individual.
Instalación de Certbot y Plugins DNS
Instala Certbot y el plugin DNS que corresponda a tu proveedor DNS. Para Cloudflare:
sudo apt update
sudo apt install certbot python3-certbot-nginx python3-certbot-dns-cloudflare
Para otros proveedores, reemplaza el paquete del plugin:
# AWS Route 53
sudo apt install python3-certbot-dns-route53
# DigitalOcean
sudo apt install python3-certbot-dns-digitalocean
# Google Cloud DNS
sudo apt install python3-certbot-dns-google
Si la versión empaquetada está desactualizada, instala mediante pip:
sudo pip3 install certbot certbot-nginx certbot-dns-cloudflare
A continuación, crea el archivo de credenciales para tu proveedor DNS. Para Cloudflare, crea /etc/letsencrypt/cloudflare.ini:
# Cloudflare API token (recommended over Global API key)
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
Restringe los permisos — este archivo contiene tus credenciales API:
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
El token API de Cloudflare necesita permisos de Zone:DNS:Edit limitados a tu dominio. Crea uno en Cloudflare Dashboard → My Profile → API Tokens.
Solicitar el Certificado Wildcard
Solicita un certificado que cubra tanto el wildcard como el dominio base:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.example.com" \
-d "example.com" \
--preferred-challenges dns-01 \
--agree-tos \
-m admin@example.com
Certbot crea un registro DNS TXT, espera la propagación, lo valida y luego lo elimina. Los archivos del certificado se guardan en /etc/letsencrypt/live/example.com/:
fullchain.pem— el certificado más la cadena intermediaprivkey.pem— la clave privadachain.pem— solo el certificado intermedio
Para DNS manual (sin plugin), usa --manual --preferred-challenges dns-01. Certbot mostrará el valor del registro TXT para que lo agregues manualmente. Esto funciona para solicitudes únicas pero no permite la renovación automática.
Configuración de Nginx
Crea o actualiza tu bloque server de Nginx para usar el certificado wildcard. Esta configuración maneja HTTPS para cualquier subdominio y redirige HTTP a HTTPS:
# Redirect all HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com *.example.com;
return 301 https://$host$request_uri;
}
# HTTPS server block for all subdomains
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com *.example.com;
# Let's Encrypt wildcard certificate
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL hardening
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
# HSTS (optional, enable once confirmed working)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Prueba y recarga Nginx:
sudo nginx -t
sudo systemctl reload nginx
Para enrutamiento específico por subdominio, usa bloques server separados que compartan las mismas rutas de certificado pero con diferentes directivas server_name y root / proxy_pass.
Wildcard vs SAN vs Certificados Individuales
| Característica | Wildcard (*.example.com) | SAN (Multi-Dominio) | Certificados Individuales |
|---|---|---|---|
| Cubre todos los subdominios | Sí (solo primer nivel) | Solo dominios listados | Un dominio por certificado |
| Cobertura del dominio raíz | Debe agregarse explícitamente | Sí, si está listado | Sí |
| Subdominios multinivel | No (*.*.example.com no soportado) | Sí, si están listados | Sí |
| Número de certificados | 1 | 1 | 1 por dominio |
| Requiere DNS challenge | Sí | No (HTTP-01 funciona) | No (HTTP-01 funciona) |
| Complejidad de renovación | Necesita plugin DNS o paso manual | Puede usar HTTP-01 | Simple con HTTP-01 |
| Ideal para | Muchos subdominios, subdominios dinámicos | Conjunto fijo de dominios diferentes | Servidores de un solo dominio |
Renovación Automática
Certbot configura un temporizador systemd automáticamente en la mayoría de distribuciones. Verifica que esté activo:
sudo systemctl status certbot.timer
Si muestra active (waiting), la renovación está programada. También puedes verificar:
sudo certbot renew --dry-run
Agrega un hook post-renovación para recargar Nginx después de cada renovación. Crea /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh:
#!/bin/bash
systemctl reload nginx
Hazlo ejecutable:
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
Si prefieres cron sobre systemd, agrega al crontab de root:
# Renew certificates twice daily (Certbot skips if not due)
0 3,15 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
Escenario del Mundo Real
Estás desplegando una plataforma de microservicios con api.example.com para el backend, app.example.com para el frontend, staging.example.com para pruebas y docs.example.com para documentación. Sin un certificado wildcard, tendrías que ejecutar Certbot para cada subdominio, gestionar cuatro certificados separados y agregar nuevos comandos de Certbot cada vez que se lance un nuevo servicio. Con un certificado wildcard, emites un solo comando certbot certonly, apuntas cada bloque server de Nginx a los mismos archivos de certificado y los nuevos subdominios funcionan inmediatamente — sin necesidad de cambios en el certificado. Cuando el equipo levante monitoring.example.com el próximo mes, simplemente funcionará.
Problemas Comunes y Casos Especiales
- El dominio raíz no está cubierto:
*.example.comNO coincide conexample.com. Incluye siempre ambos-d "*.example.com" -d "example.com"en tu comando de Certbot. - Retrasos en la propagación DNS: Algunos proveedores DNS tardan minutos en propagar los registros TXT. Certbot espera 10 segundos por defecto. Auméntalo con
--dns-cloudflare-propagation-seconds 60si la validación falla. - Límites de tasa: Let’s Encrypt permite 50 certificados por dominio registrado por semana y 5 certificados duplicados por semana. Un wildcard cuenta como un certificado, por lo que es poco probable alcanzar estos límites en uso normal. Usa
--stagingpara pruebas. - Subdominios multinivel:
*.example.comNO cubredev.api.example.com. Necesitas un certificado separado o un certificado SAN para subdominios anidados. - Registros de transparencia de certificados: Todos los certificados de Let’s Encrypt se registran públicamente. Los nombres de tus subdominios serán visibles en los registros CT. Esto es inevitable con cualquier certificado de confianza pública.
- Seguridad de credenciales del plugin: Tus credenciales API de DNS otorgan la capacidad de modificar registros DNS. Almacénalas en
/etc/letsencrypt/con permisos600y considera limitar el alcance de los tokens API solo al dominio y permisos necesarios.
Resumen
- Let’s Encrypt emite certificados wildcard gratuitos que cubren
*.tudominio.com, válidos por 90 días - Los certificados wildcard requieren DNS-01 challenge — usa un plugin DNS de Certbot para tu proveedor
- Solicita siempre tanto
*.example.comcomoexample.comen el mismo certificado - Almacena las credenciales del plugin DNS de forma segura con
chmod 600 - Configura Nginx con
ssl_certificateapuntando al fullchain de Let’s Encrypt - Fortalece SSL con TLSv1.2+, OCSP stapling y cabeceras HSTS
- Configura la renovación automática mediante temporizador systemd o cron con un post-hook para recargar Nginx
- Usa la bandera
--stagingdurante pruebas para evitar límites de tasa