通过端口80远程监视和管理基于Linux / OpenWrt / Lede的设备...

大家好,这是我第一次在Habré工作。 我想写有关如何在外部网络中管理非标准网络设备的文章。 非标准是什么意思:在大多数情况下,要控制外部网络中的设备,您需要:

  • 公用IP地址。 好吧,或者如果设备位于某人的NAT后面,则使用公共IP和“转发”端口。
  • 通向中央节点的隧道(PPTP / OpenVPN / L2TP + IPSec等)。

因此,当标准方法不适合您时,您将需要“我的自行车”,例如:
  1. 设备位于NAT的后面,除了通常的http(端口80)之外,所有设备均处于关闭状态。 对于大型联邦公司网络来说,这种情况很正常。 注册端口-它们可以但不能立即,不迅速,不适合您。
  2. 不稳定和/或“狭窄”的沟通渠道。 低速,恒定损耗。 尝试组织隧道时感到痛苦和沮丧。
  3. 一个昂贵的通信通道,实际上每兆字节都很重要。 例如卫星通信。 再加上大的延迟和“狭窄”的地带。
  4. 当您需要“玩弄”大量小型路由器时,一方面要安装OpenWrt / Lede以扩展功能,另一方面,路由器的资源(内存)远远不够。

笔记次数
是什么阻止了USB棒从路由器上的安装以及扩展了路由器的内存?

通常,对解决方案整体成本的要求,但有时形状因素也起着关键作用。 例如,TP-Link ML3020位于对象上,其唯一的USB端口用于2G / 3G调制解调器,所有这些都包裹在带有小塑料盒的螺纹中,并放置在高,高(在桅杆上),远,远(在(距离移动运营商最近的基站30公里)。 是的,您可以插入USB集线器并扩展端口数量,但是经验表明,它既麻烦又不可靠。

因此,我试图向您描述我的典型情况:“在遥远的某个地方,有一个非常重要的,孤独的小型路由器正在运行Linux。 每天至少要知道他“还活着”,并且在必要时向他发送了命令,例如“太阳,重新启动!”,这一点很重要。

让我们继续执行:

1)在路由器端,每5/10/1440分钟执行一次cron,或者每当您需要使用wget向服务器发送http请求时,将请求的结果保存到文件中,使该文件可执行并执行。

我在cron中的行看起来像这样:

文件/ etc / crontabs /根目录:

*/5 * * * * wget "http://xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai/a.php?u=user&p=password" -O /tmp/wa.sh && chmod 777 /tmp/wa.sh && /tmp/wa.sh 

其中:
xn-80abgfbdwanb2akugdrd3a2e5gsbj.xn-p1ai-我的服务器的域。 我马上会注意到:是的,您也可以指定一个特定的服务器IP地址,我们之前已经这样做过,而在我的奋斗状态下,我似乎再也没有看到-并未阻止对DigitalOcean和Amazon的“云”中最大份额的访问。 在使用符号域的情况下,当发生此类事件时,您可以冷静地提出备份云,将域重定向到它并恢复设备监视。

a.php-服务器端脚本的名称。 是的,我知道用一个字母来命名变量和文件名是错误的……我建议我们在发送请求时节省一些字节:)
u-用户名,硬件登录
p-密码
“ -O /tmp/wa.sh”是远程路由器上将保存服务器响应的文件,例如,重新启动命令。

第二注:
啊,为什么我们使用wget而不是curl,因为通过curl您可以发送https请求而不是GET而是POST? 嗯,因为就像在一个古老的笑话中一样,“ NE爬进了小屋!”。 Curl包含大小约为2MB的加密库,因此,您将能够为一个小型TP-LINK ML3020组装一个映像。 和wget,请。

2)在服务器端(我有Ubuntu),我们将使用Zabbix。 原因:我希望它既美观(带有图形)又方便(通过上下文菜单发送命令)。 Zabbix与zabbix代理一样有趣。 通过代理,我们将在服务器上调用php脚本,该脚本将返回有关路由器是否在所需时间段内注册的信息。 为了存储有关注册时间和设备命令的信息,我使用MySQL,它是一个单独的用户表,具有大约以下字段:

  CREATE TABLE `users` ( `id` varchar(25) NOT NULL, `passwd` varchar(25) NOT NULL, `description` varchar(150) NOT NULL, `category` varchar(30) NOT NULL, `status` varchar(10) NOT NULL, `last_time` varchar(20) NOT NULL, //    `last_ip` varchar(20) NOT NULL, // IP   `last_port` int(11) NOT NULL, //    `task` text NOT NULL, //     `reg_task` varchar(150) NOT NULL, // "" ,          `last_task` text NOT NULL, //   `response` text NOT NULL, //     `seq` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

所有资源都可以从Git存储库获取: https : //github.com/BazDen/iotnet.online.git
现在,PHP脚本托管在服务器端(为方便起见,您可以将它们放在/ usr / share / zabbix /文件夹中):

A.php文件:

 <?php //   :  ,       //   message ?    ,         $user=$_REQUEST['u']; $password=$_REQUEST['p']; $message=$_REQUEST['m']; //      (MySQL) $conn=new mysqli("localhost","db_login","db_password","DB_name"); if (mysqli_connect_errno()) { exit(); } $conn->set_charset("utf8"); //         $sql_users=$conn->prepare("SELECT task, reg_task, response, last_time FROM users WHERE id=? AND passwd=? AND status='active';"); $sql_users->bind_param('ss', $user, $password); $sql_users->bind_result($task, $reg_task, $response, $last_time); $sql_users->execute(); $sql_users->store_result(); if (($sql_users->num_rows)==1){ $sql_users->fetch(); //       echo $task; echo "\n"; echo $reg_task; //           $response_history="[".date("Ymd H:i")."] ".$message; //  ,    ,     ,  -   $last_ip=$_SERVER["REMOTE_ADDR"]; $last_port=$_SERVER["REMOTE_PORT"]; $ts_last_conn_time=$last_time; $sql_users=$conn->prepare("UPDATE users SET task='', seq=1 WHERE (id=?);"); $sql_users->bind_param('s', $user); $sql_users->execute(); if (strlen($message)>1){ $sql_users=$conn->prepare("UPDATE users SET response=?, seq=1 WHERE (id=?);"); $sql_users->bind_param('ss', $response_history, $user); $sql_users->execute(); } //      ,      .    $ts_now=time(); $sql_users=$conn->prepare("UPDATE users SET last_time=?, last_ip=?, last_port=? WHERE (id=?);"); $sql_users->bind_param('ssss', $ts_now, $last_ip, $last_port, $user); $sql_users->execute(); } //         ,    "",   ...    reboot.... //    ?     ,      " ". else { echo "reboot"; } $sql_users->close(); ?> 

Agent.php文件(这是调用的zabbix代理的脚本):

 <?php //   Zabbix.      users   "1"        // user  password -    $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"); $sql_users=$conn->prepare("SELECT seq FROM users WHERE id=? AND passwd=? AND status='active';"); $sql_users->bind_param('ss', $user, $password); $sql_users->bind_result($seq); $sql_users->execute(); $sql_users->store_result(); //      seq.        "1" if (($sql_users->num_rows)==1){ $sql_users->fetch(); echo $seq; } //  $seq. $sql_users=$conn->prepare("UPDATE users SET seq=0 WHERE id=? AND passwd=? AND status='active';"); $sql_users->bind_param('ss', $user, $password); $sql_users->execute(); $sql_users->close(); ?> 

好了,最后一个阶段:开一个代理商并添加时间表。

如果尚未安装zabbix代理,则:

 apt-get install zabbix-agent 

编辑文件/etc/zabbix/zabbix_agentd.conf。

添加行:

 UserParameter=test,php /usr/share/zabbix/agent.php user password 

其中:
测试是我们代理商的名字
“ Php /usr/share/zabbix/agent.php用户密码”-带有设备注册数据的被调用脚本。

添加图形:打开zabbix Web界面,从菜单中选择:
设置->主机->创建主机。 指定主机名,它的组,默认代理接口就足够了:



现在我们需要为此主机添加一个数据元素。 请注意两个字段:“键”正是我们在/etc/zabbix/zabbix_agentd.conf文件中指定的参数(在我们的示例中是test),而“更新间隔”-我设置了5分钟,因为设备每五分钟在服务器上注册一次。



好吧,添加时间表。 我建议选择“填充”作为绘图样式。



输出非常简洁,例如:



对于一个合理的问题:“值得吗?”,我将回答:当然,请参见本文开头的“制造自行车的原因”。

如果我的第一笔绘画狂经验会引起读者的兴趣,那么在以下文章中,我将描述如何向远程设备发送命令。 也有可能为基于RouterOS(Mikrotiks)的设备实施整个方案。

Source: https://habr.com/ru/post/zh-CN445568/


All Articles