Skip to content

SSL con Let's Encrypt ​

Hoy ningún sitio profesional puede estar sin HTTPS: los navegadores marcan como "No seguro" los sitios HTTP, Google los posiciona peor y muchas APIs del navegador (geolocalización, cámara, service workers) solo funcionan con HTTPS. La buena noticia: con Let's Encrypt y Certbot los certificados son gratis y se renuevan solos.

Concepto ​

  • TLS (antes SSL) cifra la comunicación entre navegador y servidor. HTTPS = HTTP + TLS.
  • Un certificado demuestra que el servidor realmente es dueño del dominio. Lo emite una autoridad certificadora (CA).
  • Let's Encrypt es una CA gratuita y automatizada. Sus certificados duran 90 días (y la industria se mueve hacia periodos aún más cortos), por eso la renovación automática es obligatoria.
  • Certbot es el programa que pide, instala y renueva los certificados.

Cómo comprueba Let's Encrypt que el dominio es tuyo ​

MétodoCómo funcionaCuándo usarlo
HTTP-01Certbot coloca un archivo en http://tudominio.com/.well-known/acme-challenge/... y Let's Encrypt lo descarga.El caso normal. Requiere puerto 80 abierto y DNS apuntando al servidor.
DNS-01Creas un registro TXT _acme-challenge en el DNS.Certificados wildcard (*.tudominio.com) o servidores sin puerto 80.

Requisitos previos ​

  • [ ] El dominio (y www) apunta a la IP del servidor: dig +short tudominio.com.
  • [ ] Puertos 80 y 443 abiertos: sudo ufw status.
  • [ ] Nginx o Apache sirviendo el sitio por HTTP con el server_name / ServerName correcto.

Paso 1: instalar Certbot ​

El método recomendado oficialmente es con snap:

bash
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/bin/certbot

certbot --version

Alternativa con apt

También funciona sudo apt install certbot python3-certbot-nginx (o python3-certbot-apache). La versión de apt puede ser un poco más antigua, pero es perfectamente válida en Ubuntu 24.04.

Paso 2: obtener el certificado ​

bash
sudo certbot --nginx -d tudominio.com -d www.tudominio.com
bash
sudo certbot --apache -d tudominio.com -d www.tudominio.com

Certbot te pedirá un correo (para avisos de expiración), aceptar términos y listo: edita tu configuración automáticamente para usar el certificado y redirigir HTTP a HTTPS.

Los archivos quedan en:

txt
/etc/letsencrypt/live/tudominio.com/
├── fullchain.pem   ← certificado + cadena (el que usa el servidor)
├── privkey.pem     ← llave privada (¡secreta!)
├── cert.pem
└── chain.pem

Varios dominios a la vez ​

bash
sudo certbot --nginx \
  -d clientea.com -d www.clientea.com \
  -d api.clientea.com

Solo obtener el certificado (sin tocar la configuración) ​

bash
sudo certbot certonly --nginx -d tudominio.com
# o con el modo webroot, indicando la carpeta pública
sudo certbot certonly --webroot -w /var/www/tudominio.com/public -d tudominio.com

Así queda la configuración de Nginx ​

Esto es lo que Certbot genera (lo puedes escribir tú a mano también):

nginx
# Redirección HTTP → HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name tudominio.com www.tudominio.com;
    return 301 https://tudominio.com$request_uri;
}

# Sitio con HTTPS
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name tudominio.com www.tudominio.com;

    ssl_certificate     /etc/letsencrypt/live/tudominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # HSTS: el navegador solo usará HTTPS durante 1 año
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    root /var/www/tudominio.com/public;
    index index.html;

    location / {
        try_files $uri $uri.html $uri/ =404;
    }
}

http2 en versiones nuevas de Nginx

Ubuntu 24.04 trae Nginx 1.24, que usa listen 443 ssl http2;. Desde Nginx 1.25.1 la forma recomendada es listen 443 ssl; más una línea http2 on; (la forma antigua sigue funcionando, solo muestra un aviso en nginx -t).

Y en Apache ​

apache
<VirtualHost *:80>
    ServerName tudominio.com
    ServerAlias www.tudominio.com
    Redirect permanent / https://tudominio.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName tudominio.com
    ServerAlias www.tudominio.com
    DocumentRoot /var/www/tudominio.com/public

    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/tudominio.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/tudominio.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

    <Directory /var/www/tudominio.com/public>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Requiere sudo a2enmod ssl headers.

Paso 3: renovación automática ​

Certbot instala un temporizador que intenta renovar dos veces al día (solo renueva lo que vence en menos de 30 días).

bash
# Ver el temporizador (instalación con snap)
systemctl list-timers | grep certbot

# Simular una renovación: si no hay errores, la renovación real funcionará
sudo certbot renew --dry-run

# Ver certificados y fechas de expiración
sudo certbot certificates

Si necesitas recargar el servidor tras cada renovación (por ejemplo, para otros servicios que usan el certificado), agrega un hook:

bash
sudo tee /etc/letsencrypt/renewal-hooks/deploy/recargar-nginx.sh > /dev/null <<'EOF'
#!/bin/sh
systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/recargar-nginx.sh

Certificado wildcard (DNS-01) ​

Para *.tudominio.com (útil en plataformas multi-cliente: cliente1.tuapp.com, cliente2.tuapp.com):

bash
sudo certbot certonly --manual --preferred-challenges dns \
  -d "tudominio.com" -d "*.tudominio.com"

Certbot te mostrará un valor para crear un registro TXT en _acme-challenge.tudominio.com. Créalo, verifica con dig +short TXT _acme-challenge.tudominio.com y continúa.

El modo manual no se renueva solo

Con --manual tendrás que repetir el proceso cada 90 días. Para automatizar usa un plugin DNS de tu proveedor, por ejemplo Cloudflare:

bash
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

# Token de API de Cloudflare con permiso Zone:DNS:Edit
sudo mkdir -p /root/.secrets
echo "dns_cloudflare_api_token = TU_TOKEN" | sudo tee /root/.secrets/cloudflare.ini
sudo chmod 600 /root/.secrets/cloudflare.ini

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d "tudominio.com" -d "*.tudominio.com"

Comprobar tu HTTPS ​

bash
curl -I https://tudominio.com
# Ver fechas del certificado
echo | openssl s_client -connect tudominio.com:443 -servername tudominio.com 2>/dev/null | openssl x509 -noout -dates

Errores comunes ​

ErrorCausaSolución
DNS problem: NXDOMAINEl dominio no existe o no tiene registro A.Revisa el DNS con dig.
Timeout during connectPuerto 80 cerrado.sudo ufw allow 80/tcp; revisa el firewall del proveedor.
unauthorized ... 404El dominio apunta a otro servidor o el server_name no coincide.Verifica la IP y la configuración.
too many certificates already issuedLímite de emisiones de Let's Encrypt.Usa --dry-run o --staging para probar; espera.
Bucle de redirecciones con CloudflareCloudflare en modo SSL "Flexible".Cambia a Full (strict).

Buena práctica con Cloudflare

Si el dominio usa el proxy de Cloudflare (nube naranja), el reto HTTP-01 suele funcionar igual, pero lo más robusto es usar el plugin DNS de Cloudflare o un Origin Certificate de Cloudflare. Ver Rendimiento y CDN.

HSTS con cuidado

Strict-Transport-Security obliga al navegador a usar HTTPS durante el tiempo indicado. Si activas includeSubDomains y algún subdominio no tiene HTTPS, dejará de funcionar. Empieza con max-age=300 y súbelo cuando estés seguro.

Ejercicios ​

  1. Escribe el comando para obtener certificado en Nginx para tienda.com, www.tienda.com y admin.tienda.com.
  2. ¿Cómo compruebas que la renovación automática funcionará sin esperar 60 días?
  3. Un cliente tiene 50 subdominios dinámicos. ¿Qué tipo de certificado y reto usarías?
Ver solución
bash
sudo certbot --nginx -d tienda.com -d www.tienda.com -d admin.tienda.com
  1. sudo certbot renew --dry-run.
  2. Un certificado wildcard (*.tienda.com) con reto DNS-01, idealmente con un plugin DNS (Cloudflare, Route 53, DigitalOcean) para que se renueve solo.

Resumen ​

  • HTTPS es obligatorio; Let's Encrypt lo da gratis y Certbot lo automatiza.
  • Requisitos: DNS apuntando y puertos 80/443 abiertos.
  • certbot --nginx / --apache obtiene, instala y configura la redirección.
  • Los certificados duran 90 días: verifica la renovación con renew --dry-run.
  • Wildcard requiere DNS-01; con Cloudflare usa SSL Full (strict).
  • Siguiente: Docker y docker-compose.

Academia Web — aprende, copia y construye.