Header Ads

BandwidthD

BandwidthD es una de esas herramientas de antaño, que a pesar de que su última actualización fue en 2013, actualmente sigue siendo muy útil y está vigente (compatible con ubuntu 20.04/22.04). Se usa básicamente para monitoreo del ancho de banda en una red local, aunque los datos recopilados pueden tener otros usos. 
Según el portal oficial, se puede " rastrear el uso de subredes de red TCP/IP y crea archivos html con gráficos, que se crean por IP individuales, mostrando la utilización en períodos (de 2, 8, 40, 400 días). Además, la utilización de cada dirección IP se puede cerrar en intervalos de 3.3 minutos, 10 minutos, 1 hora o 12 horas en formato cdf, o en un servidor de base de datos backend. El tráfico HTTP, TCP, UDP, ICMP, VPN y P2P están codificados por colores." 
Su instalación es sencilla. El paquete está en los repositorios oficiales:
sudo apt -y install bandwidthd
Si tenía una versión previa, se recomienda que elimine directorios y archivos antiguos antes de instalar:
sudo rm -rf /usr/sbin/bandwidthd /etc/bandwidthd /var/lib/bandwidthd /etc/init.d/bandwidthd /var/run/bandwidthd* >/dev/null 2>&1
Sin embargo, instalarla de manera desatendida puede ser un problema, ya que solicita la interfaz de red y rango de IPs a monitorear. 
Selección de interfaz de red (opción "any" para monitorear todas)

Seleccione el/los rango/s de red
Selección de rangos IP/CIDR Y el "man" o "help" no sirven de mucho:
bandwidthd --help
Usage: bandwidthd [OPTION]
Options:
    -D      Do not fork to background
    -l      List detected devices
    -c      filename Alternate configuration file
    --help  Show this help

FILES
    /usr/sbin/bandwidthd               - daemon binary.
    /etc/init.d/bandwidthd             - startscript.
    /etc/bandwidthd/bandwidthd.conf    - configuration file.
    /var/run/bandwidthd.pid            - main process id file.
    /var/lib/bandwidthd/               - log directory.
    /var/lib/bandwidtd/htdocs/         - html and graphs output directory.
Entonces, para evitar estas molestas pantallas, se debe instalar de la siguiente manera:
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install bandwidthd
Una vez instalado, verifique los parámetros por default:
sudo debconf-show bandwidthd
  bandwidthd-pgsql/sensorid:
  bandwidthd/dev: any
  bandwidthd/promisc: false
  bandwidthd/metarefresh:
  bandwidthd/subnet: 169.254.0.0/16, 192.168.1.0/24, 192.168.122.0/24
  bandwidthd/outputcdf: true
  bandwidthd/recovercdf: true
Edite el archivo de configuración:
sudo nano /etc/bandwidthd/bandwidthd.conf
Y cambiarlos según sus necesidades. Ejemplo, reemplazando el parámetro dev y subnet:
subnet 192.168.0.0/16
dev "wlp1s0"
Guarde los cambios y reinicie:
sudo /etc/init.d/bandwidthd restart
También puede realizar los cambios en el archivo de configuración sin editarlo, directamente desde el terminal, con el siguiente comando. Ej: para cambiar todos los rangos por 192.168.0.0/16. (Para mayor información sobre sponge pulse AQUI):
sudo sed "s:^subnet.*:subnet 192.168.0.0/16:g" /etc/bandwidthd/bandwidthd.conf | uniq | sudo sponge /etc/bandwidthd/bandwidthd.conf
Pero esto no es lo más recomendable, ya que este aplicativo detecta durante la instalación los rangos que usan sus interfaces de red, y si tiene dos, entonces al hacer lo anterior no podría monitorear ambas. Por defecto muestra los rangos así:
subnet 169.254.0.0/16
subnet 192.168.0.0/24
Donde el primero es por defecto del programa y el segundo cambia de acuerdo al equipo según el rango de IP/mascara que tenga la primera interfaz por defecto en su equipo. Entonces lo mejor sería reemplazar el rango por defecto 169.254.0.0/16 por el de su interfaz de red secundaria. Ejemplo:
sed -i "s:169.254.0.0/16:192.168.88.0/24:g" /etc/bandwidthd/bandwidthd.conf
Quedando así:
subnet 192.168.88.0/24 # corresponde a la interfaz de red secundaria
subnet 192.168.0.0/24 # corresponde a la interfaz de red primaria (que detecta bandwidthd)
También puede cambiar la interfaz de red (ej: "wlp1s0") desde la línea de comandos, pero se sugiere dejalo en "any" por si tiene dos interfaces pueda monitorear ambas:
sudo sed -i 's:^dev "any":dev "wlp1s0":g' /etc/bandwidthd/bandwidthd.conf
Acceda a la plataforma:
http://localhost/bandwidthd/
Hasta aquí podría ser suficiente, sin embargo, este aplicativo trabaja por el puerto 80 y esto eventualmente puede generar conflictos con otras aplicaciones que usen este puerto y el archivo de configuración no tiene opción para cambiarlo, así que hay dos maneras: La fácil y la difícil. 
La difícil, como bien lo indican en el foro, hay que descargar el código fuente y modificar el archivo bandwidthd.c en la línea 249, reemplazando el puerto (por ejemplo el 80 por el 8000) y compilar:
 if (sport == 8000 || dport == 8000)
                Stats->http += size;
La fácil es con Apache:
sudo apt -y install apache2
Asumiendo que ya tenemos instalado y parametrizado apache2 y bandwidthd, creamos el directorio de monitoreo de bandwidthd en /var/www
sudo mkdir -p /var/www/bandwidthd
Creamos un archivo VirtualHost en la ruta indicada (cambie el nombre del archivo según sus preferencias):
/etc/apache2/sites-enabled/bandwidthdaudit.conf
Con el siguiente contenido (el puerto 11400 es de ejemplo. Puede ser cualquiera de su elección que esté libre):
< VirtualHost *:11400>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/bandwidthd
	
		< Directory/>
		Options FollowSymLinks
		DirectoryIndex index.html
		Options ExecCGI
		AllowOverride None
	< /Directory>
	< Directory /var/www/bandwidthd/>
		AuthType Basic
        	AuthName "Restricted Content"
        	AuthUserFile /etc/apache2/.htpasswd
        	Require valid-user
	< /Directory>

	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	
< Directory "/usr/lib/cgi-bin">
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        	Require all granted
	< /Directory>

	ErrorLog ${APACHE_LOG_DIR}/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	CustomLog ${APACHE_LOG_DIR}/access.log combined
< /VirtualHost>
En el VirtualHost anterior elegimos a modo de ejemplo el puerto 11400 (pero puede cambiarlo por cualquier otro disponible en su sistema). En cualquier caso debe agregarlo a Apache (y si tiene firewall, abrirlo):
Edite el archivo ports.conf, agregue el número de puerto y guarde los cambios:
sudo nano /etc/apache2/ports.conf
# bandwidthd
Listen 11400
Creamos un enlace simbólico al directorio donde se encuentran los archivos de estadísticas:
sudo ln -s /var/lib/bandwidthd/htdocs/* /var/www/bandwidthd/
Reiniciamos los servicios:
sudo service apache2 restart
sudo /etc/init.d/bandwidthd restart
localhost:port
Y voilà. Ahora puede acceder por localhost o la IP del equipo con el nuevo puerto. Ejemplo:
http://localhost:11400
# o
http://192.168.0.10:11400
Plan de Datos
Las estadísticas generadas por BandwidthD pueden ser altamente provechosas. Por ejemplo, supongamos que queremos crear un "Plan de Datos" para nuestros usuarios de la red local. En este caso, ejecutamos el siguiente script (ejecutelo con privilegios. Ej: sudo ./bandata.sh):
#!/bin/bash
### GLOBAL ###
iptables=/sbin/iptables
ipset=/sbin/ipset
# modificar esta variable a la carpeta donde se guardan las listas de IPs permitidas y denegadas
acl="path_to/listas"

### BANDATA ###
# maximum daily data consumption
max_bandwidth="1G"
# path files
html_file=/var/lib/bandwidthd/htdocs/index.html
allow_list=$acl/allowdata.txt
block_list=$acl/bandata.txt
# create lst if doesn't exist
if [[ ! -f {$allow_list,$block_list} ]]; then touch {$allow_list,$block_list}; fi
# bandata
reorganize="sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n"
ips=$(grep -Pi '\]+>: :g' | grep 192.168.1 | awk '{gsub(/\./, ",", $2); print $2" "$1}')
max_bw=$(echo $max_bandwidth | tr '.' ',' | numfmt --from=iec)
echo "$ips" | numfmt --from=iec | awk '$1 > '$max_bw' {print $2}' | grep -vf $white_list | $reorganize | uniq > $block_list

### IPSET FOR BANDATA ### 
$ipset flush BANDATA
$ipset -N -! BANDATA hash:net maxelem 1000000
for ip in $(cat "$bandatalst"); do
    $ipset -A BANDATA "$ip"
done
$iptables -t mangle -I PREROUTING -m set --match-set BANDATA src,dst -j DROP
$iptables -I INPUT -m set --match-set BANDATA src,dst -j DROP
$iptables -I FORWARD -m set --match-set BANDATA src,dst -j DROP
$iptables -I OUTPUT -m set --match-set BANDATA src,dst -j DROP
El script anterior define varias cosas. Primero hay que establecer manualmente la variable max_bandwidth con la cantidad de gigas de datos a asignar por usuario de la red local. En el ejemplo anterior seleccionamos 1G (1G = 1 Gigabyte (GB) de datos = 1024M. Pueden escribir con puntos. Ejemplo: 1.5G, 2.0G, 0.8G, etc.). 
Hay que aclarar que esta cuota de datos es diaria, ya que el script revisa solamente la estadística del log diario de BandwidthD. Puede modificarlo según sus preferencias para que revise el html semanal, mensual o anual y aumentar la cantidad de gigas de datos. Por ejemplo, asignar 30G al mes:
max_bandwidth="30G"
html_file=/var/lib/bandwidthd/htdocs/index2.html
Una vez definido, lo que hace el script es revisar el archivo html correspondiente y con el comando grep depura este archivo, extrayendo los valores "G" de cada IP, y el programa numfmt convierte esos números con prefijos en números naturales y compara la salida con la variable max_bandwidth, y si es mayor (en este caso a 1G; por ejemplo: 2.5G o 4.1G), envía la dirección IP a la lista negra bandata.txt, que finalmente es bloqueada por Ipset con reglas de Iptables, hasta la nueva rotación del log de BandwidthD.
Se recomienda poner en la lista allowdata.txt las direcciones IP que quiera excluir del bloqueo (y del plan) y programar este script en el cron para que se ejecute cada 10 min.
*/10 * * * * /etc/scr/bandata.sh
Problemas conocidos
Inseguro
Para  Lynis este programa es inseguro. Puede ignorar esta advertencia, pero sepa que es vulnerable.
Logs
Los logs de BandwidthD se encuentran en la carpeta /var/lib/bandwidthd/:
htdocs  log.1.0.cdf  log.2.0.cdf  log.3.0.cdf log.4.0.cdf
Según README significan lo siguiente:
These logs are log.1.0.cdf-log.1.5.cdf for daily, log.2.0.cdf-log.2.5.cdf for weekly, etc, etc.
Y las gráficas se encuentran en la carpeta htdocs. Entonces podemos concluir lo siguiente:
Daily report = log.1.0.cdf-log.1.5.cdf (htdocs/index.html)
Weekly report = log.2.0.cdf-log.2.5.cdf (htdocs/index2.html)
Monthly report = log.3.0.cdf-log.3.5.cdf (htdocs/index3.html)
Yearly report = log.4.0.cdf-log.4.5.cdf (htdocs/index4.html)
El gráfico diario grafica hasta 4000 direcciones IP locales cada 200 segundos (3.3 min), actualiza el reporte el semanal cada 10 min, mensual cada hora y anual cada 12 horas.
Sin embargo, es bien conocido que en algunos escenarios estas estadisticas no hacen lo que se supone (ver hilo de problemas con logs en el foro de BandwidthD). El problema concreto es que los log no rotan. De hecho pueden ejecutar manualmente el script para rotar sin resultados:
sudo /etc/init.d/bandwidthd rotate
sudo /etc/init.d/bandwidthd force-reload 
No está claro el por qué sucede y desde 2005 su creador no responde a las solicitudes, sin embargo, en este  README recomiendan que para solucionarlo, programe el siguiente comando en el cron:
Nota: Lo hemos modificado, ya que contiene un error.
0 0 * * * /bin/kill -HUP $(cat /var/run/bandwidthd.pid) && sleep 5m && /etc/init.d/bandwidthd restart
El comando anterior envía un kill al pid para que pueda hacer la rotación, le da 5 minutos de tiempo para generar estadísticas (el doble de tiempo que el archivo de configuración establece por defecto para la generación de gráficas que es 2.5 minutos) y reinicia el demonio:
nano /etc/bandwidthd/bandwidthd.conf
# An interval is 2.5 minutes, this is how many 
# intervals to skip before doing a graphing run
skip_intervals 0
Sin embargo, puede suceder que el log rote, pero las gráficas no se generen y siga apareciendo todo el tráfico diario del día anterior, en lugar del contador a 0. En este caso se soluciona eliminando el archivo rotado, programando el siguiente comando en el cron:
find "/var/lib/bandwidthd" -type f -name "log.1.*.cdf" -not -name "log.1.0.cdf" -delete
Nota: El anterior comando es solo para el log diario. Puede hacer lo mismo para semanal, etc.
Y si a pesar de lo anterior, sigue sin funcionar, hay un último recurso y es vaciar el log diario con una tarea en el cron:
# vaciar log diario (crontab)
0 0 * * * cat /dev/null | tee /var/lib/bandwidthd/log.1.0.cdf && sleep 5m && /etc/init.d/bandwidthd restart
# si no tiene el equipo encendido a esa hora, entonces:
@daily cat /dev/null | tee /var/lib/bandwidthd/log.1.0.cdf && sleep 5m && /etc/init.d/bandwidthd restart
# vaciar todos los logs, ejecute con privilegios:
cat /dev/null | tee /var/lib/bandwidthd/log.* && /etc/init.d/bandwidthd restart
Otros bugs
Otro asunto es que bandwidthd tiene problemas para graficar algunos protocolos, como FTP, o que se demore mucho en graficar los logs más allá de los 2.5 minutos, así lo programe a 0, entre otros bugs. 
Finalmente, tenga en cuenta su obsolencia y no espere milagros, pero para un monitoreo sencillo del ancho de banda de una red local es más que suficiente.

Para descargarlo visite nuestro repositorio Vault
Con la tecnología de Blogger.