Bloqueo de Internet en Openwrt mediante mensajes mqtt

La idea de este proyecto es que nuestro router bloquee la salida de internet a ciertas Ips o rangos de Ips, al recibir un mensaje por mqtt.

Un siguiente paso sería buscar un botón rojo y uno verde, y preparar un dispositivo que bloquee o permita el internet a un aula. Por ahora nos conformaremos con activarlo o desactivarlo mediante comandos.

Explicando los pasos.

Lo primero que haremos es crear dos scripts que se almacenarán en el router. A uno lo llamaremos block.sh y el otro se llamará allow_all.sh.

block.sh

Recibe por parámetro una ip o una subred. Lo podremos llamar de las siguiente maneras:
block.sh ip o block.sh CIDR. Ejemplos válidos serían:

block.sh 192.168.20.6
block.sh 192.168.20.0/24

El script además comprueba si recibe ips válidas. En caso contrario no hará nada.

allow_all.sh

No recibe parámetros. Al ejecutarlo libera todas las restricciones y añade una iptable para solo dejar a un equipo que nos interese que tenga siempre acceso a Internet.

A continuación crearemos un script llamado escucha.sh.

Se ejecutará en Openwrt y quedará escuchando de un topic (router/input) por donde recibirá las ordenes. Cuando recibe la orden de bloquear, llama a block.sh. Por ejemplo, si recibe bloquear 192.168.20.5, llamará a block.sh 192.168.20.5. Además publicará en el topic (router/output) el valor Bloqueado o Permitido. Así consultando este topic sabremos si hay algún bloqueo o no. e instalar en el ro

Poco más queda por decir, sólo que necesitaremos instalar o acceder a un servidor de mqtt (mosquitto) e instalar los clientes de mosquitto en el router.

1. Creando los scripts que permiten o deniegan acceso.

Accederemos por ssh al router e instalaremos el editor nano, que siempre nos facilita la edición de los scripts y configuraciones del router.

opkg update; opkg install nano

Hacemos nano block.sh e introducimos lo siguiente. Para guardar le damos a ctrl+s.

#!/bin/sh
# Script block.sh
# Pasamos por parámetro el rango de Ips a bloquear.
# ejemplo de llamadas: block.sh 192.168.20.0/24 o block.sh 192.168.20.4
#!/bin/sh

check_ip(){

# si no se le han pasado parámetros a la funcion devuelve error
if [ -z "$1" ]
then
      echo "Debe poner parámetro ejemplo: test.sh 192.168.24.33/22"
      return 1
fi

# Separamos la ip de la máscara

ip=$( echo "$1" | cut -d"/" -f1 )
mask="$(basename "$1")"

# Si la máscara está vacía devuelve lo mismo en mask y en ip
# por eso compruebo si son iguales para poner cadena vacía en mask

if [ "$mask" = "$ip" ]; then
  mask=""
fi

# Si la máscara no está vacía miro a ver si es un número
# En caso de que no lo sea da error
if [ ! -z "$mask" ]; then
  re='^[0-9]+$'
  if ! [[ $mask =~ $re ]] ; then
     return 1
  fi
fi

if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then
  for i in 1 2 3 4; do
    if [ $(echo "$ip" | cut -d. -f$i) -gt 255 ]; then
      return 1  # Internamente ip con numeros > 255
    fi
  done
  ip="ok"
else
  return 1
fi

# Si la máscara está vacíalo aceptamos
if [ -z "$mask" ]; then
  if [ $ip = "ok" ]; then
    return 0
  fi
fi

# si la máscara es mayor de 32 no la aceptamos
if [ $mask -gt 32 ]; then
  return 1
fi

# si la máscara es menor que 0 no la aceptamos
if [ $mask -lt 0 ]; then
  return 1
fi
}

check_ip $1
retval=$?
if [ $retval -eq 1 ]; then
  echo "Ip no válida"
  exit
fi

regla=$(iptables -L --line-numbers | grep -i "Bloqueo" | grep "$1" | awk '{print $1}')
if [ "$regla" -gt 0 ] 2>/dev/null; then
  echo "La regla ya existe"
else
  iptables -A forwarding_rule -m comment --comment "Bloqueo de $1" -s $1 -j DROP
fi

Haremos lo mismo con allow_all.sh. Haremos nano allow_all.sh y meteremos lo siguiente:

#!/bin/sh
# Script allow_all.sh
iptables -F forwarding_rule
permitida="192.168.20.2"
regla=$(iptables -L --line-numbers | grep -i "Permite" | grep "$permitida" | awk '{print $permitida}')
if [ "$regla" -gt 0 ] 2>/dev/null; then
  echo "La regla ya existe"
else
  iptables -A forwarding_rule -m comment --comment "Permite $permitida" -s $permitida -j ACCEPT
fi

Hay que señalar que en este script siempre permitirá el acceso a la ip 192.168.20.2. Cámbiala tú por la que quieras. Además al meter una regla de bloqueo, le añade un comentario a la iptable por lo que podremos buscar si ya existe.

A continuación les daremos permisos de ejecución:

chmod +x block.sh
chmod +x allow_all.sh

Podemos llamarlos desde línea de comando para ver si funcionan. Desde el interfaz web del router podrás ver las iptables en la sección: Status —> Firewall. Busca en la página la cadena forwarding_rule.

2. Creando el script que escucha.

Haremos nano escucha.sh y meteremos lo siguiente:

#!/bin/sh
# Script: escucha.sh
# Configuración del broker a escuchar.
broker="192.168.20.1"
port="1883"
topic_input="router/input"
topic_output="router/output"

# Por el topic_input podremos recibir lo siguiente:
#bloquear dirección_ip
#bloquear dirección_ip/mask
#permitir

# Ponemos el cliente de mosquitto escuchando
mosquitto_sub -t $topic_input -h $broker| while read value; do
# Separamos la acción de la ip.
accion=$(echo "$value" | cut -d' ' -f1)
ip=$(echo "$value" | cut -d' ' -f2)

case $accion in 
   "bloquear")
#--------------------------------------------------------------
     #Añadimos la iptable correspondiente de "bloqueo"
      /root/block.sh $ip
     #Publicamos en el tópico de salida mensaje de aviso 
       mosquitto_pub -t $topic_output -h $broker -m "Bloqueado";;
    
 #--------------------------------------------------------------
   "permitir")
      /root/allow_all.sh
      mosquitto_pub -t $topic_output -h $broker -m "Permitido";;
#--------------------------------------------------------------
esac
done

Si te fijas debes poner tú la dirección IP del broker de mosquitto y el puerto de escucha. En mi caso pongo que el broquear está en mi propio router escuchando por la ip 192.168.20.1.

Luego le daremos permisos de ejecución:

chmod +x escucha.sh

3. Instalando servidor de mosquitto.

Nosotros instalaremos en el propio router el servidor de mosquitto y lo configuraremos para que escuche en la dirección IP de la LAN. (192.168.20.1) !!! CUIDADO ESTA IP EN TU ROUTER ES DIFERENTE !!!

Puedes saltarte este paso si ya tienes otro servidor mosquitto funcionando o vas a usar uno de Internet.

opkg update; opkg install mosquitto-ssl

Editaremos la configuración de mosquitto para que escuche en la ip de la LAN 192.168.20.1. !!! CUIDADO ESTA IP EN TU ROUTER ES DIFERENTE !!!

Haremos:

nano /etc/mosquitto/mosquitto.conf

y pondremos al principio:

allow_anonymous true
listener 1883 192.168.20.1
#  !!! CUIDADO ESTA IP EN TU ROUTER ES DIFERENTE !!!

Guardamos y reiniciamos el servicio con:

/etc/init.d/mosquitto restart

Hemos configurado el servidor para que cualquiera pueda publicar en él. Si quieres más seguridad, usa conexiones de red cifradas y autenticación.

4. Instalando los clientes de mosquitto.

Instalaremos los clientes de mosquitto en el router para que pueda conectarse a él.

opkg update; opkg install mosquitto-client-ssl

5. Probándolo todo.

Ejecutaremos el script de escucha y lo dejaremos ejecutándose de fondo con el & añadido.

 /root/escucha.sh &

Desde un ordenador o desde otra conexión ssh al openwrt mandaremos un bloqueo con la siguiente orden:

mosquitto_pub -h 192.168.20.1 -t "router/input" -m "bloquear 192.168.20.0/24"

Con esto bloqueo toda la red 192.168.70.0/24. Si lo que quieres es bloquear tu red, pon la tuya.

!!! OJO que yo estoy enviando a mi servidor que está en la ip 192.168.20.1, el tuyo estará en otra IP DIFERENTE y tu rango de IPS será diferente también!!!

Para que vuelva todo a su sitio como estaba al principio y permitir a todo el mundo puedes hacer siempre este comando:Haciéndo que el script de escucha comience al arrancar el router.

mosquitto_pub -h 192.168.20.1 -t "router/input" -m "permitir"

!! OJO que yo estoy enviando a mi servidor que está en la ip 192.168.20.1, el tuyo estará en otra IP DIFERENTE !!!

Comprueba desde el interfaz web del router en la sección: Status —> Firewall. Busca en la página la cadena forwarding_rule. Deberá aparecerte en comentarios el Bloqueo que hiciste

6. Que el script de escucha se ejecute al arrancar el router.

Crearemos el siguiente fichero y le daremos a continuación permisos de ejecución:

nano /etc/init.d/escucha

Y le añadimos lo siguiente:

#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org

START=99
STOP=15

start() {
        /root/allow_all.sh
        /root/escucha.sh &
}

stop() {

   kill -9 `ps |grep 'escucha'|grep -v grep|awk '{print $1}'`
   kill -9 `ps |grep 'mosquitto_sub'|grep -v grep|awk '{print $1}'`
}

Guardamos y le damos permiso de ejecución:

chmod +x /etc/init.d/escucha

Y haremos que arranque al encender el router con lo siguiente:

/etc/init.d/escucha enable

Prueba a arrancarlo con la orden /etc/init.d/escucha start y enviar al servidor de mosquitto un mensaje a ver si suena la locución. Con /etc/init.d/escucha stop podrás pararlo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

+ 75 = 77