--- title: "Certificado SSL comodín con Let's Encrypt en Ubuntu 24.04" description: "Obtén un certificado comodín de Let's Encrypt con Certbot y el desafío DNS de Cloudflare en Ubuntu 24.04, úsalo en Nginx y deja la renovación automática lista." category: "SSL/TLS y Certificados" language: es source: https://cubepath.com/es/docs/ssl-tls-y-certificados/certificados-ssl-comodin-con-lets-encrypt updated: 2026-09-25 --- # Certificado SSL comodín con Let's Encrypt en Ubuntu 24.04 Un certificado comodín (wildcard) cubre todos los subdominios de primer nivel de un dominio, como `api.example.com` o `shop.example.com`, con un único certificado. Let's Encrypt solo emite certificados comodín mediante el desafío DNS-01, que demuestra el control del dominio creando un registro TXT. En este tutorial obtendrás un certificado para `your_domain` y `*.your_domain` con Certbot y el plugin de Cloudflare en Ubuntu 24.04, lo usarás en Nginx y comprobarás que se renueva solo. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, y un usuario no root con privilegios `sudo`. - Un dominio cuya zona DNS esté gestionada en Cloudflare. Si usas otro proveedor, consulta la sección "Otros proveedores DNS". - Nginx instalado (`sudo apt install nginx`). El desafío DNS no necesita ningún puerto abierto; los puertos 80 y 443 solo hacen falta para servir la web. - Registros DNS `A` para `your_domain` y para los subdominios que vayas a servir apuntando a `your_server_ip` (puedes usar un registro `*` comodín). A lo largo de la guía, sustituye `your_domain` por tu dominio real (por ejemplo `example.com`). ## Qué cubre un certificado comodín Conviene tener claro el alcance antes de pedirlo: | Nombre | ¿Lo cubre `*.your_domain`? | |---|---| | `api.your_domain` | Sí | | `www.your_domain` | Sí | | `your_domain` (dominio raíz) | No, hay que añadirlo aparte | | `v1.api.your_domain` | No, el comodín solo cubre un nivel | Por eso en esta guía pedirás un único certificado con dos nombres: `your_domain` y `*.your_domain`. ## Paso 1: Instalar Certbot y el plugin de Cloudflare El proyecto Certbot recomienda instalarlo con snap, que trae la versión más reciente y un temporizador de renovación ya configurado. Si tienes el paquete `certbot` de apt, elimínalo antes para no tener dos versiones: ```bash sudo apt remove certbot sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/local/bin/certbot ``` Los plugins DNS se instalan como snaps independientes. Primero permite que Certbot cargue plugins con permisos de root y después instala y conecta el de Cloudflare: ```bash sudo snap set certbot trust-plugin-with-root=ok sudo snap install certbot-dns-cloudflare sudo snap connect certbot:plugin certbot-dns-cloudflare ``` Comprueba que Certbot detecta el plugin: ```bash sudo certbot plugins ``` ```output * dns-cloudflare Description: Obtain certificates using a DNS TXT record (if you are using Cloudflare for DNS). ... ``` ## Paso 2: Crear un token de API de Cloudflare Certbot necesita crear y borrar registros TXT en tu zona. Usa un token de API con permisos limitados, nunca la Global API Key de la cuenta. En el panel de Cloudflare, ve a **My Profile** > **API Tokens** > **Create Token**, elige la plantilla **Edit zone DNS** y, en **Zone Resources**, selecciona solo la zona de `your_domain`. Copia el token generado, porque Cloudflare no vuelve a mostrarlo. Guarda el token en un archivo que solo pueda leer root: ```bash sudo mkdir -p /root/.secrets/certbot sudo nano /root/.secrets/certbot/cloudflare.ini ``` ```ini dns_cloudflare_api_token = your_cloudflare_api_token ``` Restringe los permisos. Certbot muestra un aviso si el archivo lo pueden leer otros usuarios: ```bash sudo chmod 600 /root/.secrets/certbot/cloudflare.ini ``` ## Paso 3: Solicitar el certificado comodín Haz primero una prueba contra el entorno de staging de Let's Encrypt con `--dry-run`. Así compruebas el token y la propagación DNS sin consumir los límites de emisión de producción: ```bash sudo certbot certonly --dry-run \ --dns-cloudflare \ --dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \ --dns-cloudflare-propagation-seconds 30 \ -d your_domain -d '*.your_domain' ``` Las comillas en `'*.your_domain'` evitan que la shell expanda el asterisco. La opción `--dns-cloudflare-propagation-seconds` indica cuánto espera Certbot tras crear el registro TXT antes de pedir la validación. ```output The dry run was successful. ``` Si la prueba funciona, repite el comando sin `--dry-run` para obtener el certificado real. La primera vez Certbot te pedirá un correo y que aceptes las condiciones de servicio: ```bash sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \ --dns-cloudflare-propagation-seconds 30 \ -d your_domain -d '*.your_domain' ``` ```output Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem This certificate expires on 2026-12-24. ``` Comprueba los nombres incluidos en el certificado: ```bash sudo certbot certificates ``` ```output Certificate Name: your_domain Domains: your_domain *.your_domain Expiry Date: 2026-12-24 10:12:45+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/your_domain/fullchain.pem Private Key Path: /etc/letsencrypt/live/your_domain/privkey.pem ``` ## Paso 4: Usar el certificado en Nginx Como el certificado cubre cualquier subdominio, puedes reutilizar las mismas rutas en todos los bloques `server`. Crea un archivo de configuración: ```bash sudo nano /etc/nginx/sites-available/your_domain ``` Este ejemplo redirige HTTP a HTTPS, sirve el dominio raíz y `www`, y define un subdominio `api` que hace de proxy a una aplicación local en el puerto 3000 (ajústalo a tu caso): ```nginx server { listen 80; listen [::]:80; server_name your_domain *.your_domain; return 301 https://$host$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name your_domain www.your_domain; ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem; root /var/www/html; index index.html; } server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name api.your_domain; ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` Usa siempre `fullchain.pem` y no `cert.pem`: el primero incluye el certificado intermedio que los clientes necesitan para validar la cadena. Activa el sitio, comprueba la sintaxis y recarga Nginx: ```bash sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` ```output nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` Si usas UFW, permite el tráfico web: ```bash sudo ufw allow 'Nginx Full' ``` Comprueba desde cualquier equipo que el subdominio sirve el certificado comodín: ```bash openssl s_client -connect api.your_domain:443 -servername api.your_domain /dev/null \ | openssl x509 -noout -subject -ext subjectAltName ``` ```output subject=CN = your_domain X509v3 Subject Alternative Name: DNS:*.your_domain, DNS:your_domain ``` ## Paso 5: Verificar la renovación automática Los certificados de Let's Encrypt caducan a los 90 días. El snap de Certbot instala un temporizador de systemd que ejecuta `certbot renew` dos veces al día y renueva los certificados a los que les quedan menos de 30 días. Comprueba que está activo: ```bash systemctl list-timers snap.certbot.renew.timer ``` ```output NEXT LEFT LAST PASSED UNIT ACTIVATES Fri 2026-09-25 21:48:00 UTC 9h left - - snap.certbot.renew.timer snap.certbot.renew.service ``` Certbot guarda en `/etc/letsencrypt/renewal/your_domain.conf` el plugin y el archivo de credenciales que usaste, así que la renovación no necesita parámetros. Lo que no hace es recargar Nginx para que cargue el certificado nuevo. Para eso, crea un hook de despliegue, que solo se ejecuta cuando un certificado se renueva de verdad: ```bash sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh ``` ```bash #!/usr/bin/env bash set -euo pipefail systemctl reload nginx ``` Hazlo ejecutable y simula una renovación completa: ```bash sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh sudo certbot renew --dry-run ``` ```output Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/your_domain/fullchain.pem (success) ``` ## Otros proveedores DNS El desafío DNS-01 funciona igual con cualquier proveedor que tenga plugin de Certbot; solo cambian el nombre del plugin y el archivo de credenciales. Algunos disponibles como snap son `certbot-dns-route53`, `certbot-dns-digitalocean`, `certbot-dns-google`, `certbot-dns-ovh` y `certbot-dns-rfc2136` (para servidores DNS propios como BIND o PowerDNS). Consulta la documentación de cada plugin para el formato de credenciales. Si tu proveedor no tiene plugin ni API, puedes usar `--manual --preferred-challenges dns` y crear el registro TXT a mano, pero ese certificado no se podrá renovar automáticamente y tendrás que repetir el proceso cada 90 días. En ese caso es mejor delegar el subdominio `_acme-challenge` a un proveedor con API. ## Solución de problemas **`Unable to determine zone_id` o `Error determining zone_id`.** El token no tiene acceso a la zona. Revisa en Cloudflare que el token incluye el permiso **Zone** > **DNS** > **Edit** y la zona correcta en **Zone Resources**. **`Incorrect TXT record` o `No TXT record found`.** Let's Encrypt consultó el DNS antes de que el registro se propagara. Aumenta `--dns-cloudflare-propagation-seconds` a 60 y, mientras Certbot espera, comprueba el registro desde otra terminal: ```bash dig +short TXT _acme-challenge.your_domain @1.1.1.1 ``` **`CAA record for your_domain prevents issuance`.** Tu zona tiene registros CAA que no autorizan a Let's Encrypt. Para certificados comodín se aplica la etiqueta `issuewild` (o `issue` si no existe `issuewild`). Añade un registro CAA con `0 issuewild "letsencrypt.org"` y revisa los existentes: ```bash dig +short CAA your_domain ``` **`too many certificates already issued`.** Has alcanzado un límite de emisión de Let's Encrypt, normalmente por repetir pruebas en producción. Espera a que se libere el límite y usa `--dry-run` para las pruebas. ## Conclusión Tienes un certificado de Let's Encrypt válido para `your_domain` y todos sus subdominios de primer nivel, servido por Nginx y con renovación automática mediante DNS-01 y un hook que recarga el servidor. Como siguientes pasos, puedes reforzar la configuración TLS de Nginx (protocolos, cabecera HSTS), añadir nuevos subdominios con solo crear su bloque `server`, o revisar la guía de protocolo ACME para entender cómo funcionan los desafíos por debajo.