TL;DR — Resumen Rápido

Certificado SSL wildcard de Let's Encrypt con Certbot, desafío DNS y Nginx para renovación automática de certificados *.dominio.com multi-subdominios.

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í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
Subdominios multinivel No (*.*.example.com no soportado) Sí, si están listados
Número de certificados 1 1 1 por dominio
Requiere DNS challenge 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.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