viernes, 7 de agosto de 2015

¿Como puedo programar un botón de mi router con OpenWRT?

En la necesidad de modernizar diferentes industrias del país, Juan Perón invitó a un número de personalidades de la técnica, que estableciendo vínculos con la Argentina, pudieron mejorar los prospectos de la industria. De entre las enseñanzas, guardamos aquella de cómo programar los botones de nuestro router a través del firmware OpenWRT para darle nuevos usos.

(...)
Muchas veces me preguntaron porqué traje a los hombres de ciencia de un país derrotado a nuestro Vergel de Paz. Pero la respuesta era simple: los científicos Alemanes nos enseñaron los rudimentos de ciencia en la que nuestros hombres atrasaban, y nos permitieron afianzar la industria del país en un camino de grandeza como lo han tenido las Grandes Naciones del Tierra.


Todo lo que hemos aprendido ha sido bueno, y de lo que no hemos sacado rédito instantáneo, lo hemos hecho al tiempo. Así es como ha de lograrse un verdadero progreso. En ocasiones, nos hemos valido de la improvisación para encontrar un uso a la técnica y utillaje que siquiera sus creadores preveían.

La industria mecánica de Córdoba es un claro ejemplo, con su rastrojero iniciado a partir de utillaje aeronáutico y de circunstancias. Si este ejemplo puede encontrarse en el desarrollo de la industria pesada, cómo no va a haberlo en la telemática. Encontraremos ejemplos en lo que algo pensado para una cosa, termina siendo mejor aplicado para otra.

La mayoría de los enruteadores modernos disponen de un botón nomenclado como WPS. Dicho botón activa una funcionalidad telemática capaz de "asociar" un dispositivo Wifi a nuestra red local inalámbrica cifrada con contraseña sin necesidad de compartir la clave. Explicado de manera sencilla, al presionar el botón se dará inicio a una ventana de tiempo de dos minutos, durante el cual el router - en confianza - asociará a cualquier dispositivo Wifi en el que también se presione dicho botón. Una vez transcurrido los dos minutos, volverá a cifrarse y cerrarse la red inalámbrica.
La idea original estaba bien intencionada. Sin embargo, muchas cosas malas pueden hacerse en dos minutos, y si lo sabrá su madre. Nada impide que durante dicha ventana temporal, usuarios malévolos en las cercanías puedan asociarse a la red sin que tuviésemos maneras obvias de saberlo. Por lo tanto, la funcionalidad WPS - en lugar de hacer la vida más fácil al Pueblo - terminó perjudicándolo y llevándole inseguridad por partes iguales...

Pues bien, en tratados anteriores he relatado a la Masa que muchos routers (como por ejemplo, el TP-Link TL-WR941ND peronista) pueden ser dotados de un firmware libre que reemplaza al limitado programa interno original. He explicado como instalar dicho firmware libre OpenWRT en nuestro router y cómo configurarlo para hacer de él una potente máquina multifunción. ¡Lo hemos dicho! En vista de las mencionadas deficiencias con el sistema de asociación WPS, el firmware libre OpenWRT no usa esta característica, y ello significará que el botón WPS del router (nomenclado como "QSS" en los routers TP-Link) quedará "como cenicero de Pochoneta".

Sin embargo, gracias al Justicialismo y a nuestra doctrina de Software Libre, nos será bien posible utilizar el botón QSS para realizar otras acciones que nos plazcan, si sabemos configurarlo. Podremos programar el botón WPS/QSS para que nos sirva para apagar o encender el radioemisor de Wifi (y por lo tanto, de la red inalámbrica). Esto presenta algunas ventajas: podríamos dejar el router encendido 24x7 realizando tareas de enrutamiento por cable, servicio de correo, o un mini-servidor web, etc, pero decidir apagar el Wifi cuando no estamos en el hogar, o apagarlo de forma manual cuando nadie lo vaya a utilizar, o apagarlo automáticamente siguiendo un patrón de horarios.


Naturalmente que en primer lugar, debemos tener ya instalado y configurado OpenWRT en nuestro aparato (en este caso tomaré como referencia el TP-Link TL-WR941ND). Hemos de notar también que por la característica de esta tarea, nos convendrá conectarnos al router de manera cableada.

Acto seguido, será útil asegurarnos de que el botón QSS del router funciona, y conocer en particular cuál es su "nombre de hardware".

Para ello nos logueamos al router como se ha explicado en otros tratados (normalmente con ssh root@dirección_ip_del_router). Una vez dentro del router (el prompt podría indicar root@OpenWrt o similar) crearemos una carpeta donde irán las rutinas autoejecutables para los botones. Lo haremos ingresando en el router,:

mkdir -p /etc/hotplug.d/button

Ahora usaremos el editor peronista Vi para crear un archivo llamado buttons en dicho directorio, con el comando:

vi /etc/hotplug.d/button/buttons

Es importante conocer bien el funcionamiento del editor, para ser práctico a la hora de configurar el router. El editor Vi normalmente opera en modo revisión, por lo cual no podremos modificar ni agregar ningún texto. Para pasar al modo de inserción de texto hemos de presionar la tecla i. Solo entonces podremos escribir o pegar en la Terminal el texto que querramos. En este caso, hemos de pegar allí el siguiente código, pensado para evaluar el funcionamiento de los botones del router:

#!/bin/sh
# Script para que los botones reporten sus acciones.
logger el boton $BUTTON reporta accion $ACTION


Para guardar los cambios en el archivo recién editado en Vi, hemos de presionar Esc, y tipear el comando :wq que se encargará de grabar (w) y salir (q) del editor. Nos devolverá a la línea de comandos del router.

Conforme estemos en el prompt de nuestro enruteador, habremos de evaluar el botón correspondiente: en el caso del TP-Link TL-WR941ND presionamos el botón "QSS" que se encuentra en la derecha del panel frontal (es el único botón).
Hecho esto, en la terminal del router ejecutaremos el comando:

logread

...y nos devolverá un largo archivo, el cual al final debería indicarnos final algo como:

user.notice root: el boton wps reporta accion pressed
user.notice root: el boton wps reporta accion released


Esta información recabada es importante pues nos confirma el nombre de hardware del botón QSS, que en realidad es "wps", y los estadíos que puede tomar dicho botón de software: "pressed" (presionado) y "released" (soltado).

Sabiendo esto, agregaremos dos archivos nuevos para configurarlo. Unos es el archivo /etc/hotplug.d/button/00-button, que configura el funcionamiento general de los botones, y otro es el que especificará el funcionamiento particular el botón QSS. Para ello los agregamos con Vi:

vi /etc/hotplug.d/button/00-button

Una vez en el editor, presionamos i e insertamos el siguiente código:

#!/bin/sh
. /lib/functions.sh
do_button () {
        local button
        local action
        local handler
        local min
        local max
 
        config_get button $1 button
        config_get action $1 action
        config_get handler $1 handler
        config_get min $1 min
        config_get max $1 max
 
        [ "$ACTION" = "$action" -a "$BUTTON" = "$button" -a -n "$handler" ] && {
                [ -z "$min" -o -z "$max" ] && eval $handler
                [ -n "$min" -a -n "$max" ] && {
                        [ $min -le $SEEN -a $max -ge $SEEN ] && eval $handler
                }
        }
}
 
config_load system
config_foreach do_button button

Guardamos los cambios y salimos de Vi con Esc + :wq.


Acto seguido, agregaremos la especificación de funcionamiento del botón QSS en el fichero configuración correspondiente, que es /etc/config/system. Para ello ingresamos el comando:

vi /etc/config/system

Las especificaciones de funcionamiento del botón QSS/WPS será la de apagar el emisor Wifi y la red inalámbrica al presionarlo brevemente (durante menos de un segundo). Si lo presionamos entre uno y cinco segundos, encenderá el Wifi y la red inalámbrica. Considerando esto, en Vi pasamos al modo inserción con la tecla i, y al final del archivo /etc/config/system, habremos de agregarle las siguientes lineas de configuración:

# Agregado al archivo /etc/config/system 
# para configurar el botón OSS/WPS del Router TP-Link
# Esto apaga el emisor Wifi y la red inalámbrica
# al presionar el boton QSS/WPS menos de 1 segundo.
config button
    option button 'wps'
    option action 'released'
    option handler 'uci set wireless.@wifi-device[0].disabled=1 && wifi'
    option min '0'
    option max '1'
 

# Esto enciende el emisor Wifi y la red inalámbrica
# si se presiona el boton QSS/WPS entre 1 y 5 segundos.
config button
    option button 'wps'
    option action 'released'
    option handler 'uci set wireless.@wifi-device[0].disabled=0 && wifi'
    option min '1'
    option max '5'



...guardamos los cambios y salimos del editor Vi con la consabida combinación de teclas Esc + :wq

Para probar los cambios, debemos reiniciar el router con:

reboot

Una vez que el router se reinicie, debemos presionar y soltar el botón QSS durante menos de un segundo, y se apagará el Wifi (podremos comprobarlo al comprobar el apagado de la luz "WLAN" del panel frontal del router. Para reencender el Wifi, debemos presionar el botón QSS entre 1 y 5 segundos (se encenderá la luz WLAN y podremos conectarnos inalámbricamente).

Configurar el encendido / apagado del Wifi a un horario determinado:

Hemos mencionado la potencia y versatilidad que nos permiten los scripts de Cron para activar o desactivar el Wifi en horarios particulares. Por ejemplo, supongamos que según nuestros horarios de trabajo y sueño nos conviene que el Wifi se apague automáticamente a la 23:30PM y se encienda a diana, a las 6:30 AM durante los días de semana.

Para ello será necesario crear dos scripts ejecutables, uno para encender el Wifi y otro para apagarlo, y programar el cronómetro del router (cron). Todo ello lo haremos también desde la terminal del router. Una vez logueados en él, podremos ingresar:

vi /root/wifioff

...presionamos i y le pegamos el siguiente código

#!/bin/sh
# Apaga la WLAN (sin detener el dispositivo de emision radio0)
wifi down


Una vez guardado el fichero y salido del editor (Esc + :wq), utilizaremos el siguiente comando para crear el archivo de encendido:


vi /root/wifion

...y nuevamente usamos i para pegarle su código correspondiente que figura a continuación:

#!/bin/sh
# Enciende la WLAN (sin detener el dispositivo de emision radio0)
wifi on


Guardamos y salimos con Esc + :wq


Conforme hayamos ingresado ambos archivos, nos será imprescindible otorgarles permisos de ejecución para que dichos guiones puedan utilizarse. Lo haremos con el comando:

chmod +x wifionoff wifion wifioff

Ahora podremos programar el cronómetro de ejecución (cron). Esto se hace por medio de una tabla de texto (crontab), modificando el archivo /etc/crontabs/root. Para hacer la tabla crontab editamos el archivo referenciado usando Vi, con el comando:

vi /etc/crontabs/root

...presionamos i para configurar al siguiente texto al final del archivo:

# Ejecuta este script wifioff todos los dias
# a las 23:30pm
30 23 * * * /root/wifioff
# ejecuta el script wifion a las 06:30am
# a las 6:30am

30 06 * * * /root/wifion

...guardamos la tabla de cron recién creada con Esc + :wq y al volver al prompt del router, debemos ejecutar el comando reboot para que surta efecto. Veremos que con ello el Wifi se apagará automáticamente a las 23:30 y se encenderá a las 06:30. Si necesitásemos encenderlo durante ese horario, bien podríamos presionar el botón del aparato durante 1 y 5 segundos para activarlo.


Podría ser que en determinadas ocasiones necesitemos un script distinto, que  si el Wifi está encendido lo apague, y si está apagado, lo encienda. Para ello, debemos ingresar el siguiente script:

vi /root/wifionoff

y le pegamos el siguiente código:

#!/bin/sh
STATEFILE="/tmp/wifionoff.state"

if [ $# -eq 1 ]; then
  case $1 in
    "up"|"on")
      STATE=off
      ;;
    "down"|"off")
      STATE=on
      ;;
  esac
else
  if [ ! -e ${STATEFILE} ]; then
    STATE=on
  else
    . ${STATEFILE}
  fi
fi
if [ -z ${STATE} ]; then
  STATE=on
fi

if [ ${STATE} == "on" ]; then
  /sbin/wifi down
  STATE=off
else
  /sbin/wifi up
  STATE=on
fi

echo "STATE=${STATE}" > ${STATEFILE}


Guardamos y salimos del editor Vi con Esc + :wq.

4 comentarios:

  1. Un cordial saludo estimado caballero, lo felicito por tan excelente material que nos comparte, se me ocurren muchas mas funciones para este botón pero al no tener suficientes conocimientos en programación me toca preguntarle, sera posible configurarlo para que al accionarlo envíe una linea de comando a otro equipo en la red? como por ejemplo este sencillo comando que envío mediante consola a un pequeño aparato para que accione un contacto seco, ((setstate,1:1,1)) y este otro para que abra el contacto ((setstate,1:1,0)).

    ResponderEliminar
    Respuestas
    1. Estimado César Marcano:

      Puede incorporar las instrucciones que nos indica como script en un archivo .sh, y que se envíe dicho comando. No explica demasiado, pero podría ser:

      #!/bin/sh
      # Archivo seco.sh. Enciende ctto seco:
      ((setstate,1:1,1))

      #!/bin/sh
      # archivo abrircto.sh
      ((setstate,1:1,0))

      Sin embargo, esto se ejecuta en el mismo router. Si sabe cómo conectarse al aparato que usted tiene, debe agregar dichas líneas antes del comando a accionar. Por ejemplo, si el aparato cuenta con una consola telnet o SSH, debe incorporar los comandos de conexión antes. Por ejemplo:

      telnet 192.168.1.21 23 (suponiendo que la conexión es por red telnet a una IP 192.168.1.21, por puerto 23

      También hemos explicado aquí como disponer estos scripts para dispararlos por medio de cron. De esta forma podrían hacerse que el comando se active en una hora o día determinado.

      Atte.

      Juan Perón

      Eliminar
  2. Muy agradecido por su respuesta, al final el script que use quedo así:
    #!/bin/sh #Script para activar contactos remotos
    (sleep 1
    echo "setstate,1:1,1." #cambiar funciones NO-NC
    sleep 2) | nc 192.168.1.212 4998

    Funciona perfectamente.

    ResponderEliminar
    Respuestas
    1. Estimado César Marcano:

      Enhorabuena por el éxito conseguido. Sólo quienes dan todo por la liberación son quienes merecen los éxitos y las buenaventuras que prodiga el esfuerzo.

      De ahora en adelante, toda vez que lo ejecute dicho script, gritará al cielo un estruendoso:

      "¡VIVA PERÓN!".

      Atte.

      Juan Perón

      Eliminar