Cómo instalar Let's Encrypt en Apache Ubuntu: guía HTTPS gratis
Aprende a instalar Let's Encrypt en Apache Ubuntu con Certbot, configurar HTTPS gratuito, renovación automática y redirección 301 en producción.
HTTPS dejó de ser opcional. Los navegadores marcan los sitios HTTP como “No seguro”, las APIs externas rechazan webhooks sin TLS, y el SEO penaliza dominios sin certificado. Let’s Encrypt resuelve esto gratis — certificados X.509 válidos, reconocidos por todos los navegadores modernos, emitidos por una autoridad certificadora pública.
Este tutorial cubre la instalación de Let’s Encrypt en un servidor Apache ejecutando Ubuntu 22.04 o 24.04, usando el cliente oficial Certbot. El foco está en la configuración de producción: emisión, redirección 301 de HTTP a HTTPS, renovación automática y validación real del certificado. Tiempo estimado de ejecución: 15 a 20 minutos, asumiendo que el DNS ya apunta al servidor.
La persona objetivo es un sysadmin o desarrollador que ya tiene un Apache configurado sirviendo un sitio funcional en HTTP y necesita añadir TLS. Si todavía estás aprovisionando el servidor desde cero, instala Apache primero (sudo apt install apache2) y vuelve aquí después de que curl http://tu-dominio devuelva HTML.
Prerrequisitos
Antes de empezar, confirma que el servidor cumple con los prerrequisitos correctos. La validación HTTP-01 de Let’s Encrypt necesita alcanzar el servidor por el puerto 80, por lo que cualquier bloqueo de firewall o DNS desalineado hará que la emisión falle ya en el primer certbot run.
Ubuntu 22.04 LTS o 24.04 LTS con acceso sudo. Apache 2.4+ ya instalado y sirviendo el sitio en HTTP. Dominio público (ej.: ejemplo.com) con registro A apuntando a la IP del servidor. Puertos 80 y 443 abiertos en el firewall y en cualquier security group del proveedor. Email válido para notificaciones de expiración.
Certbot 2.x python3-certbot-apache 80 (HTTP-01) 90 días Verifica el DNS antes de continuar. Ejecuta dig +short tu-dominio.com y confirma que la IP devuelta es la del servidor. Si no lo es, la propagación todavía puede estar en curso (TTL típico de 1 a 24 horas) — espera antes de intentar emitir.
Instalando Certbot y el plugin de Apache
Certbot está disponible como paquete APT en Ubuntu, pero la versión de los repositorios oficiales suele estar desactualizada. Para producción, el método recomendado por el propio proyecto es snap, que mantiene el cliente actualizado automáticamente. Esta sección cubre la instalación vía snap, que es la más robusta.
Actualiza el índice de paquetes y elimina cualquier versión antigua de Certbot que haya venido de APT:
sudo apt update
sudo apt remove certbot python3-certbot-apache -ySi nunca lo instalaste antes, remove simplemente no hará nada — es seguro ejecutarlo.
Instala el snap core (ya viene por defecto en Ubuntu 22.04+, pero garantiza la versión más reciente):
sudo snap install core
sudo snap refresh coreInstala Certbot vía snap y crea el symlink para que el binario quede disponible en el PATH:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotEl modo --classic es necesario porque Certbot necesita escribir en directorios fuera del sandbox de snap (/etc/letsencrypt, /etc/apache2, /var/log/letsencrypt).
Confirma la instalación:
certbot --versionLa salida debe ser algo como certbot 2.11.0. Si aparece “command not found”, verifica si /snap/bin está en el PATH o rehaz el symlink.
Verificando la configuración de Apache
El plugin --apache de Certbot lee los archivos de VirtualHost en /etc/apache2/sites-enabled/ para descubrir cuáles dominios están servidos y cuál vhost editar. Para que el plugin funcione, cada vhost necesita tener la directiva ServerName (y opcionalmente ServerAlias) configurada correctamente.
Lista los vhosts activos:
sudo apachectl -SBusca entradas con port 80 namevhost listando tu dominio. Si el servidor responde con *:80 is a NameVirtualHost pero ServerName está vacío, edita el vhost antes de continuar.
Abre el vhost de tu sitio (generalmente /etc/apache2/sites-available/tu-dominio.conf o 000-default.conf) y confirma que tiene ServerName:
<VirtualHost *:80>
ServerName ejemplo.com
ServerAlias www.ejemplo.com
DocumentRoot /var/www/ejemplo
</VirtualHost>Si editaste, recarga Apache:
sudo systemctl reload apache2Ubuntu viene con UFW deshabilitado por defecto, pero si lo activaste, libera HTTPS antes de la emisión:
sudo ufw allow 'Apache Full'
sudo ufw statusLa regla Apache Full libera 80 y 443. Si solo liberas Apache (sin Full), el puerto 443 queda bloqueado y el sitio ni siquiera carga después de la configuración.
Emitiendo el certificado
Con Certbot instalado y Apache configurado, la emisión es un único comando. El plugin --apache detecta los dominios, dialoga con Let’s Encrypt vía HTTP-01, recibe el certificado, edita los VirtualHosts para incluir las directivas SSL y (opcionalmente) configura el redirect 301.
Ejecuta Certbot en modo interactivo:
sudo certbot --apacheSe te preguntará:
- Email para notificaciones (recovery + expiración próxima)
- Aceptación de los Términos de Servicio (
Apara aceptar) - Opt-in para el newsletter de la EFF (
Nsi prefieres no recibirlo) - Cuáles dominios certificar (selecciona todos si quieres HTTPS en todos)
- Si quieres redirigir HTTP a HTTPS automáticamente (elige
2para forzar el redirect — recomendado)
Si todo salió bien, la salida termina con algo parecido a:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/ejemplo.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/ejemplo.com/privkey.pem
This certificate expires on 2026-08-27.Certbot también crea un nuevo archivo de vhost con sufijo -le-ssl.conf en /etc/apache2/sites-available/ que contiene el bloque <VirtualHost *:443> con las directivas SSL.
Let’s Encrypt limita 5 emisiones fallidas por hora desde la misma IP y 50 certificados por dominio registrado por semana. Si estás haciendo pruebas, usa el flag --staging (sudo certbot --apache --staging) — emite contra el ambiente de prueba, el certificado no es confiable para los navegadores pero no consume el rate limit de producción.
Configurando la renovación automática
La instalación vía snap ya viene con la renovación automática configurada vía systemd timer. No necesitas editar crontab ni crear scripts — snap mantiene el timer ejecutando dos veces al día, y Certbot solo hace la llamada real a la API cuando el certificado está a menos de 30 días del vencimiento.
Verifica si el timer está activo:
sudo systemctl status snap.certbot.renew.timerLa salida debe mostrar Active: active (waiting) y la próxima ejecución programada.
Haz un dry-run de la renovación para confirmar que todo está funcionando:
sudo certbot renew --dry-runEl dry-run simula una renovación contra el ambiente de staging de Let’s Encrypt — no consume rate limit, no sustituye el certificado real. Si la salida termina con Congratulations, all simulated renewals succeeded, todo está correcto.
Si usas Apache detrás de un proxy reverso (HAProxy, por ejemplo) que mantiene el certificado en otra ruta, añade un deploy hook en /etc/letsencrypt/renewal-hooks/deploy/:
#!/bin/bash
cp /etc/letsencrypt/live/ejemplo.com/fullchain.pem /etc/haproxy/cert.pem
systemctl reload haproxyMárcalo como ejecutable (chmod +x). Certbot ejecuta todos los scripts de ese directorio después de cada renovación exitosa.
Verificando el certificado en producción
Después de la emisión, valida el certificado desde fuera — no basta con que Certbot diga que salió bien, necesitas confirmar que el navegador ve el sitio como seguro y que la cadena de certificación está completa.
Ejecuta en la terminal local (no en el servidor):
curl -I https://ejemplo.com
La respuesta debe empezar con HTTP/2 200 o HTTP/1.1 200 OK. Si aparece un error de certificado, algo está mal con la cadena.
Para inspeccionar el certificado en detalle:
echo | openssl s_client -connect ejemplo.com:443 -servername ejemplo.com 2>/dev/null | openssl x509 -noout -dates -issuer -subject
La salida muestra el issuer (Let's Encrypt), el subject (tu dominio) y las fechas de validez. Confirma que la fecha notAfter está ~90 días por delante.
Para una prueba completa de la configuración SSL/TLS, usa SSL Labs en https://www.ssllabs.com/ssltest/analyze.html?d=ejemplo.com. Una configuración estándar de Certbot 2.x generalmente saca nota A.
Resolución de problemas comunes
Error “Failed authorization procedure”
Significa que Let’s Encrypt no pudo acceder a http://tu-dominio/.well-known/acme-challenge/.... Causas comunes: puerto 80 bloqueado en el firewall, DNS apuntando a una IP equivocada, o Apache no escuchando en 0.0.0.0:80. Verifica en este orden:
sudo ufw status
sudo ss -tlnp | grep :80
dig +short tu-dominio.com
Error “Could not find a usable ‘apache2ctl’ binary”
Certbot busca apache2ctl en el PATH. En algunos sistemas personalizados, el binario está en /usr/sbin/ pero el PATH de snap no lo incluye. Crea el symlink:
sudo ln -s /usr/sbin/apache2ctl /usr/local/bin/apache2ctl
Redirect loop después de la instalación
Generalmente es Apache detrás de un proxy reverso (CloudFront, Cloudflare) que termina TLS antes del servidor. Apache recibe HTTP, redirige a HTTPS, el proxy envía HTTP de nuevo, loop. Solución: configura HTTPS=on vía header confiable en el vhost o deshabilita el redirect de Apache (deja que el proxy se encargue).
Próximos pasos
Con HTTPS funcionando, vale la pena endurecer la configuración TLS:
- Ajusta
SSLProtocolpara deshabilitar TLS 1.0 y 1.1 en el vhost SSL (SSLProtocol -all +TLSv1.2 +TLSv1.3) - Añade el header HSTS después de validar que todo está funcionando bien:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" - Configura OCSP stapling con
SSLUseStapling onpara reducir la latencia de la validación - Considera migrar a HTTP/2 (
Protocols h2 http/1.1) — exigemod_http2habilitado
Si estás llevando esto a producción y quieres infraestructura sin tener que preocuparte por firewall, kernel updates o tuning de Apache, una VPS Hostini viene con Ubuntu LTS, snap instalado y puertos 80/443 ya liberados — solo hace falta apuntar el DNS y ejecutar certbot --apache.
Preguntas frecuentes
¿Cuánto dura el certificado Let's Encrypt y cómo funciona la renovación?
Los certificados Let's Encrypt tienen una validez de 90 días. Certbot instala un timer de systemd (`certbot.timer`) que ejecuta `certbot renew` dos veces al día. La renovación solo hace la llamada a la API cuando el certificado está a menos de 30 días de expirar, así que ejecutarlo con frecuencia no consume el rate limit.
¿Puedo usar Let's Encrypt en un dominio sin DNS público apuntando hacia él?
No para la validación HTTP-01 (que es la que Certbot usa por defecto con `--apache`). Let's Encrypt necesita alcanzar `http://tu-dominio/.well-known/acme-challenge/...` durante la emisión. Para dominios internos, usa el desafío DNS-01 con el plugin `certbot-dns-*` apropiado para tu proveedor.
¿Cómo instalo un certificado wildcard (*.ejemplo.com) con Apache?
Los wildcards exigen el desafío DNS-01, así que el plugin `--apache` no sirve. Usa `certbot certonly --manual --preferred-challenges=dns -d '*.ejemplo.com' -d ejemplo.com` o un plugin DNS específico (`certbot-dns-cloudflare`, etc.) y configura manualmente `SSLCertificateFile` y `SSLCertificateKeyFile` en los VirtualHosts.
¿Por qué Certbot falla con 'Connection refused' durante la validación?
Generalmente es el firewall bloqueando el puerto 80, Apache no escuchando en 0.0.0.0:80, o el DNS no resolviendo a la IP del servidor. Verifica `sudo ufw status`, `sudo ss -tlnp | grep :80` y `dig +short TU-DOMINIO` antes de intentarlo de nuevo.
¿Cómo forzar HTTPS sin romper el ACME challenge de la renovación?
Certbot añade automáticamente una excepción `RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/` en el redirect cuando eliges `2 - Redirect` durante `certbot --apache`. Si editas el vhost manualmente, mantén esa excepción — sin ella, la renovación HTTP-01 falla.
¿Cuál es la diferencia entre `certbot --apache` y `certbot certonly --webroot`?
`--apache` usa el plugin que edita los vhosts automáticamente, instala el certificado y configura el redirect. `certonly --webroot` solo emite el certificado en un directorio, dejando que tú configures Apache manualmente — útil cuando tienes plantillas de configuración personalizadas o gestionas muchos sitios vía Ansible.