martes, 24 de octubre de 2017

Otro intento para configurar QoS en Linux: Segunda introducción

Sobre como configurar ancho de banda en TC

Sobre este punto, tc puede ser complicado en tanto las nociones sobre unidades de transmisión suelen ser confusas para la mayoría de administradores de sistemas. Aún más, suelen confundirse las notaciones y usarse los términos indistintamente.

Al hablar de ancho de banda, la unidad de medida a usar es bites por segundo, que debería abreviarse como bps. Esta es la unidad de medida que suelen usar los proveedores de internet: Así, al decir megas, se refieren a Megabits por segundo; así por ejemplo, 2 Mbps en su forma abreviada.

Por otra parte, la mayoría de aplicaciones suelen medir la cantidad de bytes (Entendido como unidad de almacenamiento) que recibimos en una unidad de tiempo. Esta es la que se debería escribir como bytes/s

Para entender que estamos midiendo, pues considere dos cosas: Primero, la relación entre bytes/s y bps y  es de 1 a 8: 1 bytes/s = 8bps.  Luego, que como son unidades muy pequeñas, es común que ambas se usen como el prefijo kilos: KB/s y kbps, la relación sigue siendo la misma. 
(El truco más barato para saber que unidad de medida esta usando, es que si es muy grande, posiblemente se refiera a bps)

Luego esta tc. Se supone que tc acepta ambas unidades de medidas al agregar la unidad como sufijo. Hay que prestar atención para entender la confusión:
  • kbit se refiere a kilobits por segundo (Para este no hay problema). Esta también puede escribirse como Kbit
  • kbps se refiere a kilobytes por segundo (Acá se usa la notación que se espera para la otra unidad de medida)

Si ya domina la confusión sobre unidades de transferencia, puede venir a entender a tc

tc usa bits por segundo como unidad por defecto

Sobre como clasificar tráfico para tc
Nuestra primera opción es la de usar el componente filter de tc. En este caso, se considera que el clasificador u32 es el máximo exponente. Pero dado que puede convertirse en algo complicado, tenemos la opción de seguir usando a filter con algo más sencillo: Buscar "marcas" hechas con iptables mediante MARK target. También es posible usar a TOS target (Nos limitaría un poco) y a DSCP target (Con más opciones) para buscar valores en ambas cabeceras, pero tienen el inconveniente que podría tener efectos inesperados con algunos paquetes que ya tienen marca de acuerdo a sus programas de origen.

Mi mejor apuesta es a usar el CLASSIFY target, que como se verá en las pruebas que realicemos, nos ahorra, al menos a nivel de configuración, al componente filter de tc, casi nada.

lunes, 23 de octubre de 2017

Otro intento para configurar QoS en Linux: Introducción

Aunque no tengo algo como esto en producción, quería empezar a registrar algunas ideas al respecto:

Es posible que lo que entiendas por QoS sea una especie de cajón de sastre: 

Como muchos otros conceptos en informática, dicho sea de paso.
En este caso, no ayuda que en realidad haya muchos conceptos involucrados:
  • La definición misma del Protocolo de Internet (RFC791) describe en sus cabeceras al campo TOS, que permitiría elegir la calidad de servicio, es decir, los parámetros requeridos a la red por la que el paquete va a atravesar. 
  • Para ser más preciso, quizá casi a manera de curiosidad, parece haber un RFC específico para TOS, pero esta marcado como obsoleto debido a RFC2474
  • Precisamente, una ampliación de TOS se realiza en Differentiated Services (RFC2474), que básicamente define más técnicas para mejorar la calidad de la red.
  • Dentro del campo DS (Differentiated Service), de los 8 bits que lo componen, 6 bits se corresponden con DSCP (Differentiated Service Code Point). Pues sí, DSCP es parte de DiffServ, algo que en la práctica no puede tener mayor repercusión, pero que parece confundir a muchos
En GNU/Linux, la Linux Advanced Routing & Traffic Control debe considerarse La Guía de Referencia sobre QoS en este ambiente. En realidad, trata sobre casi todas las cosas más avanzadas que es posible configurar en la red de un sistema GNU/Linux, así que después después de los primeros capítulos, introductorios, nos interesa Chapter 9. Queueing Disciplines for Bandwidth Management. Es una lectura poco extensa pero que como introducción cumple bastante bien su cometido.
Recomendable leer HTB Linux queuing discipline manual - user guide, manual sobre la disciplina de encolado que vamos a usar, y que representa el núcleo de toda la configuración. De hecho, todo lo demás que puedan ofrecer esta guía proviene de allí, así que igual podría irse a las fuentes originales

Qos no es el mesías hecho software

No va a aumentar el ancho de banda mágicamente. Su función es resolver problemas bien específicos, entre los cuales no está el acelerar la navegación web. Es decir, puede hacerse algo, pero no tanto: Parece que en general, podrían haber cambios de percepción de cara al usuario, pero al final hablamos de un par de milisegundos ganados.

Algunos conceptos a tener en cuenta

A grandes rasgos, tres cosas se realizan dentro de las reglas de QoS: Restringir ancho de banda, modelar colas y clasificar el tráfico para establecer precisamente que tipo de tráfico recibirá que reglas
  • Shaping:  Se refiere a la administración del ancho de banda. Dentro de tc, se realiza con las class
  • Queueing: Se refiere a la forma en modelamos las colas. De hecho, la mayoría de documentación se vertebran respecto a este aspecto. Dentro de tc, se realiza con qdisc (Disciplina de colas)
  • Filter: Clasificar el tráfico es realmente el paso fundamental en QoS. Por diseño, el tráfico en TCP/IP no lo está, clasificarlo es el primer paso de cara a establecer un comportamiento de parte de la red hacia ellos
Pero estos activadades no se corresponden con todos sus componentes. Debería leerse Traditional Elements of Traffic Control, que de todo lo disponible, es la lectura teórica más importante que podría hacer de todo este tema.
Aprovechando, a Components of Linux Traffic Control prácticamente debe memorizarlo

Fuentes y lecturas complementarias

jueves, 12 de octubre de 2017

Resolviendo problemas con Nvidia GLX en Fedora 26

Aunque Fedora 26 ya tenía mucho andando en mi equipo, no había resentido el problema de GLX excepto en algunas cuestiones puntuales:
  • Al intentar ejecutar glxinfo desde consola, aparecía un mensaje de error: BadWindow (invalid Window parameter). También aparecía cuando intentaba acceder a la pestaña
  • También aparecía al intentar acceder a  X Screen 0 > OpenGL/GLX Information en Nvidia X Server Settings
  • Al estar usando LXQT como entorno gráfico, SDDM, el gestor gráfico (No me había dado cuenta de como llamo a estas cosas) no se mostraba en pantalla. Básicamente, SDDM cargaba como pantalla negra (Pero cargaba: Bastaba escribir la contraseña, hacer Enter y cargaba mi sesión) . Este era precisamente lo único que se me antojaba como un error.
Al revisar los log de SDDM, encontré algo parecido a Unrecognized OpenGL Version. Supuse que GLX no cargo y decidí buscar en los log de Xorg en /var/log/Xorg.0.log:
[    35.236] (EE) NVIDIA(0): Failed to initialize the GLX module; please check in your X
[    35.236] (EE) NVIDIA(0):     log file that the GLX module has been loaded in your X
[    35.236] (EE) NVIDIA(0):     server, and that the module is the NVIDIA GLX module.  If
[    35.236] (EE) NVIDIA(0):     you continue to encounter problems, Please try
[    35.236] (EE) NVIDIA(0):     reinstalling the NVIDIA driver.
Revisé con más atención el fichero y me doy cuenta que la carga del módulo ocurre, pero lo hace con el módulo de Xorg
(II) LoadModule: "glx"
(II) Loading /usr/lib/xorg/modules/extensions/libglx.so
(II) Module glx: vendor="X.Org Foundation"
compiled for 7.1.1, module version = 1.0.0
ABI class: X.Org Server Extension, version 0.3
De todas las soluciones posibles (Borrarlo, enlace simbólico, etc), me pareció que la mejor opción era cambiar el nombre del módulo GLX de Xorg para que al no hallarlo cargara el de NVIDIA
cd /usr/lib64/xorg/modules/extensions/
mv libglx.so libglx.xorg.so
Y al reiniciarlo, todo bien, ningún problema

Fuentes: (Lo más cercano que tuve a un consejo)

miércoles, 30 de agosto de 2017

Configurando Squid como proxy transparente HTTPS: Configuración de SslBump en Squid

En este punto, la terminología empieza a ser un poco confusa. Como ya lo he dicho, muchas otras guías consiguen lo mismo en Debian Jessie usando Squid 3.4 (1, 2); CentOS 7 (1 la cual a su modo es muy completa) y CentOS 6 (1) entre otros.

Fue esta guía (Squid (v3.5+) proxy with SSL Bump la que señala la forma correcta de configurar ssl_bump en squid v3.5+; básandome en ella, hago una mejora mínima con la cuestión del certificado.
Crear un certificado puede ser algo tan sencillo como se recoge en Intercept HTTPS CONNECT messages with SSL-Bump, pero ese procedimiento tiene el inconveniente de enviar al cliente la clave pública y privada con la que funciona el servidor. La separamos creando primero la clave privada de la siguiente forma:
 $ openssl genrsa -out myCA.key 4096                                                                                                                                                                          [0/1508]
Generating RSA private key, 4096 bit long modulus
..........++
.....................................................................++
e is 65537 (0x010001)
Y luego la clave pública así:
$ openssl req -sha256 -new -x509 -days 1826 -key myCA.key -out myCA.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:SV
State or Province Name (full name) [Some-State]:San Salvador
Locality Name (eg, city) []:San Salvador
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Dirección Central
Organizational Unit Name (eg, section) []:Establecimiento
Common Name (e.g. server FQDN or YOUR name) []:Establecimiento dependiente
Email Address []:vtacius@gmail.com
Cambiamos un poco el esquema de seguridad para los ficheros de la siguiente forma. Incluso las podría haber mejores
$ usermod -G ssl-cert proxy
$ chmod 770 /etc/ssl/private/
$ chmod 640 myCA.*
$ chown root:proxy myCA.*
$ cp -a myCA.key /etc/ssl/private/
$ cp -a myCA.crt /etc/ssl/certs/
Ahora configuramos precisamente a squid. No se necesita más que asegur tener las siguientes líneas:
http_port 10.168.4.1:3128
http_port 10.168.4.1:3129 transparent
https_port 10.168.4.1:3130 ssl-bump intercept generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/ssl/certs/myCA.crt key=/etc/ssl/private/myCA.key

...
ssl_bump stare all
ssl_bump splice all
...
La configuración de ssl_bump aún sigue siendo un poco complicada, aún cuando existe bastante documentación al respecto, hasta ahora entiendo que va de esta forma:
  • ssl_bump stare all:  Básicamente, permite una primera conexión con el servidor remoto. Por este paso es que se requiere que los clientes que usen proxy transparente tenga bien configurado la resolución DNS. Y no, no encuentro una mejor forma de cambiar este paso, si no se especifica, pues que la conexión no realiza bien.
  • ssl_bumps splice all: En esta parte hacemos precisamente la conexión. Usar splice en lugar de bump permite al tráfico salir con menos trabajo por parte del servidor. En este punto, ni siquiera entiendo para iría a necesitar tanto trabajo por parte del proxy
En las guías anteriores, se recomiendan configuraciones como
ssl_bump server first all  
sslproxy_cert_error deny all  
sslproxy_flags DONT_VERIFY_PEER 
Pero ninguna de estas deberían ser necesarias para esta versión de squid. La otra opción que valdría la pena configurar es:
sslcrtd_program /usr/lib/squid/ssl_crtd -s /var/lib/squid_ssl/ -M 4MB
Ya que los valores por defecto no están del todo bien:
sslcrtd_program /usr/local/squid/libexec/ssl_crtd -s /var/lib/ssl_db -M 4MB
En ambos casos, es necesario inicializar el directorio mencionado:
/usr/lib/squid/ssl_crtd -c -s /var/lib/squid_ssl/
Initialization SSL db...
Done
TODO: Pueden hacerse bastante mejoras aún con el certificado

martes, 29 de agosto de 2017

Configurando Squid como proxy transparente HTTPS: Squid con soporte SSL

 Build errors with Squid 3.5.24 under Debian
La mejor forma de modificar los parámetros de compilación en Debian es mediante sus herramientas de compilación, casi, casi como si fuéramos a trabajar como empaquetadores.

Que bien podría bajarse el source desde la página oficial, pero había que configurar más cosas a manos y olvidarnos del soporte de Debian; podríamos bajar una versión o rama más novedosa (Para squid, v4 esta en Beta, aunque la gente de Fedora ya la considera lo suficientemente estable como para incluirla como versión por defecto)

Por tanto, los pasos a realizar serán básicamente los siguientes:
apt-get install dpkg-dev devscripts quilt libcrypto++-dev libssl1.0-dev

mkdir /root/paquetes
chown _apt -R paquetes/
cd paquetes/ 
apt-get source squid
apt-get build-dep squid

# Podríamos verificar el caso improbable que el proceso de compilación del paquete tenga problemas
cd squid3-3.5.23/ 
debuild -b -uc -us
Respecto al siguiente paso, hay varias versiones de lo que podríamos hacer. El parche podría trabajarse de la siguiente forma
quilt push -a
quilt new 0032-add_ssl_crtd.patch
quilt add debian/rules
## Hacemos la modificación en este punto
quilt refresh
quilt pop -a -f
Pero es un poco innecesario, creo que realizando la modificación directamente en el fichero correpondiente, debian/rules no debería haber mayores problemas: Modificamos DEB_CONFIGURE_EXTRA_FLAGS agregando estas opciones:
vim debian/rules
+       --with-openssl \
+       --enable-ssl-crtd \
Sea como sea, una vez modificadas las reglas de configuración previas, podemos contruir el paquete.
debuild -b -uc -us
Pues deberían haberse construido los paquetes y podemos probar a instalar en el mismo equipo
apt-get install squid-langpack libdbi-perl libcap2-bin libecap3
dpkg -i ../squid-common_3.5.23-5_all.deb ../squid_3.5.23-5_amd64.deb ../squid3_3.5.23-5_all.deb
Ahora, la mejor recomendación que puedo hacer es que se construyan los paquetes en un equipo diferente al firewall. Una máquina virtual incluso debería funcionar Una vez contruidos, los enviamos al firewall y lo instalamos de la siguiente forma:
apt-get install squid-langpack libdbi-perl libcap2-bin libecap3 libssl1.1
dpkg -i squid_3.5.23-5_amd64.deb squid-common_3.5.23-5_all.deb squidclient_3.5.23-5_amd64.deb squid3_3.5.23-5_all.deb
# A partir de este punto, todo paquete que dependa de squid se dará por satisfecho. Por ejemplo
apt-get install squidguard{,-doc} sarg
Escojo pinning como método para evitar que el paquete sea actualizado
cat <<MAFI >/etc/apt/preferences.d/squid
Package: squid 
Pin: release n=stretch
Pin-Priority: -1

Package: squid3
Pin: release n=stretch
Pin-Priority: -1

Package: squid-common
Pin: release n=stretch
Pin-Priority: -1

Package: squidclient
Pin: release n=stretch
Pin-Priority: -1
MAFI
Fuentes: 1, 2

lunes, 28 de agosto de 2017

Configurando Squid como proxy transparente HTTPS: Introducción

La comunidad ha esperado mucho para llegar a este punto. Los manuales sobre la configuración aún siguen siendo bastante confusos al respecto, pero al fin logré una configuración funcional a integrar en mi proyecto ya existente.

Descrito pronto, el proyecto usa a squid como proxy caché, y este, usa a squidGuard mediante  url_rewrite_program para filtrar la navegación de los usuarios mediante las listas negras de shallalist .

Esta configuración mejora el proyecto en dos cosas básicamente:
  • Los usuarios no necesitan configurar proxy para navegar por HTTPS (Aunque si necesitarían instalar un certificado)
  • Los usuarios podrán ver un mensaje de error cuando navegan a un sitio bloqueado que usa HTTPS, aunque parezca poca cosa, se considera en realidad un gran avance de cara a los usuarios
 En este momento, me preocupan dos cosas que también deberían preocuparle a todos los que quieran seguir esta guía:
  • El rendimiento por parte de squid para servir las páginas
  • ¿Tendrá algún sitio demasiados problemas para funcionar con esta configuración?
Al momento de escribir esta entrada, esta configuración no ha entrado en producción, so...

Tome en cuenta que como debo instalar en varios firewall, la idea será compilar en un equipo independiente de lo que sea el firewall. De hecho, aún cuando se compile para un sólo equipo, debería considerar trabajar de esta forma.

Voy a repetir lo que ya se ha dicho hasta el cansancio: Hay cuestiones éticas muy importantes en esta configuración. Básicamente, lo mejor es explicar al usuario lo que se esta haciendo.

jueves, 22 de junio de 2017

Apuntes sobre el error de Squid / SquidGuard en Debian: Solucionado

La nueva versión de Debian ha salido el sábado pasado. Y me aventuré a probar que se hubiera solucionado el problema con redirector protocol que detuvo tan mal a mi proyecto de firewall.

Pues resulta que no, el problema seguía siendo tal, pero esta vez tenía un poco más de tiempo disponible que la última vez (Y un problema más serio, al estar dos lanzamientos atrasados con el sistema base).

Lo quiero resumir de esta forma: El problema no era tal.
Básicamente porque es un problema que es posible resolver con un cambio en la configuración, no se debía (No del todo, al menos) a un falta de actualización en la forma en que squidGuard entendía el redirector protocol, como yo pensé en mi primer post

El truco está en la configuración del redirector en Squid. Por defecto, yo tenía
url_rewrite_children 15 startup=0 idle=1 concurrency=3
Pero según la documentación en Squid configuration directive url_rewrite_children:
concurrency=

 The number of requests each redirector helper can handle in
 parallel. Defaults to 0 which indicates the redirector
 is a old-style single threaded redirector.

 When this directive is set to a value >= 1 then the protocol
 used to communicate with the helper is modified to include
 an ID in front of the request/response. The ID from the request
 must be echoed back with the response to that request.
 
La cuestión es que al programa configurado como redirector le debe llegar una petición por parte de squid de la siguiente forma:
"http://www.google.com.sv/ 10.168.3.5/10.168.3.5 - GET myip=10.168.3.1 myport=3128";
Pero configurado concurrency, tal como lo ha dicho la documentación, se le antepone un identificador, de modo que la consulta queda de la siguiente forma.
"0 http://www.google.com.sv/ 10.168.3.5/10.168.3.5 - GET myip=10.168.3.1 myport=3128";
Lo que pasa es que lo interpreta mal: Para el, la URL que se solicita es 0 y el identificador del cliente es la URL; de hecho, toma a http: como la dirección IP del cliente, es decir, la primera parte de ip_cliente/fqdn...

La solución es algo tan sencillo como retirar concurrency:
url_rewrite_children 15 startup=0 idle=1 concurrency=0 

Si bien squidGuard debería ser capaz de manejar este problema, pues no, no voy a reclamarle tanto a la única opción viable frente a cosas como e2guardian.
Yo mismo he intentando parchear el paquete en Debian, intentando quitar el ID de la petición antes de que squidGuard lo siguiera parseando, pero tampoco, es que aunque ha funcionado parece que todo va mal, las respuestas hacia el cliente ralentizan la navegación. Que ni siquiera revisé los log de Squid con mayor detenimiento, es que tampoco tengo todo el tiempo del mundo.

Otros apuntes interesantes

Otros apuntes interesantes