El problema
Se me planteó el de problema de intentar controlar el ancho de banda de cada uno de mis clientes de la red. De preferencia por dirección IP y me llevó algo de tiempo encontrar una solución.
El propósito es evitar que un cliente acapare de todo el ancho de banda disponible y anule o limite a los demás.
A lo mejor puede sonar algo trivial, considerando que actualmente existen proveedores de internet que pueden llegar a ofrecer 100 Mbps de descarga o cantidades así, pero en donde estoy solo disponemos de 3 Mbps que tengo que hacer rendir.
Lamentablemente por nuestra ubicación no tenemos otras opciones y si las hay son inestables o costosas, así que no queda más que leer para ver que se puede hacer.
IPCop como tal no ofrece ninguna opción similar, de hecho he considerado varias veces en cambiarme a pFsense, pero le tengo aprecio a esta herramienta, nunca me ha fallado y me parece un poco ingrato cambiarlo por otro software.
tc (traffic control)
Existe un programa en linux que se llama tc que permite controlar el tráfico de paquetes que circula en una interfaz de red.
Haciendo un símil, imaginen que la tarjeta de red es una carretera, los automóviles son los paquetes que fluyen libremente intercambiando información entre su equipo y sus vecinos.
Básicamente tc permite establecer los mecanismos que controlan la transmisión y recepción de paquetes. Es como poner límites de velocidad a la carretera de la información.
Mejor que eso, en lugar de establecer un ancho de banda máximo permitido en toda “la carretera”, se puede establecer un límite de velocidad dependiendo del destino al que quieren llegar los paquetes, de esta forma es posible controlar la cantidad de paquetes que consumen cada uno de los destinos (o clientes).
Creo que ni yo me entendí pero la idea es esa.
Instalación
Les recuerdo que utilizo Manjaro una distribución de linux basada en Arch. El paquete que contiene a tc se llama iproute2. IPCop lo tiene instalado por default y Manjaro también, así que probablemente ya lo tienen y ni cuenta se han dado.
El script
Leí mucho sobre el tema hasta que me encontré con un sencillo script en bash que hace lo que necesito en How can I do traffic shaping in Linux by IP?. Sólo tenía que hacerle algunos ajustes.
#! /bin/bash NETCARD=eth0 MAXBANDWIDTH=100000 # reinit tc qdisc del dev $NETCARD root handle 1 tc qdisc add dev $NETCARD root handle 1: htb default 9999 # create the default class tc class add dev $NETCARD parent 1:0 classid 1:9999 htb rate $(( $MAXBANDWIDTH ))kbit ceil $(( $MAXBANDWIDTH ))kbit burst 5k prio 9999 # control bandwidth per IP declare -A ipctrl # define list of IP and bandwidth (in kilo bits per seconds) below ipctrl[192.168.1.1]="256" ipctrl[192.168.1.2]="256" ipctrl[192.168.1.3]="256" ipctrl[192.168.1.4]="256" ipctrl[192.168.1.5]="256" ipctrl[192.168.1.6]="256" ipctrl[192.168.1.7]="256" ipctrl[192.168.1.8]="256" ipctrl[192.168.1.9]="256" ipctrl[192.168.1.10]="256" ipctrl[192.168.1.11]="256" ipctrl[192.168.1.12]="256" ipctrl[192.168.1.13]="256" ipctrl[192.168.1.14]="256" ipctrl[192.168.1.15]="256" ipctrl[192.168.1.16]="256" ipctrl[192.168.1.17]="256" ipctrl[192.168.1.18]="256" ipctrl[192.168.1.19]="256" ipctrl[192.168.1.20]="256" ipctrl[192.168.1.21]="256" ipctrl[192.168.1.22]="256" ipctrl[192.168.1.23]="256" ipctrl[192.168.1.24]="256" ipctrl[192.168.1.25]="256" ipctrl[192.168.1.26]="256" ipctrl[192.168.1.27]="256" ipctrl[192.168.1.28]="256" ipctrl[192.168.1.29]="256" ipctrl[192.168.1.30]="256" ipctrl[192.168.1.31]="256" ipctrl[192.168.1.32]="256" ipctrl[192.168.1.33]="256" ipctrl[192.168.1.34]="256" ipctrl[192.168.1.35]="256" ipctrl[192.168.1.36]="256" ipctrl[192.168.1.37]="256" ipctrl[192.168.1.38]="256" ipctrl[192.168.1.39]="256" ipctrl[192.168.1.40]="256" ipctrl[192.168.1.41]="256" ipctrl[192.168.1.42]="256" ipctrl[192.168.1.43]="256" ipctrl[192.168.1.44]="256" ipctrl[192.168.1.45]="256" ipctrl[192.168.1.46]="256" ipctrl[192.168.1.47]="256" ipctrl[192.168.1.48]="256" ipctrl[192.168.1.49]="256" ipctrl[192.168.1.50]="256" ipctrl[192.168.1.51]="256" ipctrl[192.168.1.52]="256" ipctrl[192.168.1.53]="256" ipctrl[192.168.1.54]="256" ipctrl[192.168.1.55]="256" ipctrl[192.168.1.56]="256" ipctrl[192.168.1.57]="256" ipctrl[192.168.1.58]="256" ipctrl[192.168.1.59]="256" ipctrl[192.168.1.60]="256" ipctrl[192.168.1.61]="256" ipctrl[192.168.1.62]="256" ipctrl[192.168.1.63]="256" ipctrl[192.168.1.64]="256" ipctrl[192.168.1.65]="256" ipctrl[192.168.1.66]="256" ipctrl[192.168.1.67]="256" ipctrl[192.168.1.68]="256" ipctrl[192.168.1.69]="256" ipctrl[192.168.1.70]="256" ipctrl[192.168.1.71]="256" ipctrl[192.168.1.72]="256" ipctrl[192.168.1.73]="256" ipctrl[192.168.1.74]="256" ipctrl[192.168.1.75]="256" ipctrl[192.168.1.76]="256" ipctrl[192.168.1.77]="256" ipctrl[192.168.1.78]="256" ipctrl[192.168.1.79]="256" ipctrl[192.168.1.80]="256" ipctrl[192.168.1.81]="256" ipctrl[192.168.1.82]="256" ipctrl[192.168.1.83]="256" ipctrl[192.168.1.84]="256" ipctrl[192.168.1.85]="256" ipctrl[192.168.1.86]="256" ipctrl[192.168.1.87]="256" ipctrl[192.168.1.88]="256" ipctrl[192.168.1.89]="256" ipctrl[192.168.1.90]="256" ipctrl[192.168.1.91]="256" ipctrl[192.168.1.92]="256" ipctrl[192.168.1.93]="256" ipctrl[192.168.1.94]="256" ipctrl[192.168.1.95]="256" ipctrl[192.168.1.96]="256" ipctrl[192.168.1.97]="256" ipctrl[192.168.1.98]="256" ipctrl[192.168.1.99]="256" ipctrl[192.168.1.100]="256" ipctrl[192.168.1.101]="256" ipctrl[192.168.1.102]="256" ipctrl[192.168.1.103]="256" ipctrl[192.168.1.104]="256" ipctrl[192.168.1.105]="256" ipctrl[192.168.1.106]="256" ipctrl[192.168.1.107]="256" ipctrl[192.168.1.108]="256" ipctrl[192.168.1.109]="256" ipctrl[192.168.1.110]="256" ipctrl[192.168.1.111]="256" ipctrl[192.168.1.112]="256" ipctrl[192.168.1.113]="256" ipctrl[192.168.1.114]="256" ipctrl[192.168.1.115]="256" ipctrl[192.168.1.116]="256" ipctrl[192.168.1.117]="256" ipctrl[192.168.1.118]="256" ipctrl[192.168.1.119]="256" ipctrl[192.168.1.120]="256" ipctrl[192.168.1.121]="256" ipctrl[192.168.1.122]="256" ipctrl[192.168.1.123]="256" ipctrl[192.168.1.124]="256" ipctrl[192.168.1.125]="256" ipctrl[192.168.1.126]="256" ipctrl[192.168.1.127]="256" ipctrl[192.168.1.128]="256" ipctrl[192.168.1.129]="256" ipctrl[192.168.1.130]="256" ipctrl[192.168.1.131]="256" ipctrl[192.168.1.132]="256" ipctrl[192.168.1.133]="256" ipctrl[192.168.1.134]="256" ipctrl[192.168.1.135]="256" ipctrl[192.168.1.136]="256" ipctrl[192.168.1.137]="256" ipctrl[192.168.1.138]="256" ipctrl[192.168.1.139]="256" ipctrl[192.168.1.140]="256" ipctrl[192.168.1.141]="256" ipctrl[192.168.1.142]="256" ipctrl[192.168.1.143]="256" ipctrl[192.168.1.144]="256" ipctrl[192.168.1.145]="256" ipctrl[192.168.1.146]="256" ipctrl[192.168.1.147]="256" ipctrl[192.168.1.148]="256" ipctrl[192.168.1.149]="256" ipctrl[192.168.1.150]="256" ipctrl[192.168.1.151]="256" ipctrl[192.168.1.152]="256" ipctrl[192.168.1.153]="256" ipctrl[192.168.1.154]="256" ipctrl[192.168.1.155]="256" ipctrl[192.168.1.156]="256" ipctrl[192.168.1.157]="256" ipctrl[192.168.1.158]="256" ipctrl[192.168.1.159]="256" ipctrl[192.168.1.160]="256" ipctrl[192.168.1.161]="256" ipctrl[192.168.1.162]="256" ipctrl[192.168.1.163]="256" ipctrl[192.168.1.164]="256" ipctrl[192.168.1.165]="256" ipctrl[192.168.1.166]="256" ipctrl[192.168.1.167]="256" ipctrl[192.168.1.168]="256" ipctrl[192.168.1.169]="256" ipctrl[192.168.1.170]="256" ipctrl[192.168.1.171]="256" ipctrl[192.168.1.172]="256" ipctrl[192.168.1.173]="256" ipctrl[192.168.1.174]="256" ipctrl[192.168.1.175]="256" ipctrl[192.168.1.176]="256" ipctrl[192.168.1.177]="256" ipctrl[192.168.1.178]="256" ipctrl[192.168.1.179]="256" ipctrl[192.168.1.180]="256" ipctrl[192.168.1.181]="256" ipctrl[192.168.1.182]="256" ipctrl[192.168.1.183]="256" ipctrl[192.168.1.184]="256" ipctrl[192.168.1.185]="256" ipctrl[192.168.1.186]="256" ipctrl[192.168.1.187]="256" ipctrl[192.168.1.188]="256" ipctrl[192.168.1.189]="256" ipctrl[192.168.1.190]="256" ipctrl[192.168.1.191]="256" ipctrl[192.168.1.192]="256" ipctrl[192.168.1.193]="256" ipctrl[192.168.1.194]="256" ipctrl[192.168.1.195]="256" ipctrl[192.168.1.196]="256" ipctrl[192.168.1.197]="256" ipctrl[192.168.1.198]="256" ipctrl[192.168.1.199]="256" ipctrl[192.168.1.200]="256" ipctrl[192.168.1.201]="256" ipctrl[192.168.1.202]="256" ipctrl[192.168.1.203]="256" ipctrl[192.168.1.204]="256" ipctrl[192.168.1.205]="256" ipctrl[192.168.1.206]="256" ipctrl[192.168.1.207]="256" ipctrl[192.168.1.208]="256" ipctrl[192.168.1.209]="256" ipctrl[192.168.1.210]="256" ipctrl[192.168.1.211]="256" ipctrl[192.168.1.212]="256" ipctrl[192.168.1.213]="256" ipctrl[192.168.1.214]="256" ipctrl[192.168.1.215]="256" ipctrl[192.168.1.216]="256" ipctrl[192.168.1.217]="256" ipctrl[192.168.1.218]="256" ipctrl[192.168.1.219]="256" ipctrl[192.168.1.220]="256" ipctrl[192.168.1.221]="256" ipctrl[192.168.1.222]="256" ipctrl[192.168.1.223]="256" ipctrl[192.168.1.224]="256" ipctrl[192.168.1.225]="256" ipctrl[192.168.1.226]="256" ipctrl[192.168.1.227]="256" ipctrl[192.168.1.228]="256" ipctrl[192.168.1.229]="256" ipctrl[192.168.1.230]="256" ipctrl[192.168.1.231]="256" ipctrl[192.168.1.232]="256" ipctrl[192.168.1.233]="256" ipctrl[192.168.1.234]="256" ipctrl[192.168.1.235]="256" ipctrl[192.168.1.236]="256" ipctrl[192.168.1.237]="256" ipctrl[192.168.1.238]="256" ipctrl[192.168.1.239]="256" ipctrl[192.168.1.240]="256" ipctrl[192.168.1.241]="256" ipctrl[192.168.1.242]="256" ipctrl[192.168.1.243]="256" ipctrl[192.168.1.244]="256" ipctrl[192.168.1.245]="256" ipctrl[192.168.1.246]="256" ipctrl[192.168.1.247]="256" ipctrl[192.168.1.248]="256" ipctrl[192.168.1.249]="256" ipctrl[192.168.1.250]="256" ipctrl[192.168.1.251]="256" ipctrl[192.168.1.252]="256" ipctrl[192.168.1.253]="256" ipctrl[192.168.1.254]="256" mark=0 for ip in "${!ipctrl[@]}" do mark=$(( mark + 1 )) bandwidth=${ipctrl[$ip]} # traffic shaping rule tc class add dev $NETCARD parent 1:0 classid 1:$mark htb rate $(( $bandwidth ))kbit ceil $(( $bandwidth ))kbit burst 5k prio $mark # netfilter packet marking rule iptables -t mangle -A INPUT -i $NETCARD -s $ip -j CONNMARK --set-mark $mark # filter that bind the two tc filter add dev $NETCARD parent 1:0 protocol ip prio $mark handle $mark fw flowid 1:$mark echo "IP $ip is attached to mark $mark and limited to $bandwidth kbps" done #propagate netfilter marks on connections iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark
Por ejemplo en donde dice, NETCARD no es eth0, IPCop lo llama lan-1. Luego en donde se define el array ipctrl lo ajuste a un valor adecuado de para mis direcciones IP, por ejemplo alguien tendrá direcciones del tipo 192.168.0.x o 192.168.1.x y en el ejemplo le di un valor por default de 256 kbps a cada uno, pero esto es lo bonito de este script, que se puede personalizar individualmente el ancho de banda y eso es una maravilla.
Claro que tiene que guardar el script en un archivo, darle permisos de ejecución, que se ejecute durante el arranque y todas esas cosas que hacemos los administradores de sistemas.
Conclusiones
Tengo algunos puntos de acceso inalámbricos a los que les voy a establecer un límite, total para mandar un mensaje por el Whatsapp no se requiere mucho ancho de banda ¿cierto?, pero una actualización de dispositivo (y si me refiero a tí Apple !!!) eso es muy diferente ¿Ahora me entienden?.
Intento reservar el ancho de banda para donde lo creo más prioritario. De esa forma todos mis usuarios tiene internet, pero a distintas velocidades.
Como siempre, lo interesante de compartir estas ideas es la posibilidad de recibir sugerencias, señalar errores o analizar otros enfoques. Espero ansioso sus comentarios.
Y cómo se puede establecer un consumo diario de datos por usuario? Digamos que le asignas 1 GB de datos (subida + bajada) y si llega al límite lanza una alerta o bloquea la IP local?. Gracias
Hola Alecbox,
Pues la verdad no lo se, este artículo lo aplicaba cuando usaba ipcop, pero hace tiempo que dejé y en su lugar utilizo pfSense.
pfSense tiene un traffic shaper, pero lo que tu quieres más bien suena como a quotas.
Supongo que es posible, pero como nunca lo he utilizado, no tengo un consejo rápido para darte.
En la documentación de pfSense mencionan Traffic Quota a lo mejor te sirve de algo esa información.
Saludos !!!
Genial esta herramienta, hace mucho tiempo que busco algo así pues tengo tu mismo problema de ancho de banda y actualizaciones de Windows 10 y Apple, solamente le alta poder declarar rangos de IP para hacerlo más sintético.
Una pregunta, el MAXBANDWIDTH=100000 que significa? 100 megas? yo tengo un máximo de 4 megabits (500 kbytes) de internet. Qué número tendría que poner?
Muy buena idea esa de hacerlo en hoja de cálculo, ya me estaba por sentar a escribir direcciones una por una…
Graciasss!!
Muy buena pregunta Daniel,
Si más no recuerdo, creo que son kilobits por segundo. Todo depende del ancho de banda que tengas disponible.
Saludos 🙂
Excelente ……
lo voy a probar Venezuela ………
hola amigo crees que funcione para limitar a usuarios de internet telmex,mi tarjeta de red no se llama eth0 tiene otro nombre ¿deberia poner ese en el script?
Pues no pierdes nada con intentarlo.
Con respecto a tu tarjeta de red, prueba con el comando ifconfig a ver si te dice el nombre que tiene asignado.
Saludos 🙂
como puedo limitar el ancho de subida con tc
Hola!
Espero no sonar tan fresa, pero no hay alguna opción que conozcas para Mac? la verdad no tengo espacio para meter una una máquina virtual de Linux y hacer todos los pasos, por eso si de pura buena casualidad tienes una opción alternativa y nativa, te lo agradeceré.
Saludos
Lo siento David,
Pero con linux no he tenido la necesidad (bueno tampoco he tenido el dinero) de conseguir una Mac… así que a trabajarle 🙂
¡Suerte!
Y si quieres controlar la subida y la bajada independientemente? Como debria hacerlo?
Y esa es una muy buena pregunta Marc 🙂
Muy buen tutorial, salvó a un amigo mio en una ocación… Salu2 LinuxMan4R
Creo recordar que SmoothWall hacia justamente eso, te daba la opcion de controlar el ancho de banda por IP, por interface (GREEN), ademas de otras cosillas como poner horarios de disponibilidad a internet entre otras cosillas. Te hablo de hace mas de 3 años xDD
Siempre es bueno tener opciones.
Saludos!!
Que tal César,
Nunca conocí a Smoothwall, aunque creo que algunos plugins de las primeras versiones de IPCop se podían usar en ambas plataformas. Lo de los horarios creo que es en el proxy y también ipcop tiene algo similar.
Supongo que se puede hacer algo parecido con un cron, y segun la hora del sistema aplicar unos u otros límites de velocidad.
Saludirijillos. 🙂
En lo personal uso tc tambien, tengo 3 miseros megas que me entrega Telmex y tengo que balancear lo que usa el Apple TV, mi esposa, el iPad de Sofia y mis dispositivos, obvio, dandole preferencia a mi computadora pues es con la que trabajo.
Para esto defino clases, con esto puedo tener a mi hija en una clase, a mi esposa en otra, el Apple TV en otra, etc. Con esto logro que los dispositivos de una clase en particular tengan un ancho de banda limite, que se comparte de forma equitativa entre ellos (digamos, mis dispositivos) procurando no afectar a los demás.
Esto lo acompaño con DHCP asociados por dirección MAC y con direcciones IP definidas (siempre son las mismas). Tal vez quieras echarle ojo a este script:
https://github.com/markuz/scripts/blob/master/tclimit.sh y https://github.com/markuz/scripts/blob/master/rclocalvars
Muy interesante mi estimado Marcus,
Veo que hasta la impresora tiene su lugarcito en el script, pero ¿Telmex de 3 megas? conmigo lo entiendo, pero contigo ¿Cuál es su excusa? creo que el mínimo anda en 5 ¿o me equivoco?
Saludos 🙂
Tremendo artículo. Nunca me tocó hacer traffic shaping en Linux. ¿Sabés si además de filtrar por IP se puede filtrar por protocolo/puerto?
Saludos!!
Pues podría investigar Emiliano, lo que pasa es que en su momento quise establecer controles por cliente, será cosa de leer y buscar un poco.
Saludirijillos !!!
Vale. Yo esto lo hice en FreeBSD con dummynet, pero en Linux nunca tuve la necesidad.
Saludos y felicitaciones!!
Muy bueno !!, en el define estaría padre poner un contador para la la IP ipctrl[$IP++] = $bw .. algo así no ? para automatizar y ya solo definir las IP que se ocupan por aparte 😛 !!
Saludos lm4 !
Y es una excelente recomendación Bucio !!!
Pero no creas que escribí todas las líneas a mano, hice una pequeña hoja de calculo, concatené los textos y en un abrir y cerrar de hojas ya estaba lista la definición de las 254 IP’s 🙂
Saludos 🙂
¿Ya lo probaste Héctor? Has intentado dejar a alguien con 32 kbps, sólo por la nostalgia de la velocidad de un módem telefónico 🙂
Me dan ganas de ponerle este control a los desarrolladores para que aprendan lo que es usar su app cuando se termina el servicio LTE aqui…
Pues no esta mala la idea 🙂
Muchas gracias, tengo un hospedaje universitario y es un dolor de cabeza, me ha servido un montón. Gracias crack.
de pronto con un Microtik es más fácil, digo yo, pero nunca está de más tener una alternativa (de las decenas que existen).
Felicitaciones por el post, Saludos.
Hola Iván,
Tengo mucho tiempo escuchando sobre Mikrotik, que Mikrotik aquí, que Mikrotik allá, pero tiene el detalle de la licencia. A lo mejor exagero y la licencia no es muy cara, pero eso evita que me acerque a él. Ahora, si por alguna razón llegara a quitar IPCop (que no tiene para cuando morirse) lo más probable es que lo sustituya por pFsense, que no es linux pero hace bastante ruido :).
Gracias por comentar 🙂
claro, si instalas el software en un equipo, claro, es con licencia, pero yo siempre he comprado los dispositivos, hay desde USD$80 hacia arriba. La verdad es que son muy versátiles, los configuras a tu antojo y usan un transformador pequeño de 12V 2A, osea, el consumo es mínimo, incluso puedes configurar cache DNS, priorizar conexiones, bloquear sitios, incluso hay una nueva directiva para bloquear redes sociales y aplicaciones de mensajería como WhatsApp, Messenger y Telegram. O bien puedes permitir el uso, pero bloquear el envío/recepción de contenido multimedia (que es lo que realmente consume ancho de banda), te permite crear VLAN para visitas, uuffff, tienen un montón de aplicaciones y anda muy bien, incluso hay algunos rakeables. Los compro en esta tienda, http://linkstore.cl/#!/Producto=7754&hap-ac-lite-mikrotik-5-100-24ghz-2×2-5ghz-1×1-usb-l4-poe-in-out-rb952ui-5ac2nd al día de hoy, el USD cuesta CLP$660 (son como USD$92).
Dale una vuelta, al principio también era reacio, pero una vez que los conoces, no tomas otras opciones, al menos en mi caso.
Saludos.
Gracias por tus comentarios Ivan,
Ahora tengo un problema, me gustaría probar pfSense, pero no veo que este IPCop vaya a dejar de funcionar en poco tiempo y ahora que me dio la curiosidad por Mikrotik lo tengo que agregar a la lista.
Quizás, pruebe algunos dispositivos que vi en la tienda en México, solo para no dejar.
Saludos !!! 🙂