Descripción General
Let’s Encrypt es una autoridad certificadora gratuita y automatizada que provee certificados SSL/TLS confiables por todos los navegadores principales. Certbot es el cliente oficial que automatiza la emisión, instalación y renovación de certificados. Juntos eliminan el costo y trabajo manual de configurar HTTPS.
Antes de Let’s Encrypt, obtener un certificado SSL válido requería comprar a una CA comercial, generar un CSR, validar la propiedad del dominio vía email e instalar el certificado manualmente. El proceso tomaba horas o días y costaba cientos de dólares por año. Let’s Encrypt redujo esto a un solo comando y costo cero.
Cuándo Usar
Usa esta receta cuando:
- Configuras HTTPS para una nueva aplicación web pública.
- Reemplazas certificados expirados o autofirmados con otros confiables por navegadores.
- Automatizas la renovación de certificados para que nunca expiren inadvertidamente.
- Configuras SSL en un reverse proxy (Nginx, Apache, HAProxy) o load balancer.
- Habilitas HTTPS en un contenedor Docker o ingress de Kubernetes.
Implementación Paso a Paso
Instalar Certbot
# Ubuntu / Debian
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
# macOS (para testing)
brew install certbot
# Verificar instalación
certbot --version
Nginx (Plugin Automático)
# Emitir e instalar certificado en un solo paso
certbot --nginx -d example.com -d www.example.com
# Probar renovación automática
sudo certbot renew --dry-run
El plugin --nginx lee automáticamente el server block, instala el certificado y configura la redirección a HTTPS.
# /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Configuración TLS moderna
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Apache (Plugin Automático)
certbot --apache -d example.com -d www.example.com
# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# TLS moderno
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder on
</VirtualHost>
Standalone (Sin Servidor Web)
# Usar modo standalone cuando no hay servidor web corriendo
certbot certonly --standalone -d example.com
# Los certificados se guardan en /etc/letsencrypt/live/example.com/
# Configura tu aplicación para leer:
# /etc/letsencrypt/live/example.com/fullchain.pem
# /etc/letsencrypt/live/example.com/privkey.pem
Docker / Certbot
# docker-compose.yml
version: '3'
services:
certbot:
image: certbot/certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
- ./certbot/log:/var/log/letsencrypt
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./certbot/conf:/etc/letsencrypt:ro
- ./certbot/www:/var/www/certbot:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
# nginx.conf
server {
listen 80;
server_name example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://app:3000;
}
}
Auto-Renovación (Systemd Timer)
# Certbot instala un systemd timer automáticamente en la mayoría de sistemas
sudo systemctl status certbot.timer
# Fallback con cron manual
sudo crontab -e
# Agregar:
# 0 3 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
Lo que funciona
- Usa el plugin del servidor web (
--nginx,--apache) cuando sea posible. Maneja la configuración automáticamente y reduce errores humanos. - Configura la auto-renovación desde el día uno. Los certificados de Let’s Encrypt expiran cada 90 días. Un cron job olvidado causa downtime en producción.
- Incluye dominio y subdominio www en la solicitud del certificado para evitar warnings del navegador en cualquiera de las URLs.
- Redirige HTTP a HTTPS a nivel de servidor web, no en código de aplicación. Es más rápido y confiable.
- Usa
fullchain.pem, nocert.pem. La cadena completa incluye certificados intermedios que los navegadores necesitan para validar la cadena de confianza.
Errores Comunes
- Abrir el puerto 80 solo temporalmente durante la configuración inicial y luego cerrarlo. Let’s Encrypt requiere el puerto 80 abierto para validación HTTP-01 en cada renovación.
- Solicitar un certificado para un dominio interno (ej.,
app.local). Let’s Encrypt solo emite certificados para dominios públicamente resolvibles. - Usar
cert.pemen lugar defullchain.pemcausa errores “certificado no confiado” en algunos navegadores porque faltan intermedios. - No probar la renovación con
--dry-run. Una emisión inicial exitosa no garantiza que la renovación funcionará. Pruébalo antes de los 90 días. - Ejecutar Certbot como root innecesariamente. Usa
sudopara la instalación, pero considera ejecutar la renovación como un usuario dedicado con privilegios limitados.
Tips de Rendimiento
- Habilita OCSP stapling. Los clientes verifican el estado del cert sin contactar a la CA, reduciendo latencia del handshake:
ssl_stapling on;
ssl_stapling_verify on;
- Usa session resumption. Cachéa sesiones TLS para saltar el handshake completo en clientes recurrentes:
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
- Prefiere ECDSA sobre RSA. Llaves más pequeñas significan handshakes más rápidos y menos uso de CPU:
certbot certonly --key-type ecdsa --elliptic-curve secp256r1 -d example.com Preguntas frecuentes
¿Cuál es la diferencia entre un certificado autofirmado y uno firmado por CA?
Un certificado autofirmado lo emites tú y generará advertencias en el navegador. Un certificado firmado por CA es confiable por defecto porque los navegadores confían en la Autoridad Certificadora emisora.
¿Cómo funciona Let's Encrypt?
Let's Encrypt es una CA gratuita que valida la propiedad del dominio mediante desafíos HTTP o DNS y emite certificados de corta duración, típicamente válidos por 90 días.
¿Por qué debería automatizar la renovación de certificados?
Los certificados TLS expiran. La renovación automatizada previene interrupciones del servicio por certificados vencidos y reduce el trabajo operativo manual.
Recursos Relacionados
Playbook de Ansible para Configuración de Servidores
Cómo escribir y ejecutar playbooks de Ansible para provisionar, configurar y gestionar servidores con tareas idempotentes, roles y archivos de inventario.
RecipeFundamentos de Docker
Cómo containerizar una aplicación, escribir un Dockerfile y ejecutar contenedores con Docker Compose.
RecipeGestionar Secretos de Aplicaciones de Forma Segura
Cómo almacenar, rotar e inyectar API keys, contraseñas de base de datos y certificados sin hardcodearlos en código fuente o archivos de entorno.
RecipeImágenes de Producción Slim con Multi-Stage Docker
Cómo construir imágenes Docker de producción minimales usando multi-stage builds con distroless base images, cubriendo Go, Node.js, Python y Java con reducción de tamaño.
RecipeMontar Configs y Secrets en Pods de Kubernetes
Cómo montar ConfigMaps y Secrets en pods de Kubernetes usando env vars, volumes, projected volumes y secret management con external secrets.
DocPlantilla de Renovación de Certificados SSL
Plantilla para rastrear la caducidad de certificados SSL y los flujos de trabajo de renovación.