HTTPS en Apache con TLS: certificados, redirecciones y configuración segura

Capítulo 8

Tiempo estimado de lectura: 9 minutos

+ Ejercicio

Qué es HTTPS y qué aporta TLS en Apache

HTTPS es HTTP encapsulado dentro de TLS. TLS aporta cifrado (evita que terceros lean el tráfico), integridad (detecta modificaciones) y autenticación (el servidor demuestra su identidad mediante un certificado). En Apache, HTTPS se implementa normalmente con el módulo mod_ssl y un VirtualHost en el puerto 443.

Componentes clave: certificado, clave privada y cadena

  • Clave privada (.key): secreto del servidor. Debe estar protegida por permisos estrictos.
  • Certificado del servidor (.crt o .pem): contiene la clave pública y el nombre (CN/SAN) del sitio.
  • Cadena de certificados (intermedios): certificados que enlazan el certificado del servidor con una CA raíz confiable. En muchos casos se entrega como fullchain.pem (servidor + intermedios).

En validación TLS, el cliente verifica: (1) que el nombre del sitio coincide con el certificado (SAN), (2) que la cadena es confiable, (3) que el certificado no está caducado o revocado (según cliente), y (4) que los parámetros criptográficos son aceptables.

Habilitar SSL/TLS en Apache

Debian/Ubuntu (a2enmod)

sudo a2enmod ssl headers rewrite http2

Activa mod_ssl (TLS), mod_headers (cabeceras de seguridad), mod_rewrite (redirecciones) y mod_http2 (HTTP/2, si aplica).

RHEL/CentOS/Alma/Rocky

En estas familias suele venir mod_ssl como paquete separado.

sudo dnf install -y mod_ssl

Verifica que el módulo esté cargado (según distribución):

Continúa en nuestra aplicación.
  • Escuche el audio con la pantalla apagada.
  • Obtenga un certificado al finalizar.
  • ¡Más de 5000 cursos para que explores!
O continúa leyendo más abajo...
Download App

Descargar la aplicación

apachectl -M | grep -E 'ssl|headers|rewrite|http2'

Certificados: laboratorio (autofirmado) vs público (CA)

Opción A: certificado autofirmado para laboratorio

Útil para pruebas internas. Los navegadores mostrarán advertencia porque no hay una CA confiable detrás. Aun así, permite practicar configuración, redirecciones y endurecimiento TLS.

Paso 1: crear directorio seguro para claves

Usa una ruta fuera del DocumentRoot y con permisos restrictivos. Un patrón común:

sudo install -d -m 0750 /etc/ssl/apache

Paso 2: generar clave privada y certificado (con SAN)

Los navegadores modernos requieren SAN (Subject Alternative Name). Crea un archivo de configuración mínimo para OpenSSL, por ejemplo /tmp/openssl-san.cnf:

[req]distinguished_name = dnreq_extensions = req_extprompt = no[dn]CN = ejemplo.local[req_ext]subjectAltName = @alt_names[alt_names]DNS.1 = ejemplo.localDNS.2 = www.ejemplo.local

Genera clave y certificado (válido 365 días):

sudo openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes -keyout /etc/ssl/apache/ejemplo.local.key -out /etc/ssl/apache/ejemplo.local.crt -config /tmp/openssl-san.cnf

Ajusta permisos (la clave debe ser legible solo por root y el grupo de Apache si lo necesitas):

sudo chown root:root /etc/ssl/apache/ejemplo.local.key /etc/ssl/apache/ejemplo.local.crtsudo chmod 0600 /etc/ssl/apache/ejemplo.local.keysudo chmod 0644 /etc/ssl/apache/ejemplo.local.crt

Si tu Apache corre como usuario/grupo específico y requiere leer la clave (depende de cómo esté configurado), puedes asignar grupo y permisos mínimos:

sudo chgrp www-data /etc/ssl/apache/ejemplo.local.keysudo chmod 0640 /etc/ssl/apache/ejemplo.local.key

Adapta www-data al grupo real del servicio (por ejemplo apache en RHEL-like).

Opción B: certificado público (pauta práctica)

Para producción, usa una CA pública. El flujo típico es:

  • Generar una clave privada en el servidor.
  • Crear un CSR (Certificate Signing Request) con SAN.
  • Validar dominio con la CA (HTTP-01/DNS-01 u otros métodos).
  • Recibir certificado del servidor y intermedios (cadena).

Ejemplo para generar clave y CSR con SAN (sin autofirmar). Crea /tmp/csr-san.cnf:

[req]distinguished_name = dnreq_extensions = req_extprompt = no[dn]CN = midominio.com[req_ext]subjectAltName = @alt_names[alt_names]DNS.1 = midominio.comDNS.2 = www.midominio.com

Genera clave y CSR:

sudo openssl req -new -newkey rsa:2048 -nodes -keyout /etc/ssl/apache/midominio.com.key -out /etc/ssl/apache/midominio.com.csr -config /tmp/csr-san.cnf

Tras emitir el certificado, muchas CAs entregan archivos como:

  • cert.pem (certificado del servidor)
  • chain.pem (intermedios)
  • fullchain.pem (certificado + intermedios)

En Apache suele ser más simple apuntar SSLCertificateFile a fullchain.pem (si existe) y SSLCertificateKeyFile a la clave.

Montar un VirtualHost en 443 (HTTPS)

A continuación tienes un ejemplo de VirtualHost en 443 con parámetros recomendados. Ajusta ServerName, rutas y logs según tu sitio.

Ejemplo de configuración (SSL + HTTP/2 + cabeceras)

<IfModule mod_ssl.c><VirtualHost *:443>    ServerName ejemplo.local    ServerAlias www.ejemplo.local    DocumentRoot /var/www/ejemplo/public    ErrorLog ${APACHE_LOG_DIR}/ejemplo-ssl-error.log    CustomLog ${APACHE_LOG_DIR}/ejemplo-ssl-access.log combined    SSLEngine on    # Certificado (laboratorio: .crt; público: idealmente fullchain.pem)    SSLCertificateFile      /etc/ssl/apache/ejemplo.local.crt    SSLCertificateKeyFile   /etc/ssl/apache/ejemplo.local.key    # Si tu CA entrega cadena separada y NO tienes fullchain, puedes usar:    # SSLCertificateChainFile /etc/ssl/apache/chain.pem    # Protocolos recomendados (ajusta según compatibilidad requerida)    SSLProtocol -all +TLSv1.2 +TLSv1.3    # Cifrados: en TLSv1.3 no aplica SSLCipherSuite; en TLSv1.2 sí.    SSLCipherSuite HIGH:!aNULL:!MD5:!3DES:!RC4    SSLHonorCipherOrder off    # Rendimiento y seguridad adicional    SSLCompression off    SSLSessionTickets off    # OCSP Stapling (útil con CA pública; requiere mod_ssl)    SSLUseStapling on    SSLStaplingCache "shmcb:/var/run/apache2/ssl_stapling(32768)"    # HTTP/2 (si mod_http2 está habilitado)    Protocols h2 http/1.1    # Cabeceras de seguridad (ajusta según tu aplicación)    Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"    Header always set X-Content-Type-Options "nosniff"    Header always set X-Frame-Options "SAMEORIGIN"    Header always set Referrer-Policy "strict-origin-when-cross-origin"    # Opcional: desactivar "Server" y otros detalles se gestiona a nivel global en hardening    <Directory /var/www/ejemplo/public>        Options -Indexes        AllowOverride All    </Directory></VirtualHost></IfModule>

Nota sobre HSTS: habilítalo cuando estés seguro de que el sitio funcionará siempre por HTTPS. En entornos de laboratorio puedes omitirlo para evitar “bloquearte” en HTTPS durante pruebas.

Redirección HTTP → HTTPS

La forma más limpia es un VirtualHost en 80 que solo redirige. Esto evita reglas dispersas y hace el comportamiento predecible.

VirtualHost en 80 para redirigir

<VirtualHost *:80>    ServerName ejemplo.local    ServerAlias www.ejemplo.local    # Redirección permanente a HTTPS    Redirect permanent / https://ejemplo.local/</VirtualHost>

Si necesitas preservar host y URI automáticamente (por ejemplo múltiples alias), usa mod_rewrite:

<VirtualHost *:80>    ServerName ejemplo.local    ServerAlias www.ejemplo.local    RewriteEngine On    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]</VirtualHost>

Ubicación y permisos seguros de key/crt

Buenas prácticas

  • Guarda claves en rutas como /etc/ssl/... o /etc/pki/tls/..., nunca dentro del DocumentRoot.
  • Permisos típicos: clave 0600 (o 0640 con grupo del servicio), certificado 0644.
  • Evita copias de la clave en directorios temporales o repositorios.
  • Si usas automatización, valida que el proceso de renovación no deje archivos con permisos laxos.

Tabla rápida: qué archivo va en cada directiva

DirectivaQué esperaEjemplo
SSLCertificateKeyFileClave privada del servidor/etc/ssl/apache/sitio.key
SSLCertificateFileCertificado del servidor o fullchain/etc/ssl/apache/fullchain.pem
SSLCertificateChainFileIntermedios (si no usas fullchain)/etc/ssl/apache/chain.pem

Validaciones y pruebas

1) Comprobar sintaxis y recargar Apache

sudo apachectl configtestsudo systemctl reload apache2

En algunas distribuciones el servicio se llama httpd:

sudo systemctl reload httpd

2) Verificar el handshake y la cadena con openssl s_client

Prueba el sitio indicando el nombre (SNI). Esto es clave si hay varios sitios en el mismo IP:443.

openssl s_client -connect ejemplo.local:443 -servername ejemplo.local -showcerts

Qué mirar en la salida:

  • subject= y X509v3 Subject Alternative Name deben incluir el hostname.
  • Verify return code: 0 (ok) indica cadena confiable (solo ocurrirá si el cliente confía en la CA; en autofirmado no será 0).
  • Versión TLS negociada y cipher seleccionado.

Para forzar una versión y comprobar compatibilidad:

openssl s_client -connect ejemplo.local:443 -servername ejemplo.local -tls1_2openssl s_client -connect ejemplo.local:443 -servername ejemplo.local -tls1_3

3) Probar redirección HTTP→HTTPS

curl -I http://ejemplo.local/

Debes ver 301 o 308 y un Location: https://....

4) Probar cabeceras de seguridad

curl -I https://ejemplo.local/

Verifica la presencia de Strict-Transport-Security (si la activaste) y otras cabeceras configuradas con mod_headers.

Configuración de protocolos y cifrados: recomendaciones por entorno

Entorno moderno (recomendado)

  • Permitir solo TLSv1.2 y TLSv1.3.
  • Deshabilitar compresión TLS.
  • Preferir suites fuertes en TLS 1.2 (en TLS 1.3 el conjunto es fijo y seguro por diseño).

Ejemplo:

SSLProtocol -all +TLSv1.2 +TLSv1.3SSLCipherSuite HIGH:!aNULL:!MD5:!3DESSSLCompression off

Entorno con clientes legacy (solo si es imprescindible)

Si necesitas compatibilidad con clientes antiguos, podrías habilitar configuraciones menos estrictas, pero esto aumenta el riesgo. En ese caso, documenta el motivo y limita el alcance (por ejemplo, solo en un sitio específico).

# Ejemplo conservador (evalúa con tu equipo de seguridad)SSLProtocol -all +TLSv1.2

Evita reactivar TLS 1.0/1.1 salvo requisitos muy específicos y temporales.

Fallos típicos y cómo resolverlos

1) “Certificado inválido” en navegador

  • Causa común (laboratorio): certificado autofirmado no confiable.
  • Solución: importar la CA/Certificado en el almacén de confianza del sistema (solo laboratorio) o usar un certificado de CA pública en producción.
  • Causa común (público): falta la cadena intermedia.
  • Solución: usa fullchain.pem en SSLCertificateFile o configura SSLCertificateChainFile con los intermedios correctos.

2) Hostname mismatch (CN/SAN no coincide)

  • Síntoma: el certificado es válido pero no para www o para el dominio exacto.
  • Diagnóstico: revisa SAN con openssl s_client -showcerts o inspecciona el certificado.
  • Solución: reemitir el certificado incluyendo todos los nombres necesarios en SAN (por ejemplo midominio.com y www.midominio.com).

3) Apache no arranca: error leyendo la clave

  • Síntoma: en el log aparece “Permission denied” o “unable to load private key”.
  • Causas: permisos demasiado restrictivos para el usuario/grupo del proceso, ruta incorrecta, formato inválido, clave cifrada con passphrase sin soporte de arranque automático.
  • Solución: verifica ruta, propietario y permisos; asegúrate de que el proceso pueda leer la clave sin exponerla. Si la clave tiene passphrase, considera usar mecanismos de gestión de secretos o una clave sin passphrase en servidores con controles adecuados.

4) Se sirve el certificado equivocado (SNI/VirtualHost)

  • Síntoma: al conectar a un dominio, el certificado corresponde a otro sitio del mismo servidor.
  • Diagnóstico: prueba con -servername en openssl s_client.
  • Solución: asegúrate de que cada <VirtualHost *:443> tenga ServerName correcto y su par de SSLCertificateFile/KeyFile. Revisa el orden de carga de sitios y que no haya un vhost “por defecto” capturando tráfico.

5) Redirección en bucle (HTTP↔HTTPS)

  • Causa: reglas de redirección duplicadas (en vhost 80 y también en 443) o aplicación detrás de proxy que no detecta HTTPS.
  • Solución: mantén la redirección solo en el vhost 80. Si hay proxy inverso, revisa cabeceras como X-Forwarded-Proto y la configuración de la aplicación.

Ahora responde el ejercicio sobre el contenido:

¿Cuál es la forma más limpia y predecible de implementar una redirección de HTTP a HTTPS en Apache?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

La práctica recomendada es definir un VirtualHost en 80 dedicado solo a redirigir a HTTPS. Esto evita reglas dispersas y reduce el riesgo de comportamientos inesperados o bucles.

Siguiente capítulo

Rendimiento y operación diaria de Apache: MPM, compresión y caché

Arrow Right Icon
Portada de libro electrónico gratuitaApache desde Cero: Guía Práctica para Principiantes
80%

Apache desde Cero: Guía Práctica para Principiantes

Nuevo curso

10 páginas

Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.