Introducción a Control del trafico y a Calidad de servicio en GNU/Linux

Jon Latorre Martinez
Metabolik Bio Hacklab
mailto:moebius@etxea.net

versión 0.1

XX de mes de 2004

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

Introducción

Que es QoS y TC

Falta explicacion

Motivos para usarlo

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.

Localizando los problemas

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.

Un solo usuario acaparar la conexión

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.

Las conexiones interactivas (ssh)

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.

Los buffers del router/modem no dan a basto

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.

Como arreglarlo con TC/QoS

Reparto equitativo

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.

Priorizando tipos de trafico

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.

Limitar el caudal que le mandamos al router/modem

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.

Teoría

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.

No existen los milagros

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.

Control del tráfico (tc) en GNU/Linux

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

Clases y colas

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.

Que son las classes y las 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:

Disciplinad de cola (Queueing Discipline, qdisc)

Es el algoritmo que se encarga de gestionar los paquetes de salida (egress) o de entrada (ingress)

root qdisc

Esta es la cola que esta unida al dispositivo de red (la cola principal)

colas sin clases

Un tipo de cola que no permite la subdivisión interna

colas con clases

Tipo de cola que permite en su interior albergar clases, estas clase pueden ser colas o subclases.

Scheduling

Cuando en una cola se decide que unos paquetes tienen que salir antes que otros estamos haciendo scheduling

Shaping

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,...

Principales tipos de clases y colas

Lo que vamos a usar: HTB y SQF

Como regular la entrada de tráfico

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.

IMQ

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.

Es una pequeña farsa, pero funciona

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".

Filtros

Como preparar nuestra GNU/Linux box para hacer QoS

Usar una distro específica

Tipo CoyoteLinux o así.

A pedal

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

Opciones de kernel

Lograr un kernel e iptables para IMQ

Para que imq funcione necesitamos 2 cosas:

  1. Un kernel parcheado para tener el dispositivo virtual imqX

  2. 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

Herramientas Necesarias

Utiles

Ejemplos

Un par de shapers pillados de inet (del propio lartc y de san google).

Una muy simple: Limitando el correo

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

Ejemplo completo

 #!/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

Extra: compilar el kernel y el iptables necesario ?

URLs

IMQ

ejemplos

varios

Licencia

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

http://creativecommons.org/images/public/somerights20.gif