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 intermedia
  • privkey.pem — la clave privada
  • chain.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ísticaWildcard (*.example.com)SAN (Multi-Dominio)Certificados Individuales
Cubre todos los subdominiosSí (solo primer nivel)Solo dominios listadosUn dominio por certificado
Cobertura del dominio raízDebe agregarse explícitamenteSí, si está listado
Subdominios multinivelNo (*.*.example.com no soportado)Sí, si están listados
Número de certificados111 por dominio
Requiere DNS challengeNo (HTTP-01 funciona)No (HTTP-01 funciona)
Complejidad de renovaciónNecesita plugin DNS o paso manualPuede usar HTTP-01Simple con HTTP-01
Ideal paraMuchos subdominios, subdominios dinámicosConjunto fijo de dominios diferentesServidores 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.com NO coincide con example.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 60 si 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 --staging para pruebas.
  • Subdominios multinivel: *.example.com NO cubre dev.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 permisos 600 y 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.com como example.com en el mismo certificado
  • Almacena las credenciales del plugin DNS de forma segura con chmod 600
  • Configura Nginx con ssl_certificate apuntando 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 --staging durante pruebas para evitar límites de tasa

Artículos Relacionados