Administrando anchos de banda en la red usando QoS en GNU/Linux

Que desastroso resulta en muchas ocasiones administrar algo tan simple como una red, especialmente cuando existen usuarios en ella que les importa poco el trabajo de quienes si quieren trabajar en internet.

No me explayare mucho en este asunto, muchos manuales y tutoriales hay de QoS, yo me dedicare a explicar brevemente como implementar uno

QoS es calidad de servicio, prácticamente lo contrario a DoS denegación de servicio, la calidad trata de asegurarse de que el servicio siempre esté disponible.

Como evitar que Paquito bajando 20 canciones en el ares o Manuelito bajando 2 distribuciones de Linux por FTP consuman todo el ancho de banda disponible y evitando que Pedro no pueda ver la pagina de Continental Airline para comprar ese boleto de avión urgente y que no lo puede comprar por que la pagina esta tan lenta que no termina de cargar nunca, por la falta de ancho de banda disponible.
En una red pequeña Pedro se levantaría y les pediría a Paquito y Manuelito, que dejen de perder el tiempo y que lo dejen trabajar, pero en un corporativo con cientos de empleados a veces no sabes ni quien es el gandalla comiéndose todo el ancho de banda y es aquí donde QoS salva el dia.

Una tarjeta de red o cualquier dispositivo de Red se comporta como buffer de tipo FIFO, Primero en entrar, Primero en salir, Estos buffer se le denominan colas de paquetes y por default están presente en modo FIFO en la mayoría de los sistemas operativos y esta cola tiene un ancho de banda, del total de la tarjeta, que es de 10Mbps o 100Mbps o 1000Mbps dependiendo de la tarjeta de red o el dispositivo conectado como DSL que suelen tener solo 2Mbps a 8Mbps de ancho de banda de bajada y 512kbps de subida
¿Esto que significa?
Significa que si entra primero 20 paquetes de ares a la cola y el 21 es de web, saldrán primero los 20 de ares y hasta el final el de web, en una oficina esto es absurdo, aunque entraran los 20 paquetes de ares seria natural que quisiéramos que primero salgan los de web porque es de trabajo y hasta el final los de ares. En resumen ares se gasta el ancho de banda y no deja casi nada para navegar en páginas web.

Si tenemos un equipo Linux con almenos 2 tarjetas de red haciéndola de ruteador o de enmasquerador con NAT, podemos controlar el tráfico que saldrá a internet, ordenando los paquetes con prioridades haciendo de esta forma una red muy veloz aunque haya gente bajando música con P2P como ares y otros.

¿Que es lo que podemos hacer y que no.?

Podemos controlar todo el tráfico que inicia en nuestra red hacia internet, no podemos controlar el tráfico que inicia en otro lado fuera de nuestra red, y que viene a nuestra red, esto es porque los paquetes vienen en desorden al estilo FIFO desde su punto de origen, existen módulos como el IMQ para Linux que pueden controlar el tráfico que no iniciamos nosotros, mediante discriminación de paquetes con una efectividad del 90% pero no hablare de este modulo aquí.

¿Qué necesitamos?

El paquete iproute2 e iptables, iproute2 agrega el comando tc para controlar las colas e iptables nos permitirá manipular los paquetes que llegan a las colas

¿Qué hay que hacer para controlar nuestro ancho de banda en la red?

Lo primero es cambiar la forma FIFO en la que opera la tarjeta de red a htb , le cambiare el ancho de banda a la velocidad del ancho de banda del enlace de internet, de nada sirve una tarjeta de red de 100mbps conectada directamente a internet, si el enlace es de, por ejemplo 2mbps asi que no habrá ningún inconveniente con limitarlo a eso que luego nos servidora para hacer un ancho de banda dinamico, después de ese ancho de banda de 2mbps creare subanchos de banda en colas con prioridades, después a estos subanchos de banda les pondré su propio buffer o cola de nuevo con htb y con iptables marcare los paquetes para filtrarlos a estos sub colas de los subanchos de banda del ancho de banda principal de la tarjeta de red =)

¿Por qué es tan de locos esto del QoS con htb?

FiFo es fácil porque es entrada y salida de datos como llegan, consumiendo a su vez todo el ancho de banda disponible, pero htb permite prioridad y heredar ancho de banda sobrante hasta un límite establecido.

Por ejemplo si tenemos un enlace de 2mbps y queremos 3 niveles de prioridades, acomodaremos los servicios en esos niveles según su importancia.

Por ejemplo si es importante el WEB haremos que el WEB salga por la cola 1 y le podemos dar una GARANTIA, que al menos 1mbps de los 2mbps estarán disponibles para web, el otro mega se reparte entre las otras colas, pero que pasa si las otras colas no tienen tráfico, habría 1mbps desperdiciado, así que podemos tomar ese ancho de banda dinámicamente asignarlo al web.
Para entender mejor, le garantizamos 1mbps pero puede navegar a 2mpbs si el ancho de banda está disponible

Ahora imaginemos que en de esos 2mbps le queremos garantizar 512kbps al FTP en una prioridad 2 esto significaría que bajaran cosas a 512kbps pero si nadie esta navegando en internet podría usar también los 2mbps disponibles

Lo mismo para el ARES en la cola mas baja le garantizamos 512kbps y si nadie esta bajando paginas web ni ftp ares tendra los 2mbps.

En el momento que alguien navegue en páginas web el ares será relegado y así, la páginas WEB navegaran a un mega, si nadie estuviera bajando nada por el FTP el ares podría continuar bajando ahora con el mega sobrante, hasta el momento en que alguien decida bajar algo del FTP entonces seria relegando nuevamente a su ancho de banda garantizado que es de 512kbps por el ftp tiene garantizado 512kbps. Cuando ya nadie baje nade de la web y el ftp haya terminado su descarga. El ARES podrá recuperar el uso de los 2Mbps-

Ahora la práctica, como implementarlo.
Para esta práctica asumiremos que el servidor de NAT o Ruteo tiene 3 tarjetas de red, la eth2 es la que está conectada a internet.

Para confirmar el estado de nuestra tarjeta de red podemos usar el comando

tc -s -d qdisc show dev eth2
qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 17459001308 bytes 20574182 pkt (dropped 0, overlimits 0 requeues 6)
rate 0bit 0pps backlog 0b 0p requeues 6

Encontramos que se encuentra en el modo pfifo_fast de Linux, que es simplemente el método FIFO tradicional de toda tarjeta

Cambiando la cola de FIFO a htb en la tarjeta de red

tc qdisc add dev eth2 root handle 1: htb default 11

el comando agrega al eth2 la cola física de la tarjeta de red el método htb además le puso un nombre, la llamo 1: y el parámetro default 11 indica que espera encontrar una subcola llamada 11 por donde pasaran los datos que no fueron clasificados, generalmente el default es la cola de más baja prioridad, ya que si no los clasificas seguramente es porque son servicios que importan menos que los que clasificaste como prioritarios.

Volvemos a ejecutar el comando

tc -s -d qdisc show dev eth2
para ver que sucedio con la tarjeta de red, el resultado sera:

qdisc htb 1: r2q 10 default 11 direct_packets_stat 1732 ver 3.17
Sent 1558805 bytes 1732 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0

ya no es pfifo_fast es htb

Ahora limitare el ancho de banda físico en la cola de la tarjeta de red, lo bajare a la velocidad de 2mbps
Con el comando

tc class add dev eth2 parent 1: classid 1:1 htb rate 2000kbit ceil 2000kbit
Es importante saber que rate es el ancho de banda garantizado y ceil el tope máximo del ancho de banda alcanzable.
las class son las colas virtuales, en este caso esta cola está ligada a la de la tarjeta de red, la de la red la llamamos 1: aquí le decimos con parent 1: que esta cola se ligara a su padre en la tarjeta de red y classid 1:1 es el nombre que tendrá esta cola con un ancho de banda garantizado (rate) de 2000kbps y que nunca habrá mas (ceil) de 2000kbps como ancho de banda por que este es el ancho de banda máximo del enlace dedicado

Ahora es tiempo de partir en pedazos más pequeño la cola 1:1, esto lo hacemos con el comando

tc class add dev eth2 parent 1:1 classid 1:10 htb rate 1512kbit ceil 2000kbit
esta línea dice que esta cola es hija de la cola anterior (parent 1:1) y que esta a su vez se llama 1:10 continua usando el método htb, le decimos que está sub cola garantiza 1.5 mbps (rate 1512kbps) pero que podría alcanzar hasta los 2mbps (ceil 2000kbps) si el ancho de banda estuviera disponible, al final de la línea debería ir un prior 0, mientras más baja es la prioridad más importante es la cola prior 0 es más importante y ojo, no se especifica cuando es 0, solo cuando es menos importante como 1, 2 o 3 y así.

Ahora creamos la cola menos importante

Con el comando

tc class add dev eth2 parent 1:1 classid 1:11 htb rate 512kbit ceil 2000kbit prio 1
Esta cola también es hija de 1:1 y hermana de 1:10 se llama así misma 1:11, recuerdan el default en la cola física de la tarjeta de red, se llamaba 11, efectivamente esta es la cola a la que vendrán los paquetes no clasificados, a esta cola se le garantizan 512kbps pero si está disponible más ancho de banda puede llegar a usar hasta 2mbps, la prioridad dice que es 1 menos importante que 0 así como otras subcolas con prior 2 o 3 sería menos importantes que prior 1

Con el comando tc -s -d class show dev eth2 , se puede visualizar el trafico que pasa por cada cola.

tc -s -d class show dev eth2

obtendríamos algo como esto:

class htb 1:11 parent 1:1 prio 1 quantum 6400 rate 512000bit ceil 2000Kbit burst 1664b/8 mpu 0b overhead 0b cburst 1850b/8 mpu 0b overhead 0b level 0
Sent 9870557 bytes 9434 pkt (dropped 0, overlimits 0 requeues 0)
rate 1233Kbit 148pps backlog 0b 23p requeues 0
lended: 2433 borrowed: 6978 giants: 0
tokens: -27390 ctokens: -10484

class htb 1:1 root rate 2000Kbit ceil 2000Kbit burst 1850b/8 mpu 0b overhead 0b cburst 1850b/8 mpu 0b overhead 0b level 7
Sent 9847632 bytes 9411 pkt (dropped 0, overlimits 0 requeues 0)
rate 1262Kbit 152pps backlog 0b 0p requeues 0
lended: 6978 borrowed: 0 giants: 0
tokens: -10484 ctokens: -10484

class htb 1:10 parent 1:1 prio 0 quantum 18900 rate 1512Kbit ceil 2000Kbit burst 1788b/8 mpu 0b overhead 0b cburst 1850b/8 mpu 0b overhead 0b level 0
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
lended: 0 borrowed: 0 giants: 0
tokens: 9465 ctokens: 7400

hay 3 colas!!! Exacto, la cola padre que es la de la tarjeta de red, y las 2 hijas

Recordemos que todo trafico no clasificado por default se va a la hija 11, si ponen atención verán que el valor send del 1:10 esta en 0, esto es porque no hay tráfico en la cola prioritaria, no lo hay porque no hemos clasificado nada toda la red esta desclasificada asi que todo los paquetes que van a internet se van a la cola 11, no hay problema, recordemos que en el ceil dijimos que podría alcanzar 2mbps si el ancho de banda está disponible, asi que en este punto todos siguen navegando a 2mbps sin ningún problema

Ahora se agrega otra cola a las colas hijas, pero con el método sfq que permite reorganizar paquetes del mismo tipo, para que salgan juntos, de esta forma intentaremos que si en las colas hay paquetes desordenados, digamos defragmentados, ya que es un término mejor conocido por el comportamiento de los archivos del disco duro. El sfq los defragmenta para que los paquetes de web salgan todos juntos, los de ftp salgan todos juntos, y así, esto le diremos que lo haga cada 10 segundos que es un tiempo razonable. Para reorganizar los paquetes en la cola.

Entonces si en la cola había estos paquetes por ejemplo:

Web,ftp,ssh, web,ssh,ftp,ftp,web el sfq los dejara asi
Web,web,web,ftp,ftp,ftp,ssh,ssh

Esto lo hacemos con los siguientes comandos.

tc qdisc add dev eth2 parent 1:10 handle 10: sfq perturb 10

esta cola es hoja de 1:10 (parent 1:10) asi misma se llamara 10 (handle 10) con el método sfq que sucederá cada 10 segundos y para la otra cola igual
tc qdisc add dev eth2 parent 1:11 handle 11: sfq perturb 10

Nótese que esto es jerárquico, las colas sfq nietas de la cola de 2mbps, le entregan la cola a las hijas htb de la cola de 2mbps htb y esta ultima a la cola de su propio padre que es la tarjeta de red que también es htb

Hasta aquí está bien, ya organizamos paquetes y sabemos la prioridad, pero aun no hemos clasificado los paquetes por lo que si volvemos a ver la información de las colas, la 1:10 seguirá en 0 bytes enviados, la cola que se moverán seguirá siendo la 11 porque es la default y por ahí sigue pasando todo el trafico de la red, porque todo continua sin clasificarse.

Preparando las colas para recibir paquetes clasificados

tc filter add dev eth2 protocol ip prio 1 parent 1: handle 1 fw classid 1:10
filtramos protocol ip prioridad 1 (mas alta en filtracion) de la cola padre 1: manejara paquetes firmados con la marca 1 (handle 1) estos paquetes sera reenviados (fw) a la clase 1:10
tc filter add dev eth2 protocol ip prio 2 parent 1: handle 2 fw classid 1:11
igual que el anterior, pero con prioridad menor (2) los paquetes con la marca 2 se reenvían a la cola 1:11. OJO en esta configuración podríamos omitir este comando, recordemos que todo lo que no esté firmado o marcado, de todos modos terminara en la cola 11 es la default.

En este punto ya hay un filtrador de colas esperando paquetes con marcas 1 y 2, pero, ¿Quién marca esos paquetes?, no hay ningún paquete marcado a pesar de contar con los filtros los paquetes no vienen marcados así que en este momento continuamos con que la única cola en movimiento es la 11 porque la 10 no recibe paquetes, ya que físicamente ningún paquete viene con la marca 1 que es la marca que los filtraría a la cola prioritaria.

Es hora de iptable para marcar con mangle

iptables -t mangle -A FORWARD -p tcp –dport 80 -j MARK –set-mark 1
iptables -t mangle -A FORWARD -p tcp –dport 80 -j RETURN

Todo el tráfico que mandamos a internet que sea un paquete tcp y que lleve por destino el Puerto 80 deberá ser marcado como 1, la segunda línea la del return indica que no debe ser remarcado, fue marcado como 1 y con esa debe quedarse, por si hubiera por la red algún otro equipo remarcando paquetes.

LISTO!!!!!, comprobando que es verdad

tc -s -d class show dev eth2

debemos obtener algo como esto

class htb 1:11 parent 1:1 prio 1 quantum 6400 rate 512000bit ceil 2000Kbit burst 1664b/8 mpu 0b overhead 0b cburst 1850b/8 mpu 0b overhead 0b level 0
Sent 524112583 bytes 499349 pkt (dropped 0, overlimits 0 requeues 0)
rate 1971Kbit 230pps backlog 0b 41p requeues 0
lended: 128668 borrowed: 370640 giants: 0
tokens: -14475 ctokens: -8151

class htb 1:1 root rate 2000Kbit ceil 2000Kbit burst 1850b/8 mpu 0b overhead 0b cburst 1850b/8 mpu 0b overhead 0b level 7
Sent 524189335 bytes 500233 pkt (dropped 0, overlimits 0 requeues 0)
rate 1980Kbit 241pps backlog 0b 0p requeues 0
lended: 370640 borrowed: 0 giants: 0
tokens: -11447 ctokens: -11447

class htb 1:10 parent 1:1 prio 0 quantum 18900 rate 1512Kbit ceil 2000Kbit burst 1788b/8 mpu 0b overhead 0b cburst 1850b/8 mpu 0b overhead 0b level 0
Sent 121393 bytes 925 pkt (dropped 0, overlimits 0 requeues 0)
rate 8752bit 10pps backlog 0b 0p requeues 0
lended: 925 borrowed: 0 giants: 0
tokens: 9127 ctokens: 7144

En la cola 10, ya hay movimiento ya le llegan los paquetes de tráfico WEB el cual en esta configuración decidimos que es más importante que cualquier otro paquete, podríamos tener más colas e incluso colas que comparten varios servicios por ejemplo podemos marcar el ssh en la cola prioritaria

iptables -t mangle -A FORWARD -p tcp –dport 22 -j MARK –set-mark 1
iptables -t mangle -A FORWARD -p tcp –dport 22 -j RETURN

Con eso todo paquete ssh se marca con 1, compartiendo prioridad con los paquetes de WEB

¿Qué es lo que tenemos?

Tenemos un ancho de banda de 2mbps
El WEB es metido en la cola de prioridad 0 que tiene un ancho de banda garantizado de 1.5mbps y pudiendo llegar a 2mbps si los otros 512kbps no estan siendo usados.

Tenemos que el resto del tráfico no marcado como 1 se va a la cola de 512kbps pudiendo llegar a 2mbps si no hay trafico prioritario en la cola de 1.5mbps

En resumen, en el caso de ARES podríamos bajar ARES a 2mbps siempre y cuando nadie navegue en internet, si alguien navega a 1.5mbps en las páginas web, los ares de la red y otros servicios se quedaran con su ancho de banda garantizado de solo 512kbps

Controlando todas las conexiones que inician desde dentro de nuestra red local y van hacia internet.

Toda esta explicación puede verse aparatosa y complicada, no lo es, de hecho no hemos tipiado mas e 10 comandos

tc qdisc add dev eth2 root handle 1: htb default 11

tc class add dev eth2 parent 1: classid 1:1 htb rate 2000kbit ceil 2000kbit

tc class add dev eth2 parent 1:1 classid 1:10 htb rate 1512kbit ceil 2000kbit prior 0
tc class add dev eth2 parent 1:1 classid 1:11 htb rate 512kbit ceil 2000kbit prio 1

tc qdisc add dev eth2 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth2 parent 1:11 handle 11: sfq perturb 10

tc filter add dev eth2 protocol ip prio 1 parent 1: handle 1 fw classid 1:10
tc filter add dev eth2 protocol ip prio 2 parent 1: handle 2 fw classid 1:11

iptables -t mangle -A FORWARD -p tcp –dport 80 -j MARK –set-mark 1
iptables -t mangle -A FORWARD -p tcp –dport 80 -j RETURN

Antes de subir este articulo google por otros artículos similares, como dije al inicio, hay un montón de ellos. Pero encontré uno que explican este mismo método el htb desde otro enfoque y al leerlos puede quedar bien claro lo que explique aquí.

QoS Parte 1
http://cafetera.etsit.upv.es/~carlos/carblog/2007/01/30/qos-local-en-linux-i/
QoS Parte 2
http://cafetera.etsit.upv.es/~carlos/carblog/2007/01/31/qos-local-en-linux-ii/
QoS Parte 3
http://cafetera.etsit.upv.es/~carlos/carblog/2007/02/02/qos-local-en-linux-iii/

IMQ;
http://www.etxea.net/docu/qos/qos.html

Este otro artículo incluye información de IMQ para quienes intenten controlar el tráfico de entrada, es útil si se quiere evitar DoS o administrar el ancho de banda que invertirnos en los servicios que publicamos a internet hosting WEB, correo, ftp y todas las conexiones que podríamos recibir.

21 Comments

Add a Comment

Comment spam protected by SpamBam