Control Ancho de Banda con OpenWRT

Improvisa :: Informática :: Control Ancho de Banda en OpenWRTLo prometido es deuda, y como así lo hice en el documento de "Hackear una Wep", os dejo un nuevo manual. Os enseñaremos a "compartir" vuestra red con control de ancho de banda efectivo y a enseñar al cliente que conecte a vuestra red inalámbrica un anuncio para decirle gracias a quien navega.

Este proyecto surgió como una meta a realizar en la red de GuadaWireless , donde lo que hacemos es compartir con los usuarios un ADSL, anunciando que navega gracias a GuadaWireless y Redlibre.  Para que no se abuse de la red añadimos control de ancho de banda a los usuarios que conectan a través de la wifi.

Para realizar este nuevo proyecto hemos utilizado los siguientes paquetes iptables, lighttpd, tc, y algún que otro módulo. Para ello necesitaremos un router reflasheable con OpenWRT, os puede valer un Buffalo, un WRT54g, hay muchos que lo aceptan, podéis verlo en esta tabla de hardware válido para esta distribución.

No vale decir que esta solución es cara, podeis ver esta gran oferta en uno de los routers que aguanta el firmware Openwrt y fue en principio generado para él. 

Manos a la Obra: ­

Antes de empezar y como siempre en todos los manuales de Improvisa, CUIDADO con los saltos de linea y las preguntas al foro ;-). 

Lo que hacemos en este manual no es nada nuevo, ya que existe mucha documentación para realizarlo con squid y delay pools o con el mismo apache iptables, lo curioso del manual es que lo consigamos hacer sin apoyarnos en grandes aplicaciones, es decir hacerlo funcionar en un router de 50 euros, con paquetes de nos mas de 100 KB.

Sin más pasaremos a realizar todo lo necesario para Controlar el ancho de banda y a anunciar nuestra web.

Dividiremos el manual en varios pasos, si solo os hace falta uno de los pasos pues ya sabéis, pasad de los demás y coged el que os haga falta.

Comenzaremos realizando la parte en la cual enseñaremos al cliente nuestra pagina de bienvenida.

Os cuento el funcionamiento del script que realizaremos, añadiremos una regla a iptables para que nos "contee" el numero de paquetes recibidos por el puerto 80, de esta forma solamente la primera petición del puerto 80 sera redirigida a nuestro servidor web con la pagina de Bienvenida, a partir de ahí no redirigiremos ninguna petición hasta que pasen 15 minutos (configurable). Pasados esos 15 minutos el contador se reinicializará y volveremos a redirigir la primera petición al puerto 80 para volver a anunciar al benefactor del ADSL. El funcionamiento es simple, cuando me conecto a la red wifi y abro mi navegador para visitar Google, no saldrá Google sino que nos saldrá la pagina de bienvenida con un botón que "refrescara" la conexión para lanzarme a la dirección a la que iba antes de salir la pagina.

Crearemos otro script para mandar a los que abusen a otro servidor con otro tipo de bienvenida, mas bien malvenida y se redirigirá todo a esa malvenida, hasta que queramos.

INSTALACIÓN DE LIGHTTPD y MÓDULOS PARA IPTABLES 

Necesitaremos el paquete lighttpd, este servidor web tiene la propiedad de poder "reescribir" la dirección, cosa que el pequeñisimo servidor web que trae openwrt no es capaz de hacer, así que le debemos instalar y preparar par su posterior utilización. Necesitaremos también los dos módulos que realizan lo que queremos

Para instalarlo:

root@openwrt:/# ipkg install lighttpd
root@openwrt:/# ipkg install lighttpd-mod-rewrite
root@openwrt:/# ipkg install lighttpd-mod-redirect

Debemos configurar nuestro servidor web, para ello le pondremos a escuchar en el puerto 8080, no queremos que siempre que se entre a nuestra ip salga la bienvenida, solo cuando nosotros queramos.

La instalación nos deja un archivo para configurar en /etc/ llamado lighttpd.conf copiémoslo y editémoslo:

root@openwrt:/# cp /etc/lighttpd.conf /etc/lighttpd_bienvenida.conf
root@openwrt:/# vi /etc/lighttpd_bienvenida.conf

Descomentad el modulo rewrite, ojo con las comas.
Decidle donde estará el document root, este sitio normalmente es un directorio dentro de /www, aquí es donde alojaremos la pagina de bienvenida, yo he puesto server.document-root = "/www_capta_clientes/"

Configurad el server.port, sera el puerto donde escuchemos, por defecto escucha en el 80, yo lo pongo en el 8080:

server.port = 8080

Tendremos que decirle que reescriba cualquier dirección que venga detrás del dominio por index.html, o el nombre que tenga nuestra pagina de bienvenida, esto lo haremos para que si alguien entra por ejemplo a https://www.improvisa.com/index.php, le salga http://nuestrip/index.html, de la redirección del dominio se encargará iptables pero de reemplazar el nombre la pagina se tiene que encargar lighttpd. Lo haremos añadiendo esto al archivo de configuración, justo donde se encuentran los comentarios de como hacer el rewrite, buscad esto: #### url handling modules (rewrite, redirect, access) y lo añadís despues de los comentarios:

url.rewrite = ( "^(.*)" => "/index.html" )

Ya tenemos configurado el nuevo servidor solo nos falta lanzarlo, esto es solo para que probeis, ya que el script que haremos lo lanzara solo:

root@openwrt:/# lighttpd -f /etc/lighttpd_bienvenida.conf

Para instalar los módulos de Iptables haremos lo siguiente:

root@openwrt:/# ipkg install iptables-mod-extra
root@openwrt:/# ipkg install iptables-mod-nat

CREACIÓN DE SCRIPT PARA REDIRECCIONAR PETICIONES A LOS BIENVENIDOS

Muy bien ya tenemos creado el servidor hagamos ahora el script para que todo se ejecute como queremos. Asumiré que tenemos en distintas redes nuestra conexión de are local y el acceso a Internet, por ejemplo:

Subred Internet: 192.168.0.0/24
Subred Area Local: 172.16.0.0/24

root@openwrt:/# vi /etc/init.d/capta_clientes

########## COMIENZO SCRIPT ##########
#!/bin/sh

Subred_internet=192.168.0.0/24 ##La que nos da acceso a Internet
Segundos_reinicio_contador=900  # (15 minutos). Cuando es una imagen no hace nada, sólo que no se ve la imagen
Numero_peticiones_redirigidas=1  # Asegurarse del número de peticiones al puerto 80 que tenemos que redirigir: 1 por la propia página más 1 por cada imagen de dicha página
IP_servidor_web=172.16.0.1 ## O la ip del openwrt donde tenemos levantado el lighttpd
Puerto_servidor_web=8080
Accion_de_los_no_redirigidos=RETURN  # Puede ser RETURN (continúa con las reglas posteriores) o ACCEPT (no continúa)

status()
  {
  ps xa | grep lighttpd | grep -v grep
  iptables -L PREROUTING -n -v -t nat | grep Chain
  iptables -L PREROUTING -n -v -t nat | grep capta_clientes | grep -v Chain
  iptables -L capta_clientes -n -v -t nat
  }
 
stop()
  {
  iptables -t nat -D PREROUTING -p TCP -s 0/0 -d 0/0 –dport 80 -j capta_clientes 2> /dev/null
  iptables -t nat -F capta_clientes 2> /dev/null
  iptables -t nat -X capta_clientes 2> /dev/null
 
  killall -9 lighttpd 2> /dev/null
  }
 
restart()
  {
  stop
  sleep 1
 
  /usr/sbin/lighttpd -f /etc/lighttpd_bienvenida.conf
 
  # Necesario el paquete ipkg iptables-mod-extra
  insmod ipt_recent > /dev/null 2>&1
  # Necesario el paquete ipkg iptables-mod-nat
  insmod ipt_REDIRECT > /dev/null 2>&1

  # Creamos nuestra cadena nueva
  iptables -t nat -N capta_clientes
  # Excluimos a los rangos de IPs internas privadas
  iptables -t nat -A capta_clientes -s $Subred_internet -d 0/0 -j $Accion_de_los_no_redirigidos
  # Excluimos a los rangos de IPs internas que queramos, si no quieres excluir comenta
  iptables -t nat -A capta_clientes -s 0/0 -d 172.16.0.1 -j $Accion_de_los_no_redirigidos
  # Si el contador es mayor que uno (ya ha mostrado nuestra página) se sale de la cadena. A los X minutos se reinicia el contador
  iptables -t nat -A capta_clientes -s 0/0 -d 0/0 -p tcp –dport 80 -m state –state NEW -m recent –name contador –update –seconds $Segundos_reinicio_contador –hitcount $Numero_peticiones_redirigidas -j $Accion_de_los_no_redirigidos
  # Redirige a servidor web de localhost en el puerto indicado donde se muestra nuestra página para captar clientes 😉
  iptables -t nat -A capta_clientes -s 0/0 -d 0/0 -p tcp –dport 80 -m state –state NEW -m recent –name contador –set -j REDIRECT –to-port $Puerto_servidor_web
  ###iptables -t nat -A capta_clientes -s 0/0 -d 0/0 -p tcp –dport 80 -m state –state NEW -m recent –name contador –set -j DNAT –to-destination $IP_servidor_web:$Puerto_servidor_web

  # Envía a nuestra cadena todas las peticiones web, luego se discierne si redirigirlas a nuestra página o no
  # Asegurarse de que esta misma regla se elimina en stop()
  iptables -t nat -A PREROUTING -p TCP -s 0/0 -d 0/0 –dport 80 -j capta_clientes
 
  status
  }
 
case "$1" in
  status)
    status
    ;;
  stop)
    echo "Parando capta_clientes:"
    stop
    ;;
  start)
    echo "Reiniciando capta_clientes:"
    restart
    ;;
  restart)
    echo "Reiniciando capta_clientes:"
    restart
    ;;
  *)
    echo "Modo de uso: $0 (start|stop|restart|status)"
    exit 1
    ;;
esac

########## FIN SCRIPT ##########

Démosle permisos de ejecución:

root@openwrt:/# chmod x /etc/init.d/capta_clientes

Muy bien de esta forma ya tenemos todo hecho, esta todo el script comentado si tenéis alguna duda al foro. Todas las peticiones salvo las excluidas pasaran cada 15 minutos por nuestro servidor web que esta escuchando en el puerto 8080.

CREACIÓN DE SCRIPT PARA REDIRECCIONAR A LOS QUE ABUSAN

Pues el funcionamiento es parecido pero sin contador, crearemos un script el cual añadirá una regla para la ip que le digamos y siempre sera redirigida a otro servidor web que lanzaremos en otro puerto.

Configuraremos el nuevo servidor web en otro archivo de configuración:

root@openwrt:/# cp /etc/lighttpd.conf /etc/lighttpd_abuso.conf
root@openwrt:/# vi /etc/lighttpd_abuso.conf

Descomentar el modulo redirect, no el rewrite como arriba, ojo con las comas
Cambiad el puerto de escucha, el mi ahora es server.port = 8888
Utilizare el mismo document_root pero con otra redirección en vez de sobreescribir, ya no lo pasare a index.html sino a abuso.html
url.redirect = ("^/(.*)" => "http://direccionopenwrt/abuso.html")

Para quitar a los que abusan lo único que hago es reiniciar, pero si queréis hacerlo para quitarlos con el propio script es fácil.

root@openwrt:/# vi /etc/init.d/abuso

########## COMIENZO SCRIPT ##########

#!/bin/sh

if [ "$1" = "" ]; then
  echo "Modo de uso: $0 IP_ABUSADORA"
  exit 1
fi

/usr/sbin/lighttpd -f /etc/lighttpd_abuso.conf

iptables -t nat -D PREROUTING -s $1 -d 0/0 -p tcp -j REDIRECT –to-port 8888 2> /dev/null
iptables -t nat -A PREROUTING -s $1 -d 0/0 -p tcp -j REDIRECT –to-port 8888

iptables -L PREROUTING -t nat -n -v

########## FIN SCRIPT ##########

Démosle permisos de ejecución:

root@openwrt:/# chmod x /etc/init.d/abuso

CREACIÓN DE SCRIPT PARA AÑADIR CONTROL DE TRAFICO 

Vale hasta ahora no teníamos control de trafico, ahora con este nuevo script y un par de módulos añadiremos el control deseado.

Necesitaremos instalar TC y y kmod-sched

root@openwrt:/# ipkg install tc
root@openwrt:/# ipkg install kmod-sched

Crearemos el Script , solo necesitaremos modificar el ancho que queremos modificar, en el ejemplo se están compartiendo 30 KB/s de bajada y 10 KB/S de subida.

Para poder saber que sube y que baja de la red de internet, marcaremos los paquetes con iptables.

root@openwrt:/# vi /etc/init.d/control_trafico

########## COMIENZO SCRIPT ##########
#!/bin/sh
#
#  Todos los anchos están del Kbps
#  ej. 25Kbps == 3.125KB/s
#
TC=/usr/sbin/tc
DNLD=720Kbit               # Límite de bajada
DWEIGHT=240Kbit            # Factor de Bajada
UPLD=240KBit               # Límite de Subida
UWEIGHT=80Kbit             # Factor de Subida

IF_SALIDA=vlan0 # La pata de Internet
IF_ENTRADA=eth1 # La pata de la Red Local, donde se conectan los usuarios de "gorra"

tc_start() {

# Añadimos Módulos necesarios

insmod sch_cbq
insmod sch_prio
insmod sch_htb
insmod sch_sfq
insmod sch_ingress
insmod cls_tcindex
insmod cls_fw
insmod cls_route
insmod cls_u32

# Marcamos la Subida de paquetes que van a Internet, pongo 2 redes de area local si solo hay una quitad la otra
iptables -t mangle -N MARCA_SUBIDA
iptables -t mangle -A MARCA_SUBIDA -s 10.0.0.0/8 -d 172.16.0.0/16 -j RETURN
iptables -t mangle -A MARCA_SUBIDA -s 10.0.0.0/8 -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A MARCA_SUBIDA -s 10.0.0.0/8 -d 0/0 -j MARK –set-mark 3

iptables -t mangle -A FORWARD -s 10.0.0.0/8 -d 0/0 -j MARCA_SUBIDA

# Marcamos los paquetes de bajada que vienen de Internet, pongo 2 redes de area local si solo hay una quitad la otra
iptables -t mangle -N MARCA_BAJADA
iptables -t mangle -A MARCA_BAJADA -s 10.0.0.0/8 -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A MARCA_BAJADA -s 172.16.0.0/16 -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A MARCA_BAJADA -s 0/0 -d 10.0.0.0/8 -j MARK –set-mark 4

iptables -t mangle -A POSTROUTING -s 0/0 -d 10.0.0.0/8 -j MARCA_BAJADA

# Creamos las colas para TC

    $TC qdisc add dev $IF_ENTRADA root handle 11: cbq bandwidth 100Mbit avpkt 1000 mpu 64
    $TC class add dev $IF_ENTRADA parent 11:0 classid 11:1 cbq rate $DNLD weight $DWEIGHT allot 1514 prio 1 avpkt 1000 bounded
    $TC filter add dev $IF_ENTRADA parent 11:0 protocol ip handle 4 fw flowid 11:1

    $TC qdisc add dev $IF_SALIDA root handle 10: cbq bandwidth 10Mbit avpkt 1000 mpu 64
    $TC class add dev $IF_SALIDA parent 10:0 classid 10:1 cbq rate $UPLD weight $UWEIGHT allot 1514 prio 1 avpkt 1000 bounded
    $TC filter add dev $IF_SALIDA parent 10:0 protocol ip handle 3 fw flowid 10:1

}

tc_stop() {
#Borramos Módulos

rmmod sch_cbq
rmmod sch_prio
rmmod sch_htb
rmmod sch_sfq
rmmod sch_ingress
rmmod cls_tcindex
rmmod cls_fw
rmmod cls_route
rmmod cls_u32

#Borramos Colas de TC

$TC qdisc del dev $IF_ENTRADA root
$TC qdisc del dev $IF_SALIDA root

# Borramos subida de Iptables

iptables -t mangle -D FORWARD -s 10.0.0.0/8 -d 0/0 -j MARCA_SUBIDA

iptables -t mangle -D MARCA_SUBIDA -s 10.0.0.0/8 -d 172.16.0.0/16 -j RETURN
iptables -t mangle -D MARCA_SUBIDA -s 10.0.0.0/8 -d 10.0.0.0/8 -j RETURN
iptables -t mangle -D MARCA_SUBIDA -s 10.0.0.0/8 -d 0/0 -j MARK –set-mark 3

iptables -t mangle -X MARCA_SUBIDA

# Borramos bajada de Iptables

iptables -t mangle -D POSTROUTING -s 0/0 -d 10.0.0.0/8 -j MARCA_BAJADA

iptables -t mangle -D MARCA_BAJADA -s 10.0.0.0/8 -d 10.0.0.0/8 -j RETURN
iptables -t mangle -D MARCA_BAJADA -s 172.16.0.0/16 -d 10.0.0.0/8 -j RETURN
iptables -t mangle -D MARCA_BAJADA -s 0/0 -d 10.0.0.0/8 -j MARK –set-mark 4

iptables -t mangle -X MARCA_BAJADA

}

tc_restart() {

    tc_stop
    sleep 1
    tc_start

}

tc_show() {

    echo ""
    echo "$IF_ENTRADA:"
    $TC qdisc show dev $IF_ENTRADA
    $TC class show dev $IF_ENTRADA
    $TC filter show dev $IF_ENTRADA
    echo ""

    echo "$IF_SALIDA:"
    $TC qdisc show dev $IF_SALIDA
    $TC class show dev $IF_SALIDA
    $TC filter show dev $IF_SALIDA
    echo ""

}

case "$1" in
  start)
    echo -n "Activando control de Ancho de Banda: "
    tc_start
    echo "Hecho"
    ;;
  stop)
    echo -n "Parando control de Ancho de Banda: "
    tc_stop
    echo "Hecho"
    ;;
  restart)
    echo -n "Reiniciando control de Ancho de Banda "
    tc_restart
    echo "Hecho"
    ;;
  show)
    tc_show
    ;;
  *)
    echo "Modo de Uso: /etc/init.d/tc.sh {start|stop|restart|show}"
    exit 1
    ;;
esac
exit 0
########## FIN SCRIPT ##########

Démosle permisos de ejecución:

root@openwrt:/# chmod x /etc/init.d/control_trafico

Si os fijais la colocacion de los scripts la he hecho en /etc/init.d, para ejecutarlos al inicio debeis añadirlo en algun script de inicio, en mi caso me creo uno que se llama S99ultimo donde hago configuraciones finales.

Bueno pues con esto podemos tranquilamente montarnos nuestra Red Compartida sin ningún miedo a quedarnos sin ADSL, simplemente darás tus 30 kb sino las estas utilizando.

Solo queda dar las gracias a quien ha hecho casi todo 😉
Como siempre Alfonso de Microalcarria.
A toda la red de Guadawireless que en esto de routers son unos cracks.
Y como siempre a vosotros que mejoraremos el documento.­

Print Friendly, PDF & Email
Comentarios

    Warning: Use of undefined constant type - assumed 'type' (this will throw an Error in a future version of PHP) in /home/improvisa_com/web/improvisa.com/public_html/wp-content/themes/grassland/comments.php on line 38
  • Juanmi dice:

    Miembro te metiste mucho con el manual de hackear una wep, no dices nada sobre este ;-).

    Saludos.

  • miembro dice:

    ajá! ¿nos estamos retractando? Seguro que te han llamado los cuerpos y fuerzas de seguridad del estado para que pidas perdón.