Configuración de Apache con soporte SSL/TLS.

Autor: Joel Barrios Dueñas
Correo electrónico: darkshram en gmail punto com
Sitio de Red: https://www.alcancelibre.org

Licencia Creative Commons
© 1999-2026 Joel Barrios Dueñas. Este manual se distribuye bajo la licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional (CC BY-NC-SA 4.0). Usted es libre de compartir y adaptar el material bajo los siguientes términos: debe dar crédito al autor, no puede utilizarlo para fines comerciales y debe compartir las obras derivadas bajo la misma licencia. La licencia completa está disponible en https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.es.

Introducción.

La seguridad en las comunicaciones web es fundamental en la Internet moderna. Este manual complementa la «Configuración básica de Apache» y detalla los pasos para habilitar el protocolo HTTPS, garantizando la confidencialidad e integridad de los datos intercambiados entre el servidor y los clientes. Se cubren desde los conceptos teóricos hasta la configuración práctica, incluyendo la generación de certificados y el uso de herramientas de automatización.

Acerca de HTTPS.

HTTPS es la versión segura del protocolo HTTP, inventada en 1996 por Netscape Communications Corporation. Es un protocolo dependiente de HTTP, consistiendo en una combinación de éste con un mecanismo de transporte SSL o TLS, garantizando así una protección razonable durante la comunicación cliente-servidor. Se utiliza ampliamente en la red mundial (WWW) para operaciones sensibles como transacciones bancarias y pago de bienes y servicios.

El servicio utiliza el puerto 443 por TCP para realizar las comunicaciones (a diferencia del puerto 80 usado por HTTP). El esquema URI (Uniform Resource Identifier o Identificador Uniforme de Recursos) es, comparando sintaxis, idéntico al de HTTP, utilizándose como «https:» seguido del subconjunto denominado URL (Uniform Resource Locator o Localizador Uniforme de Recursos). Ejemplo: https://www.empresa.com.mx/

URL: https://es.wikipedia.org/wiki/HTTPS y http://wp.netscape.com/eng/ssl3/draft302.txt

Acerca de RSA.

RSA, acrónimo de los apellidos de sus autores, Ron Rivest, Adi Shamir y Len Adleman, es un algoritmo para el cifrado de claves públicas que se publicó en 1977 y se patentó en EE.UU. en 1983 por el Instituto Tecnológico de Michigan (MIT). RSA se utiliza ampliamente en todo el mundo para los protocolos destinados al comercio electrónico.

URL: https://es.wikipedia.org/wiki/RSA

Acerca de Triple DES.

Triple DES o TDES, es un algoritmo que realiza un triple cifrado DES, desarrollado por IBM en 1978. Su origen tuvo como finalidad aumentar la longitud de una clave sin necesidad de cambiar el algoritmo de cifrado, lo cual lo hace más seguro que el algoritmo DES, obligando a un atacante a triplicar el número de operaciones para poder hacer daño. A pesar de que actualmente está siendo reemplazado por el algoritmo AES (Advanced Encryption Standard, también conocido como Rijndael), sigue siendo estándar para las tarjetas de crédito y operaciones de comercio electrónico.

URL: https://es.wikipedia.org/wiki/Triple_DES

Acerca de X.509.

X.509 es un estándar ITU-T (estandarización de Telecomunicaciones de la International Telecommunication Union) para infraestructura de claves públicas (PKI o Public Key Infrastructure). Entre otras cosas, establece los estándares para certificados de claves públicas y un algoritmo para validación de ruta de certificación. Este último se encarga de verificar que la ruta de un certificado sea válida bajo una infraestructura de clave pública determinada ―es decir, desde el certificado inicial, pasando por certificados intermedios, hasta el certificado de confianza emitido por una Autoridad Certificadora (CA o Certification Authority).

URL: https://es.wikipedia.org/wiki/X.509

Acerca de OpenSSL.

OpenSSL es una implementación libre, de código abierto, de los protocolos SSL (Secure Sockets Layer o Nivel de Zócalo Seguro) y TLS (Transport Layer Security o Seguridad para Nivel de Transporte). Está basado sobre el extinto proyecto SSLeay, iniciado por Eric Young y Tim Hudson.

URL: https://www.openssl.org

Acerca de mod_ssl.

Mod_ssl es un módulo para el servidor HTTP Apache, el cual provee soporte para SSL versiones 2 y 3 y TLS versión 1. Es una contribución de Ralf S. Engeschall, derivado del trabajo de Ben Laurie.

URL: https://httpd.apache.org/docs/2.4/mod/mod_ssl.html

Requisitos.

Es necesario disponer de una dirección IP pública para cada sitio de red virtual que se quiera configurar con soporte SSL/TLS. Debido a la naturaleza de estos protocolos, es imposible utilizar múltiples anfitriones virtuales con soporte SSL/TLS compartiendo una misma dirección IP. Cada certificado utilizado requerirá una dirección IP independiente en el anfitrión virtual. Como alternativa, se puede optar por conseguir un certificado multi-dominio (SAN) o un certificado tipo comodín (wildcard), los cuales permiten servir varios nombres de dominio bajo una misma IP, simplificando la gestión a costa de consideraciones de seguridad específicas.

El paquete mod_ssl instala el archivo /etc/httpd/conf.d/ssl.conf. Es innecesario modificar este archivo directamente si se utilizan archivos de inclusión con extensión .conf dentro del directorio /etc/httpd/conf.d/. Este método se recomienda para preservar la configuración predeterminada y disponer de un punto de retorno en caso de problemas, limitándose sólo a modificar las opciones del archivo ssl.conf para configurar las rutas del certificado y la firma digital.

Modificaciones necesarias en el muro cortafuegos (firewall).

Es necesario abrir ―además del puerto 80― el puerto 443 por TCP (https). Configure el muro cortafuegos como se describe en el documento «Configuración básica de Apache».

firewall-cmd --add-service=https --permanent
firewall-cmd --reload

Equipamiento lógico (software) necesario.

El módulo mod_ssl es el componente esencial para habilitar HTTPS en Apache.

En AlmaLinux, Rocky Linux y Red Hat™ Enterprise Linux.

dnf -y install mod_ssl

En ALDOS y sistemas que utilicen yum.

yum -y install mod_ssl

Procedimientos.

Esta sección guía a través de la generación de certificados, la configuración de Apache para un dominio único y múltiples dominios, y la automatización del proceso mediante Certbot.

Generando firma digital y certificado.

Acceda al sistema como root.

Durante los siguientes procedimientos se utilizará el comando `hostname` para calcular automáticamente el nombre de anfitrión del servidor. Ejecute lo siguiente para verificar cuál es el nombre de anfitrión del sistema, el cual se utilizará automáticamente en el nombre de los archivos de certificados y firmas digitales.

De existir, elimine los archivos de certificados y firmas digitales previos.

rm -f /etc/pki/tls/*/$(hostname).*

Cree una clave con algoritmo RSA de 4096 octetos y estructura x509, la cual se cifra utilizando Triple DES (Data Encryption Standard), almacenada en formato PEM de modo que sea interpretable como texto ASCII. Se solicitará una contraseña para asignar a la firma digital; se recomienda utilizar una contraseña robusta y compleja.

openssl genrsa -des3 \
    -out /etc/pki/tls/private/$(hostname).key 4096

Si se utiliza el archivo .key para la configuración del anfitrión virtual, se requerirá interacción del administrador cada vez que se inicie o reinicie el servicio httpd, ingresando la contraseña de la firma digital. Este es el procedimiento más seguro. Sin embargo, debido a que requiere ingresar una contraseña en cada inicio, resulta más conveniente generar una firma digital RSA que permita iniciar el servicio sin interacción.

openssl rsa \
    -in /etc/pki/tls/private/$(hostname).key \
    -out /etc/pki/tls/private/$(hostname).pem

El archivo .pem será el que se especifique más adelante como valor de la opción SSLCertificateKeyFile en la configuración de Apache.

Ejecute lo siguiente para crear el archivo CSR (Certificate Signing Request o Solicitud de Firma de Certificado):

openssl req -sha256 -new \
    -key /etc/pki/tls/private/$(hostname).key \
    -out /etc/pki/tls/certs/$(hostname).csr

Lo anterior solicitará ingresar varios datos:

La salida será similar a la siguiente:

You are about to be asked to enter information that will be
incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or
a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:MX
State or Province Name (full name) [Berkshire]:Distrito Federal
Locality Name (eg, city) [Newbury]:Mexico
Organization Name (eg, company) [My Company Ltd]:Empresa, S.A. de C.V.
Organizational Unit Name (eg, section) []:Direccion Comercial
Common Name (eg, your name or your server's hostname) []:www.empresa.com.mx
Email Address []:alguien@algo.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

El archivo de solicitud CSR resultante es el que se entrega a una Autoridad de Certificación o Registration Authority ―como Verisign, Comodo, Geotrust, etc.― que a su vez entrega de vuelta un archivo de certificado firmado.

Ejecute lo siguiente para crear un certificado auto-firmado con estructura X.509 con una validez de 1825 días (5 años):

openssl x509 -sha256 -req -days 1825 \
    -in /etc/pki/tls/certs/$(hostname).csr \
    -signkey /etc/pki/tls/private/$(hostname).key \
    -out /etc/pki/tls/certs/$(hostname).crt

Cambie los permisos de todos los archivos creados a lectura y escritura sólo para root.

chmod 600 /etc/pki/tls/*/$(hostname).*

Configuración simple de Apache para un único dominio.

Confirme cuál es el nombre de anfitrión del sistema ejecutando:

hostname

Edite el archivo /etc/httpd/conf.d/ssl.conf:

vim /etc/httpd/conf.d/ssl.conf

Localice las siguientes directivas:

#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
SSLCertificateFile /etc/pki/tls/certs/localhost.crt

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

Cambie localhost.crt y localhost.key por los nombres de sus archivos, por ejemplo www.empresa.com.mx.crt y www.empresa.com.mx.pem:

#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
SSLCertificateFile /etc/pki/tls/certs/www.empresa.com.mx.crt

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /etc/pki/tls/private/www.empresa.com.mx.pem

Localice la directiva SSLProtocol:

#   SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect.  Disable SSLv2 access by default:
SSLProtocol all -SSLv2

Notará que está deshabilitado el protocolo SSLv2. Por razones de seguridad es imperativo deshabilitar también el soporte para SSLv3, un protocolo inseguro y susceptible a la tristemente célebre vulnerabilidad conocida como POODLE. Si atacantes explotan exitosamente esta vulnerabilidad sólo necesitan hacer alrededor de 256 solicitudes SSL 3.0 para revelar datos de las conexiones cifradas. La medida más inteligente es deshabilitar el soporte para SSLv3.

#   SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect.  Disable SSLv2 access by default:
SSLProtocol all -SSLv2 -SSLv3

Guarde los cambios y salga del editor de texto.

Recargue el servicio para que surtan efecto los cambios:

systemctl reload httpd

O bien, en sistemas con SysVinit:

service httpd reload

Lo anterior deberá proceder sin solicitar la contraseña de la firma digital. Si se solicita una contraseña, significa que estableció el archivo .key (en lugar del .pem) como valor de la opción SSLCertificateKeyFile.

Configuración de Apache para múltiples dominios.

Es importante resaltar que cada dominio deberá contar con su propia dirección IP, pues Apache impedirá utilizar más de un certificado por dirección IP. La alternativa es utilizar certificados multi-dominio (SAN) o comodín (wildcard).

El primer paso consiste en crear la estructura de directorios para el anfitrión virtual.

mkdir -p /var/www/dominio/{cgi-bin,html,logs,etc}

De todos los directorios creados, sólo /var/www/dominio/html, /var/www/dominio/etc y /var/www/dominio/cgi-bin pueden pertenecer a un usuario sin privilegios, quien administrará este anfitrión virtual.

Cree el archivo /etc/httpd/conf.d/dominio.conf:

vim /etc/httpd/conf.d/dominio.conf

Adapte la siguiente plantilla como contenido de este archivo, donde a.b.c.d corresponde a una dirección IP y dominio corresponde al nombre de dominio a configurar para el anfitrión virtual:

### dominio ###
NameVirtualHost a.b.c.d:80
    <VirtualHost a.b.c.d:80>
        ServerAdmin webmaster@dominio
        DocumentRoot /var/www/dominio/html
        ServerName www.dominio
        ServerAlias dominio
        Redirect 301 / https://www.dominio/
        CustomLog logs/dominio-access_log combined
        Errorlog logs/dominio-error_log
    </VirtualHost>

NameVirtualHost a.b.c.d:443
    <VirtualHost a.b.c.d:443>
        ServerAdmin webmaster@dominio
        DocumentRoot /var/www/dominio/html
        ServerName www.dominio
        ScriptAlias /cgi-bin/ /var/www/dominio/cgi-bin/
        <Directory "/var/www/dominio/cgi-bin">
            SSLOptions +StdEnvVars
        </Directory>
        SSLEngine on
        SSLProtocol all -SSLv2 -SSLv3
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
        SSLCertificateFile /etc/pki/tls/certs/dominio.crt
        SSLCertificateKeyFile /etc/pki/tls/private/dominio.pem
        SetEnvIf User-Agent ".*MSIE.*" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
        CustomLog logs/dominio-ssl_request_log \
            "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
        Errorlog logs/dominio-ssl_error_log
        TransferLog logs/dominio-ssl_access_log
        LogLevel warn
    </VirtualHost>

A fin de que surtan efecto los cambios, es necesario reiniciar el servicio httpd.

systemctl restart httpd

O bien, en sistemas con SysVinit:

service httpd restart

Automatización con Certbot (Let's Encrypt).

Para simplificar la obtención y renovación de certificados TLS gratuitos y reconocidos públicamente, se puede utilizar Certbot, el cliente oficial de Let's Encrypt. Certbot se encargará de modificar la configuración de Apache automáticamente, siempre que el anfitrión virtual esté configurado correctamente y sea accesible desde Internet.

Requisitos previos:

Instalación de Certbot.

En AlmaLinux, Rocky Linux y Red Hat™ Enterprise Linux:

dnf -y install certbot python3-certbot-apache

En ALDOS y sistemas que utilicen yum:

yum -y install certbot python39-certbot-apache

Obtención del certificado.

Ejecute Certbot con el plugin para Apache y especifique el dominio con la opción -d:

certbot --apache -d nombre.dominio.tld

Siga las instrucciones interactivas. Certbot obtendrá el certificado, lo instalará y modificará los archivos de configuración de Apache para habilitar HTTPS, incluyendo una redirección automática de HTTP a HTTPS. También configurará la renovación automática.

Renovación automática.

Los certificados de Let's Encrypt expiran cada 90 días. Certbot instala un temporizador (timer) de systemd o una tarea cron para renovarlos automáticamente. Puede probar la renovación manualmente con:

certbot renew --dry-run

Comprobación.

Acceda con cualquier navegador web hacia https://www.dominio/ a fin de verificar que todo funcione correctamente. Si utiliza un certificado auto-firmado, el navegador mostrará una advertencia de seguridad ―porque carece de la firma de una autoridad de certificación reconocida― que deberá aceptar. Tras ello, deberá observarse un candado o signo en la barra de dirección, lo cual indica que se trata de una conexión segura.