вторник, 23 августа 2016 г.

Умный скриптовый аналог Netwatch Mikrotik.

  Есть небольшая "домашняя" сеть, в ней несколько клиентов подключено по WiFi методом точка-точка. Расстояния каждого линка небольшие (до 1 км.), эти линки нужно мониторить. Следить мы будет за ответными точками 4 клиентов, если точка отпала - оповещать в чат Telegram операторов. Родной Netwatch нам не подходит, так как не учитывает кратковременные пропадания, которые допустимы (например точку перегрузили). А значит будет куча ложных срабатываний. При написании скрипта нужно учитывать, что он выполняется по регламенту, а значит при пропадании одной из точек сообщения будут отправляться каждый раз при выполнении скрипта (через промежуток времени, который задан в шедуллере). Что-бы этого измежать нам нужно вводить глобальную переменную статуса точек. Однако, глобальные переменные при перезагрузке пропадают, но это тоже учтено в скрипте.


# Указываем имена наших wifi точек, которые находятся у клиентов
:local name1 yuraBPriem;
:local name2 erikPriem;
:local name3 obchagaPriem;
:local name4 viktortanyaPriem;
# указываем IP этих точек, которые будут пинговатся
:local IP1 192.168.23.167;
:local IP2 192.168.23.172;
:local IP3 192.168.23.184;
:local IP4 192.168.23.205;
# вводим глобальные переменные "статусов точек", которые при выключенной точке не позволят нам отправлять кучу сообщений что данная точка недоступна
:global NAME1sts;
:global NAME2sts;
:global NAME3sts;
:global NAME4sts;
# указываем время в переменную
:local time [/system clock get time];
#указываем количество пингов
:local PingCount 3;
# проверяем наличие адрес-листов для сохранения значений наших переменных "статуса точек". Адрес-листы нужны как контейнер, куда мы будем записывать комментарий, который является значением работы точек (on или off). Из этого комментария мы будет излекать значения глобальных переменных "статуса точек", после перезагрузки роутера. Это нужно, что бы сохранить глобальные переменные "статуса точек" после перезагрузки роутера. Если адрес-лист есть, ничего не делаем, если нет - создаем.
:do {:put [ip firewall address-list get value-name=list [find list="netwatch_$name1"]]} on-error={ip firewall address-list add list="netwatch_$name1" address=$IP1};
:do {:put [ip firewall address-list get value-name=list [find list="netwatch_$name2"]]} on-error={ip firewall address-list add list="netwatch_$name2" address=$IP2};
:do {:put [ip firewall address-list get value-name=list [find list="netwatch_$name3"]]} on-error={ip firewall address-list add list="netwatch_$name3" address=$IP3};
:do {:put [ip firewall address-list get value-name=list [find list="netwatch_$name4"]]} on-error={ip firewall address-list add list="netwatch_$name4" address=$IP4};
# проверяем на наличие регламентного задания, которое будет после перезагрузки извлекать из комментария адрес-листа значение и передавать его в глобальную переменную "статуса точек". Если такого задания нет - создаем.
:do {:put [/system scheduler get value-name=name "netwatch_$name1"]} on-error={/system scheduler add name="netwatch_$name1" on-event=":delay 3; :global NAME1sts [ip firewall address-list get value-name=comment [find list=netwatch_$name1]]" start-time=startup};
:do {:put [/system scheduler get value-name=name "netwatch_$name2"]} on-error={/system scheduler add name="netwatch_$name2" on-event=":delay 3; :global NAME2sts [ip firewall address-list get value-name=comment [find list=netwatch_$name2]]" start-time=startup};
:do {:put [/system scheduler get value-name=name "netwatch_$name3"]} on-error={/system scheduler add name="netwatch_$name3" on-event=":delay 3; :global NAME3sts [ip firewall address-list get value-name=comment [find list=netwatch_$name3]]" start-time=startup};
:do {:put [/system scheduler get value-name=name "netwatch_$name4"]} on-error={/system scheduler add name="netwatch_$name4" on-event=":delay 3; :global NAME4sts [ip firewall address-list get value-name=comment [find list=netwatch_$name4]]" start-time=startup};
# пингуем точки. задержка 300 секунд между двумя попытками, для того, что-бы точка,  которая, например, перегружается, успела загрузиться и подцепится по вай-фаю.
:local Ping1 [/ping $IP1 count=$PingCount];
:local Ping2 [/ping $IP2 count=$PingCount];
:local Ping3 [/ping $IP3 count=$PingCount];
:local Ping4 [/ping $IP4 count=$PingCount];
:delay 300;
:local Ping11 [/ping $IP1 count=$PingCount];
:local Ping12 [/ping $IP2 count=$PingCount];
:local Ping13 [/ping $IP3 count=$PingCount];
:local Ping14 [/ping $IP4 count=$PingCount];
# проверяем доступность 1 точки. Тут опишу, дальше описывать аналогию не буду. Если все пинги и в первую попытку и во вторую равны 0, мы делаем вывод что линк не рабочий. Мы проверяем переменную статуса первой точки $NAME1sts, если она не равна "off", то выполняем отправку в Telegram сообщения "$time BAIRAK $name1 off", которое содержит время, название села, имя и статус точки. Так же в лог пишем сообщение. Оповещение происходит только один раз, до того момента, когда статус точки не изменится на "on". Тогда придет сообщение "$time BAIRAK $name1 on". И опять, когда пришло сообщение с статусом "on", оно больше отсылаться не будет, пока точка опять не пропадет. Так же, во время изменения статусов, в комментарий, созданных для технических целей адрес-листов, записывается значение "статуса точки". Это для сохранения их после перезагрузки.
if (($Ping1 = 0) and ($Ping11 = 0)) do={
if ($NAME1sts = "off") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name1 off"; set $NAME1sts off; /ip firewall address-list set comment=$NAME1sts [find list="netwatch_$name1"]; log warning "$time BAIRAK $name1 off"}} else={ if ($NAME1sts = "on") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name1 on"; set $NAME1sts on; /ip firewall address-list set comment=$NAME1sts [find list="netwatch_$name1"]; log warning "$time BAIRAK $name1 on"}}
# проверяем доступность 2 точки. 
if (($Ping2 = 0) and ($Ping12 = 0)) do={
if ($NAME2sts = "off") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name2 off"; set $NAME2sts off; /ip firewall address-list set comment=$NAME2sts [find list="netwatch_$name2"]; log warning "$time BAIRAK $name2 off"}} else={ if ($NAME2sts = "on") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name2 on"; set $NAME2sts on; /ip firewall address-list set comment=$NAME2sts [find list="netwatch_$name2"]; log warning "$time BAIRAK $name2 on"}}
# проверяем доступность 3 точки.
if (($Ping3 = 0) and ($Ping13 = 0)) do={
if ($NAME3sts = "off") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name3 off"; set $NAME3sts off; /ip firewall address-list set comment=$NAME3sts [find list="netwatch_$name3"]; log warning "$time BAIRAK $name3 off"}} else={ if ($NAME3sts = "on") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name3 on"; set $NAME3sts on; /ip firewall address-list set comment=$NAME3sts [find list="netwatch_$name3"]; log warning "$time BAIRAK $name3 on"}}
# проверяем доступность 4 точки.
if (($Ping4 = 0) and ($Ping14 = 0)) do={
if ($NAME4sts = "off") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name4 off"; set $NAME4sts off; /ip firewall address-list set comment=$NAME4sts [find list="netwatch_$name4"]; log warning "$time BAIRAK $name4 off"}} else={ if ($NAME4sts = "on") do={} else={/tool fetch url="https://api.telegram.org/bot123456789:AAyJyyZ_W67Vyst9wSGRWzcXqeFI5E85RVy/sendMessage\?chat_id=-123456789&text=$time BAIRAK $name4 on"; set $NAME4sts on; /ip firewall address-list set comment=$NAME4sts [find list="netwatch_$name4"]; log warning "$time BAIRAK $name4 on"}}

  Это скрипт у меня выполняется раз в 12 минут, так как задержка между попытками пинга - 5 минут. Синтаксис отправки в Telegram можно посмотреть тут, за что авторам данной статьи большое спасибо!
  Сохраню html версию статьи КАК «ПРИКРУТИТЬ» БОТА TELEGRAM К MIKROTIK
 для архива.

Подписаться на новые статьи.

Комментариев нет:

Отправить комментарий