Let’s Encrypt es una Autoridad de Certificación (CA) que facilita la obtención e instalación de certificados TLS/SSL gratuitos, permitiendo así el cifrado HTTPS en servidores web. Con la herramienta Certbot, se puede automatizar la mayoría (si no todos) de los pasos necesarios. Actualmente, todo el proceso de obtención e instalación de un certificado está totalmente automatizado tanto en Apache como en Nginx.
En esta guía, utilizaremos Certbot para obtener un certificado SSL gratuito para Apache en Ubuntu 22.04, y nos aseguraremos de que este certificado está configurado para renovarse automáticamente.
Requisitos previos
- Un servidor Ubuntu 22.04 configurado con un usuario no root con privilegios administrativos
sudo
y firewall activado. Para ello, puedes leer nuestra guía Configuración básica de un VPS. - Un nombre de dominio registrado. Este tutorial utilizará tu_dominio.com como ejemplo, pero debes sustituirlo por tu propio nombre de dominio.
- Un servidor Apache instalado. Puedes leer el Paso 1 de nuestra guía Cómo instalar LAMP en Ubuntu 22.04.
Paso 1 – Configurar registros DNS
Tenemos que iniciar sesión en la web donde tengamos registrado nuestro dominio, e ir a la sección Gestión de DNS. Nos asegurarnos de que tanto tu_dominio.com como www.tu_dominio.com apuntan a la IP de nuestro servidor, creando dos registros A de la siguiente manera:
Hay que tener en cuenta que cualquier cambio que realicemos en los registros DNS, estos pueden tardar hasta 48 horas en propagarse.
Paso 2 – Configurar un host virtual
Por defecto, Apache está configurado para servir documentos desde el directorio /var/www/html
. Aunque esto funciona bien para un solo sitio, puede llegar a ser difícil de manejar si estamos alojando varios sitios. En lugar de modificar /var/www/html
, creamos una estructura de directorios dentro de /var/www
para el sitio tu_dominio.com, dejando /var/www/html
en su lugar como el directorio predeterminado que se servirá si la solicitud de un cliente no coincide con ningún otro sitio.
Creamos el directorio tu_dominio.com de la siguiente manera:
$ sudo mkdir /var/www/tu_dominio.com
A continuación, asignamos como propietario del directorio al usuario con el que hemos iniciado sesión mediante la variable de entorno $USER
:
$ sudo chown -R $USER:$USER /var/www/tu_dominio.com
Configuramos los permisos necesarios de lectura|escritura|ejecución para nuestro usuario|grupos|otros usuarios, con el siguiente comando:
$ sudo chmod -R 755 /var/www/tu_dominio.com
Dentro de este directorio, creamos un archivo index.html
con el siguiente contenido:
<html> <head> <meta charset="utf-8"/> <title>Bienvenido a Tu_Dominio.com</title> </head> <body> <h1>¡El host virtual tu_dominio.com funciona correctamente!</h1> </body> </html>
Para que Apache pueda servir este contenido, es necesario crear un fichero de host virtual con las directivas correctas. En lugar de modificar directamente el archivo de configuración por defecto ubicado en /etc/apache2/sites-available/000-default.conf
, creamos uno nuevo en /etc/apache2/sites-available/tu_dominio.com.conf
:
$ sudo nano /etc/apache2/sites-available/tu_dominio.com.conf
Añadimos el siguiente bloque de configuración, que es similar al predeterminado, pero actualizado para nuestro nuevo directorio y nombre de dominio:
<VirtualHost *:80> ServerAdmin webmaster@localhost ServerName tu_dominio.com ServerAlias www.tu_dominio.com DocumentRoot /var/www/tu_dominio.com ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Hemos actualizado el DocumentRoot
a nuestro nuevo directorio y el ServerAdmin
a un email al que el administrador del sitio tu_dominio.com pueda acceder. También hemos añadido dos directivas: ServerName
, que establece el dominio base que coincidirá con esta definición de host virtual, y ServerAlias
, que define otros nombres que serán tratados igual que si fueran el nombre base.
Ahora habilitamos el archivo con la herramienta a2ensite
:
$ sudo a2ensite tu_dominio.com.conf
Desactivamos el sitio por defecto definido en 000-default.conf
:
$ sudo a2dissite 000-default.conf
A continuación, comprobamos si hay errores de configuración:
$ sudo apache2ctl configtest
Output
. . .
Syntax OK
Reiniciamos Apache para aplicar los cambios:
$ sudo systemctl restart apache2
Apache estará ahora sirviendo nuestro nombre de dominio. Podemos probar esto navegando a http://tu_dominio.com, donde veremos algo como lo siguiente:
Paso 3 – Instalar Certbot
Para obtener un certificado SSL con Let’s Encrypt, necesitamos instalar el software Certbot en nuestro servidor. Para ello, utilizaremos los repositorios de paquetes predeterminados de Ubuntu.
Primero, actualizamos el índice de paquetes local:
$ sudo apt update
Necesitamos dos paquetes: certbot
, y python3-certbot-apache
. Este último es un plugin que integra Certbot con Apache, haciendo posible automatizar la obtención de un certificado y la configuración de HTTPS dentro de nuestro servidor web con un solo comando:
$ sudo apt install certbot python3-certbot-apache
Ahora Certbot está instalado en nuestro servidor.
Paso 4 – Permitir el tráfico HTTPS a través del cortafuegos
Tras la instalación, Apache registra diferentes perfiles de aplicación UFW. Podemos aprovechar el perfil Apache Full para permitir tanto el tráfico HTTP como HTTPS en snuestro servidor:
$ sudo ufw allow 'Apache Full'
Si teníamos activado el perfil «Apache», podemos eliminarlo ya que es redundante:
$ sudo ufw delete allow 'Apache'
Nuestro estado quedaría de la siguiente manera:
$ sudo ufw status
Output
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Apache Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Apache Full (v6) ALLOW Anywhere (v6)
Ahora estamos listos para ejecutar Certbot y obtener nuestros certificados SSL.
Paso 5 – Obtener certificados SSL
Certbot proporciona varias formas de obtener certificados SSL a través de plugins. El plugin de Apache se encargará de reconfigurar Apache y recargar la configuración siempre que sea necesario. Para utilizar este plugin, ejecutamos lo siguiente:
$ sudo certbot --apache
Este script nos pedirá que respondamos a una serie de preguntas para configurar nuestro certificado SSL. En primer lugar, nos pedirá una dirección de correo electrónico válida. Este correo electrónico se utilizará para notificaciones de renovación y avisos de seguridad:
Output Saving debug log to /var/log/letsencrypt/letsencrypt.log Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): you@your_domain
Después de proporcionar una dirección de correo electrónico válida, pulsamos ENTER
para continuar con el siguiente paso. Nos pedirá que confirmemos si aceptamos los términos de servicio de Let’s Encrypt, pulsando Y
y después ENTER
:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
A continuación, nos pregunta si deseamos compartir nuestro correo electrónico con la Electronic Frontier Foundation para recibir noticias y otra información. Si no quieres suscribirte a sus contenidos, escribe N
. En caso contrario, escribe Y
y pulsa ENTER
para pasar al siguiente paso:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: N
El siguiente paso nos pedirá que informemos a Certbot de los dominios para los que deseamos activar HTTPS. Los nombres de dominio de la lista se obtienen automáticamente de la configuración de nuestro host virtual Apache, por lo que es importante asegurarnos de tener configurados los parámetros ServerName
y ServerAlias
correctos en nuestro host virtual.
Para habilitar HTTPS a todos los nombres de dominio de la lista (recomendado), dejamos la pregunta en blanco y pulsamos ENTER
para continuar (si deseas habilitar HTTPS solamente a algunos de los dominios, introduce el número correspondiente, separado por comas y/o espacios, luego presiona ENTER
):
Which names would you like to activate HTTPS for? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: tu_dominio.com 2: www.tu_dominio.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel):
Después de este paso, la configuración de Certbot ha terminado, y se presentarán las observaciones finales sobre nuestro nuevo certificado y dónde localizar los archivos generados:
Output Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/tu_dominio.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/tu_dominio.com/privkey.pem This certificate expires on 2022-07-10. These files will be updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in the background. Deploying certificate Successfully deployed certificate for tu_dominio.com to /etc/apache2/sites-available/tu_dominio.com-le-ssl.conf Successfully deployed certificate for www.tu_dominio.com to /etc/apache2/sites-available/tu_dominio.com-le-ssl.conf Congratulations! You have successfully enabled HTTPS on https:/tu_dominio.com and https://www.tu_dominio.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - If you like Certbot, please consider supporting our work by: * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate * Donating to EFF: https://eff.org/donate-le - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nuestro certificado está ahora instalado y cargado en la configuración de Apache. Si recargamos nuestro sitio web utilizando https://
podemos observar el indicador de seguridad del navegador. Debería indicar que el sitio está correctamente protegido, normalmente mediante un icono de candado en la barra de direcciones.
Paso 6 – Verificar la renovación automática de Certbot
Los certificados de Let’s Encrypt sólo son válidos durante noventa días. Esto es para animar a los usuarios a automatizar su proceso de renovación de certificados, así como para asegurar que los certificados mal utilizados o las claves robadas caduquen más pronto que tarde.
El paquete certbot
que hemos instalado es capaz de realizar las renovaciones gracias a un script incluido en /etc/cron.d
, que es gestionado por un servicio systemctl
llamado certbot.timer
. Este script se ejecuta dos veces al día y renovará automáticamente cualquier certificado que esté a menos de treinta días de caducar.
Para comprobar el estado de este servicio y asegurarnos de que está activo, ejecutamos lo siguiente:
$ sudo systemctl status certbot.timer
Output
● certbot.timer - Run certbot twice daily
Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset:>
Active: active (waiting) since Mon 2022-04-11 20:52:46 UTC; 4min 3s ago
Trigger: Tue 2022-04-12 00:56:55 UTC; 4h 0min left
Triggers: ● certbot.service
Apr 11 20:52:46 jammy-encrypt systemd[1]: Started Run certbot twice daily.
Para probar el proceso de renovación, podemos realizar un simulacro con certbot
:
$ sudo certbot renew --dry-run
Output
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/tu_dominio.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for tu_dominio.com and www.tu_dominio.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/tu_dominio.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Si no aparece ningún error, ya está todo listo. Cuando sea necesario, Certbot renovará nuestros certificados y recargará Apache para aplicar los cambios. Si el proceso de renovación automática falla alguna vez, Let’s Encrypt enviará un mensaje al correo electrónico que hayamos especificado, avisándonos de que nuestro certificado está a punto de caducar.
Paso 7 – Redirigir WWW a no-WWW
Tras instalar el certificado SSL con Certbot, podemos ver que la configuración de nuestro host virtual ha cambiado, haciendo que todo el trafico HTTP sea redirigido a HTTPS:
$ sudo cat /etc/apache2/sites-available/tu_dominio.com.conf
<VirtualHost *:80>
ServerName tu_dominio.com
ServerAlias www.tu_dominio.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/tu_dominio.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.tu_dominio.com [OR]
RewriteCond %{SERVER_NAME} =tu_dominio.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Esto está muy bien en cuanto a seguridad y SEO, pero nuestro sitio se sirve tanto desde https://tu_dominio.com como desde https://www.tu_dominio.com, y esto puede llegar a ser un problema, ya que los buscadores indexarían nuestro contenido por duplicado.
Para servir únicamente la versión https://tu_dominio.com, debemos modificar el archivo sustituyendo la línea RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
por RewriteRule ^ https://tu_dominio.com%{REQUEST_URI} [END,NE,R=permanent]
, quedando el archivo de la siguiente manera:
$ sudo cat /etc/apache2/sites-available/tu_dominio.com.conf
<VirtualHost *:80>
ServerName tu_dominio.com
ServerAlias www.tu_dominio.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/tu_dominio.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.tu_dominio.com [OR]
RewriteCond %{SERVER_NAME} =tu_dominio.com
RewriteRule ^ https://tu_dominio.com%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Una vez guardados los cambios, también debemos modificar el archivo del host virtual SSL /etc/apache2/sites-available/tu_dominio.com-le-ssl.conf
añadiendo las siguientes líneas justo antes de </VirtualHost>
:
RewriteEngine onRewriteCond %{SERVER_NAME} =www.tu_dominio.comRewriteRule ^ https://tu_dominio.com%{REQUEST_URI} [END,NE,R=permanent]
De manera que el archivo quede así:
$ sudo nano /etc/apache2/sites-available/tu_dominio.com-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName tu_dominio.com
ServerAlias www.tu_dominio.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/tu_dominio.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/tu_dominio.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/tu_dominio.com/privkey.pem
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.tu_dominio.com
RewriteRule ^ https://tu_dominio.com%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
</IfModule>
Una vez guardados los cambios, recargamos Apache:
$ sudo systemctl reload apache2
¡Atención! Si vas a usar WordPress, asegúrate de configurar la versión de dominio preferida en WordPress Address y Site Address antes de editar los archivos de host virtual de Apache. Si los ajustes de WordPress contradicen la configuración de Apache, tu sitio estará en un bucle de redirección.