Está en la página 1de 7

Distribución del ancho de banda utilizando HTB e 

IPTables

Autor: Luis Vargas Castro


Correo: luisvargascastro arroba gmail punto com

Creative Commons Reconocimiento-NoComercial-CompartirIgual 2.1

© 2006 Usted es libre de copiar, distribuir y comunicar públicamente la obra y hacer obras
derivadas bajo las condiciones siguientes: a) Debe reconocer y citar al autor original. b) No
puede utilizar esta obra para fines comerciales (incluyendo su publicación, a través de
cualquier medio, por entidades con fines de lucro). c) 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. Los derechos derivados de usos legítimos u otras
limitaciones no se ven afectados por lo anterior. Licencia completa en castellano. La
información contenida en este documento y los derivados de éste se proporcionan tal cual
son y los autores no asumirán responsabilidad alguna si el usuario o lector hace mal uso de
éstos.

Introducción.
En muchas ocasiones los administradores de red experimentan cuellos de botella
prolongados debido al mal uso que algunos usuarios dan del acceso a internet. Gran parte
de esos abusos son llevados a cabo por las descargas que se realizan ya sea música, video o
software através de programas P2P. Si bien existen alternativas para limitar el ancho de
banda como los Delay Pools de Squid, pero solo funciona para limitar el ancho de banda de
aquellas descargas vía HTTP y para el FTP.

Para implementar una solución que permita distribuir al ancho de banda y la tasa de
transferencia de una forma más justa que incluyan no solo a HTTP y FTP sino inclusive a
los programas P2P existen herramientas como CBQ y HTB que realizan la tarea.

En este documento se presenta una guía básica y funcional para la correcta implementación
de HTB+Iptables para una distribución justa del ancho de banda.

Hierarchical Token Bucket (HTB)

Para poder particionar el acceso a internet, HTB se vale de clases. Estas clases son
instrucciones jerárquicas que indican cómo debe manejarse el canal y qué prioridad tiene
una clase ante otra tomando el principio de colas. El primer paso es configurar la disciplina
de encolamiento de HTB:

[root@lanserver]#tc qdisc add dev eth0 root handle 1: htb default 13


Este comando crea la disciplina de encolamienta raíz de HTB en la interfaz eth0 que en este
caso, es la interfaz del servidor GNU/Linux que conecta hacia la LAN. Puede sustituirse
por la interfaz que en su caso particular sea la interfaz hacia la LAN. Se indica que la
disciplina 1:13 será la disciplina por defecto en tanto se indican más cambios.

[root@lanserver]#tc class add dev eth0 parent 1: classid 1:1 htb rate
140kbit ceil 140kbit

Esta instrucción indica la tasa máxima con la que la disciplina raíz cuenta para la división
del canal. El parámetro rate establecerá el ancho de banda inicial permitido para la
disciplina de encolamiento en cuestión y el parámetro ceil indica el ancho de banda
máximo.

[root@lanserver]#tc class add dev eth0 parent 1:1 classid 1:10 htb rate
80kbit ceil 140kbit prio 0

Con esta instrucción se crea la clase 1:10 y se indica utilizar un ancho de banda incial de
80kbit y un máximo de 140kbit cuando el canal no está en uso.

tc class add dev eth0 parent 1:1 classid 1:11 htb rate 20kbit ceil $
{CEIL}kbit prio 1
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 20kbit ceil $
{CEIL}kbit prio 2
tc class add dev eth0 parent 1:1 classid 1:13 htb rate 20kbit ceil $
{CEIL}kbit prio 3

Lo anterior crea tres clases 1:11, 1:12 y 1:13. Estas clases utilizarán un ancho de banda
incial de 20kbit cuando el canal está en uso y del máximo disponible del canal, 140kbit,
cuando no exista carga en la red al igual que la clase anterior 1:10.

[root@lanserver]#tc qdisc add dev eth0 parent 1:11 handle 120: sfq
perturb 10
[root@lanserver]#tc qdisc add dev eth0 parent 1:12 handle 130: sfq
perturb 10
[root@lanserver]#tc qdisc add dev eth0 parent 1:13 handle 140: sfq
perturb 10

Lo anterior añade 3 clases hijas a cada una de las clases padre creadas anteriormente: 1:11,
1:12 y 1:13 que permitirán que se distribuya de forma justa la oportunidad de transmitir
datos hacia la red basándose en un número arbitrario de flujos. Esta funcionalidad está
basada en el encolamiento estocástico justo (Stochastic Fair Queuing) SFQ.

Note el parámetro sfq perturb 10. Esto le indica a la disciplina de encolamiento de quien la
instrucción es hija, que implemente una interrupción o perturbación de la transmisión de 10
segundos. En la medida que sea necesario reajuste este parámetro siempre y cuando no
vaya en detrimendo de la transmisión de datos que enrute hacia esta disciplina.

Clasificación de paquetes
Hasta ahora se ha creado la configuración inicial de qdisc pero no se han clasificado los
paquetes hacia las distintas rutas. Para hacerlo utilizaremos IPTables y clasificaremos los
paquetes hacia las distintas clases creadas anteriormente.

tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 1 fw classid
1:10
tc filter add dev eth0 parent 1:0 protocol ip prio 2 handle 2 fw classid
1:11
tc filter add dev eth0 parent 1:0 protocol ip prio 3 handle 3 fw classid
1:12

Con lo anterior le hemos indicado al kernel que los paquetes que tienen una marca
específica con el valor fwmark con los parámetros handle x fw vayan hacia clases
específicas classid x:xx.

Debemos indicarle al kernel que debe realizar el reenvío de paquetes por las interfaces de
red utilizadas para este caso. Edite el archivo /etc/sysconfig.ctl en el parámetro
ipv4_forward=0 y cámbielo a 1:

ipv4_forward=1

Ahora debería poder ver el tráfico fluyendo através de la clase 1:13 con el siguiente
comando:

[root@lanserver]#tc -s class show dev eth0

IPTables

Ahora puede empezar añadir reglas de clasificación a iptables ya sea por protocolo o bien
por puerto según

[root@lanserver]#iptables -t mangle -A PREROUTING -p icmp -j MARK --set-


mark 0x1
[root@lanserver]#iptables -t mangle -A PREROUTING -p icmp -j RETURN

o bien por puerto dependiendo lo que necesita:

[root@lanserver]#iptables -t mangle -A PREROUTING -p tcp -m tcp --sport


22 -j MARK --set-mark 0x1
[root@lanserver]#iptables -t mangle -A PREROUTING -p tcp -m tcp --sport
22 -j RETURN

observe el parámetro -j MARK –set-mark 0×1 y -j RETURN. Estos parámetros se encargan


del marcado de paquetes según la prioridad; el primer parámetro indica el número de
prioridad en forma hexadecimal 0xX desde 0 hasta 9 donde 0 es el indicador de mayor
prioridad o más importancia, y 9 el de menor importancia.
Una buena práctica es priorizar con marca 0×1 todos aquellos paquetes propios de la
comunicación de las redes LAN: SYN, ACK, RST pues un retardo en estos paquetes
significaría un desastre de comunicaciones en la red:

iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK


--set-mark 0x1
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK
--set-mark 0x5
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN
iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j MARK
--set-mark 0x6
iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j
RETURN

Con lo anterior indicamos a iptables 3 tipos de T.O.S. y le decimos con qué número de
marcado identificarlos. Minimize-Delay, Minimize-Cost y Maximize-Troughput
marcándolos con 0×1, 0×5 y 0×6 respectivamente. Es imporante mencionar que no existen
solo estos T.O.S. y que es imporante introducir las reglas pertinentes según sea necesario
por parte del administrador de la red. Para motivos de explicación de este manual y del
posterior ejemplo éstas reglas son las necesarias.

Es una buena práctica repetir las instrucciones creadas para iptables con PREROUTING
con el parámetro OUTPUT de modo que el tráfico generado localmente también sea
clasificado. Puede terminarse cada sentencia de -A OUTPUT con -j MARK –set-mark 0×3
de modo que el tráfico local tenga prioridad.

Poniendo la teoría en práctica

Ejemplo. Una red local que cuenta con 15 PCs con acceso a internet sale por medio de un
servidor GNU/Linux através de una línea ADSL de 1024Kbps con 140Kbps de tasa de
transferencia; las aplicaciones habituales del internet en la LAN son correo electrónico,
chat, mensajería, FTP, HTTP, y programas P2P. Usualmente los programas P2P consumen
casi todo el ancho de banda de la red. Se desea distribuir de forma justa el ancho de banda
de modo que todo funcione bien y no hayan cuellos de botella debido en especial a los
programas P2P.

Creamos un script que configure a HTB y le damos permisos de ejecución para root. edite
con su editor de textos preferido el nuevo que llamaremos bwtc y ubíquelo en /etc/:

[root@lanserver]#gedit /etc/bwtc

añada el siguiente contenido:

CEIL=140
tc qdisc add dev eth0 root handle 1: htb default 13
tc class add dev eth0 parent 1: classid 1:1 htb rate ${CEIL}kbit ceil $
{CEIL}kbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 80kbit ceil $
{CEIL}kbit prio 0
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 20kbit ceil $
{CEIL}kbit prio 1
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 20kbit ceil $
{CEIL}kbit prio 2
tc class add dev eth0 parent 1:1 classid 1:13 htb rate 20kbit ceil $
{CEIL}kbit prio 3
tc qdisc add dev eth0 parent 1:11 handle 120: sfq perturb 10
tc qdisc add dev eth0 parent 1:12 handle 130: sfq perturb 10
tc qdisc add dev eth0 parent 1:13 handle 140: sfq perturb 10
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 1 fw classid
1:10
tc filter add dev eth0 parent 1:0 protocol ip prio 2 handle 2 fw classid
1:11
tc filter add dev eth0 parent 1:0 protocol ip prio 3 handle 3 fw classid
1:12
tc filter add dev eth0 parent 1:0 protocol ip prio 4 handle 4 fw classid
1:13

edite /etc/sysctl.conf y cambie el parámetro ipv4_forward=0 a 1:

ipv4_forward=1

Configuración de IPTables para marcado de paquetes

Agregue las reglas necesarias a IPTables de la siguiente manera: (puede hacerlo


directamente en consola con los comandos siguientes o bien editando el archivo
/etc/sysconfig/iptables y agregando las reglas en la sección mangle, claro sin el prefijo
iptables -t mangle) :

iptables -t mangle -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK


SYN -j RETURNiptables -t mangle -A PREROUTING -p tcp -m tcp --tcp-flags
SYN,RST,ACK SYN -j MARK --set-mark 0x1iptables -t mangle -A PREROUTING -p
tcp -m tcp --sport 3128 -j MARK --set-mark 0x1iptables -t mangle -A
PREROUTING -p tcp -m tcp --sport 3128 -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j MARK --set-
mark 0x1

iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j RETURN

iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j MARK --set-


mark 0x3iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j
RETURN

iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j MARK --set-


mark 0x3iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j
RETURN

iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 0x1iptables


-t mangle -A PREROUTING -p icmp -j RETURN
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK
--set-mark 0x1
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j
RETURNiptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK
--set-mark 0x5

iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j


RETURNiptables -t mangle -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK
SYN -j MARK --set-mark 0x1

iptables -t mangle -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j


RETURNiptables -t mangle -A OUTPUT -p tcp -m tcp --sport 3128 -j MARK
--set-mark 0x1

iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 3128 -j RETURNiptables


-t mangle -A OUTPUT -p tcp -m tcp --sport 80 -j MARK --set-mark 0x1

iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 80 -j RETURNiptables


-t mangle -A OUTPUT -p tcp -m tcp --sport 25 -j MARK --set-mark 0x1

iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 25 -j RETURNiptables


-t mangle -A OUTPUT -p tcp -m tcp --sport 110 -j MARK --set-mark 0x1

iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 110 -j RETURNiptables


-t mangle -A OUTPUT -p icmp -j MARK --set-mark 0x1

iptables -t mangle -A OUTPUT -p icmp -j RETURN


iptables -t mangle -A OUTPUT -m tos --tos Minimize-Delay -j MARK --set-
mark 0x1iptables -t mangle -A OUTPUT -m tos --tos Minimize-Delay -j
RETURN

iptables -t mangle -A OUTPUT -m tos --tos Minimize-Cost -j MARK --set-


mark 0x5iptables -t mangle -A OUTPUT -m tos --tos Minimize-Cost -j RETURN

iptables -t mangle -A OUTPUT -m tos --tos Maximize-Throughput -j MARK


--set-mark 0x6
iptables -t mangle -A OUTPUT -m tos --tos Maximize-Throughput -j RETURN

Ejecute el comando:

service iptables save

en caso que haya ingresado las reglas para iptables en la terminal o bien guarde el archivo
si lo editó con su editor de textos preferido. Reinicie el servicio iptables con el comando

service iptables restart

Dé privilegios de ejecución para el archivo /etc/bwtc:

[root@lanserver]#chmod +x /etc/bwtc

ejecute el archivo de configuración de HTB (/etc/bwtc):

[root@lanserver]#./etc/bwtc
y por último, monitoree el tráfico de red:

[root@lanserver]#tc -s class show dev eth0

También podría gustarte