Featured image of post Controlar el ancho de banda por dirección IP en Linux

Controlar el ancho de banda por dirección IP en Linux

Como controlar el ancho de banda por dirección IP de cada uno de mis clientes de la red usando el comando tc de linux

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 para controlar el ancho de banda, 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.

controlar el ancho de banda por dirección IP en linux

controlar el ancho de banda por dirección IP en linux

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.

Referencias

Licensed under CC BY-NC-SA 4.0
Última actualización 30 ago. 2016 830:00 CST
Todas las imágenes, nombres de productos y nombres de empresa o logotipos citados en esta página web son propiedad de sus respectivos propietarios.
Creado con Hugo
Tema Stack diseñado por Jimmy