Un pregunta de un lector en la entrada Hardening de SSL/TLS en servidores HTTPS me llevó a buscar y probar una solución para este problema: cómo predecir el impacto, en los clientes de un sitio Web, al deshabilitar un protocolo inseguro dentro de la configuración de suites de cifrado de TLS.

Este lector en particular, necesitaba saber si alguno de sus clientes se verían afectados al deshabilitar el algoritmo criptográfico de encriptación de flujo RC4, el cual es inseguro (vulnerable a un amplio abanico de ataques y ya sin soporte por los principales navegadores). La solución consiste en lograr que el servidor Web registre en el log de accesos el protocolo y suite de cifrado elegidas durante la negociación (handshake) para cada acceso. De esta forma es posible, luego de un tiempo, determinar si existen cliente que aún utilizan el protocolo/suite de cifrado que deseamos deshabilitar (para mejorar la seguridad).



Tanto Nginx como Apache permiten agregar información relacionada al protocolo SSL/TLS (HTTPS), cuando se utiliza un formato de log personalizado.

Al habilitar el registro de protocolo y suite de cifrado negociada por cada cliente, es posible luego elaborar una estadística y detectar el uso de suites de cifrado que utilicen protocolos criptográficos inseguros. Cabe destacar que es recomendable llevar a cabo un hardening de HTTPS para evitar el uso de protocolos inseguros, aunque a veces no queda otra alternativa que soportar alguno de ellos a causa de clientes desactualizados (a los que debemos obligatoriamente dar soporte por cuestiones de negocio, contrato o cual fuese la razón). Lo mejor es deshabilitarlos e indicar al cliente que actualice su navegador Web, aunque a veces, claro está, no tenemos alternativa.

En servidores Nginx con soporte para HTTPS es posible configurar un formato de log personalizado, que incluya información sobre el protocolo y suite de cifrado negociados por el cliente, de la siguiente forma.

Editar el archivod e configuración del servidor:

# nano /usr/local/nginx/conf/nginx.conf

Dentro del protocolo http:


http {

Definir un formato de log personalizado:


    log_format combined_ssl '$remote_addr - $remote_user [$time_local] $ssl_protocol/$ssl_cipher '
                    '"$request" $status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

combined_ssl indica el nombre del formato de log personalizado. Las variables de entorno $ssl_protocol y $ssl_cipher registran el protocolo y suite de cifrado utilizados respectivamente. Es posible incorporar estas variables en cualquier parte de la cadena que define el formato de log, ya que es un formato personalizado. En este ejemplo se registran luego de la fecha local, separadas por una barra ('/').

Una vez definido el formato de log personalizado, es necesario configurarlo dentro de la sección del servidor HTTPS:


    server {
        listen 443 ssl;

Agregar (o modificar de acuerdo, en caso de que exista) la siguiente línea:

        access_log logs/access-linuxito-ssl.log combined_ssl;

Esta línea indica el nombre del archivo de log de accesos (en este ejemplo en una ruta relativa al directorio de instalación de Nginx, pero se puede utilizar una ruta absoluta), junto con el formato del mismo (combined_ssl).

Finalmente, reiniciar el servidor para que tome los cambios en la configuración:

# service nginx restart

Inmediatamente es posible revisar el log de accesos (logs/access-linuxito-ssl.log) y verificar que se esté registrando correctamente esta nueva información

212.128.102.133 - - [17/Nov/2016:06:27:23 -0500] TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256 "GET /images/diaspora32-green.png HTTP/1.1" 200 1072 "http://www.linuxito.com/gnu-linux/nivel-basico/72-como-reiniciar-una-interfaz-de-red-en-red-hat" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36" "-"
152.201.161.52 - - [17/Nov/2016:06:27:29 -0500] TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384 "GET /templates/linuxito/favicon.ico HTTP/1.1" 200 4286 "http://www.linuxito.com/contacto/15-miscelaneo/107-ubuntu-17-04-zombie-zebra" "Mozilla/5.0 (Linux; Android 5.1; XT1032 Build/LPBS23.13-56-2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36" "-"
212.128.102.133 - - [17/Nov/2016:06:27:38 -0500] TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256 "GET /templates/linuxito/favicon.ico HTTP/1.1" 200 4286 "http://www.linuxito.com/gnu-linux/nivel-basico/72-como-reiniciar-una-interfaz-de-red-en-red-hat" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36" "-"
181.14.239.10 - - [17/Nov/2016:06:27:39 -0500] TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384 "GET /?format=feed&type=rss HTTP/1.1" 200 3383 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2914.3 Safari/537.36" "-"

Con un simple comando, es posible listar todos los pares de protocolo/suite diferentes utilizados por los clientes:

# cat /usr/local/nginx/logs/access-linuxito-ssl.log | cut -d']' -f2 | cut -d'"' -f1 | sort | uniq
 TLSv1.1/ECDHE-RSA-AES256-SHA 
 TLSv1.2/DHE-RSA-AES256-GCM-SHA384 
 TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256 
 TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384 
 TLSv1/ECDHE-RSA-AES128-SHA 
 TLSv1/ECDHE-RSA-AES256-SHA 

O mejor (más interesante), generar una estadística al respecto:

# cat /usr/local/nginx/logs/access-linuxito-ssl.log | cut -d']' -f2 | cut -d'"' -f1 | sort | uniq -c |sort -nr
   2628  TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384 
    645  TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256 
     23  TLSv1.1/ECDHE-RSA-AES256-SHA 
     22  TLSv1/ECDHE-RSA-AES256-SHA 
     19  TLSv1.2/DHE-RSA-AES256-GCM-SHA384 
      1  TLSv1/ECDHE-RSA-AES128-SHA

Es interesante notar que la mayoría de los clientes de este sitio utilizan el protocolo TLSv1.2. Nadie utiliza SSL (porque el servidor no lo permite), y apenas unos pocos no soportan Diffie-Hellman con curvas elípticas (ECDHE).

Tener en cuenta que, al alterar el formato de log del servidor Web, es posible que se vea afectado el normal funcionamiento de toda herramienta que realice algún tipo de revisión de logs (por ejemplo, logwatch o cualquier otro script personalizado).

En servidores Apache la configuración es similar. Cuando Apache cuenta con el módulo SSL (mod_ssl) instalado, se agrega un conjunto de variables de entorno adicionales las cuales es posible utilizar en conjunto con el módulo mod_log_config.

Por ejemplo es posible definir un formato de log personalizado agregando las variables de entorno definidas por mod_ssl SSL_PROTOCOL y SSL_CIPHER, las cuales indican respectivamente el protocolo y suite de cifrado negociados con el cliente:

CustomLog "logs/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

Referencias

Module ngx_http_ssl_module - Embedded Variables - Nginx

Apache Module mod_ssl - Custom Log Formats

Apache Module mod_log_config


Tal vez pueda interesarte


Compartí este artículo