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
- https://wiki.squid-cache.org/Features/Authentication
- https://wiki.squid-cache.org/Features/HTTPS
- https://wiki.squid-cache.org/Technology/WPAD/DNS
- http://www.squid-cache.org/Versions/v3/3.5/cfgman/https_port.html
- http://www.squid-cache.org/Versions/v3/3.5/cfgman/http_port.html
- http://lists.squid-cache.org/pipermail/squid-users/2017-December/017097.html
- https://docs.diladele.com/administrator_guide_5_2/install/debian9/install.html
- http://squid-web-proxy-cache.1019090.n4.nabble.com/Build-errors-with-Squid-3-5-24-under-Debian-td4681637.html
- https://tools.ietf.org/html/draft-ietf-wrec-wpad-01
- https://doc.pfsense.org/index.php/WPAD_Autoconfigure_for_Squid
- http://cavaliercoder.com/blog/proxy-auto-configuration-script-to-bypass-proxy-for-local-addresses.html
- https://letsencrypt.org/
- https://certbot.eff.org/lets-encrypt/debianstretch-other
- https://certbot.eff.org/docs