通过API从RouterOS Mikrotik管理Internet中继

MikroTik RODOS-8 / 9/10

用于在MikroTik路由器中管理PDU的便捷工具


MikroTik是网络设备的制造商,以低廉的价格提供了高可靠性,并提供了丰富的功能。 MikroTik产品的软件基础是RouterOS ,这是一个基于Linux的网络操作系统。 它运行在RouterBOARD上, RouterBOARD是一系列硬件解决方案,其中包括纯操作员设备和家用平台。 RouterOS为管理员/用户提供了用于配置和管理路由器的出色选项,使您不仅可以使用系统的内置功能进行操作,还可以通过脚本编程为几乎任何解决方案创建自己的选项。

在本文中,我将讨论如何使用MikroTik路由器的高级功能通过脚本功能直接从路由器通过PDU(Internet中继)发出电源管理命令。 作为PDU,我使用了OLIMP公司的以太网中继RODOS-8 / 9/10(设备在控制方面是绝对相同的),该以太网中继在几个项目之后仍然存在并且“在手”。

用于PDU管理的RouterOS功能


RouterOS的高级功能可以允许:

  • 远程打开/关闭连接到PDU的设备的电源
  • 在网络中发生各种事件时远程控制PDU(例如,如果将特定的VPN客户端,WiFi网络客户端等连接到路由器,则从任何设备发出的对ping的响应都没有响应),具体取决于时间(预定)
  • 通过电子邮件或电话号码(通过SMS)通知管理员或用户PDU上中继状态的变化

因此,可以组织例如服务器设备的控制,打开/关闭/重新启动“挂起”的网络设备,打开冷却或加热,照明,管理作为智能家居一部分额定功率可接受的任何负载,以及可以做的更多工作。你的想象力。

fetch router命令提供了从RouterOS控制Internet中继的功能,其语法在本文结尾的链接中进行了详细说明。

通过“获取”路由器命令管理PDU


RODOS-8 / 9/10 PDU支持以下URL格式:

http:// [登录]:[密码] @ [IP地址] [/保护] / rb [X-1] [操作] .cgi
  • 登录名和密码-在“保护模式”(保护)下访问设备的相关数据
  • IP地址-网络上设备的IP地址
  • /保护-“保护模式”中的访问密钥。 如果设备上安装了“开放式”访问权限,则未指定/保护,也未指定登录名和密码
  • [动作]-对继电器采取的动作:n开启,f关闭,s发出持续1秒的脉冲
  • X是正在访问的中继的编号;可能的值取决于设备的型号:
    1. RODOS-8-未标明,为 该设备只有一个继电器
    2. RODOS-9-X = 1或X = 2
    3. RODOS-10-X = [1-4]

所有指定的参数均不带括号[]传递。

因此,要解决我们在RouterOS中的问题,启用PDU的第一个中继,以下条目就足够了:

/tool fetch url="http://[:]@192.168.1.20/protect/rb0n" 

如果我们希望设备响应,则应使用:

 /tool fetch url="http://[:]@192.168.1.20/protect/rb0n" mode=http dst-path="Rodosanswer.txt"; :local Rodosanswer [/file get Rodosanswer.txt contents]; 

在本例中,PDU响应使用json机制以以下形式返回Rodosanswer变量:

  • “成功! “-在成功执行命令的情况下
  • “故障”-如果命令未执行(通常,在未显示URL的PDU登录名和密码的情况下访问,如果PDU处于“保护”模式)

我们在Mikrotik路由器的存储库中创建Rodos PDU管理功能


因此,让我们开始吧。 让我们使用MikroTik路由器的脚本存储库中名为“ Func_RODOS10rele”的RODOS-10控制示例创建中继控制功能:

代码“ Func_RODOS10rele”
 ################ FuncRODOS10rele ###################### #     PDU RODOS-10 # by Sergej Serkov 23.12.2017 ####################################################### #  ,   :global FuncRODOS10rele do={ :local Sport ""; :if ([:len $Rport]=0) do={:set Sport "80";} else={:set Sport $Rport;} :global FuncPing; :local PingAnswer [$FuncPing PingAdr=$Radr]; :if ($PingAnswer="OK") do={ :local Rprotect; :local Wprotect; :local Rmode "0"; :local Nrele 0; :local Act; :if (([:len $Rlogin]=0) and ([:len $Rpass]=0)) do={:set Rprotect ""; set Wprotect "";} else={:set Rprotect ("$Rlogin".":"."$Rpass"."@"); set Wprotect "/protect";} :if ($Rstatus="on") do={:set Rmode "1"; :set Act "n"} :if ($Rstatus="off") do={:set Rmode "1"; :set Act "f"} :if ($Rstatus="inv") do={:set Rmode "1"; :set Act "s"} else={} :if ($Rmode="1") do={ :set Nrele ([:tonum $Rrele] - 1); :if (($Nrele > -1 and ($Nrele < 4)) do={ :local StrFetchRodos; :set StrFetchRodos ("http://"."$Rprotect"."$Radr".":"."$Sport"."$Wprotect"."/rb"."$Nrele"."$Act".".cgi"); do { [/tool fetch url=$StrFetchRodos mode=http dst-path="Rodosanswer.txt";]; } on-error={: log info ""; :log error ("Call ERROR function <RODOS10rele> ERROR fetch command"); :local Rodosanswer "ERROR: command ROS <fetch>"; : log info ""; :return $Rodosanswer} :log info ""; :log warning ("all "."$Wprotect "."function <RODOS10rele> set rele #"."$Rrele "."is ["."$Rstatus"."]"); :log info ""; :delay 2s; :local Rodosanswer [/file get Rodosanswer.txt contents]; /file remove Rodosanswer.txt; :return $Rodosanswer; } else={ :log info ""; :log error ("all ERROR"."$Wprotect "."function <RODOS10rele> set rele#"."$Rrele"." but NUMBER RELE MISMATCH"); :log info ""; :local Rodosanswer "ERROR: rele range mismath"; :return $Rodosanswer;} } else={ :log info ""; :log error ("all ERROR"."$Wprotect "."function <RODOS10rele> set rele#"."$Rrele"." but RELE REGIME SET MISMATCH"); :log info ""; :local Rodosanswer "ERROR: rele regime set mismatch"; :return $Rodosanswer;} } else={ :log info ""; :log error ("all ERROR"."$Wprotect "."function <RODOS10rele> but DEVICE NOT RESPONDED"); :log info ""; :local Rodosanswer "ERROR: device not responded"; :return $Rodosanswer;} } 

FuncRODOS10rele函数在其工作中还使用了另一个小的功能,用于检查ping的网络地址-FuncPing ,该功能应在主功能运行期间出现在路由器存储库变量的环境中。

代码“ Func_Ping”
 :global FuncPing do={ :local PingCount 3; #  ; :local Result [/ping $PingAdr count=$PingCount]; :delay 2s; :local PingAnswer ""; :local MainIfInetOk false; :set MainIfInetOk ((3*$Result) >= (2 * $PingCount)) :put "MainIfInetOk=$MainIfInetOk" if (!$MainIfInetOk) do={ :set PingAnswer "ERROR" } if ($MainIfInetOk) do={ :set PingAnswer "OK" } :return $PingAnswer;} 

继电器控制功能的应用


必须将以下内容作为参数传递给FuncRODOS10rele函数:

  • Radr-设备IP地址
  • Rport-HTTP端口。 如果配置了http(80)的标准端口,则可以省略此参数
  • Rrele-执行操作的继电器的编号(对于RODOS-10 [1-4]),
    对于RODOS-9 [1-2],对于RODOS-8不发送)
  • Rstatus-正在采取的措施(“关闭”-禁用;“打开”-启用;“ inv”-发出脉冲)
  • Rlogin-登录,Rpass-设备访问密码
    (如果未设置,则使用命令调用时不带“ /保护”)

示例1:当模块中的“保护模式”关闭时,通过标准的http端口调用可访问PDU的功能,打开继电器2:
 [$FuncRODOS10rele Radr="192.168.1.20" Rrele="2" Rstatus="on"] 

示例2:通过已配置的http 8021端口(设置为“保护模式”)调用可访问PDU的功能,关闭2号继电器
 [$FuncRODOS10rele Radr="192.168.1.20" Rport="8021" Rrele="2" Rstatus="off" Rlogin="login" Rpass="password"] 

该函数的响应可以返回到Rodosanswer字符串变量。

Rodosanswer可能包含以下文本:
  •“成功!”-成功调用并执行团队后

  •“故障”-如果错误处理和不执行命令

  •“错误:继电器范围不匹配”-如果指定了无效的继电器号 
	在此版本设备的Rrele函数的参数中

  •“错误:权限体制设置不匹配”-如果未指定或不正确 
     Rstatus函数的指定参数(“ on”,“ off”,“ inv”)

  •“错误:设备未响应”-如果设备未响应 
     ping

  •“错误:命令ROS <fetch>”-如果直接发生错误
    在执行RouterOS提取URL命令时(通常不是
     Rport中指定的端口号,Rlogine参数指定错误
    和/或Rpass)

您可以通过以下任何其他脚本在PDU上调用中继控制功能:

  1. 首先,您需要执行将必要功能放置在路由器存储库变量环境中的脚本。 这可以完成一次,例如,从RouterOS Scheduler( / system scheduler )启动路由器时

     #          /system script run Func_RODOS10rele; #      «FuncPing» # (  FuncRODOS10rele) /system script run Func_Ping; 
  2. 定义函数后,即可使用它们(尤其是调用FuncRODOS10rele)

    例如,我们通过向PDU RODOS-10的4号继电器施加脉冲来调用函数:

     :global FuncRODOS10rele; :local Rodosanswer [$FuncRODOS10rele Radr="192.168.1.20" Rport="8021" Rrele="4" Rstatus="inv" Rlogin="login" Rpass="password"]; :log info $Rodosanswer; 

    响应将返回到Rodosanswer变量,在这种情况下,将显示在路由器日志中。

    现成的功能库,用于处理PDU


    为了易于使用,我为DIN执行的模型8、9、10和10的Rodos PDU创建了一个函数库(日期为2017年12月25日的库版本1.0)。 库脚本被合并到Func_RODOS.rsc文件中,该文件可以通过以下WINBOX实用程序终端命令导入到RouterOS中:

     /import file= Func_RODOS.rsc 

    导入过程可能需要20秒到1分钟,具体取决于Mikrotik路由器的型号(其速度)。
    在这种情况下,路由器中以前可用的所有脚本均不受影响,将Func_RODOS库的功能和脚本添加到现有存储库脚本中。

    Rodos.rsc库版本1.0包含以下脚本:
    • start_RODOS-运行此脚本会将所有功能设置为环境变量
    • Func_Ping-检查“ ping”地址的功能
    • Func_Mail-用于向管理员的邮件发送任意消息的函数
    • Func_RODOS8rele-RODOS-8 PDU中继控制功能
    • Func_RODOS8reset-PDU RODOS-8继电器的重置功能(“重置”)
    • Func_RODOS9rele-...类似,适用于所示型号...
    • Func_RODOS9reset
    • Func_RODOS10rele
    • Func_RODOS10reset
    • call_example [...]-库函数调用的示例
    • Func_RODOS_lib-一个脚本文件中的所有PDU功能(Ping和Mail除外)

    导入库后,您可以从存储库中删除不必要的功能和脚本,仅将PDU模型的功能和脚本保留在FuncMail和FuncPing函数中。

    在该库中,对于每种受支持的PDU型号,还提供了方便的重置(“ reset”)功能(在名称中标记为“〜reset”)。 复位功能的参数与继电器安装功能的参数相似,但“ Rstatus”参数(在“重新引导”期间不使用)和可选的可选参数Rtime(用于定义继电器关闭和再次打开之间的时间,以秒为单位)(默认情况下未使用Rtime)被使用。时间5秒)。

    重新启动功能的工作方式如下:
    1. 向指定的继电器发送关闭命令
    2. 然后,它使用后续包含命令等待Rtime秒。 在这种情况下,复位功能是指相应的继电器安装功能,这些功能必须在首次安装之前确定。

    因此,如果在调用复位功能之前打开了某个继电器,则将其关闭,并在指定的时间后将其重新打开(并且与其相连的负载将被“复位”)。 在关闭的继电器上执行类似的操作,并且在激活功能后,继电器将打开(即,在这种情况下,该功能作为继电器的切换功能得以实现)。 使用重置功能来重新启动连接到Rodos PDU的“挂起”网络设备(接入点,路由器,交换机,各种服务器等)非常方便。

    Rodos.rsc库的源代码(函数和脚本,访问它们的示例)已进行了足够详细的“注释”,这对于希望详细了解该库(或可能自己修改或编写自己的版本)的人员很有用。

    在重新启动功能的调用示例中,完成该功能后,可以将消息发送到路由器管理员的电子邮件地址(在脚本变量设置中,您可以指定您的邮件地址)。 在这种情况下,脚本使用来自/ tool电子邮件的RouterOS邮件服务,您必须事先正确配置其参数。

    未来计划


    将来,将扩展Rodos PDU的脚本库-计划为Internet气象站RODOS-16创建功能,该功能除了继电器,输入/输出线和温度/湿度/大气压传感器外,还具有“内置”功能。 还计划将功能记录不仅记录到路由器的日志和邮件中,而且记录到用户选择的指定电话号码中(通过路由器的调制解调器发送SMS消息)。

    也许,在用户(包括本材料的读者)使用该库的过程中,会发现一些错误,通常,这些错误在任何开发过程中都是不可避免的。 如果有任何错误,意见和建议,请告知我,以便对其进行纠正。

    链接到MikroTik路由器的Fetch命令的描述
    链接到使用过的PDU的文档
    链接到Rodos PDU的脚本功能库

    塞尔科夫·谢尔盖·弗拉基米罗维奇,2017年12月26日

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


All Articles