Anteriormente se ha hablado del uso del modulo ModSSL para habilitar SSL v2/v3 y TLSv1 en Apache, sin embargo se ha hablado de este potente módulo de una forma muy superficial, por este motivo, la intensión de este articulo es simplemente, explicar en mayor profundidad el uso de ModSSL y algunas de las directivas más interesantes que se encuentran disponibles.

CONCEPTOS BASICOS SOBRE PROTOCOLO SSL/TLS

El protocolo SSL (Secure Sockets Layer) y su inmediato sustituto TLS (Transport Layer Security) son los protocolos que se han utilizado con mayor frecuencia en entornos como internet para asegurar las comunicaciones y los datos que se intercambian entre clientes y servidores. Son protocolos robustos que definen una serie de fases que deben ser implementadas por cada implementación. Probablemente para el lector, las siglas HTTPS y SSL le son bastante familiares, sin embargo en algunos casos no se comprende muy bien como funcionan estos protocolos y que es lo que realmente hacen, para dar un poco más de “luz” en estos temas, se explican los pasos que son llevados a cabo cuando un cliente realiza una petición a un servidor utilizando SSL.

Fase 1.

  1. En el primer paso, el cliente inicia una conexión SSL con un servidor, en este paso, debe enviar al servidor web los settings de configuración que el cliente soporta para el proceso de comunicación entre ambas partes, estos settings incluyen detalles tales como:- Versión del protocolo SSL que el cliente soporta.

    – Algoritmos criptograficos que el cliente soporta para el cifrado de la comunicación (algoritmos de clave pública y clave privada).

    – Generación de un número aleatorio usando la clave publica del cliente que será utilizada nuevamente en un paso posterior (en este caso se llamará RNc recordarlo para las siguientes fases).

    Toda esta información es incluida en un mensaje llamado ClientHello que es enviada al servidor. Este tipo de mensaje pertenece a un sub-protocolo conocido como handshake

  2. El servidor recibe el mensaje ClientHello emitido por el cliente y valida la información contenida en él, si todos los parámetros son correctos (algoritmos de cifrado validos, versión del protocolo SSL, etc.) elige algunos de los parámetros de conexión enviados por el cliente y que son también soportados por el servidor y procede a enviar también su certificado digital al cliente (y exige que el cliente responda con un certificado digital en el caso de que el servidor requiera autenticación), el mensaje que el Servidor envía al cliente es conocido como ServerHello y ademas de los datos anteriores, también incluye un numero aleatorio utilizando su clave pública (en este caso se llamará RNs recordarlo para las siguientes fases)

Fase 2.

  1. El cliente y el servidor ahora conocen cual será la configuración que se deberá emplear para establecer la conexión y ahora proceden a intercambiar sus correspondientes certificados (que dependen de los algoritmos de clave pública seleccionados anteriormente). El formato de los certificados actualmente soportados en este protocolo son X.509. En cualquier caso, el cliente debe validar el certificado enviado por razones de seguridad en el caso de que sea un certificado auto-firmado, en el caso de que se encuentre firmado por una CA, el certificado será confiable para el cliente.
  2. Cliente y servidor intentan negociar una clave secreta simétrica (este proceso es conocido como “negotiation”) dicha clave simétrica es comúnmente conocida como Pre-Master Secrety es generada utilizando alguno de los algoritmos de cifrado soportados por ambas partes, donde los algoritmos más habituales son AES, DES, TripleDES, RC2 o RC4. Para el intercambio de dichas claves simétricas, se siguen los siguientes pasos
    1. El cliente crea la Pre-Master Secret utilizando los settings incluidos en el mensaje ServerHello enviado por el servidor
    2. La Pre-Master Secret generada, es posteriormente cifrada por el cliente utilizando la clave publica del servidor (que se encuentra incluida en el certificado digital que se encuentra adjunto al mensaje ServerHello enviado por el servidor con anterioridad.
    3. El cliente envía al servidor la Pre-Master Secret cifrada con la clave pública del servidor.
    4. En el caso de que el servidor haya solicitado autenticación al cliente, este se encarga de cifrar un número aleatorio que es único para este HandShake y que es conocido tanto por cliente como por servidor. En este caso, el cliente envía los datos firmados, su certificado digital y la Pre-Master Secret generada en el paso anterior.

Fase 3.

  1. Si el servidor ha exigido autenticación al cliente, obtiene su certificado e intenta autenticarlo, en el caso de que el cliente no pueda ser autenticado la conexión es inmediatamente terminada. Si el cliente ha podido ser autenticado por el servidor, procede a leer la Pre-Master Secret generada por el cliente e intenta descifrarla utilizando su clave privada (recordar que la PMS ha sido cifrada utilizando la clave publica del servidor)
  2. El siguiente paso, es la generación de la Master Secret que es generada tanto por el cliente como por el servidor partiendo de la Pre-Master Secret creada anteriormente por el cliente, este proceso se realiza de forma paralela en el cliente y el servidor, el resultado final para ambos será el mismo. Este procedimiento en el cliente se realiza utilizando el número aleatorio generado por el servidor llamado RNs y la Pre-Master Secret. En el servidor se realiza utilizando el número aleatorio generado por el cliente llamado RNcy la Pre-Master Secret.De esta forma, tanto cliente como servidor tendrán la misma Master Secret que será utilizada de ahora en adelante.
  3. Con la Master Secret generada en el paso anterior, tanto cliente como servidor comienzan a generar las session keys las cuales son claves simétricas usadas para cifrar y descifrar información intercambiada durante la sesión SSL y para verificar su integridad.
  4. El cliente ha generado su session key y envía un mensaje al servidor indicando que el handshake por parte del cliente ha terminado y ademas envía un mensaje adicional indicando que los futuros mensajes de error que se emitan desde el cliente serán cifrados con la session key generada.
  5. El servidor ha generado su session key y envía un mensaje al cliente indicando que el handshake por parte del servidor ha terminado y ademas envía un mensaje adicional indicando que los futuros mensajes de error que se emitan desde el servidor serán cifrados con la session key generada.

Fase 4

  1. El handshake ha finalizado y la sesión SSL ahora puede comenzar, de ahora en adelante, tanto cliente como servidor utilizarán sus session keys generadas para cifrar y descifrar información, que envían entre ellos y para validar la integridad de los datos.

Este es el procedimiento completo para el establecimiento de una sesión SSL entre clientes y servidores. Dado que probablemente es difícil de comprender leyendo cada uno de estos pasos, la siguiente imagen puede aclarar un poco las cosas.

 

Ahora, se explicará como Apache soporta el protocolo SSL por medio del uso de ModSSL y las directivas más interesantes incluidas en dicho módulo.

Directivas de ModSSL

Para comenzar, se hablará sobre un mecanismo de autenticación bastante común en aplicaciones web: Autenticación por Certificado (que se ha mencionado en párrafos anteriores). Para cualquier usuario es común presenciar el típico formulario de login y password para autenticarse en un sitio web determinado, sin embargo el mecanismo de autenticación por certificados basa su “confianza” en un cliente partiendo del hash de alguno de los certificados que tiene almacenado el usuario en el repositorio de su navegador, un certificado es valido para un servidor web (en condiciones normales), si dicho certificado ha sido emitido por una de las autoridades de confianza validas por el servidor web. Cuando un usuario se autentica con un servidor web utilizando este método, entra en una zona conocida como “Client Authentication Realm” que es simplemente la zona autenticada. Ahora bien, no todos los certificados son validos para un servidor web aunque haya sido emitido por una entidad certificadora de confianza, es aquí donde surge el concepto de CRL (Certificate Revocation List). Es una lista de certificados del cliente que ya no son validos y que no podrán ser usados para acceder a un “Client Authentication Realm” esto responde a que posiblemente dichos certificados que se encuentran dicha CRL han caído “en las manos equivocadas” o han sido comprometidos, por esta razón (o cualquier otra razón) el uso de cualquier certificado que se incluye en esta lista, dará como resultado un acceso denegado. Una vez explicada esta breve introducción, básica para comprender el funcionamiento de SSL, se procede a explicar algunas de las directivas incluidas en este módulo.

SSLCACertificateFile

Con esta directiva se puede definir el fichero completo que ha emitido las CA y que los clientes van a tratar para acceder a una zona “Client Authentication Realm”. Estos certificados son utilizados principalmente para autenticación de clientes y es simplemente una concatenación de ficheros PEM codificados y ordenados por preferencia

SSLCACertificateFile /opt/WebServerApacheFull/httpd-2.2.22/CACerts/CACerts.crt

SSLCACertificatePath

Esta directiva es similar a la anterior en el sentido que permite definir al servidor web donde se encuentran ubicados los certificados emitidos por una CA. Con la directiva SSLCACertificateFile se define la ruta donde se encuentra declarado UN solo certificado con todos los certificados de las CA concatenados, pero con esta directiva, simplemente se define un directorio donde se encuentran todos los certificados (concatenados e independientes) que el servidor web utilizará para enviar al cliente.

SSLCACertificatePath /opt/WebServerApacheFull/httpd-2.2.22/CACerts/

SSLCARevocationFile

Funciona del mismo modo que la directiva SSLCACertificateFile sin embargo es valida para la definición de listas CRL (Certificate Revocation List) del mismo modo que la directiva mencionada, aquí se define un fichero único con todos los certificados concatenados en un solo fichero PEM ordenados por preferencia.

SSLCARevocationFile /opt/WebServerApacheFull/httpd-2.2.22/CACRL/webserverCRL.crl

SSLCARevocationPath

Funciona igual que SSLCACertificatePath con la diferencia que permite definir un directorio donde se encuentran todos los certificados digitales que serán incluidos en la CRL (Certificate Revocation List)

SSLCARevocationPath /opt/WebServerApacheFull/httpd-2.2.22/CACRL/

SSLCipherSuite

Esta directiva permite configurar la Suite de cifrado que será utilizada entre el cliente y servidor en la fase de Handshake de la conexión SSL. Se trata de una cadena de texto que puede llegar a ser muy compleja ya que sigue las especificaciones de Ciphers de OpenSSL.

La especificación se compone principalmente de 4 atributos

  • Key Exchange Algorithm
  • Authentication Algorithm
  • Cipher/Encription Algorithm
  • MAC Digest Algorithm

Ahora, estas secciones, se pueden unir y especificar el orden en el que los Ciphers serán usados, cada una de las 4 secciones anteriores tiene una serie de valores definidos que pueden ser consultados aquí:

http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#sslciphersuite

Ademas existen ALIAS que permiten definir un grupo de Ciphers que también pueden verse del enlace anterior. Ahora, todas estas tags, (Para los Alias y las secciones) se pueden definir una serie de prefijos para personalizar su comportamiento. Dichos prefijos son:

  • none: Adicionar un Cipher a la lista
  • +: Mover los ciphers a la localización actual en la lista
  • -: Remover los ciphers de la lista actual (posteriormente pueden adicionarse nuevamente)
  • !: Elimina completamente los ciphers de la lista actual (no pueden adicionarse nuevamente)

Con esta breve descripción, es difícil comprender el uso de esta directiva (y otras que se verán más adelante) por este motivo se enseñarán algunos ejemplos de como funciona todo esto en próximas publicaciones.

SSLEngine

Se trata de una directiva fundamental para el uso de ModSSL, ya que habita o deshabilita el uso del motor de protocolo SSL/TLS. Se trata de una directiva que habitualmente se incluye dentro hosts virtuales para activar el soporte SSL para solamente determinadas zonas, pero que puede incluirse también a nivel de configuración global del servidor. Por defecto el valor de esta directiva es Off, tanto para el servidor principal como para todos los hosts virtuales declarados en el fichero de configuración. Para habilitar SSL en el servidor principal o en algún host virtual.

SSLEngine on

SSLProtocol

Esta directiva es frecuentemente utilizada para controlar cual(es) protocolo(s) serán empleados en las conexiones SSL establecidas con los clientes. Esto significa que los clientes que se conecten al servidor (principal o virtual) solamente podrán establecer una conexión utilizando uno de los protocolos definidos en esta directiva.

Los protocolos disponibles son (estos valores son sensibles a mayúsculas/minúsculas):

SSLv2: Versión 2 del protocolo SSL, se trata del protocolo original diseñado por Netscape Corporation.

SSLv3: Versión 3 del protocolo SSL y evolución de la versión 2, es el estándar de-facto y actualmente se encuentra soportado por prácticamente todos los navegadores web modernos.

TLSv1: Transport Layer Security (TLSv1) se trata del sucesor de SSLv3 y actualmente se encuentra bajo construcción, no esta soportado por todos los navegadores web modernos, pero si se encuentra adaptado por los más utilizados como Firefox y Chrome.

ALL: Indica a la directiva que debe soportar todos los protocolos disponibles.

Ejemplos:

#Todos los protocolos

SSLProtocol ALL

#Habilitado solamente SSLv2

SSLProtocol -ALL +SSLv2

#Habilitados todos, menos TLSv1

SSLProtocol ALL -TLSv1

Como puede verse, se pueden utilizar los comodines “+” y “-” para habilitar o desactivar protocolos.

SSLRequiereSSL

Todos los clientes que se conecten a una instancia del servidor con esta directiva habilitada, tienen que usar SSL para establecer las conexiones, de otro modo la respuesta del servidor será un acceso denegado para la conexión.

SSLSessionCache

Esta directiva permite configura el tipo de almacenamiento de cache para las sesiones SSL. Se trata de una utilidad opcional que acelera el procesamiento paralelo de peticiones, que se procesan en el mismo proceso de servidor web (con la cabecera HTTP Keep-Alive) OpenSSL se encarga de cachear la información de la sesión SSL localmente, sin embargo las peticiones de clientes modernos, frecuentemente realizan peticiones paralelas (carga de imágenes, estilos y otros recursos comunes en aplicaciones web) todas estas peticiones paralelas son tratadas de forma independiente por otros procesos fork del proceso del servidor principal, aquí una cache inter-proceso ayuda evitar la penalización que implica el establecimiento de handshakes innecesarios para cada petición atendida por un proceso fork. En esencia, esta directiva, activa la característica de cache inter-proceso de 3 modos diferentes:

none: Cache interproceso desactivada.

dbm: Indica un fichero DBM almacenado en disco para sincronizar la memoria local de OpenSSL del proceso principal del servidor. Se trata del tipo de almacenamiento más recomendado ya que permite acelerar las peticiones de los clientes aumentando el rendimiento de operaciones I/O

shm: Indica un fichero donde se almacenará una tabla de hash dentro de un segmento de memoria compartida en RAM para sincronizar la memoria local de OpenSSL del proceso principal del servidor. No se encuentra disponible en todas las plataformas.

NOTA: Esta directiva solamente puede aplicarse al contexto principal del servidor web, no puede incluirse en ningún host virtual, dado que se producirá un error al intentar iniciar el servidor web.

SSLSessionCacheTimeout

Permite establecer el tiempo en segundos que se almacenarán los datos de la cache para cada sesión SSL y la cache de la memoria interna de OpenSSL, normalmente se suelen establecer valores superiores a 300 en entornos productivos.

SSLSessionCacheTimeout 600

SSLVerifyClient

Se trata de una directiva de seguridad que permite al servidor web, definir como será el proceso de verificación de clientes que pueden intentar establecer una conexión SSL con el servidor web, es una forma de “filtrar” cuales clientes pueden establecer una conexión SSL con el servidor y cuales no. Esta directiva puede aplicarse a nivel de servidor principal, host virtual o incluso a nivel de directorio. Los posibles valores que pueden asignarse a esta directiva son:

-none: El cliente no necesita presentar un certificado valido al servidor.

-optional: El cliente es libre de presentar un certificado valido al servidor si lo desea.

-optional_no_ca: El cliente es libre de presentar un certificado valido al servidor si lo desea, pero dicho certificado no necesariamente debe ser verificable (esto quiere decir que el cliente puede presentar cualquier certificado sin necesidad de que este sea validado por una CA).

-require: El cliente tiene que proporcionar un certificado valido para la autenticación con el servidor.

Estos son los únicos valores admitidos para esta directiva, sin embargo en la practica, se suelen emplear none y require, principalmente porque el valor optional y optional_no_ca no tienen ningún sentido para establecer un sistema seguro de autenticación, lo más común es que se solicite un certificado valido o que no se solicite ninguno, pero no es normal solicitar cualquier tipo de certificado (incluso invalido) o dejar que este tipo de restricciones sean opcionales para cualquier cliente.

SSLVerifyDepth

Indica con un valor numérico la profundidad que se aplicará sobre el certificado de un cliente antes de determinar que dicho certificado es valido. En realidad este valor es el número máximo de entidades intermedias que han participado en la generación del certificado (issuers). Por ejemplo, en el caso de que este valor sea 0, solamente certificados auto-firmados serán aceptados como validos, en el caso de que sea 1, indica que un certificado auto-firmado puede ser valido, al igual que uno que ha sido firmado por una CA la cual es directamente conocida por el servidor web (por ejemplo certificados emitidos por la CA al servidor y ubicados en la ruta definida en la directiva SSLCACertificatePath)

SSLVerifyDepth 10