🔒 Instalar SSL Let's Encrypt con Certbot + Nginx#
Asegura tus sitios web con certificados SSL gratuitos de Let's Encrypt usando Certbot. Esta guía te acompaña para configurar HTTPS y el renovado automático.
🎯 Objetivos#
- 🔐 Instalar certificados SSL gratuitos de Let's Encrypt
- ⚡ Configurar Certbot para Nginx
- 🔄 Configurar la renovación automática
- 🛡️ Optimizar la configuración SSL para la seguridad
- ✅ Probar y validar la instalación HTTPS
🧰 Prerequisitos#
- Nginx + PHP-FPM instalado (ver guía Nginx + PHP-FPM)
- Nombre de dominio válido apuntando a tu VPS
- Puertos 80 y 443 abiertos en tu servidor
- Acceso root o sudo
💡 Importante: Esta guía se basa en la instalación de Nginx del tutorial anterior. Asegúrate de tener Nginx configurado correctamente primero.
1️⃣ Preparación y verificaciones#
🌐 Verificación del dominio#
Antes de comenzar, verifica que tu dominio apunte a tu servidor:
# Verificación DNS nslookup tu-dominio.com dig tu-dominio.com # Prueba de acceso HTTP (debe funcionar) curl -I http://tu-dominio.com
🔧 Verificación de Nginx#
# Verificación de la configuración de Nginx sudo nginx -t # Estado del servicio sudo systemctl status nginx # Prueba de puertos sudo netstat -tlnp | grep -E ':80|:443'
2️⃣ Instalación de Certbot#
📦 Instalación via APT (Ubuntu/Debian)#
# Instalación de Certbot y el plugin de Nginx sudo apt update sudo apt install certbot python3-certbot-nginx -y
✅ Verificación de la instalación#
# Prueba de Certbot certbot --version # Ayuda y opciones disponibles certbot --help
3️⃣ Obtención del certificado SSL#
🎫 Primera instalación con configuración automática#
Certbot puede modificar automáticamente tu configuración de Nginx:
# Instalación automática para un dominio sudo certbot --nginx -d tu-dominio.com -d www.tu-dominio.com # Instalación para múltiples dominios sudo certbot --nginx -d sitio1.com -d www.sitio1.com -d sitio2.com -d www.sitio2.com
Durante la instalación:
- Ingresa tu email (notificaciones de expiración)
- Acepta los términos de uso
- Elige si quieres recibir newsletters (opcional)
- Certbot configurará automáticamente Nginx y creará la redirección HTTPS
🔧 Instalación manual (control total)#
Si prefieres controlar la configuración:
# Obtención del certificado solamente (sin modificación automática) sudo certbot certonly --nginx -d tu-dominio.com -d www.tu-dominio.com
4️⃣ Configuración manual de Nginx (si instalación manual)#
Si elegiste la instalación manual, modifica tu configuración de Nginx:
📝 Configuración SSL completa#
# Modificación de tu sitio sudo nano /etc/nginx/sites-available/misitio
Configuración completa con SSL:
# Redirección HTTP a HTTPS server { listen 80; listen [::]:80; server_name tu-dominio.com www.tu-dominio.com; # Redirección permanente a HTTPS return 301 https://$server_name$request_uri; } # Configuración HTTPS server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name tu-dominio.com www.tu-dominio.com; # Certificados SSL ssl_certificate /etc/letsencrypt/live/tu-dominio.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/tu-dominio.com/privkey.pem; # Configuración SSL segura ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # Seguridad HTTPS add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # Configuración del sitio (idéntica a la versión HTTP) root /var/www/html/misitio; index index.php index.html index.htm; # Logs access_log /var/log/nginx/misitio_ssl_access.log; error_log /var/log/nginx/misitio_ssl_error.log; # Configuración PHP location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Seguridad location ~ /\.ht { deny all; } # Optimización de cache location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|zip)$ { expires 1y; add_header Cache-Control "public, immutable"; } # Gestión de URLs location / { try_files $uri $uri/ /index.php?$query_string; } }
✅ Aplicación de la configuración#
# Prueba de la configuración sudo nginx -t # Recarga de Nginx sudo systemctl reload nginx
5️⃣ Configuración SSL optimizada#
🔐 Creación de un archivo de configuración SSL reutilizable#
# Crear un archivo de configuración SSL sudo nano /etc/nginx/snippets/ssl-params.conf
Configuración SSL optimizada:
# Protocolos SSL ssl_protocols TLSv1.2 TLSv1.3; # Cifrados seguros ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA; ssl_prefer_server_ciphers off; # Cache de sesiones SSL ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; ssl_session_tickets off; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Headers de seguridad add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always;
🔄 Uso del archivo SSL en tus sitios#
Modifica las configuraciones de tus sitios para usar este archivo:
server { listen 443 ssl http2; server_name tu-dominio.com; # Certificados ssl_certificate /etc/letsencrypt/live/tu-dominio.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/tu-dominio.com/privkey.pem; # Inclusión de la configuración SSL include /etc/nginx/snippets/ssl-params.conf; # ... resto de la configuración }
6️⃣ Renovación automática#
🔄 Configuración de la renovación#
Let's Encrypt genera certificados válidos por 90 días. La renovación automática es esencial:
# Prueba de renovación (dry-run) sudo certbot renew --dry-run # Verificación de certificados instalados sudo certbot certificates
⏰ Configuración de cron para la renovación#
# Edición del crontab root sudo crontab -e
Agrega la siguiente línea (recomendación oficial):
# Renovación automática Let's Encrypt (dos veces al día) 0 */12 * * * root certbot -q renew --nginx
7️⃣ Pruebas y validación#
🧪 Pruebas básicas#
# Prueba HTTPS local curl -I https://tu-dominio.com # Verificación de certificados openssl s_client -connect tu-dominio.com:443 -servername tu-dominio.com
🌐 Pruebas en línea#
- SSL Labs: https://www.ssllabs.com/ssltest/
- Security Headers: https://securityheaders.com/
- Certificate Transparency: https://crt.sh/
📊 Verificación de puntuaciones#
Una buena configuración debe obtener:
- Grado A o A+ en SSL Labs
- Grado A en Security Headers
- Verde en todas las pruebas de compatibilidad
8️⃣ Gestión de múltiples dominios#
🌍 Agregar un nuevo dominio#
# Agregar un certificado para un nuevo sitio sudo certbot --nginx -d nuevo-sitio.com -d www.nuevo-sitio.com # O extender un certificado existente sudo certbot --nginx --expand -d sitio-antiguo.com -d www.sitio-antiguo.com -d nuevo-sitio.com
🔧 Gestión de subdominios#
# Certificado wildcard (requiere validación DNS) sudo certbot certonly --manual --preferred-challenges dns -d "*.tu-dominio.com" -d tu-dominio.com
9️⃣ Solución de problemas#
🔍 Problemas comunes#
Error: "Challenge failed"
# Verificación de que el dominio sea accesible curl -I http://tu-dominio.com/.well-known/acme-challenge/test # Verificación de la configuración de Nginx sudo nginx -t
Error: "Certificate already exists"
# Forzar la renovación sudo certbot renew --force-renewal # O eliminar y nueva instalación sudo certbot delete --cert-name tu-dominio.com sudo certbot --nginx -d tu-dominio.com
Error: "Port 80 not accessible"
# Verificación del firewall sudo ufw status sudo iptables -L # Verificación de puertos sudo netstat -tlnp | grep :80
📋 Logs útiles#
# Logs de Certbot sudo tail -f /var/log/letsencrypt/letsencrypt.log # Logs de Nginx sudo tail -f /var/log/nginx/error.log # Prueba de configuración detallada sudo certbot renew --dry-run --verbose
✅ Resumen de la instalación#
Tu instalación SSL Let's Encrypt ahora está completa con:
- 🔒 Certificados SSL gratuitos y válidos
- ⚡ Configuración HTTPS optimizada
- 🔄 Renovación automática configurada
- 🛡️ Seguridad reforzada con headers apropiados