--- title: Securizar Apache con mod_md y Let’s Encrypt author: Daniel A. Rodriguez date: 2020-12-19 --- # Securizar Apache con mod_md y Let’s Encrypt Apache incluye un módulo llamado [**mod_md**](https://github.com/icing/mod_md). Podemos usarlo para el aprovisionamiento de certificados a través del [**protocolo ACME**](https://www.ssl.com/es/faqs/que-es-el-protocolo-acme/). Este artículo explica cómo instalar, configurar y poner en marcha Apache con un módulo mod_md para asegurar el tráfico con el certificado gratuito Let’s Encrypt TLS/SSL en un servidor Debian. `mod_md` hace dos cosas: * Proporciona certificados SSL para sus dominios desde Let's Encrypt (u otra autoridad certificadora que admita el protocolo ACME). * Ofrece un sólido OCSP Stapling de certificados SSL, lo cual es importante para una carga rápida de las páginas en los navegadores modernos. Ambas funciones trabajan bien juntas, pero se puede utilizar una sin la otra. Let’s Encrypt es una Autoridad de Certificación (CA) que emplea el protocolo ACME. Es posible usar Let’s Encrypt para emitir certificados TLS/SSL gratuitos para Apache, Nginx y otros servidores. En este tutorial, usarás mod_md para obtener un certificado TLS/SSL gratuito para Apache en Debian y configurarás tu certificado para que se renueve automáticamente también. Nuestro ejemplo de configuración es el siguiente: * Dominio – www.dominio.edu.ar * Puerto HTTPS – 443 * Archivo de configuración del host virtual – /etc/apache2/sites-available/www.dominio.edu.ar.conf ## Instalar mod_md para Let’s Encrypt En primer lugar resulta necesario aclarar que el soporte para la versión 2 del protocolo ACME se incorpora con la versión **2.4.41** de Apache httpd. Podemos verificar la versión instalada con: ```bash $ apache2 -v ``` ó ```bash $ apachectl -v ``` Entonces, si la versión es menor a la indicada resulta imprescindible actualizar Apache. Instalamos Apache y mod_md: ```bash apt install apache2 libapache2-mod-md ``` Habilitamos los módulos md y ssl: ```bash a2enmod md ssl ``` Para activar la nueva configuración es necesario reiniciar apache ```bash systemctl reload apache2 ``` ## Configurar el certificado SSL Verificamos que Apache está escuchando en el puerto 80: ```bash # netstat -tulpn | grep ':80' tcp6 0 0 :::80 :::* LISTEN 323897/apache2 ``` ó ```bash # ss -tulpn | grep ':80' tcp LISTEN 0 511 *:80 *:* users:(("apache2",pid=4002583,fd=4),("apache2",pid=323899,fd=4),("apache2",pid=323898,fd=4),("apache2",pid=323897,fd=4)) ``` Todos los clientes deben conectarse al servidor a través del puerto 80. De lo contrario, no será validado para el certificado Let’s Encrypt. Desde tu escritorio, ejecuta: ```bash curl -I http://www.dominio.edu.ar ``` La salida del comando curl valida que podemos conectarnos al puerto 80 TCP: ```bash HTTP/1.1 200 OK Date: Sat, 19 Dic 2020 12:45:43 GMT Server: Apache/2.4.46 (Debian) Last-Modified: Wed, 06 May 2020 19:15:29 GMT ETag: "15e-5a4ff965902a3" Accept-Ranges: bytes Content-Length: 350 Vary: Accept-Encoding Connection: close Content-Type: text/html ``` Creamos el archivo de configuración para md ```bash nano /etc/apache2/conf-available/md.conf ``` Agregamos las directivas mínimas necesarias ```bash # Habilitamos los dominios que serán administrados MDomain dominio.edu.ar www.dominio.edu.ar # Agree to the Let’s Encrypt terms of service MDCertificateAgreement accepted # Optional: where certs/keys are stored (default: /var/lib/apache2/md) MDStoreDir /var/lib/apache2/md MDPrivateKeys RSA 4096 # Correo de contacto para el registro MDDefaultContacts "mailto:admin@dominio.edu.ar" # Autoridad de certificación MDCA "https://acme-v02.api.letsencrypt.org/directory" MDRequireHttps permanent # Subdominios MDomain sub1.dominio.edu.ar MDomain sub2.dominio.edu.ar MDomain sub3.dominio.edu.ar SetHandler md-status Require ip 127.0.0.1 ``` Donde, * **MDDefaultContacts administrador@dominio.edu.ar**: Disponible desde Apache **≥ 2.4.40**. `mod_md` usará esta dirección al registrar tu dominio con la Autoridad de Certificación. Hasta Apache **≤ 2.4.35** se utilizaba la forma `MDContactEmail admin@dominio.edu.ar`. Es posible definir contactos distintos por dominio. * **MDCA**: Disponible desde Apache **≥ 2.4.48**. Indica el endpoint de la Autoridad de Certificación. Hasta Apache **≤ 2.4.43** se utilizaba la forma `MDCertificateAuthority https://acme-v02.api.letsencrypt.org/directory`. Es posible utilizar `https://acme.zerossl.com/v2/DV90`, pero implica registro de cuenta en ZeroSSL. * **MDCertificateAgreement accepted**: Es necesario aceptar las condiciones del [Acuerdo de suscripción](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf) * **MDomain www.dominio.edu.ar**: Declarar un nombre de dominio que debe ser administrado por mod_md para emitir y renovar certificados. Se puede usar un nombre de dominio completo como www.dominio.edu.ar o dominio.edu.ar. Asegúrate de que coincide con ServerAlias. * **MDPrivateKeys RSA 4096**: Establece el tipo y el tamaño de las claves privadas generadas. * **MDRequiereHttps**: Fuerza la redirección a HTTPS Opcional, * **MDRenewWindow** : Si no se especifica, el valor predeterminado es 33%. Si la validez de los certificados cae por debajo de la duración especificada, mod_md obtendrá nuevos certificados. Cada certificado tiene una validez de 90 días, el 33% son 30 días. Para establecerlo por días, especifique `d`. Habilitamos el módulo ```bash a2enconf md ``` Editamos /etc/apache2/sites-available/www.dominio.edu.ar.conf: ```bash # En caso que no hayamos definido subdominio en la configuración de mod_md, descomentar esta linea. # MDomain ventana.edu.ar # Y la siguiente es para tener un contacto específico para este dominio # MDDefaultContacts "mailto:ventana@midominio.edu.ar" ServerName dominio.edu.ar SSLEngine on Protocols h2 http/1.1 DocumentRoot /var/www/dominio.edu.ar Options FollowSymLinks AllowOverride All Require all granted ErrorLog ${APACHE_LOG_DIR}/error_dominio.edu.ar.log CustomLog ${APACHE_LOG_DIR}/access_dominio.edu.ar.log combined ``` Para incrementar el nivel de seguridad, y dado que muchas prácticas de TLS/SSL evolucionan rápido, siempre se recomienda verificar que la configuración de nuestro servidor usando las [**recomendaciones de Mozilla**](https://ssl-config.mozilla.org/) o [**SSL Labs Best Practices**](https://www.ssllabs.com/projects/best-practices/). ## Activar mod_rewrite y mod_headers de Apache Ya hemos declarado una regla de reescritura en nuestra configuración, así que necesitamos varios módulos. Por lo tanto: ```bash a2enmod rewrite headers md http2 To activate the new configuration, you need to run: systemctl restart apache2 ``` ## Comprobamos si hay errores de configuración ```bash apache2ctl configtest Syntax OK ``` ## Obtener un certificado SSL usando mod_md Hasta ahora, instalamos el mod_md para Apache, habilitamos todos los módulos esenciales. Es hora de reiniciar nuestro servidor Apache para obtener el certificado TLS/SSL. ```bash systemctl restart apache2 ``` Tan pronto como Apache 2 se reinicie, mod_md solicitará un certificado para el dominio a la Autoridad de Certificación. Normalmente tarda hasta un minuto. Se puede comprobar el registro de errores del servidor o la página de mod_status de Apache para ver si la petición ha sido satisfactoria o no. Esto lo que muestra archivo error.log: ```bash tail -f /var/log/apache2/error.log ``` También puedes usar el comando grep: ```bash grep 'The Managed Domain' /var/log/apache2/error.log ``` El siguiente ejemplo indica que LE nos ha expedido un certificado gratuito de TLS/SSL: ```bash [Wed Dic 19 10:17:38.112849 2020] [md:notice] [pid 21777:tid 139807872861952] AH10059: The Managed Domain www.dominio.edu.ar has been setup and changes will be activated on next (graceful) server restart. Por supuesto que también podemos visitar la url estado del servidor. ``` Reiniciamos el servidor Apache 2 para activar el certificado: ```bash systemctl reload apache2 ``` ## Probar la conexión segura de Apache Todo lo que tienes que hacer es escribir el siguiente comando o usar un navegador web para asegurarte de que estás recibiendo una conexión HTTPS: ```bash curl -I https://www.dominio.edu.ar ``` Otra alternativa es utilizar el [**servicio de prueba de servidores de SSL Labs**](https://www.ssllabs.com/ssltest/index.html). ## Monitoreo de estado de certificados Ahora que configuramos Apache con mod_md y conseguimos un certificado TLS/SSL, es hora de monitorear el estado de nuestro certificado. ```bash https://www.dominio.edu.ar/server-status ``` ó ```bash curl https://www.dominio.edu.ar/md-status ``` ```bash { "version": "2.4.45", "managed-domains": [ { "name": "www.dominio.edu.ar", "domains": [ "www.dominio.edu.ar", "web.dominio.edu.ar" ], "contacts": [ "mailto:administrador@dominio.edu.ar" ], "transitive": 1, "ca": { "proto": "ACME", "url": "https://acme-v02.api.letsencrypt.org/directory", "agreement": "accepted" }, "state": 2, "renew-mode": 1, "renew-window": "33%", "warn-window": "10%", "must-staple": false, "cert": { "valid-from": "Wed, 19 Dec 2020 12:17:37 GMT", "valid-until": "Tue, 19 Mar 2021 12:17:37 GMT", "serial": "040E339A0A7D2224819A550BBB4596279F67", "sha256-fingerprint": "d78933fa946cb71810111876049defa4feb6820c319c69918ba925b463bbd11c" }, "renew": false } ] } ``` ## ¿Dónde están mis archivos de certificados TLS/SSL? Es necesario listar el contenido del directorio **/etc/apache2/md**: ```bash # ls -l /etc/apache2/md/ ``` Veremos los archivos de la siguiente manera: ```bash total 76K drwxr-xr-x 9 root root 4,0K sep 11 14:01 . drwxr-xr-x 9 root root 4,0K sep 10 19:44 .. drwxr-xr-x 3 root root 4,0K dic 19 2020 accounts drwx------ 716 root root 36K oct 14 00:00 archive drwxr-xr-x 2 www-data root 4,0K oct 13 16:56 challenges drwx------ 25 root root 4,0K oct 14 00:00 domains -rw------- 1 root root 116 dic 19 2020 md_store.json drwxr-x--- 2 www-data root 4,0K dic 19 2020 ocsp drwxr-xr-x 5 www-data root 4,0K oct 14 00:00 staging drwx------ 35 root root 4,0K oct 14 00:00 tmp ``` Listamos el directorio de dominios: ```bash # ls -l /etc/apache2/md/www.dominio.edu.ar ``` Aquí están los archivos TLS/SSL para tu dominio: ```bash total 28K drwx------ 2 root root 4,0K sep 11 13:56 . drwx------ 25 root root 4,0K oct 14 00:00 .. -rw------- 1 root root 7,5K sep 10 16:54 job.json -rw------- 1 root root 744 sep 11 13:56 md.json -rw------- 1 root root 3,2K sep 10 16:54 privkey.pem -rw------- 1 root root 3,9K sep 10 16:54 pubcert.pem ``` ## Generador de configuración SSL de moz://a [En este enlace](https://mozilla.github.io/server-side-tls/ssl-config-generator) podrás obtener los detalles de configuración necesarios para tu sistema. Solo deberás escoger el tipo de servidor web, su versión y la del certificado OpenSSL.