通过端口 80 远程监控 Linux/OpenWrt/Lede 设备(续)

这是文章的最后部分,这里是开始部分 habr.com/en/post/445568
上次我写了如何实现设备监控,现在我们来谈谈管理。 在与客户方面的“技术人员”讨论时,我经常遇到对这种小型设备(内存资源和性能较低)的功能认知有限的情况,许多人认为“我们最需要的是发送重启,以获取更多信息”认真的我们会派一个团队”。
但实践表明这并不完全正确。 以下是常见典型任务的一小部分:

  1. 网络诊断和故障排除。 在路由器的以太网端口后面通常还有另一个具有自己的内部 IP 地址的硬件。 有时,您可以(应该)“ping”它。 或者隧道管理 - 如果隧道在通过 3G 调制解调器运行的路由器上突然不出现,但我们可以看到路由器本身。
  2. 系统维护。 固件更新、服务脚本升级。
  3. 平衡技术。 这可以被称为“反常”,但我引用“平衡主义者”的概念, “马戏表演者在不稳定的身体姿势下保持平衡的能力” - 更适合。 出现这种情况是由于客户的预算有限。 下面我举了几个例子,但是...... 和故事主题没有直接关系,我放在笔记里

无线网络监控这是过去五年的一个流行话题,主要是在联邦零售连锁店中。 你悠闲地漫步在交易大厅,你的手机打开Wi-Fi,试图“粘”在网络的某个线程上,定期发出Probe Request数据包,通过分析这些数据包可以计算出你:你多久来一次这家店,出于什么原因?你走过的轨迹等等。 然后收集、分析数据,绘制热图,经理们从管理层或投资者那里“勒索”这些图片的钱。 好吧,现在......“没有钱,但你坚持......”,结果(真实的)已经需要显示,好听的老歌开始:“是的,是的,然后我们当然将安装 cis 和您想要的一切,但现在我们需要向客户展示结果! 顺便说一句,我们忘了说,客户允许我们通过 Wi-Fi 将我们的设备连接到他的热点,但一般而言,就像我们是访客客户一样。” 所以我们必须做平衡路由器——拉起几个WiFi子接口,其中一个紧贴热点,第二个监控环境,疯狂地将tcpdump结果上传给自己,然后将文件内容打包成存档并风险死于“暴饮暴食”的人试图将内容吐出到 FTP 服务器上。 平衡路由器经常“崩溃”并且必须以某种方式远程“复苏”也就不足为奇了。

半径用客户的这样的陈述来描述这里的情况更容易: “我们想要一个去中心化的热点网络,该网络可以在通过渠道提前未知型号的​​设备上运行,但我们还不知道哪些设备。 哦,我们忘了说,我们不仅要向客户展示广告,还要分析热点安装位置周围的一切。 不,我们还不知道为什么,但我们会弄清楚的,别怀疑,我们能够想出这个主意。”

我们不能忘记,由于许多以前未知的情况,控制必须在非标准条件下进行,即我们无法通过 IP: 端口直接连接到路由器,而被迫简单地等待其活动。 如果我们抽象一下,服务器和路由器之间的对话可以这样表示:

  • 路由器: 你好。 我是某某路由器,有什么任务给我吗?
  • 服务器:路由器某某,我注册了你,说明你还活着。 挑战如下:向我显示 ifconfig 命令的结果?
  • 路由器: 你好。 我是某某路由器,上次你要求显示ifconfig的结果,这里就是。 有什么任务给我吗?
  • 服务器:路由器某某,我注册了你,说明你还活着。 没有适合您的任务。

最有趣的问题是:远程路由器如何发送一定量的信息? 在上一部分中,我描述了由于资源有限,路由器只有一个“精简版”wget,它只能通过 GET 工作,没有其他功能;没有 FTP 客户端或curl。 更准确地说,无论图像组装的特征如何,我们都需要一种通用的方法。 我决定使用 wget。 更准确地说,我是如何“停下来”的——我别无选择:)

只是免责声明我的管理解决方案是有效的,不是很有限,而且我确信它是歪曲的,即使它适合我的大多数客户。 您如何明智地做到这一点 - 编写一个通过端口 80 发送 POST 二进制数据的小实用程序。 将其(实用程序)包含在路由器固件中并使用 bash 访问它。 但现实是:a)我们需要快速 b)我们可能需要在现有的“路由器动物园”上做所有事情 c)“不要造成伤害!” — 如果路由器正在工作并执行其他任务,请尝试进行不会影响现有功能的更改。

让我们继续实施。 假设您的客户希望通过“点击鼠标”轻松自然地从 zabbix 重新启动路由器。 今天我们将开始描述使用Zabbix的实现。
在“管理”->“脚本”菜单中,添加一个新脚本。 我们称之为“Reboot”,输入“php /usr/share/zabbix/reboot.php {HOST.HOST}”作为命令

通过端口 80 远程监控 Linux/OpenWrt/Lede 设备(续)

接下来:菜单“监控”->“最新数据”->“右键单击所需的网络节点”。 这是添加脚本后菜单的样子。

通过端口 80 远程监控 Linux/OpenWrt/Lede 设备(续)
因此,我们将reboot.php脚本放在/usr/share/zabbix目录中(你的可能不同,我使用zabbixa根目录)。

安全免责声明为了使脚本中的解释更清楚,我只使用路由器ID,但不使用密码。 不建议在生产版本中这样做! 我为什么这样做:因为最大的问题是在哪里存储路由器的密码? 在 zabbixe 本身的“库存数据”中? 有争议的做法。 或者:限制对reboot.php 文件本身的外部访问

文件reboot.php

<?php
	// присваиваем параметры с консоли переменным
	$user = $argv[1];
	// ВНИМАНИЕ. Вот здесь в целях безопасности все-таки прописывать пароль устройства! Но для демонстрации мы будем обращаться к базе данных без использования пароля. 
	//$password = $argv[2];
		
	$conn=new mysqli("localhost","db_user","db_password","db_name");
	if (mysqli_connect_errno()) {
		exit();
	}
	$conn->set_charset("utf8");
			
	// "Отправляем" команду reboot за счет изменения поля task таблицы users. В поле task можно отправлять любую команду.
	$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();
?>

就这样。 问题仍然悬而未决:“如何获取从设备执行命令的结果。” 让我们以使用 ifconfig 命令为例来看看该任务。 该命令可以发送到设备:

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

哪里:
消息=`ifconfig` — 我们将 ifconfig 命令输出的结果分配给 $message 变量
得到“xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai/a.php — 我们的 a.php 脚本,用于注册路由器并从它们接收消息
u=用户&p=密码!&m=$消息 — 凭证和请求变量的值 m — 分配 $message 变量的内容
-O /tmp/out.txt - 在这种情况下我们不需要输出到文件/tmp/out.txt,但是如果不指定该参数,wget将不起作用

为什么这不起作用?因为这是一个潜在的安全漏洞。 例如,可能发生的最无害的错误是命令输出中存在“&”字符。 因此,有必要过滤从路由器发送的所有内容以及到达服务器的所有内容。 是的,我真的很羞耻。 在我的辩护中,我只能写整篇文章致力于如何管理具有预定义固件和未提前定义的通信通道的路由器。

好吧,未来的开始:我还没有弄清楚如何使用标准 zabbix 工具来反映到达服务器的结果(例如,执行命令的结果)。

我提醒您,所有源代码都可以从 Git 存储库获取: github.com/BazDen/iotnet.online.git

来源: habr.com

添加评论