Monitoreo y gestión remota de dispositivos basados en Linux/OpenWrt/Lede a través del puerto 80, continuación

Esta es la parte final del artículo, aquí está el comienzo habr.com/es/post/445568
En la última ocasión escribí sobre cómo implementé la monitorización de dispositivos; ahora se tratará de la gestión. En discusiones con los 'técnicos' del Cliente, a menudo me encuentro con una percepción limitada de las capacidades de estos pequeños dispositivos (con recursos de memoria y rendimiento limitados); muchos consideran que 'lo máximo que necesitaremos es enviar un reinicio, para algo más serio, llamaremos a un equipo'.
Pero la práctica demuestra que no es del todo así. Aquí hay una pequeña lista de tareas típicas frecuentes:

  1. Diagnóstico y solución de red. Detrás del puerto Ethernet de su router suele 'vivir' otro dispositivo, que tiene su propia dirección IP interna. A veces, es posible (o necesario) 'pingar' este dispositivo. O la gestión de túneles; si en el router, que está funcionando a través de un módem 3G, de repente no se levanta un túnel, pero nosotros vemos el mismo router.
  2. Mantenimiento del sistema. Actualización de firmware, actualización de scripts de servicio.
  3. Equilibrismo. Podría llamarse 'excentricidades', pero el concepto de 'equilibrismo' como, cito, «la capacidad de un artista de circo para mantener el equilibrio en una posición inestable del cuerpo» — es más apropiado. Estas situaciones surgen debido a la limitación del presupuesto del cliente. A continuación, he incluido un par de ejemplos, pero como no tienen relación directa con el tema que se trata, los he puesto en notas al pie.

Monitoreo de Wi-FiUn tema de moda en los últimos cinco años, principalmente entre las cadenas minoristas federales. Paseas lentamente por los pasillos de la tienda, y tu móvil, con Wi-Fi activado, en su intento de «engancharse» a alguna red, envía regularmente paquetes de Probe Request que pueden ser analizados para contabilizarte: cuán a menudo visitas la tienda, qué trayectorias sigues, etc. Luego, los datos se recogen, se analizan, se crean mapas de calor y los gerentes utilizan estas imágenes para «conseguir» dinero de la dirección o de los inversores. Mientras tanto… «no hay dinero, pero tú mantente a flote…», y ya hay que mostrar el resultado (real), se vuelve a repetir la vieja canción «Sí, sí, claro, después instalaremos todo lo que quieras, pero ahora tenemos que mostrarle un resultado al Cliente. Por cierto, olvidamos mencionar que el Cliente permitió que nuestro equipo se conectara a su hotspot a través de Wi-Fi, pero en condiciones generales, como si fuéramos clientes invitados». Y así, hay que hacer que los routers sean equilibristas: se levantan varios subinterfaces Wi-Fi, uno de los cuales se conecta al hotspot, mientras que el otro monitoriza el entorno, arrojando frenéticamente el resultado de tcpdump en sí mismo, luego empaqueta el contenido del archivo en un archivo comprimido y, arriesgándose a «morir de sobrealimentación», intenta soltar el contenido en un servidor FTP. No es sorprendente que el router equilibrista a menudo «se caiga» y que de alguna manera tenga que ser «reanimado» de forma remota.

RadioAquí es más fácil describir la situación con una afirmación del cliente: «Queremos una red descentralizada de hotspots que funcionen en equipos cuyo modelo no se conoce de antemano, a través de canales que aún no sabemos cuáles serán. Ah, olvidamos decir que no solo queremos mostrar publicidad a los clientes, sino también analizar todo lo que sucede alrededor del lugar donde se instala el hotspot. No, aún no sabemos para qué, pero ya lo pensaremos, no lo duden, ¡aquí hemos sido capaces de idear esta idea!»

Y no debemos olvidar que, debido a una serie de circunstancias inciertas de antemano, la gestión debe realizarse en condiciones no estándar, cuando no podemos conectarnos al router directamente a través de ip: puerto y simplemente tenemos que esperar a que se manifieste actividad de su parte. Si abstraemos, el diálogo entre el servidor y el router se puede representar así:

  • Router: hola. soy el router tal, ¿tienes tareas para mí?
  • Servidor: router tal, te he registrado, así que estás vivo. Aquí está la tarea: ¿puedes mostrarme el resultado del comando ifconfig?
  • Router: hola. soy el router tal, la última vez me pediste que mostrara el resultado de ifconfig, aquí está. ¿Tienes alguna tarea para mí?
  • Servidor: router tal, te he registrado, así que estás vivo. No hay tareas para ti.

La pregunta más interesante es: ¿cómo puede un router remoto enviar cierta cantidad de información? En la parte anterior describí que en el router, debido a la limitación de recursos, solo hay un wget 'recortado' que funciona solo a través de GET y nada más, no hay cliente ftp ni curl. Más bien, necesitamos un método universal, independientemente de las características de la construcción de la imagen. Me detuve en usar wget. Más bien, bueno, como 'me detuve' — simplemente no tenía otra opción 🙂

Una advertencia de inmediatoMi solución para la gestión es funcional, no muy limitada y estoy seguro de que es torpe, incluso si satisface a la mayoría de mis clientes. Como se podría hacer correctamente: escribir una pequeña utilidad que envíe datos binarios a través del puerto 80 con POST. Incluirla (la utilidad) en el firmware del router y luego acceder a ella mediante bash. Pero la realidad es que: a) se necesita hacer rápido b) posiblemente todo debe hacerse en el 'zoológico existente de routers' c) '¡no hagas daño!' — si el router funciona y realiza otras tareas, intenta hacer cambios que no afecten la funcionalidad existente.

Pasemos a la implementación. Supongamos que tu cliente quiere reiniciar el router fácilmente y sin esfuerzo desde zabbix, 'con un clic del ratón'. Hoy comenzaremos la descripción de la implementación desde zabbix.
En el menú 'Administración' -> 'Scripts' agregamos un nuevo script. Lo llamamos 'Reboot', y como comando escribimos 'php /usr/share/zabbix/reboot.php {HOST.HOST}'

Monitoreo y gestión remota de dispositivos basados en Linux/OpenWrt/Lede a través del puerto 80, continuación

A continuación: Menú 'Monitoreo' -> 'Datos recientes' -> 'Clic derecho en el nodo de red requerido'. Así es como se verá el menú después de agregar el script.

Monitoreo y gestión remota de dispositivos basados en Linux/OpenWrt/Lede a través del puerto 80, continuación
Por lo tanto, colocamos el script reboot.php en el directorio /usr/share/zabbix (puede que el tuyo sea diferente, yo uso el directorio raíz de zabbix).

Advertencia de seguridadPara una explicación visual en el script, solo uso el ID del enrutador, pero no utilizo una contraseña. ¡No se recomienda hacer esto en la versión en producción! La razón por la que lo hice: porque hay una gran pregunta: ¿dónde almacenar las contraseñas de los enrutadores? ¿En los "datos de inventario" de Zabbix? Práctica controvertida. Como alternativa: limitar el acceso externo al propio archivo reboot.php.

Archivo reboot.php

<?php
	// asignamos parámetros de la consola a las variables
	$user = $argv[1];
	// ATENCIÓN. Aquí, por motivos de seguridad, ¡se debe especificar la contraseña del dispositivo! Pero para la demostración, accederemos a la base de datos sin usar una contraseña.
	//$password = $argv[2];
		
	$conn=new mysqli("localhost","db_user","db_password","db_name");
	if (mysqli_connect_errno()) {
		exit();
	}
	$conn->set_charset("utf8");
			
	// "Enviamos" el comando reboot al modificar el campo task de la tabla users. En el campo task se puede enviar cualquier comando.
	$sql_users=$conn->prepare("UPDATE users SET task='reboot' WHERE id=? AND status='active';");
	$sql_users->bind_param('s', $user);
	$sql_users->execute();
	$sql_users->close();
?>

Eso es todo. La pregunta que queda abierta es «¿cómo recibir el resultado de la ejecución del comando desde el dispositivo?» Consideremos la tarea con el comando ifconfig. Se puede enviar al dispositivo un comando como este:

message=`ifconfig`; wget "http://xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai/a.php?u=user&p=password!&m=$message" -O /tmp/out.txt

, donde:
message=`ifconfig` — asignamos el resultado de la salida del comando ifconfig a la variable $message
wget «xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai/a.php — nuestro script a.php, que registra los enrutadores y recibe mensajes de ellos
u=user&p=password!&m=$message — las credenciales de usuario y el valor de la variable de consulta m asigna el contenido de la variable $message
-O /tmp/out.txt — la salida a un archivo /tmp/out.txt en este caso no es necesaria, pero si no se especifica este parámetro, wget no funciona

Por qué esto funciona torpementePorque esta es una posible brecha de seguridad. El error más inofensivo que puede ocurrir es si en la salida de tu comando, por ejemplo, hay un símbolo „&“. Por lo tanto, debes filtrar todo lo que se envía desde los enrutadores y todo lo que llega al servidor. Sí, estoy avergonzado, de verdad. En mi defensa, solo puedo escribir que todo el artículo está dedicado a cómo gestionar enrutadores con un firmware que no se puede prever de antemano, con canales de comunicación no definidos de antemano.

Y también una preparación para el futuro: aún no he averiguado cómo reflejar los resultados (por ejemplo, el resultado de la ejecución de un comando) que llegan al servidor con las herramientas estándar de Zabbix.

Recuerdo que todos los archivos fuente se pueden obtener del repositorio de Git en la dirección: github.com/BazDen/iotnet.online.git

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster