Mostrando entradas con la etiqueta QoS. Mostrar todas las entradas
Mostrando entradas con la etiqueta QoS. Mostrar todas las entradas

viernes, 1 de diciembre de 2017

Otro intento para configurar QoS en Linux: Día 2

Hasta el momento y a grandes rasgos, hemos limitado el uso de ancho de banda a un límite especifíco. Luego, hemos modelado la cola para que esta reparta el uso de ancho de banda de manera casi equitativa entre todas las conexiones: Dicha política se verifica para todo el tráfico en nuestra red.

Lo siguiente será hacer una configuración que planteé precisamente el significado de QoS: Clasificaremos tráfico y vamos a aplicarle políticas específicas a cada tipo de tráfico. Puede pensarse un poco al revés: Estableceremos políticas y luego vamos a especificar a que tráfico le aplicamos cada una.

El primer intento de configuración va de la siguiente forma:
#!/bin/bash

## Borramos la configuración anterior. 
## Cuando se tenga la configuración por defecto, se lanza un mensaje de error "RTNETLINK answers: No such file or directory"
tc qdisc delete dev ens2 root

## Cambiamos qdisc de fast_fifo a htb. 
## Dentro del esquema de HTB, este es llamado ROOT
tc qdisc add dev ens2 root handle 1:0 htb default 10

## Agregamos la primera clase. 
## Dentro del esquema de HTB, este es llamado INNER. No hay shapping en este momento, pero es necesario configurarle para el funcionamiento de los leaf
tc class add dev ens2 parent 1:0 classid 1:1 htb rate 20480 ceil 20480

## Dentro del esquema de HTB, este es llamado LEAF. Este determina la política por defecto 
tc class add dev ens2 parent 1:1 classid 1:10 htb rate 2540 ceil 2540
### Creamos los nuevos LEAF que describen dos nuevas políticas para el tráfico. 
tc class add dev ens2 parent 1:1 classid 1:20 htb rate 7680 ceil 7680
tc class add dev ens2 parent 1:1 classid 1:22 htb rate 10240 ceil 10240

## Dentro de cada clase LEAF, agregamos una QDISC de tipo SFQ. 
## SFQ intentará repartir el ancho de banda de forma más o menos equitivativa
tc qdisc add dev ens2 parent 1:10 handle 130: sfq perturb 5
tc qdisc add dev ens2 parent 1:20 handle 140: sfq perturb 5
tc qdisc add dev ens2 parent 1:22 handle 150: sfq perturb 5

## Filtro en tc
## Se especifica mediante los filtros de tc que tráfico se envía a que política
## Usamos el filtro handle, es bastante simple y económico en términos de procesamiento
tc filter add dev ens2 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20
tc filter add dev ens2 parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:22

## Pre-filtro en iptables
## Este es precisamente el filtraje del tráfico: Marcamos con iptables que tráfico es cada cosa
iptables -t mangle -F
iptables -t mangle -A POSTROUTING -p tcp -m multiport --sport 22 -j MARK --set-mark 20
iptables -t mangle -A POSTROUTING -p tcp -m multiport --dport 80,443 -j MARK --set-mark 22
Las clases por ahora se ven de la siguiente forma:
tc class show dev ens2
class htb 1:22 parent 1:1 leaf 150: prio 0 rate 10240bit ceil 10240bit burst 1600b cburst 1600b
class htb 1:1 root rate 20480bit ceil 20480bit burst 1600b cburst 1600b
class htb 1:10 parent 1:1 leaf 130: prio 0 rate 2536bit ceil 2536bit burst 1599b cburst 1599b
class htb 1:20 parent 1:1 leaf 140: prio 0 rate 7680bit ceil 7680bit burst 1599b cburst 1599b
La configuración consta de dos políticas implicítas y una por defecto. Limitan el ancho de banda: El tráfico SSH (Por ahora tendremos que servirnos de este) a 750kbps; tráfico web a 1 Mbps y el demás tráfico, todo aquello que no hallamos considerado, a 250kbps. Revisemos como es que funciona una configuración de este tipo
Un ping con alta latencia. Veamos que pasa al agregar un poco de tráfico HTTPS
La latencia del ping no cambia tanto como se espera, por otro lado, la descarga web parece ir bastante bien. Al agregar un poco de tráfico FTP, bastante conocido por saber acaparar el ancho de banda, tenemos lo siguiente
El uso de ancho de banda para FTP esta bastante contenido y apenas hizo mella en la descarga HTTP. Por ahora hemos verificado que los límites para el ancho de banda en realidad funciona. Hay un problema al que no pude sacarle captura de pantalla pero que se adivina en la alta latencia del ping: DNS puede llegar a dar timeout en estas condiciones. Esto es por la naturaleza misma del tráfico DNS. La solución a este problema es establecer prioridades para las políticas. Por defecto, todos tienen prioridad 0, así que en realidad lo que se hace es quitarle prioridad a ciertas reglas con la opción prio
...
## Dentro del esquema de HTB, este es llamado LEAF. Este determina la política por defecto 
tc class add dev ens2 parent 1:1 classid 1:10 htb rate 2540 ceil 2540 prio 1
### Creamos los nuevos LEAF que describen dos nuevas políticas para el tráfico. 
tc class add dev ens2 parent 1:1 classid 1:20 htb rate 7680 ceil 7680 prio 0
tc class add dev ens2 parent 1:1 classid 1:22 htb rate 10240 ceil 10240 prio 1
... 
Y marcar el tráfico ICMP de la siguiente forma
...
iptables -t mangle -A POSTROUTING -p icmp -j MARK --set-mark 20
...
Ahora, la tasa de transferencia para HTTP sigue con el mismo rendimiento: Es el tráfico ICMP el beneficiado, es posible ver como la latencia ha bajado considerablemente
En este punto, las políticas garantizan una máxima tasa de transferencia para el tráfico que así lo necesita, y la menor latencia posible para el tráfico que así lo requiera.

miércoles, 25 de octubre de 2017

Otro intento para configurar QoS en Linux: Día 1

Nota: Pues que creo que he tenido problemas con las capturas de pantalla y no se corresponden del todo con el trabajo en curso. Igual lo publico, así las cosas. Excepto ese pequeño detalle, todo lo demás es funcional

La idea es que modelemos el tráfico de nuestra red aplicando la siguiente configuración en nuestro firewall linux. O en nuestro IPS inline, que no es tan mala idea como en un principio lo parece. Que incluso puede hacerse una cajita específicamente para esto: Lo importante es que la configuración de este equipo pueda modelar todo el tráfico de nuestra red, al pasar toda nuestra red mediante él.

Por defecto, nuestra configuración tiene la siguiente forma:
tc qdisc show 
qdisc noqueue 0: dev lo root refcnt 2
qdisc pfifo_fast 0: dev ens2 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: 10.dev ens3 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev ens4 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev ens9 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
El usuario lo vería de la siguiente manera:

Empezamos con lo que podría considerarse una configuración mínima para hacer shaping:
#!/bin/bash

## Borramos la configuración anterior. 
## Cuando se tenga la configuración por defecto, se lanza un mensaje de error "RTNETLINK answers: No such file or directory"
tc qdisc delete dev ens2 root

## Cambiamos qdisc de fast_fifo a htb. 
## Dentro del esquema de HTB, este es llamado ROOT
tc qdisc add dev ens2 root handle 1:0 htb default 10

## Agregamos la primera clase. 
## Dentro del esquema de HTB, este es llamado INNER. No hay shapping en este momento, pero es necesario configurarle para el funcionamiento de los leaf
tc class add dev ens2 parent 1:0 classid 1:1 htb rate 20480 ceil 20480

## Dentro del esquema de HTB, este es llamado LEAF. Acá ocurre el shapping por primera vez
tc class add dev ens2 parent 1:1 classid 1:10 htb rate 20480 ceil 20480

## Dentro de la última (Y única por ahora) clase LEAF, agregamos una QDISC de tipo SFQ. 
## SFQ intentará repartir el ancho de banda de forma más o menos equitivativa
tc qdisc add dev ens2 parent 1:10 handle 130: sfq perturb 5


Ahora, estamos configurados de la siguiente forma:
tc qdisc show dev ens2
qdisc htb 1: root refcnt 2 r2q 10 default 10 direct_packets_stat 0 direct_qlen 1000

tc class show dev ens2
class htb 1:10 parent 1:1 leaf 130: prio 0 rate 20480bit ceil 20480bit burst 1600b cburst 1600b
class htb 1:1 root rate 20480bit ceil 20480bit burst 1600b cburst 1600b
El resultado es que ahora nos vamos limitar: 20480bit representa un enlace de 2 MB/s. Desde el punto de vista del cliente nos vemos de la siguiente forma: Al iniciar ambas peticiones casi al mismo tiempo, el uso de ancho de banda se reparte casi igual
Conforma pasa el tiempo, el tráfico para FTP-DATA consigue un mejor rendimiento. Luego, también podría ocurrir si se inicia la descarga de FTP primero:
En general, con pfifo_fast ocurrirá que algunas conexiones irán mejor que otras. Posiblemente las más nuevas (Esto es bien común de verificar). Algunos protocolos sbbre otros. Para tener mejor idea, descargo el mismo contenido usando HTTP en ambos clientes
El cliente a la derecha descarga con todo el ancho de banda disponible en ese momento

Cuando empieza la descarga en el cliente a la izquierda, este es claramente beneficiado de un mejor ancho de banda

Una solución a este problema (Que el ancho de banda se reparta mejor entre todas las conexiones), es usar una disciplina de cola en la clase leaf. SFQ es bastante sugerido para esta trabajo en específico. Agremos lo siguiente al final del script anterior

## Dentro de la última (Y única por ahora) clase LEAF, agregamos una QDISC de tipo SFQ.
## SFQ intentará repartir el ancho de banda de forma más o menos equitivativa
tc qdisc add dev ens2 parent 1:10 handle 130: sfq perturb 5
Una vez configurado así, no importa en que momento inicia la descarga el uno o el otro: Ambas conexiones tienen casi el mismo ancho de banda disponible. El "casi" es importante. SFQ "intenta" darles el mismo ancho de banda a ambas conexiones. Con todo lo que lleva en contra, parece que hace un trabajo bastante aceptable

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

Otros apuntes interesantes

Otros apuntes interesantes