instalar certbot apache ubuntu 24.04
Instala Certbot 2.9.0 en Ubuntu 24.04 usando apt. Evita errores de emisión por la falta de ServerName en el vhost y configura la renovación automática.
Qué vas a construir
Un sitio Apache en Ubuntu 24.04 que responde mediante HTTPS con un certificado gratuito de Let's Encrypt confiable para el navegador. El certificado es emitido por Certbot y renovado automáticamente mediante un timer de systemd. El comando que realiza el trabajo es de una sola línea. Cualquier error ocurre antes de ejecutar esa línea: un vhost sin ServerName, el puerto 80 cerrado en el firewall del proveedor, o el DNS apuntando todavía al servidor antiguo. Por ello, esta guía se centra principalmente en los requisitos previos e indica la cadena de error exacta que imprime cada fallo.
Dos notas de alcance. Si tu servidor web es nginx, el flujo es similar pero el plugin y las configuraciones cambian; utiliza la versión para nginx de esta guía en su lugar. Si el elemento que vas a asegurar es solo para uso interno —un panel de administración en una dirección privada o un servidor de staging sin acceso externo— no necesitas una autoridad de certificación; un certificado autofirmado requiere menos componentes y funciona sin conexión.
Requisitos previos, y las tres formas en que esto falla antes de ejecutar Certbot
- Apache ya está sirviendo su sitio mediante HTTP simple. El plugin de Apache de Certbot edita un sitio existente; no crea uno nuevo. Si comienza desde un VPS vacío, instale primero el LAMP stack en Ubuntu 24.04 y regrese; esta guía es el capítulo de TLS que le falta.
- Un dominio público con un registro A apuntando a la dirección de su VPS. El desafío HTTP-01 de Let's Encrypt requiere que sus servidores de validación se conecten a su equipo desde internet: no funcionará en un homelab con NAT sin redirección de puertos, sin nombres
.local, ni con IPs directas.dig +short example.comdebe devolver la dirección de su VPS; si cambió el DNS en la última hora, espere a que expire el TTL del registro anterior antes de solicitar el certificado. - Si existe un registro AAAA, debe ser correcto. Let's Encrypt prefiere IPv6 cuando hay un registro AAAA publicado. Un registro AAAA desactualizado fallará la validación incluso si el
curldesde su laptop —probablemente por IPv4— funciona correctamente. Publique un AAAA correcto o no publique ninguno.
Los puertos 80 y 443 deben estar abiertos en ufw y en el firewall de red de su proveedor; la mayoría de los paneles de hosting tienen un segundo firewall que el sistema operativo no ve. HTTP-01 valida específicamente a través del puerto 80; no puede ejecutar esto solo con el puerto 443.
sudo ufw allow "Apache Full"
sudo ufw statusCon esto configurado, el trabajo completo toma quince minutos, y diez de ellos son de lectura.
¿Snap o apt Certbot? En 24.04, apt finalmente es una opción válida
Certbot cambió a la distribución snap hace años por una razón válida: los paquetes de las distribuciones se quedan obsoletos. Ubuntu 20.04 incluía Certbot 0.40 y nunca se actualizó, y el proyecto se cansó de depurar errores de hace cinco años. En 24.04 esa razón ya no existe: el repositorio incluye Certbot 2.9.0, una versión de generación actual, y unattended-upgrades mantiene los parches al día. Mi recomendación para este SO: usa apt. Evitas el demonio snapd, el plugin de Apache se instala en la misma transacción y el temporizador de renovación se integra con systemd de la forma estándar de Debian.
sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --versionResultado correcto: certbot 2.9.0. El paquete python3-certbot-apache es el plugin que lee y edita tus configuraciones de Apache; sin él, certbot --apache falla con The requested apache plugin does not appear to be installed.
El uso de snap sigue siendo la opción correcta en dos casos: si quieres la versión más reciente de Certbot el mismo día de su lanzamiento, o si necesitas un plugin de DNS que solo se distribuya como snap (varios de los plugins de proveedores de certbot-dns-* lo son). Si eliges ese camino:
sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotElijas lo que elijas, nunca ejecutes ambos. Dos instalaciones implican dos programadores de renovación compitiendo por /etc/letsencrypt, y el certbot que encuentre tu shell en PATH podría no ser el que gestiona tus certificados. La línea apt remove de arriba no es una decoración opcional.
Los archivos de configuración de vhost para Certbot deben existir — ServerName es fundamental
certbot --apache funciona localizando el virtual host en el puerto 80 cuyo ServerName o ServerAlias coincida con cada dominio -d proporcionado. Esto demuestra el control del dominio y permite crear una configuración SSL duplicada de dicho vhost. Si no hay coincidencia con ServerName, no habrá coincidencia. La configuración predeterminada de 000-default.conf en Ubuntu incluye ServerName comentado. Esa línea comentada es la causa principal de que el comando principal de esta guía falle.
Antes de usar Certbot, asigne un nombre basado en vhost al sitio. Cree /etc/apache2/sites-available/example.com.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>Habilítelo y confirme que Apache lo procesa y redirige el nombre hacia él:
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -Sconfigtest debe mostrar Syntax OK. Si también muestra AH00558: apache2: Could not reliably determine the server's fully qualified domain name, es una advertencia sobre el ServerName global, no sobre su vhost; no tiene impacto aquí y se silencia con echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2.
La salida de -S es la verificación importante. Debe ver una línea como port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1) con alias www.example.com debajo. Apache reporta el symlink sites-enabled que realmente leyó, no el archivo que editó en sites-available. Si example.com no aparece en el puerto 80, Certbot tampoco lo encontrará.
Emita el certificado: certbot --apache
sudo certbot --apache -d example.com -d www.example.comLa primera ejecución solicita tres datos: una dirección de correo electrónico (usada para su cuenta ACME y avisos urgentes de la CA; Let's Encrypt ya no envía advertencias de expiración, por lo que el monitoreo de las renovaciones es responsabilidad del usuario), la aceptación de los términos de Let's Encrypt, y si desea compartir su correo con la EFF. Ya no existe la pregunta sobre la redirección: desde Certbot 2.0, el instalador de Apache redirige HTTP a HTTPS por defecto, que es el comportamiento deseado. Use --no-redirect si requiere mantener HTTP para servir contenido.
El éxito se muestra de esta forma; lea el mensaje en lugar de solo escanearlo:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-10-14.
Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.comTras ese mensaje, Certbot realizó cuatro acciones: habilitó el módulo ssl de Apache si no estaba activo, escribió example.com-le-ssl.conf —una copia de su vhost en *:443 con SSLEngine on y las rutas del certificado—, lo habilitó, y añadió un bloque RewriteRule al vhost original del puerto 80 que redirige todo mediante 301 a HTTPS. El archivo vhost original se edita, no se reemplaza, y el archivo SSL duplicado se guarda junto al original para su revisión.
Ubicación real del certificado y por qué nunca debe copiarlo
Todo se almacena en /etc/letsencrypt/live/example.com/: fullchain.pem (el certificado y la cadena intermedia; lo que los servidores deben apuntar), privkey.pem (la clave privada, con permisos de lectura solo para root), además de cert.pem y chain.pem para software que requiere los archivos por separado. Estos archivos son symlinks hacia /etc/letsencrypt/archive/, y esa indirección es el mecanismo de renovación: la renovación escribe archivos nuevos en archive/ y actualiza los symlinks. Si apunta cualquier otro software a las rutas de live/, detectará las renovaciones automáticamente; si copia los archivos a otra ubicación, provocará una interrupción del servicio en 90 días.
El otro archivo relevante es /etc/letsencrypt/renewal/example.com.conf, que registra cómo se emitió este certificado — authenticator = apache, installer = apache, los dominios — para que la renovación pueda repetir el proceso de forma automática, incluyendo la recarga de Apache al finalizar.
La renovación ya está programada — verifíquela, no la cree
Los certificados de Let's Encrypt duran 90 días por diseño. El paquete apt ya instaló el mecanismo necesario: un timer de systemd que ejecuta Certbot dos veces al día en horarios aleatorios, renovando cualquier certificado que falte 30 días para su vencimiento. No añada un cron job adicional; un segundo programador solo genera ruido en los logs y riesgo de alcanzar los límites de tasa (rate-limit).
systemctl list-timers certbot.timer
sudo certbot renew --dry-runEl primer comando muestra el timer activo, con un tiempo NEXT dentro de las próximas 24 horas. El cronograma es dos veces al día con un retraso aleatorio, por lo que la hora exacta es deliberadamente impredecible (en la instalación vía snap, el timer es snap.certbot.renew.timer). El dry run realiza un simulacro de renovación completo contra el entorno de staging de Let's Encrypt: el desafío es real, pero no se emite ningún certificado ni se consume el límite de tasa. El resultado correcto termina con:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Si el dry run falla, la renovación real en ~60 días fallará de la misma manera. Corrija el error ahora, mientras el certificado actual aún tiene toda su vigencia disponible. El culpable habitual es una regla de firewall añadida después de la emisión que volvió a cerrar el puerto 80.
Verificar con curl y el estado del candado
curl -sI http://example.com | head -n 3
curl -I https://example.com
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -datesEl primero debe devolver HTTP/1.1 301 Moved Permanently con un header Location: https://example.com/; este es el redirect instalado por Certbot. El segundo debe devolver HTTP/1.1 200 OK sin errores de TLS en curl. El tercero muestra el emisor —una línea O = Let's Encrypt con un CN corto como R12 o E7— y notAfter de validez aproximada de 90 días. En un navegador aparecerá el candado, y al hacer clic se mostrará el mismo emisor. Si curl funciona pero el navegador muestra una advertencia, es probable que esté viendo una página en caché o un hostname incorrecto, no un problema de certificado.
Múltiples sitios: un certificado SAN único o un certificado por sitio
Ambos métodos funcionan y se renuevan de la misma manera. Para sitios no relacionados en el mismo equipo, ejecute el comando de emisión una vez por sitio. Cada sitio obtiene su propio directorio bajo live/ y su propia configuración de renovación; un error en un dominio no impide la renovación de los demás. Este es mi método predeterminado.
Para un sitio con varios nombres, utilice un único certificado SAN; un solo certificado puede contener hasta 100 nombres. Ya realizó esto anteriormente con example.com y www.example.com. Para añadir un nombre a un certificado existente posteriormente, emita de nuevo el certificado indicando la lista completa de nombres:
sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.comCertbot detecta el conjunto de dominios modificado, solicita confirmar la expansión y reemplaza el certificado en su ubicación original —en la misma ruta live/, por lo que no es necesario modificar nada más. Tenga en cuenta que la lista es un reemplazo, no una adición: si omite www en ese comando, el nuevo certificado eliminará dicho dominio silenciosamente.
Los comodines requieren DNS-01, y normalmente no necesitas un comodín
HTTP-01 no puede emitir *.example.com; colocar un archivo en un servidor web demuestra el control de un hostname, no de todo un namespace. Los comodines requieren el desafío DNS-01: Certbot establece un registro TXT en _acme-challenge.example.com, lo que en la práctica requiere un plugin certbot-dns-* con credenciales de API de tu proveedor de DNS, o editar manualmente los registros TXT en cada renovación con --manual (proceso tedioso; no lo planifiques así). La guía completa, desde la mecánica del registro TXT hasta un plugin para renovaciones automáticas, está en certificados wildcard con Certbot sobre DNS-01. Consejo técnico: si tienes cuatro subdominios conocidos, un certificado SAN que los liste a todos es más sencillo que un comodín y no requiere tener claves de API de DNS en el servidor.
Modos de fallo y los mensajes que verá
Certbot no inicia porque la configuración de Apache es incorrecta.
The apache plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running apache2ctl configtest.\n\nAction \'configtest\' failed.\nThe Apache error log may have more information.\n\nAH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/example.com.conf')El plugin ejecuta configtest antes de realizar cambios y aborta si Apache presenta errores; los \n son literales porque Certbot imprime el repr de la excepción. Ejecute sudo apache2ctl configtest para identificar el archivo y la línea; suele ser un error tipográfico por edición manual, un SSLCertificateFile que apunta a una ruta inexistente o un módulo referenciado pero no habilitado. Corrija el error hasta que se imprima Syntax OK y vuelva a ejecutar Certbot.
Ningún vhost coincide con el dominio.
Unable to find a virtual host listening on port 80 which is currently the only challenge port.Este es el fallo por falta de ServerName mencionado anteriormente, detectado durante la emisión. Certbot buscó en todos los vhost habilitados en el puerto 80 un ServerName/ServerAlias que coincidiera con su -d y no encontró nada. sudo apache2ctl -S muestra el enrutamiento real de Apache; añada la línea ServerName al vhost correcto, recargue y reintente. Un error similar es cuando la validación llega al vhost incorrecto: la respuesta del challenge regresa como Invalid response ... 404 porque otro sitio capturó la solicitud. El diagnóstico y la herramienta son los mismos: apache2ctl -S.
La validación agota el tiempo de espera (timeout).
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)Let's Encrypt no pudo abrir una conexión TCP al puerto 80 en la dirección que anuncia su DNS. En orden de probabilidad: el firewall de red de su proveedor (distinto a ufw, configurado en el panel de hosting), un conjunto de reglas de ufw que solo permite el puerto 443 o SSH, el DNS que aún apunta a un servidor anterior, o el problema de registros AAAA obsoletos (sus servidores intentan IPv6, pero su servidor solo responde en IPv4). Pruebe desde fuera del VPS: ejecutar curl -I http://example.com desde su laptop reproduce lo que ve el validador.
Los reintentos han causado un límite de tasa (rate limit).
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/Let's Encrypt permite 5 validaciones fallidas por hostname, por cuenta y por hora. Tras la reestructuración de límites de 2025, funciona como un cubo que se llena: recupera capacidad de reintento aproximadamente cada 12 minutos. Realizar reintentos constantes contra un firewall bloqueado consume este límite rápidamente. Esperar funciona, pero la solución real es cambiar el método: tras cualquier fallo, depure con el entorno de staging hasta que tenga éxito.
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comObserve el certonly: --dry-run solo es aceptado por los subcomandos certonly y renew; la forma simple certbot --apache --dry-run no se ejecutará y le indicará --dry-run currently only works with the 'certonly' or 'renew' subcommands. El modo dry run valida contra staging, que tiene límites más amplios y no emite certificados reales, permitiendo múltiples intentos fallidos. Solo ejecute el comando real cuando staging sea exitoso. Los otros límites —50 certificados por dominio registrado por semana, 5 duplicados del mismo conjunto de nombres por semana— solo se alcanzarán si un script está reemitiendo en un bucle.
Una vez que HTTPS esté operativo, recuerde que el certificado asegura el transporte, no el servidor: el puerto 22 sigue recibiendo intentos de contraseña. Combinar esto con Fail2ban en Ubuntu 24.04 es el siguiente paso lógico.
FAQ
¿Debo instalar Certbot con snap o apt para Apache en Ubuntu 24.04?
Use apt. Ubuntu 24.04 incluye Certbot 2.9.0, que es suficiente para todo lo contenido en esta guía, recibe parches de seguridad a través de unattended-upgrades y no requiere snapd. Elija snap solo si necesita la versión más reciente de inmediato o un plugin de DNS distribuido exclusivamente como snap; si decide cambiar, ejecute apt remove certbot python3-certbot-apache primero para evitar la coexistencia de dos programadores de renovación.
¿Por qué Certbot indica "Unable to find a virtual host listening on port 80"?
Porque ningún vhost habilitado en el puerto 80 tiene un ServerName o ServerAlias que coincida con el dominio pasado con -d. El vhost por defecto de Ubuntu tiene ServerName comentado. Ejecute sudo apache2ctl -S, localice (o cree) el vhost que debe gestionar ese nombre, añada ServerName example.com, recargue Apache y vuelva a ejecutar Certbot.
¿Cómo soluciono "Timeout during connect (likely firewall problem)"?
Let's Encrypt no pudo alcanzar el puerto 80 en la dirección publicada por su DNS. Verifique el firewall de red en el panel de su proveedor y también ufw. Confirme que dig +short example.com devuelva la IP de su VPS y elimine o corrija cualquier registro AAAA obsoleto; la validación prioriza IPv6 si este existe. Verifique la solución desde fuera del servidor con curl -I http://example.com y realice una prueba con sudo certbot certonly --apache --dry-run -d example.com antes de la emisión real.
¿Certbot renueva los certificados automáticamente en Ubuntu 24.04?
Sí. El paquete apt instala certbot.timer, un timer de systemd que se ejecuta dos veces al día y renueva cualquier certificado con menos de 30 días para su vencimiento, recargando Apache después; la versión snap utiliza snap.certbot.renew.timer para la misma tarea. Verifique con systemctl list-timers certbot.timer y realice una prueba con sudo certbot renew --dry-run; no añada su propio cron job adicional.
¿Cómo obtengo un certificado wildcard con Certbot y Apache?
Los certificados wildcard requieren el desafío DNS-01: Certbot debe colocar un registro TXT en _acme-challenge.example.com. Esto requiere un plugin certbot-dns-* con credenciales de API de su proveedor de DNS (la alternativa --manual requiere editar manualmente los registros TXT en cada renovación). Si solo tiene unos pocos subdominios conocidos, un certificado SAN que los liste explícitamente es más sencillo y evita almacenar claves de API de DNS en el servidor.