Este documento intenta ser un documento para una primera y rápida aproximación al control del trafico (TC) y calidad de servicio (QoS). Básicamente lo que se intentará será mejorar las condiciones de nuestra conexión a Internet, sobre todo cuando la compartimos entre varios usuarios/as.
Usted es libre de: copiar, distribuir y comunicar públicamente la obra; hacer obras derivadas. Bajo las condiciones siguientes: Reconocimiento. Debe reconocer y citar al autor original. No comercial. No puede utilizar esta obra para fines comerciales. Compartir bajo la misma licencia. Si altera o transforma esta obra, o genera una obra derivada, sólo puede distribuir la obra generada bajo una licencia idéntica a ésta. Al reutilizar o distribuir la obra, tiene que dejar bien claro los términos de la licencia de esta obra. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor. Para mas información visitar: http://creativecommons.org/licenses/by-nc-sa/2.0/es/deed.es
Falta explicacion
En mi caso particular la motivación fue muy domestica. Teníamos un acceso ADSL a través de router adsl, el cual compartíamos mi hermana y yo. Siempre estábamos peleándonos ya que cuando hacíamos un uso intenso de el canal de bajada uno de los 2 salia perdiendo, quedándose casi sin ancho de banda. También sufríamos la pérdida de ancho de banda en uno de los canales al saturarse el otro. Además, cuando me conectaba desde fuera de mi casa a mi sobremesa por ssh a través de Internet, a experiencia era frustrante, teniendo que obligar a mi hermana a no hacer un uso intensivo de la salida a Internet en esos momentos.
Por lo tanto, como a uno le gusta mucho investigar, decidí que era el momento de pasar el router adsl de multipuesto (el solo se encargar de gestionar la salida a Internet de toda a una red) a monopuesto, y de tener un router GNU/Linux en condiciones.
No ha sido algo sencillo ni rápido. Primero el pasar el router ADSL a monopuesto me costo lo suyo. Una vez en monopuesto fui configurando con tiempo el router/firewall que corría sobre el p100 que había salvado de la basura. El lograr tener QoS funcionando me llevo un tiempo mas largo (parchear kernel, etc) que no se terminó hasta que por motivos laborales tuve que hacerlo.
Los problemas descritos a continuación son típico de una red con conexión a Internet. Se pueden encontrar los mismo en una red de oficina que en la conexión a Internet de tu casa.
Cuando tenemos mas de una maquina conectada a Internet a través de la misma salida suele pasar que si una de ellas empieza a consumir mucho ancho de banda (una descarga grande, p2pm etc) acapara la conexión haciendo que las demas maquinas no tenga casi ancho de banda y la latencia (tiempo de respuesta de la conexión) sea penosa. En esta situación ya podemos olvidarnos de usar protocolos que requieran baja latencia o sea interactivas. Un ejemplo son las conexiones SSH que veremos a continuación.
Cuando nuestra conexión a Internet va mal el intentar usar una conexión interactiva se vuelve imposible. Por ejemplo, tenemos a nuestra hermana bajándose a saco con el nicotine (un cliente de la red p2p soulseek) y nosotros necesitamos conectarnos por ssh a una maquina remota en inet. Si tecleamos algo pueden pasar varios segundos hasta que los paquetes con la orden lleguen a la maquina remota, y otros tantos segundos en que vuelva el resultado del comando. Si alguna ve os a pasado esto sabréis que es insufrible.
Otro ejemplo de conexión interactiva son los juegos. Estas haciendo frags a tope en el juego online de turno y al entrar alguien a ver la web que tenéis en casa vuestro "ping" se pone por las nubes y es imposible jugar.
En teoría nuestra conexión a Internet de banda ancha (cable o adsl o lo que sea) es fullduplex, esto es, tendriamos que poder enviar y recibir a la vez sin problemas. Pero a menudo cuando saturamos un canal 8el de subida o el de bajada) el otro canal se resiente. Esto es debido a que los paquetes que no puede enviar el router o modem los guarda en unos buffers internos. Estos buffers suelen ser bastante limitados y se comportan de una manera que no podemos controlar.
La manera de evitar que una sola conexión acapare todo el ancho de banda es que "el sistema" que montemos se asegure de ir repartiendo en ancho de banda entre todas las conexiones activas. Esto se logra eligiendo el tipo de cola (la cola es la que se encarga de mandar los paquetes a la tarjeta de red) adecuado. Luego veremos que este tipo es el SQF.
Si queremos que cierto tipo de conexiones (SSH pj) tengan prioridad sobre otras (ftp-data, redes p2p, etc), lo que haremos sera clasificar sus paquetes en una cola que tendrá prioridad con respecto a las otras.
Limitando el ancho en una maquina Linux que tenga una mejor gestión de buffers. Por ello siempre prodremoslos limites del ancho de banda un poco por debajo del ancho de banda de salida que tengamos a internet. Asi nos aseguramos que la cola/buffer se va a gestionar en la máquina GNU/Linux y no el el router ADSL o cablemodem.
Antes de entrar en la descripción técnica de los sistema de calidad de servicio y control de ancho de banda en GNU/Linux vamos a echar un ojo a problemas típico que nos pueden llevar a usar QoS/TC.
Lo primero es avisar de que los milagros no existen :) Vamos, que si tenemos supersaturada la conexión a Internet con TC/QoS en GNU/Linux podremos quiza aliviar la situación.
En GNU/Linux en control de ancho de banda tiene 2 partes: Un(os) drivers o modulos en el kernel y herramientas en espacio de usuario. Estas herramientas se encuentran dentro del paquete iproute2
El control del ancho de banda se logra clasificando los paquetes que tienen que salir (y con un truco entrar tambien) por un dispositivo de red en clases y colas.
Explicación sencilla, en la clases se va haciendo el reparto de ancho de banda y prioridas. En las colas se mandan a la tarjeta los paquetes que esperan en la clase a la que pertenece.
Algunas definiciones sacadas de lartc:
Es el algoritmo que se encarga de gestionar los paquetes de salida (egress) o de entrada (ingress)
Esta es la cola que esta unida al dispositivo de red (la cola principal)
Un tipo de cola que no permite la subdivisión interna
Tipo de cola que permite en su interior albergar clases, estas clase pueden ser colas o subclases.
Cuando en una cola se decide que unos paquetes tienen que salir antes que otros estamos haciendo scheduling
Cuando retemos paquetes que podríamos mandar para mantener un tráfico determinado estamos haciendo shaping.
Hay muchos más términos. Si quieres mas información acude al documento de LARTC.
Analogía: La clases son cajas donde se van "guardando" los paquetes antes de mandarlos por la tarjeta de red. Se pueden meter cajas dentro de otras, pueden crecer, pueden encogerse para dejar sitio a otras.... Las colas serían la manera en la que "sacamos" los paquetes almacenados en las cajas:el que primero entra primero sale, reparto equitativo entre las distintas conexiones que tienen paquetes esperando,...
Colas sin clases (no se pueden colgar de ellas otras colas ordenadas en clases).
pfifo_fast: El primero que llega primero se va :) Tiene 3 bandas de prioridades, el kernel mira el TOS (tipo de servicio) y en función de ello lo manda a una banda u otra. Teóricamente es una cola con clases(las 3 bandas de prioridad), pero de cara al usuario se puede considerar sin clases, ya que no podemos modificarlas
Token Bucket Filter (TBF). Esta cola limita a un ancho de banda concreto aunque permite pequeñas ráfagas a mayor velocidad. Útil para lograr que la cola de paquetes a enviar este en la maquina linux y no en el router adsl o cablemode.
Stochastic Fairness Queueing (SFQ). Básicamente lo que hace es un reparto equitativo entre todas las conexiones abiertas. Muy útil para evitar que un puesto acapare todo el ancho de banda.
Random Early Drop. Para usos avanzados en backbones ,... fuera de lo que queremos ver.
Colas con clases:
PRIO
CBQ. La mas completa y la mas complicada de entender/configurar. En esta cola se juega con los tiempos de retardo de los paquetes (shaping).
HTB (Hierarchical Token Bucket). Es mas sencilla de manejar que CQB. Ideal para cuando queremos dividir un ancho de banda fijo en distintas bandas.
Con HTB haremos clases que limitarán y repartirán el ancho de banda. usnado la analogia anterior decidiremos el tamaño de cada caja para que no nos saturen el routerADSL o clablemodem y para que se ajuste al reparto que nostros decidamos.
Con SQF nos aseguraremos que nadie acapara el ancho de banda. Siguiendo con la analogía, a la hora de sacar los paquetes que esperan en las cajas lo haremos sacado uno de cada conexión pendiente en ese momento.
Directamente no tenemos una manera de controlar lo que nos llega de Internet. Pero basándonos en como funciona el protocolo TCP/IP y con una pequeña "trampa" podemos hacer algo medio decente.
TCP/IP no sabe a que velocidad puede mandar cosas de un punto a otro. Entonces lo que hace es empezar a mandar mas o menos despacio e ir subiendo hasta que la otra maquina empieza a no recibir paquetes. Nosotros lo que vamos a hacer es deliberadamente dejar de atender paquetes cuando se alcance el ancho de banda que hemos decidido en ese momento.
Una manera de hacer esto si estamos trabajando en un router (un "cacharro" con 2 tarjetas de red, al menos, una conectada a Internet y otra a nuestra red local) es controlar la salida por la tarjeta de red que conecta a nuestra red local. Por ejemplo, si tenemos eth0 conectada a Internet y eth1 a nuestra red local y queremos controlar la velocidad de descarga de Internet desde la red local lo que podríamos hacer es jugar con la colas de salida de eth1 , a falta de poder hacerlo con las de entrada de eth0.
A veces este método de controlar la salida del dispositivo conectado a la red local no nos vale. Por ejemplo si queremos tener en cuenta a la propia maquina que hace de router no podremos. O si tenemos mas de 2 tarjetas de red la cosa se complicaría bastante. Entonces, ya que tc solo tiene colas de salida (tiene una de entrada, pero de muy reducidas posibilidades), lo que vamos a hacer es una pequeña trampa para tratar el trafico que nos entra como si fuera el de salida. Lo que vamos a hacer es desviar todo el trafico de entrada a un dispositivo de red virtual, IMQ (intermediate...). Así lo que era el trafico de entrada de eth0 pj, se convierte en el trafico de salida de imq0 y así podremos controlarlo a nuestro gusto.
Como hemos dicho tenemos que desviar el tráfico de entrada a este dispositivo nuevo. Esto se hace a través de una regla iptables:
iptables -t mangle -A PREROUTING -i eth0 -j IMQ
Con esta regla lo que haríamos seria mandar todo el trafico que viene por eth0 a imq0 antes de empezar el proceso de routing (decidir que vamos a hacer con ese paquete, si nos lo vamos a quedar o si lo vamos a pasar a la red local). para entender mejor que hace la tabla de PREROUTING hecharle un ojo a la tabla del tráfico de red en el kernel linux que esta en los enlaces varios.
Este metodo no es perfecto. Tenemos que descartar paquetes perfectamente validos para que el otro extremo se de por aludido y deje de mandar más paquetes. Supuestamente IPv6 va a incluir soporte de QoS y ancho de banda en el propio protocolo y na habrá que hacer estas "chapuzas".
Con el propio tc
Con iptables (la hasta ahora inutilizada tabla mangle)
Tipo CoyoteLinux o así.
Como se suele decir "la comida hecha en casa sabe mejor". En Linux tambien se cumple esta máxima muchas veces, ya muchos nos gusta hacer las cosas a mano. Luego haremos la "trampa" de usar scripts
Sencillo: meter como módulo todas las opciones de QoS e iptablesi/netfilter y así nos curamos en salud.
Para IMQ hay que parchear el kernel (e iptables?)
Después de parchear con IMQ elegir en network devices (en la rama 2.4. En la 2.6 esta en Device Drivers / Networking Support): <M> IMQ (intermediate queueing device) support
También es necesario habilitar el módulo de soporte IMQ de iptables en el kernel: <M> IMQ target support
Una vez mas revisar la docu online: http://wiki.nix.hu/cgi-bin/twiki/view/IMQ/HowToInstall
Para que imq funcione necesitamos 2 cosas:
Un kernel parcheado para tener el dispositivo virtual imqX
Un iptables parcheado para que soporte la nueva acción -j IMQ
Parchear el kernel no tiene mas misterio (que el que ya tiene compilar un kernel claro :). Buscamos en http://www.linuximq.net/ el parche para la versión del núcleo que queremos usar, lo bajamos y lo aplicamos:
# cd /usr/src/linux # patch -p1 < linux-2.6.9-imq1.diff
Ahora solo tendríamos que asegurarnos de activar el driver IMQ en la configuración del kernel. Hay un completo howto en la propia web de IMQ: http://wiki.nix.hu/cgi-bin/twiki/view/IMQ/HowToInstall
Recientemente se ha publicado una versión del driver IMQ que no necesita parchear el kernel y además está portada al 2.6. Revisar la sección de enlaces.
Lograr una versión de iptables parcheada es mas complicado.
EXPLICACION DE COMO HACERLO EN DEBIAN
apt-get source iptables (necesitamos un deb-src en nuestro /etc/apt/sources) cd iptables-X.Y.Z cd debian/build/iptables-X.Y.Z patch -p1 /path/iptables-1.2.9-imq1.diff # cp ../iptables-1.2.9-imq1.diff ./patches/007-imq1.patch dpkg-buildpackage -d ls .. -l | grep .deb
Si todo a ido bien tendremos un paquete deb parcheado para IMQ.
EXPLICACION GENERICA:
# Nos bajamos la version de iptables adecuada (por ejemplo 1.2.9 wget http://www.netfilter.org/files/iptables-1.2.9.tar.bz2 # Nos bajamos el parche wget http://www.linuximq.net/patchs/iptables-1.2.9-imq1.diff # Descomprimimos tar jxvf iptables-1.2.9.tar.bz2 # Entramos y parcheamos cd iptables-1.2.9 patch -p1 < ../iptables-1.2.9-imq1.diff #Hay que arreglar unos permisos chmod +x extensions/.IMQ-test* # Compilamos e instalamos make && make install #Deberiamos tener nuestro iptables parcheado ls -l /usr/local/lib/iptables/libipt_IMQ.so -rwxr-xr-x 1 root staff 4231 2004-10-27 10:00 /usr/local/lib/iptables/libipt_IMQ.so
iptables (con IMQ si vamos a usarlo)
iproute2 . Este nos dara el comando tc que usaremos para confidurar las colas y clases
tcpdump, ettercap, ethereal, iptraf,... Para comprobar el tráfico
Un par de shapers pillados de inet (del propio lartc y de san google).
Simply example to limit speed of incoming e-mails to 64Kbit:
#!/bin/sh
modprobe imq
ifconfig imq0 up
tc qdisc del dev imq0 root
tc qdisc add dev imq0 handle 1: root htb default 1 tc class add dev imq0 parent 1: classid 1:1 htb rate 64kbit tc qdisc add dev imq0 parent 1:1 handle 2 sfq
iptables -t mangle -A PREROUTING -i eth0 -p TCP --dport 25 -j IMQ
#!/bin/bash # # myshaper - DSL/Cable modem outbound traffic shaper and prioritizer. # Based on the ADSL/Cable wondershaper (www.lartc.org) # # Written by Dan Singletary (8/7/02) # # NOTE!! - This script assumes your kernel has been patched with the # appropriate HTB queue and IMQ patches available here: # (subnote: future kernels may not require patching) # # http://luxik.cdi.cz/~devik/qos/htb/ # http://luxik.cdi.cz/~patrick/imq/ # # Configuration options for myshaper: # DEV - set to ethX that connects to DSL/Cable Modem # RATEUP - set this to slightly lower than your # outbound bandwidth on the DSL/Cable Modem. # I have a 1500/128 DSL line and setting # RATEUP=90 works well for my 128kbps upstream. # However, your mileage may vary. # RATEDN - set this to slightly lower than your # inbound bandwidth on the DSL/Cable Modem. # # # Theory on using imq to "shape" inbound traffic: # # It's impossible to directly limit the rate of data that will # be sent to you by other hosts on the internet. In order to shape # the inbound traffic rate, we have to rely on the congestion avoidance # algorithms in TCP. Because of this, WE CAN ONLY ATTEMPT TO SHAPE # INBOUND TRAFFIC ON TCP CONNECTIONS. This means that any traffic that # is not tcp should be placed in the high-prio class, since dropping # a non-tcp packet will most likely result in a retransmit which will # do nothing but unnecessarily consume bandwidth. # We attempt to shape inbound TCP traffic by dropping tcp packets # when they overflow the HTB queue which will only pass them on at # a certain rate (RATEDN) which is slightly lower than the actual # capability of the inbound device. By dropping TCP packets that # are over-rate, we are simulating the same packets getting dropped # due to a queue-overflow on our ISP's side. The advantage of this # is that our ISP's queue will never fill because TCP will slow it's # transmission rate in response to the dropped packets in the assumption # that it has filled the ISP's queue, when in reality it has not. # The advantage of using a priority-based queuing discipline is # that we can specifically choose NOT to drop certain types of packets # that we place in the higher priority buckets (ssh, telnet, etc). This # is because packets will always be dequeued from the lowest priority class # with the stipulation that packets will still be dequeued from every # class fairly at a minimum rate (in this script, each bucket will deliver # at least it's fair share of 1/7 of the bandwidth). # # Reiterating main points: # * Dropping a tcp packet on a connection will lead to a slower rate # of reception for that connection due to the congestion avoidance algorithm. # * We gain nothing from dropping non-TCP packets. In fact, if they # were important they would probably be retransmitted anyways so we want to # try to never drop these packets. This means that saturated TCP connections # will not negatively effect protocols that don't have a built-in retransmit # like TCP. # * Slowing down incoming TCP connections such that the total inbound rate is less # than the true capability of the device (ADSL/Cable Modem) SHOULD result in little # to no packets being queued on the ISP's side (DSLAM, cable concentrator, etc). # Since these ISP queues have been observed to queue 4 seconds of data at 1500Kbps # or 6 megabits of data, having no packets queued there will mean lower latency. # # Caveats (questions posed before testing): # * Will limiting inbound traffic in this fashion result in poor bulk TCP performance? # - Preliminary answer is no! Seems that by prioritizing ACK packets (small <64b) # we maximize throughput by not wasting bandwidth on retransmitted packets # that we already have. #
# NOTE: The following configuration works well for my # setup: 1.5M/128K ADSL via Pacific Bell Internet (SBC Global Services)
DEV=eth2 RATEUP=90 RATEDN=400 # Note that this is significantly lower than the capacity of 1500. # Because of this, you may not want to bother limiting inbound traffic # until a better implementation such as TCP window manipulation can be used.
TAM_MTU=1500 # changes mtu on the outbound device. Lowering the mtu will result # in lower latency but will also cause slightly lower throughput due # to IP and TCP protocol overhead.
# # End Configuration Options #
if [ "$1" = "status" ] then echo "[qdisc]" tc -s qdisc show dev $DEV tc -s qdisc show dev imq0 echo "[class]" tc -s class show dev $DEV tc -s class show dev imq0 echo "[filter]" tc -s filter show dev $DEV tc -s filter show dev imq0 echo "[iptables]" iptables -t mangle -L MYSHAPER-OUT -v -x 2> /dev/null iptables -t mangle -L MYSHAPER-IN -v -x 2> /dev/null exit fi
# Reset everything to a known state (cleared) tc qdisc del dev $DEV root 2> /dev/null > /dev/null tc qdisc del dev imq0 root 2> /dev/null > /dev/null iptables -t mangle -D POSTROUTING -o $DEV -j MYSHAPER-OUT 2> /dev/null > /dev/null iptables -t mangle -F MYSHAPER-OUT 2> /dev/null > /dev/null iptables -t mangle -X MYSHAPER-OUT 2> /dev/null > /dev/null iptables -t mangle -D PREROUTING -i $DEV -j MYSHAPER-IN 2> /dev/null > /dev/null iptables -t mangle -F MYSHAPER-IN 2> /dev/null > /dev/null iptables -t mangle -X MYSHAPER-IN 2> /dev/null > /dev/null ip link set imq0 down 2> /dev/null > /dev/null rmmod imq 2> /dev/null > /dev/null
if [ "$1" = "stop" ] then echo "Shaping removed on $DEV." exit fi
########################################################### # # Outbound Shaping (limits total bandwidth to RATEUP)
# set queue size to give latency of about 2 seconds on low-prio packets ip link set dev $DEV qlen 30
# changes mtu on the outbound device. Lowering the mtu will result # in lower latency but will also cause slightly lower throughput due # to IP and TCP protocol overhead. ip link set dev $DEV mtu $TAM_MTU
# add HTB root qdisc tc qdisc add dev $DEV root handle 1: htb default 26
# add main rate limit classes tc class add dev $DEV parent 1: classid 1:1 htb rate ${RATEUP}kbit
# add leaf classes - # We grant each class at LEAST it's "fair share" of bandwidth. # this way no class will ever be starved by another class. Each # class is also permitted to consume all of the available bandwidth # if no other classes are in use. tc class add dev $DEV parent 1:1 classid 1:20 htb rate $[$RATEUP/7]kbit ceil ${RATEUP}kbit prio 0 tc class add dev $DEV parent 1:1 classid 1:21 htb rate $[$RATEUP/7]kbit ceil ${RATEUP}kbit prio 1 tc class add dev $DEV parent 1:1 classid 1:22 htb rate $[$RATEUP/7]kbit ceil ${RATEUP}kbit prio 2 tc class add dev $DEV parent 1:1 classid 1:23 htb rate $[$RATEUP/7]kbit ceil ${RATEUP}kbit prio 3 tc class add dev $DEV parent 1:1 classid 1:24 htb rate $[$RATEUP/7]kbit ceil ${RATEUP}kbit prio 4 tc class add dev $DEV parent 1:1 classid 1:25 htb rate $[$RATEUP/7]kbit ceil ${RATEUP}kbit prio 5 tc class add dev $DEV parent 1:1 classid 1:26 htb rate $[$RATEUP/7]kbit ceil ${RATEUP}kbit prio 6
# attach qdisc to leaf classes - # here we at SFQ to each priority class. SFQ insures that # within each class connections will be treated (almost) fairly. tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev $DEV parent 1:21 handle 21: sfq perturb 10 tc qdisc add dev $DEV parent 1:22 handle 22: sfq perturb 10 tc qdisc add dev $DEV parent 1:23 handle 23: sfq perturb 10 tc qdisc add dev $DEV parent 1:24 handle 24: sfq perturb 10 tc qdisc add dev $DEV parent 1:25 handle 25: sfq perturb 10 tc qdisc add dev $DEV parent 1:26 handle 26: sfq perturb 10
# filter traffic into classes by fwmark # here we direct traffic into priority class according to # the fwmark set on the packet (we set fwmark with iptables # later). Note that above we've set the default priority # class to 1:26 so unmarked packets (or packets marked with # unfamiliar IDs) will be defaulted to the lowest priority # class. tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:22 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 23 fw flowid 1:23 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 24 fw flowid 1:24 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 25 fw flowid 1:25 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 26 fw flowid 1:26
# add MYSHAPER-OUT chain to the mangle table in iptables - # this sets up the table we'll use # to filter and mark packets. iptables -t mangle -N MYSHAPER-OUT iptables -t mangle -I POSTROUTING -o $DEV -j MYSHAPER-OUT
# add fwmark entries to classify different types of traffic - Set fwmark from 20-26 according to # desired class. 20 is highest prio. # Default for low port traffic iptables -t mangle -A MYSHAPER-OUT -p tcp --sport 0:1024 -j MARK --set-mark 23 # "" iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 0:1024 -j MARK --set-mark 23 # ftp-data port, low prio iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 20 -j MARK --set-mark 26 # aol instant messenger iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 5190 -j MARK --set-mark 23 # ICMP (ping) - high prio, impress friends iptables -t mangle -A MYSHAPER-OUT -p icmp -j MARK --set-mark 20 # DNS name resolution (small packets) iptables -t mangle -A MYSHAPER-OUT -p udp -j MARK --set-mark 21 # secure shell iptables -t mangle -A MYSHAPER-OUT -p tcp --dport ssh -j MARK --set-mark 22 iptables -t mangle -A MYSHAPER-OUT -p tcp --sport ssh -j MARK --set-mark 22 # telnet (ew...) iptables -t mangle -A MYSHAPER-OUT -p tcp --dport telnet -j MARK --set-mark 22 iptables -t mangle -A MYSHAPER-OUT -p tcp --sport telnet -j MARK --set-mark 22 # IPSec - we don't know what the payload is though... #iptables -t mangle -A MYSHAPER-OUT -p ipv6-crypt -j MARK --set-mark 24 # Local web server iptables -t mangle -A MYSHAPER-OUT -p tcp --sport http -j MARK --set-mark 25 # small packets (probably just ACKs) iptables -t mangle -A MYSHAPER-OUT -p tcp -m length --length :64 -j MARK --set-mark 21 # redundant- mark any unmarked packets as 26 (low prio) iptables -t mangle -A MYSHAPER-OUT -m mark --mark 0 -j MARK --set-mark 26
# Done with outbound shaping # ####################################################
echo "Outbound shaping added to $DEV. Rate: ${RATEUP}Kbit/sec."
# uncomment following line if you only want upstream shaping. # exit
#################################################### # # Inbound Shaping (limits total bandwidth to RATEDN)
# make sure imq module is loaded
#modprobe imq numdevs=1
ip link set imq0 up
# add qdisc - default low-prio class 1:21
tc qdisc add dev imq0 handle 1: root htb default 21
# add main rate limit classes tc class add dev imq0 parent 1: classid 1:1 htb rate ${RATEDN}kbit
# add leaf classes - TCP traffic in 21, non TCP traffic in 20 # tc class add dev imq0 parent 1:1 classid 1:20 htb rate $[$RATEDN/2]kbit ceil ${RATEDN}kbit prio 0 tc class add dev imq0 parent 1:1 classid 1:21 htb rate $[$RATEDN/2]kbit ceil ${RATEDN}kbit prio 1
# attach qdisc to leaf classes - here we at SFQ to each priority class. SFQ insures that # within each class connections will be treated (almost) fairly. tc qdisc add dev imq0 parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev imq0 parent 1:21 handle 21: red limit 1000000 min 5000 max 100000 avpkt 1000 burst 50
# filter traffic into classes by fwmark - # here we direct traffic into priority class according to # the fwmark set on the packet (we set fwmark with iptables # later). Note that above we've set the default priority # class to 1:26 so unmarked packets (or packets marked with # unfamiliar IDs) will be defaulted to the lowest priority # class. tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21
# add MYSHAPER-IN chain to the mangle table in iptables - this sets up the table we'll use # to filter and mark packets. iptables -t mangle -N MYSHAPER-IN iptables -t mangle -I PREROUTING -i $DEV -j MYSHAPER-IN
# add fwmark entries to classify different types of traffic - Set fwmark from 20-26 according to # desired class. 20 is highest prio. iptables -t mangle -A MYSHAPER-IN -p ! tcp -j MARK --set-mark 20 # Set non-tcp packets to highest priority # short TCP packets are probably ACKs iptables -t mangle -A MYSHAPER-IN -p tcp -m length --length :64 -j MARK --set-mark 20 # secure shell iptables -t mangle -A MYSHAPER-IN -p tcp --dport ssh -j MARK --set-mark 20 iptables -t mangle -A MYSHAPER-IN -p tcp --sport ssh -j MARK --set-mark 20 # telnet (ew...) iptables -t mangle -A MYSHAPER-IN -p tcp --dport telnet -j MARK --set-mark 20 iptables -t mangle -A MYSHAPER-IN -p tcp --sport telnet -j MARK --set-mark 20 # redundant- mark any unmarked packets as 26 (low prio) iptables -t mangle -A MYSHAPER-IN -m mark --mark 0 -j MARK --set-mark 21
# finally, instruct these packets to go through the imq0 we set up above iptables -t mangle -A MYSHAPER-IN -j IMQ
# Done with inbound shaping # ####################################################
echo "Inbound shaping added to $DEV. Rate: ${RATEDN}Kbit/sec."
Como meterles mano Consejos
Sitio "oficial": http://www.linuximq.net/
Buscar en google :), por ejemplo: imq kernel patch
La versión que mantiene un tio: http://pupa.da.ru/imq/ NO HACE FALTA PARCHEAR EL KERNEL(tampoco me compila :)
Aquí se explica como parchear el kernel, iptables,... : http://www.digriz.org.uk/jdg-qos-script/index.html#qos-2.6
Diagrama del flujo de paquetes en el kernel: http://www.docum.org/docum.org/kptd/
Docu iptables/netfilter: http://www.netfilter.org/documentation/
Este trabajo esta bajo una Creative Commons License.
Puede consultar la licencia legal completa en http://creativecommons.org/licenses/by-nc-sa/2.0/es/legalcode.es