Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Protección de las credenciales enviadas por el navegador al servidor proxy

Constituye un problema de seguridad grave que el proceso de autenticación en un servidor proxy, se realice enviando las credenciales a través de un canal inseguro. Esta vulnerabilidad permite capturar fácilmente el par usuario contraseña por un usuario malicioso utilizando ataques de tipo MitM ya que viajan en texto plano.

Este documento consiste en instrucciones precisas para mitigar esta seria vulnerabilidad.

Una solución probada

Una solución viable consiste en configurar el servidor proxy con soporte para SSL de modo que el tráfico enviado desde el navegador hacia este, viaje por un canal seguro. Para esto, el navegador debe ser capaz de comunicarse con el servidor proxy a través del protocolo HTTP sobre SSL/TLS.

En este tipo de comunicación el navegador debe 'confiar' en el certificado enviado por el servidor proxy y este debe estar firmado por una Autoridad Certificadora (CA) reconocida y autorizada.

Una solución muy conveniente sería utilizar Let's Encrypt. Let’s Encrypt es una autoridad certificadora completamente gratuita, automatizada y abierta, mediante la cual se obtienen certificados SSL legítimos listos para ser utilizados en cualquier servicio que utilice TLS/SSL.

Una vez configurado correctamente el servidor proxy con soporte para SSL, es necesario preparar el navegador para que se pueda comunicar de forma segura con este. Actualmente, ningún navegador permite la configuración manual del proxy a través de HTTPS. Afortunadamente, la mayoría de los navegadores más populares son capaces de recibir la configuración a través del protocolo WPAD.

Requerimientos

  • Debian 9 (Stretch) 64 bits
  • Certificados SSL (a través de Let's Encrypt)
  • Squid 3.5.23 (código fuente o binarios precompilados con soporte para SSL)
  • Servidor Web (para el servicio WPAD)
  • Firefox

Configuración de APT

Configurar el origen de paquetes en /etc/apt/sources.list

deb http://download.jovenclub.cu/repos/debian/stretch stretch main
deb http://download.jovenclub.cu/repos/debian/stretch-updates stretch/updates main
deb http://download.jovenclub.cu/repos/debian/stretch-security stretch-updates main
# Debian Backports, necesario para la instalación de certbot
deb http://download.jovenclub.cu/repos/debian/stretch-backports stretch-backports main

# Repositorios de fuentes, necesario para la compilación
deb-src http://ftp.us.debian.org/debian stretch main

Actualizar sistema y paquetes.

sudo apt-get update && apt-get -y upgrade && reboot

Obtención de certificados SSL a través de Let's Encrypt

Instalar certbot

sudo apt-get install certbot -t stretch-backports

ANTES DE SOLICITAR LOS CERTIFICADOS ES NECESARIO DETENER CUALQUIER SERVICIO QUE ESTÉ CORRIENDO EN EL PUERTO 80, DE OTRA FORMA EL PROCESO FALLARÁ. ADEMÁS SE DEBEN CREAR LAS CONDICIONES PARA QUE EL PROXY INVERSO PUEDA ACCEDER AL SERVIDOR PROXY POR EL PUERTO 80.

export HTTPS_PROXY="http://localhost:3128" && sudo certbot certonly --standalone -d proxy.xxx.jovenclub.cu

Donde xxx es el prefijo de cada provincia, por ejemplo: proxy.iju.jovenclub.cu. No es posible utilizar otro FQDN que no tenga el formato proxy.xxx.jovenclub.cu.

Los certificados se almacenan en el directorio /etc/letsencrypt/live/proxy.xxx.jovenclub.cu/ y tienen una duración máxima de 90 días. Afortunadamente al instalar certbot se crea una tarea de cron que renovará automáticamente los certificados antes de que expiren.

Teniendo en cuenta lo anterior, es necesario hacer ajustes en los comandos que se ejecutan a través de cron, para que certbot pueda hacer uso del proxy. Editar el archivo /etc/cron.d/certbot modificando la línea:

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

Por:

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && export HTTPS_PROXY="http://localhost:3128" && certbot -q renew

Es posible probar la renovación de los certificados a través de este comando:

sudo export HTTPS_PROXY="http://localhost:3128" && certbot renew --dry-run

Instalación de paquetes necesarios

Es importante destacar que el squid disponible en los repositorios oficiales de Debian no está compilado con soporte para SSL, por lo tanto es necesario compilar el paquete con estas características.

Se adjuntan los archivos .deb precompilados con soporte para SSL para aquellos que no tienen mucho tiempo.

Instalar herramientas necesarias para la compilación de paquetes.

sudo apt-get -y install devscripts build-essential fakeroot debhelper dh-autoreconf cdbs

Instalar dependencias necesarias para la compilación de Squid.

sudo apt-get -y build-dep squid

Instalar dependencias necesarias para la compilación con soporte SSL.

sudo apt-get -y install libdbi-perl libssl1.0-dev

Compilar paquetes .deb de Squid con soporte SSL

mkdir -p build/squid3
cd build/squid3

Descargar fuentes de squid

wget http://http.debian.net/debian/pool/main/s/squid3/squid3_3.5.23-5.dsc
wget http://http.debian.net/debian/pool/main/s/squid3/squid3_3.5.23.orig.tar.gz
wget http://http.debian.net/debian/pool/main/s/squid3/squid3_3.5.23-5.debian.tar.xz

Descomprimir el paquete de fuentes

dpkg-source -x squid3_3.5.23-5.dsc

Modificar las opciones de configuración del archivo squid3-3.5.23/debian/rules añadiendo --enable-ssl, --enable-ssl-crtd y --with-openssl justo debajo de la línea que contiene --enable-icap-client

...
--enable-icap-client \
--enable-ssl \
--enable-ssl-crtd \
--with-openssl \
...

Compilar los paquetes .deb (se generan en el directorio build/squid3).

cd squid3-3.5.23
dpkg-buildpackage -rfakeroot -b

Instalar paquetes .deb

sudo apt-get -y install squid-langpack
cd build/squid3
sudo dpkg -i squid-common_3.5.23-5_all.deb
sudo dpkg -i squid_3.5.23-5_amd64.deb
sudo dpkg -i squidclient_3.5.23-5_amd64.deb

Comprobar que squid tiene soporte para SSL

squid -v | grep --color ssl

En color rojo deben aparecer --enable-ssl, --enable-ssl-crtd y --with-openssl.

Evitar que squid sea actualizado por APT

sudo apt-mark hold squid squid-common

Configuración de squid

Añadir la siguiente línea al archivo /etc/squid/squid.conf justo al inicio.

https_port 3129 cert=/etc/letsencrypt/live/proxy.xxx.jovenclub.cu/fullchain.pem key=/etc/letsencrypt/live/proxy.xxx.jovenclub.cu/privkey.pem version=4

En el parámetro cert se especifica la ruta del certificado y en key la de la llave privada. En version se especifica qué versiones de SSL/TLS se soportarán, en este caso solamente TLSv1 desechando versiones de SSL vulnerables.

Para que toda la comunicación entre los navegadores y el servidor Squid sea exclusivamente sobre SSL por el puerto 3129, es necesario configurar el parámetro http_port de modo que solamente el localhost pueda comunicarse con este puerto.

http_port 127.0.0.1:3128

No sería recomendable deshabilitar completamente el puerto porque certbot no puede comunicarse a través de un proxy SSL/TLS.

Si otros servicios como el correo o www harán uso de Let's Encrypt entonces sería conveniente permitir el acceso solo a la DMZ:

http_port x.x.x.x:3128

Donde x.x.x.x sería la IP de la interface de red.

Servicio WPAD

WPAD (Web Proxy AutoDiscovery Protocol) consiste en servir un fichero a través del protocolo HTTP que contiene los parámetros de configuración del proxy. Dadas las diferentes formas en las que los navegadores intentan acceder a este, la misma configuración debe existir en 3 archivos diferentes:

wpad.pad, wpad.pa y proxy.pac

Para esto debe preparase un servidor web que sirva los tres archivos y puedan ser accedidos a través de una dirección con esta forma: http://wpad.xxx.jovenclub.cu/wpad.pad. Pudiera utilizarse cualquier servidor web existente para estos propósitos.

Generalmente se crea solamente el archivo wpad.pad y posteriormente se generan enlaces simbólicos de este para evitar mantener 3 archivos idénticos.

Es necesario crear un nuevo registro en el servidor DNS que apunte a wpad.xxx.jovenclub.cu

El contenido de estos archivos puede quedar como sigue.

function FindProxyForURL(url, host)
{
    // No usar el proxy para las siguientes direcciones
    var exceptions = new Array(
        // Nombres de host sin dominio (por ejemplo localhost)
        /^[a-zA-Z0-9-]+$/,

        // Nombres de dominios locales y otros servicios
        /\.jovenclub\.cu$/,
        /\.cubava\.cu$/,
        /\.ecured\.cu$/,

        // Redes privadas (RFC 1918)
        /^192\.168\.\d+\.\d+$/,
        /^172\.(1[6-9])|(2[0-9])|(3[0-2])\.\d+\.\d+$/,
        /^10\.\d+\.\d+\.\d+$/,
    );

    for (i = 0; i < exceptions.length; i++)
    {
        if (exceptions[i].test(host))
        {
            return "DIRECT";
        }
    }

    return "HTTPS proxy.xxx.jovenclub.cu:3129";
}

Configuración de Firefox

Configurar Firefox (versiones +56) para que autodetecte la configuración del proxy a través de WPAD.

  • Clic en Opciones (o en el ícono de tres barras)
  • Clic en General
  • Desplazarse hasta el apartado Proxy de red
  • Clic en Configuración
  • En URL de configuración automática de proxy especificar http://wpad.xxx.jovenclub.cu/wpad.dat
  • Clic en Aceptar

Limitaciones

Herramientas como wget, curl, npm, pip, IDM, entre otras, no son compatibles con proxies HTTPS.

Referencias

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.