[Системное администрирование, Сетевые технологии, Сетевое оборудование] MikroTik Скрипт: Уведомление о успешном входе на устройство или простой парсер журнала MikroTik

Автор Сообщение
news_bot ®

Стаж: 6 лет 7 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
09-Дек-2020 15:31

Статья будет больше интересна специалистам использующим небольшой парк устройств (не использующим отдельный сервер, для системы мониторинга или логирования), домашним пользователям, тем кто в первый раз подступается к написанию скриптов устройства и тем у кого нет времени/желания разбираться.
Пример email с событиями вход/выход пользователейНаписать свой скрипт меня сподвигло желание упростить монструозные скрипты, которые можно найти по этому запросу в интернете, выполняющие это несложное действие (пример скрипта с Wiki MikroTik), а так же показать почему инженеры MikroTik сделали невозможным простой способ парсинга, если вы не житель Лондона. :)Статья разбирает пример уведомления о входе и выходе пользователя с устройства MikroTik, но так же покажет примеры:
  • Организация времени в журнале устройства;
  • Парсинг журнала устройства, поиск событий по критериям;
  • Отправка уведомлений на электронную почту;
  • Отправка сообщения Telegram.
Предыстория. Почему скрипты парсинга логов MikroTik "монструозны"?Под монструозностью будем понимать большой объем логики скрипта и конструкции вида:
:set tmpstring ([:pick [:tostr $tmpstring] 0 $findindex] . [:pick [:tostr $tmpstring] ($findindex + [:len [:tostr $ruleop]]) [:len [:tostr $tmpstring]]])
Они показывают умение администратора "оптимизировать" код, но здорово усложняют возможности понимания скриптов другими пользователями.Но самую огромную роль в усложнение логики этого скрипта внесла сама компания MIkroTik, с интересной логикой журнала на устройстве. :)Что может быть проще конструкции: "найди все события по времени старше последнего запуска с темой "account", запущенной простым казахстанцем (UTC+06)?
/log find where time > $LastRunTime topics ~ "account"
Это даже будет работать, ровно до 23:59:59 текущего дня. А после 12 ночи, скрипт превратится в тыкву А вот после 00:00:00 система начнет вываливать все события предыдущего дня. Почему?Инженеры MikroTik большие оригиналы решившие сделать хранение записей журнала следующим образом: система хранит в журнале события сегодняшнего дня только с параметром времени, а чтобы не путаться, когда сменяется день, перезаписывает время событий добавляя дату, во все события "вчерашнего" дня. Для пользователя, в журнале событий все события отображаются дата/время, но сама система, событиям текущего дня присваивает только время. Ну и где здесь оригинальность? А оригинальность в том, что MikroTik считает началом нового дня время 00:00:00 по UTC±0:00. Игнорируя часовой пояс самого устройства, т.е. у меня (UTC+06), до 6 утра, выдавались все уведомления за предыдущий день. В 06:00:00 Микротик перезаписывал всем событиям дату и скрипт снова начинал корректно работать.Так что если вы не житель Лондона (UTC±0:00), для парсинга журнала устройства по времени вам приходилось использовать костыли, решая логикой скрипта проблему организации времени на устройстве.Костыли делать мне не хотелось (в частности однажды это могут исправить), поэтому подумалось над вариантом который был бы проще в работе и проще в понимании другими пользователями.Логика скриптаПомимо параметров время события, текст события, MikroTik использует уникальный параметр id события, который мы будем использовать (.id уникален до перезапуска устройства, потом отчет начинается заново, с 0).
  • Обозначаем глобальную переменную ParseLogAccountEndArrayID - хранит последний проверенный .id сообщения;
  • Собираем в массив IDsEventsAccount все .id сообщений, в теме которых встречается "account" - (события: успешный вход на устройство, завершение сессии пользователя). Стандартное ограничение журнала лога 1000 строк, это не вызовет значимой нагрузки на устройство;
  • Получаем LenArrayIDs - количество элементов массива, StartArrayID - номер элемента с которого начнем перебор (это как раз ID последнего запуска), и EndArrayID - номер последнего элемента массива минус 1(массив начинается с элемента с индексом 0).
  • Если последний элемент .id массива (IDsEventsAccount) не равен последнему проверенному .id (ParseLogAccountEndArrayID) (т.е. появились новые события "account") и последний элемент (ParseLogAccountEndArrayID) - не пустой (первый запуск/в журнале нет событий авторизации) начинаем формировать и отправлять сообщения;
  • Если в журнале присутствуют необработанные события "account", начинаем перебор ключей в массиве (IDsEventsAccount) по их номерам, начиная с "последнего +1" (чтобы не отправлять вновь предыдущее последнее событие) до "последнего -1" (т.к. индекс начинается с 0);
  • Получаем .id сообщения (IDMessage) по его номеру в массиве;
  • Формируем текст email, записывая новой строкой сообщение журнала MikroTik;
  • Формируем текст Telegram сообщения, используя %0D%0A для переноса строки;
  • Записываем в ParseLogAccountEndArrayID последний ID сообщения с темой "account" (EndArrayID).
  • Отправляем сформированное сообщение на email;
  • Отправляем сформированное сообщение в Telegram;
Создать скриптДля запуска скрипта необходимы разрешения: read, write, test, policy.[System] -> [Scripts] -> [+] -> [Name: ParseLogAccountEvents] -> [Policy: read, write, test, policy]Код скрипта
:local DeviceName [/system identity get name];
:local Time [/system clock get time];
:local Date [/system clock get date];
:local EmailMessageText;
:local TelegramMessageText;
:global ParseLogAccountEndArrayID;
:local IDsEventsAccount [/log find where  topics ~ "account"];
:local LenArrayIDs [:len $IDsEventsAccount];
:local StartArrayID [:find $IDsEventsAccount $ParseLogAccountEndArrayID];
:local EndArrayID ($IDsEventsAccount -> ($LenArrayIDs-1));
:if ($EndArrayID != $ParseLogAccountEndArrayID and [:tobool $ParseLogAccountEndArrayID] ) do={
    :local StartArray [:find $IDsEventsAccount $ParseLogAccountLastRunID];
    :for KeyArray from=($StartArrayID+1) to=($LenArrayIDs-1) do={
        :local IDMessage ($IDsEventsAccount ->$KeyArray );
        :set EmailMessageText "$EmailMessageText \n\r  $[/log get number=$IDMessage time] - $[/log get number=$IDMessage message];";
        :set TelegramMessageText "$TelegramMessageText %0D%0A  $[/log get number=$IDMessage time] - $[/log get number=$IDMessage message];";
        }
    :set ParseLogAccountEndArrayID $EndArrayID;
    # START SEND EMAIL
    :local SendFrom "ToMail@mail.ru";
    :local PasswordMail "yourpassword";
    :local SmtpServer [:resolve "smtp.mail.ru"];
    :local UserName "FromMail@mail.ru";
    :local SmtpPort 465;
    :local UseTLS "tls-only";
    :local SendTo "ToMail@mail.ru";
    :local Subject "\F0\9F\94\93 AUTH: $DeviceName [$Date $Time]";
    :local MessageText $EmailMessageText;
    /tool e-mail send to=$SendTo server=$SmtpServer port=$SmtpPort start-tls=$UseTLS user=$SendFrom password=$PasswordMail  from=$SendFrom subject=$Subject body=$MessageText;
    # END SEND EMAIL
    # START SEND TELEGRAM MESSAGE
    :local BotToken "YourBotID";
    :local ChatID "YourChatID";
    :local ParseMode "html";
    :local DisableWebPagePreview True;
    :local SendText "\F0\9F\94\93 <b>$DeviceName: AUTH</b> $TelegramMessageText";
    :local tgUrl "https://api.telegram.org/bot$BotToken/sendMessage?chat_id=$ChatID&text=$SendText&parse_mode=$ParseMode&disable_web_page_preview=$DisableWebPagePreview";
    /tool fetch http-method=get url=$tgUrl keep-result=no;
    # END SEND TELEGRAM MESSAGE
}
Добавление скрипта в ПланировщикДля запуска скрипта необходимы разрешения: read, write, test, policy.[System] -> [Schedule] -> [+] -> [Name: ParseLogAccountEvents] —> [Interval: 00:05:00] -> [Policy: read, write, policy, test]Или выполните в терминале:
/system scheduler add name=ParseLogAccountEvents policy=read,write,policy,test on-event="/system script run ParseLogAccountEvents" interval=5m
ЗаключениеНадеюсь приведенный скрипт будет вам полезен, вы поймете как легко и просто парсить журнал устройства MikroTik выставляя триггеры по теме сообщения, или тексту сообщения.
Пример Telegram сообщенияВозможные темы сообщений в журнале устройства, можно увидеть попытавшись создать правило Logging:[System] -> [Logging] -> [Rules] -> [+] -> [Topics]Для парсинга текста сообщений используйте регулярные выражения и команду вида:[/log find where message ~ "log"]Установив более частое время проверки скрипта, вы можете выполнить дополнительные действия при входе/выходе пользователя, например автоматическое создание резервной копии (для тех кто любит править Firewall в пятницу вечером, забывая устанавливать MikroTik Safe Mode) или что еще подскажет воображение.Мой скрипт выглядит проще, чем что я находил в интернете и доступен к оптимизации, если вы любите оптимизировать код в минимальное количество строк.Если вы используете множество скриптов на вашем устройстве, указывать параметры почты и Telegram бота, в каждом из скриптов нерационально, особенно если возникнет необходимость изменить параметры. Я использую в своих скриптах вызов скриптов функций: "Отправить Email" и "Отправить сообщение Telegram", возможно и Вам это тоже будет полезно, упрощая управление устройством MikroTik.Если Вам стали интересны и другие мои скрипты для MikroTik, их можно увидеть - здесь.Работа скрипта проверена на: hAP ac lite, RouterOS 6.47.8 (stable).P.S. Это моя первая статья на Хабре, можно судить строго, но справедливо. Статья не даст ничего нового специалистам использующим системы мониторинга или отдельные лог серверы. Но для новичков, домашних пользователей, администраторов с небольшим парком сетевых устройств - надеюсь будет полезна.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_sistemnoe_administrirovanie (Системное администрирование), #_setevye_tehnologii (Сетевые технологии), #_setevoe_oborudovanie (Сетевое оборудование), #_mikrotik, #_mikrotik_script, #_mikrotik_telegram, #_mikrotik_email, #_sistemnoe_administrirovanie (
Системное администрирование
)
, #_setevye_tehnologii (
Сетевые технологии
)
, #_setevoe_oborudovanie (
Сетевое оборудование
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 05-Окт 22:44
Часовой пояс: UTC + 5