Cómo generar certificado SSL gratis con Let's Encrypt (paso a paso)
Redes & Segurança · Por Kevin Marcondes · Publicado el · Actualizado el · 8 min de lectura
En este tutorial aprenderás a generar un certificado SSL gratuito con Let's Encrypt usando Certbot. Cubriremos la instalación, la emisión con HTTP-01 o DNS-01, la configuración en Nginx/Apache, la renovación y la verificación. Requiere acceso root y precaución para no interrumpir servicios. El paso a paso es práctico, directo y funciona en la mayoría de servidores Linux.
Requisitos previos y cuándo usar Let's Encrypt
Antes de empezar, asegúrate de que tu dominio apunte al servidor y de contar con permisos administrativos. Para sitios públicos, blogs, APIs y tiendas, Let's Encrypt es adecuado con certificados DV (Domain Validation). Para entornos internos sin acceso público, prefiere DNS-01.
Requisitos esenciales:
- Dominio activo (ej.: ejemplo.com) apuntando al servidor.
- Acceso root o sudo al servidor Linux.
- Puertos 80 (HTTP) y 443 (HTTPS) abiertos en el firewall y en la nube.
- Servidor web (Nginx o Apache) instalado o posibilidad de detener el servicio para el modo standalone.
- Tiempo de propagación DNS (espera desde minutos hasta horas tras cambiar A/AAAA/CNAME).
Elección del desafío: HTTP-01 o DNS-01
Let's Encrypt valida la propiedad del dominio por dos métodos principales. Elige según tu escenario. Los comodines (*.ejemplo.com) requieren DNS-01.
Si también necesitas proteger APIs con buenas prácticas de autenticación y rate limiting, profundiza en proteger APIs.
| Método | Cuándo usar | Requisitos | Observaciones |
|---|---|---|---|
| HTTP-01 | Sitio público respondiendo en el puerto 80 | Puerto 80 abierto; contenido accesible | Más simple; funciona con webroot y los plugins de nginx o apache |
| DNS-01 | Wildcard, servicios detrás de proxy/CDN, sin puerto 80 | Acceso al DNS para crear TXT | Automatiza vía API de tu proveedor de DNS cuando sea posible |
Instalar Certbot en el servidor
Certbot es el cliente recomendado para obtener y renovar certificados. A continuación, opciones para Ubuntu/Debian (snap) y RHEL/CentOS (dnf). Ejecuta como root o antepón sudo.
# Ubuntu/Debian via snap (recomendado)
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot --version
# Alternativa Ubuntu/Debian via APT (se não usar snap)
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx python3-certbot-apache
# RHEL/CentOS 8/9
sudo dnf install -y epel-release
sudo dnf install -y certbot python3-certbot-nginx python3-certbot-apache
certbot --version
Emitir el certificado con Certbot
Elige la opción que mejor encaje. Para HTTP-01 puedes usar el plugin de Nginx/Apache o el modo webroot. El modo standalone levanta un servidor temporal (puerto 80). Detener el servidor web causa indisponibilidad temporal.
# Substitua "exemplo.com" e adicione -d para cada domínio/subdomínio
# 1) Plugin Nginx (detecta e configura automaticamente)
sudo certbot --nginx -d exemplo.com -d www.exemplo.com
# 2) Plugin Apache
sudo certbot --apache -d exemplo.com -d www.exemplo.com
# 3) Somente certificado (webroot): informe a raiz pública do site
sudo certbot certonly --webroot -w /var/www/html \
-d exemplo.com -d www.exemplo.com
# 4) Standalone (para quando não há servidor web ativo)
# ATENÇÃO: isso usa a porta 80 temporariamente
sudo systemctl stop nginx || true
sudo systemctl stop apache2 httpd || true
sudo certbot certonly --standalone -d exemplo.com
sudo systemctl start nginx || true
sudo systemctl start apache2 httpd || true
Configurar HTTPS en Nginx o Apache
Después de emitir, los archivos quedan en /etc/letsencrypt/live/TU_DOMINIO/. A continuación, ejemplos de configuración. Ajusta rutas y upstreams según tu entorno.
También puedes automatizar reloads tras el deploy en tu pipeline. Consulta ideas en CI/CD con GitHub Actions.
# Nginx: redirecionar HTTP -> HTTPS
server {
listen 80;
server_name exemplo.com www.exemplo.com;
return 301 https://$host$request_uri;
}
# Nginx: servidor HTTPS
server {
listen 443 ssl http2;
server_name exemplo.com www.exemplo.com;
ssl_certificate /etc/letsencrypt/live/exemplo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemplo.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
root /var/www/html;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
# Apache: habilitar sites com SSL (exemplo mínimo)
# Arquivo: /etc/apache2/sites-available/exemplo-ssl.conf
# Habilite módulos: a2enmod ssl rewrite && a2ensite exemplo-ssl && systemctl reload apache2
<VirtualHost *:443>
ServerName exemplo.com
ServerAlias www.exemplo.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/exemplo.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/exemplo.com/privkey.pem
</VirtualHost>
# Redireciono HTTP para HTTPS (Apache):
<VirtualHost *:80>
ServerName exemplo.com
ServerAlias www.exemplo.com
Redirect "/" "https://exemplo.com/"
</VirtualHost>
Renovación automática y prueba del proceso
Los certificados de Let's Encrypt expiran en ~90 días. Certbot instala un timer (systemd) o puedes programarlo con cron. Prueba la renovación sin riesgo con --dry-run.
Tras renovar, recarga el servidor web para aplicar el nuevo certificado.
# Testar renovação (sem emitir de fato)
sudo certbot renew --dry-run
# Ver timers do systemd relacionados ao certbot
systemctl list-timers | grep -i certbot || true
# Cron alternativo (executa 2x ao dia)
# /etc/crontab
# 0 3,15 * * * root certbot renew --quiet --deploy-hook "systemctl reload nginx || systemctl reload apache2 || systemctl reload httpd"
Cómo confirmar que funcionó
Valida el HTTPS en el navegador y desde la línea de comando. Revisa cabeceras, emisor, fechas y la cadena de certificados. Confirma que el redireccionamiento 301 de HTTP a HTTPS está activo.
Para confiabilidad continua, considera monitorización 24h de servidores Linux.
# Verificar resposta e cabeçalhos
curl -I https://exemplo.com
# Conferir certificado apresentado (emissor, sujeito e validade)
openssl s_client -connect exemplo.com:443 -servername exemplo.com </dev/null \
| openssl x509 -noout -issuer -subject -dates
Solución de problemas comunes
Consulta problemas frecuentes y cómo revisarlos. Ajusta según tu distribución y entorno de red.
- Fallo en el desafío HTTP-01: puerto 80 bloqueado, webroot incorrecto, proxy impidiendo el acceso. - DNS no propagado: espera el TTL; confirma registros A/AAAA/CNAME. - Wildcard: utiliza DNS-01. - Reverse proxy/balanceador: ejecuta Certbot en el edge o usa DNS-01. - Permisos: rutas de certificados legibles por el servicio web.
- Abre puertos 80/443 en firewall y en la nube.
- Confirma la ruta webroot; prueba un archivo en .well-known/acme-challenge/.
- Revisa los logs de Certbot para mensajes detallados.
- Verifica DNS con dig/nslookup.
- Si es necesario, cambia a DNS-01 y automatiza vía API del proveedor.
# Portas abertas localmente?
sudo ss -tulpen | egrep ':80|:443' || true
# UFW (Ubuntu):
sudo ufw allow 'Nginx Full' || sudo ufw allow 80,443/tcp
# firewalld (RHEL/CentOS):
sudo firewall-cmd --add-service=http --add-service=https --permanent
sudo firewall-cmd --reload
# Logs do Certbot
tail -n 100 -f /var/log/letsencrypt/letsencrypt.log
# Verificar DNS (substitua pelo seu domínio)
dig +short A exemplo.com || nslookup exemplo.com
# Testar acesso ao desafio HTTP-01 (crie um arquivo e acesse via navegador)
mkdir -p /var/www/html/.well-known/acme-challenge/
echo ok > /var/www/html/.well-known/acme-challenge/teste
curl http://exemplo.com/.well-known/acme-challenge/teste
Siguientes pasos y seguridad continua
Mantén el servidor actualizado, desactiva protocolos inseguros y revisa cabeceras de seguridad (HSTS, X-Frame-Options, etc.). Si identificas debilidades en la aplicación, prioriza las correcciones.
Para apoyo en diagnósticos de riesgo, consulta cómo corregir vulnerabilidades en aplicaciones web.
Preguntas frecuentes
¿Let's Encrypt es confiable para producción?
Sí. Let's Encrypt es una autoridad certificadora reconocida que emite certificados DV adecuados para la mayoría de sitios públicos, blogs, APIs y tiendas, según el tutorial. No ofrece validación organizacional o extendida (OV/EV); si necesita ese tipo de validación, debe elegir otra CA que ofrezca OV/EV y seguir sus procesos específicos.
¿Puedo emitir un certificado wildcard (*.dominio.com)?
Sí. Los certificados wildcard requieren el desafío DNS-01, lo que implica crear registros TXT en el DNS del dominio. Muchos proveedores DNS ofrecen APIs para automatizar la creación y renovación con Certbot; el tutorial sugiere automatizar via la API del proveedor para evitar intervenciones manuales en cada renovación.
¿Necesito abrir el puerto 80 para validar?
Para HTTP-01 sí: Let's Encrypt debe acceder a http://tu-dominio/.well-known/acme-challenge/, por lo que el puerto 80 tiene que estar accesible. Alternativas: usar DNS-01 (no requiere abrir puerto 80) o el modo standalone de Certbot, que exige que el puerto 80 esté temporalmente libre; con webroot o los plugins de Nginx/Apache no necesitas detener el servicio.
¿Cómo renovar sin downtime?
Configura Certbot para renovar usando webroot o los plugins de Nginx/Apache y añade un deploy-hook que recargue (reload) el servicio web tras la renovación. El reload aplica el nuevo certificado sin reiniciar procesos y evita interrupciones en la mayoría de servidores; prueba la renovación con --dry-run antes de confiar en la automatización.
¿Se pueden incluir varios dominios en el mismo certificado?
Sí. Con Certbot puedes añadir múltiples -d en el mismo comando (por ejemplo -d ejemplo.com -d www.ejemplo.com). Incluye solo dominios que puedas validar desde ese servidor; si los dominios no apuntan al mismo servidor, usa DNS-01 para validarlos y ajusta la configuración del servidor web tras la emisión.
¿Puedo usar un entorno de pruebas para evitar límites?
Sí. Usa --staging en los comandos de Certbot para emitir certificados de prueba contra el entorno de pruebas de Let's Encrypt y evitar los límites durante despliegues y automatización. En producción, quite --staging para emitir certificados válidos y use --dry-run para probar el flujo de renovación.
¿Necesitas ayuda con un escenario más complejo?
Entornos con reverse proxy, balanceadores, contenedores o múltiples dominios pueden requerir DNS-01 y automatización. Si deseas soporte puntual en la configuración, hablemos.
Hablar sobre tu configuraciónVer también
- Tutorial: implementar Canary releases con Traefik en Docker Compose usando headers y weighted routing para despliegues graduales de aplicaciones PHP
- Tutorial: configurar HAProxy con Let's Encrypt y healthchecks para balanceo de tráfico entre contenedores Docker en VPS (paso a paso)
- Tutorial práctico: implementar mTLS entre Nginx y microservicios usando smallstep CA en Docker Compose
- Tutorial: configurar cgroup v2 y systemd ResourceControl para limitar CPU, memoria e I/O de contenedores Docker en Debian