Marcar y clasificar tráfico con iptables y tc
Siguiendo el hilo de la receta anterior, vamos a ver cómo podemos clasificar el tráfico que generamos para meterlos en las colas que vamos a crear y así clasificar el tráfico. Para ello, aunque existen multitud de formas de clasificar el tráfico vamos a utilizar el campo TOS (type of service) del protocolo IP.
Clasificando paquetes
Bueno, esta claro que si queremos establecer clases de tráfico podemos hacer dos cosas, una marcar el tráfico de paquetes en el origen y sólo clasificar en el nodo que hace de enlace con, por ejemplo, Internet y otra, no marcar en el origen y filtrarlo (ademas de clasificar) todo en el nodo que hace de enlace. Si nos imaginamos un nodo con dos interfaces, una conectada a Internet y otra a una red ethernet través de la cual se conectan otros nodos podemos establecer reglas de marcado en esos nodos mientras que en el enlace simplemente clasificamos el tráfico que le llega en el sistema de colas. El problema de tener que marcar en el origen, es que pueden existir nodos que no marcan sus paquetes o que los marcan mal para obtener el ancho de banda asociado a un tráfico de prioridad mas alta. Vamos a considerar que todos los nodos son buenos y marcan sus paquetes. Para marcar un paquete debemos usar iptables. Si observamos una regla de iptables para marcar paquetes:#iptables -t mangle -I POSTROUTING 1 -p tcp -s 111.11.11.105 -j TOS --set-tos 16
# iptables -L -t mangle
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
TOS tcp -- 111.11.11.105 anywhere TOS set Minimize-Delay
#iptables -F -t mangle
#iptables -t mangle -I OUTPUT -p tcp --sport 12345 -s localhost -j TOS --set-tos 4
#iptables -t mangle -A FORWARD -p tcp -m ipp2p --kazaa ... acción
Creando colas
Como vimos en la receta anterior, para crear colas, usamos la herramienta tc. Por ejemplo si queremos establecer cuatro colas, cada una para un tipo de tráfico distinto, y que tengan el mismo ancho de banda, una estructura como esta sería apropiada:#tc qdisc add dev eth0 root handle 1: htb default 1
#tc class add dev eth0 parent 1: classid 1:1 htb rate 3125kbps
#tc class add dev eth0 parent 1: classid 1:2 htb rate 3125kbps
#tc class add dev eth0 parent 1: classid 1:3 htb rate 3125kbps
#tc class add dev eth0 parent 1: classid 1:4 htb rate 3125kbps
#tc qdisc show dev eth0
class htb 1:1 root prio 0 rate 25000Kbit ceil 25000Kbit burst 14096b cburst 14096b
class htb 1:2 root prio 0 rate 25000Kbit ceil 25000Kbit burst 14096b cburst 14096b
class htb 1:3 root prio 0 rate 25000Kbit ceil 25000Kbit burst 14096b cburst 14096b
class htb 1:4 root prio 0 rate 25000Kbit ceil 25000Kbit burst 14096b cburst 14096b
qdisc htb 1: r2q 10 default 1 direct_packets_stat 0
Clasificando paquetes
Una vez que tenemos el tráfico marcado y las clases de tráfico creado, debemos establecer las reglas para encolar el tráfico en su clase correspondiente, dentro de la clasificación de colas preestablecida. Para ello, de nuevo utilizamos la herramienta tc:#tc filter add dev eth0 parent 1:0 protocol ip prio 10 u32 match ip tos 0x10 0xff flowid 1:4
#tc filter add dev eth0 parent 1:0 protocol ip prio 9 u32 match ip tos 0x08 0xff flowid 1:3
#tc filter add dev eth0 parent 1:0 protocol ip prio 8 u32 match ip tos 0x04 0xff flowid 1:2
#tc filter add dev eth0 parent 1:0 protocol ip prio 7 u32 match ip tos 0x02 0xff flowid 1:1
# tc filter show dev eth0
filter parent 1: protocol ip pref 7 u32
filter parent 1: protocol ip pref 7 u32 fh 803: ht divisor 1
filter parent 1: protocol ip pref 7 u32 fh 803::800 order 2048 key ht 803 bkt 0 flowid 1:1
match 00020000/00ff0000 at 0
filter parent 1: protocol ip pref 8 u32
filter parent 1: protocol ip pref 8 u32 fh 802: ht divisor 1
filter parent 1: protocol ip pref 8 u32 fh 802::800 order 2048 key ht 802 bkt 0 flowid 1:2
match 00040000/00ff0000 at 0
filter parent 1: protocol ip pref 9 u32
filter parent 1: protocol ip pref 9 u32 fh 801: ht divisor 1
filter parent 1: protocol ip pref 9 u32 fh 801::800 order 2048 key ht 801 bkt 0 flowid 1:3
match 00080000/00ff0000 at 0
filter parent 1: protocol ip pref 10 u32
filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:4
match 00100000/00ff0000 at 0
#
Comprobando que todo funciona
Vale, y todo esto, ¿cómo comprobamos que funciona?, bueno, hay un script en perl que te permite visualizar las clases de tráfico que hay en tu sistema, el dispositvo y el tráfico que entra por cada clase en tiempo real:#./monitor_tc_top.pl
18:49:55 up 1 day, 2:09, 5 users, load average: 0.20, 0.17, 0.17
Interval Cumulated Total
Dev Classid Tokens Ctokens Rate Speed Send Send
-------------------------------------------------------------------------
eth0 1:1 4558 4558 24.47KB 147B/s 103.17KB 333.33KB
eth0 1:2 4620 4620 0B 0B/s 0B 0B
eth0 1:3 4620 4620 0B 0B/s 0B 0B
eth0 1:4 4620 4620 0B 0B/s 0B 0B
[ show comments ]
blog comments powered by Disqus