воскресенье, 24 июля 2016 г.

Оповещение администратора о входе в Mikrotik.

  Скрипт, который создан для обеспечения безопасности вашего устройства. Он анализирует логи Mikrotik, при наличии НОВЫХ записей входа (удачного или неудачного) на устройство - отсылает e-mail администратору. Сам скрипт можно настроить таким образом, что-бы он исключал "легитимные" входы с наших IP, а отсылал сообщения только тогда, когда входы совершаются с чужих адресов. Скрипт проверят наличие всех записей с последнего старта, и потом все найденые совпадения шлет на е-мейл. Проверен на 6.37rc5.
Переведу ключевые моменты.
  # BEGIN SETUP
# имя скрипта в scheduler
:local scheduleName "on_login"
# мыло на которое отправлять отчет
:local emailAddress "test@gmail.com"
# записи в логе по маске, которые попадают в отчет
:local startBuf [:toarray [/log find message~"logged in" || message~"login failure"]]
# слова-исключения. Сюда добавляем наши "легитимные" IP, или, например, сервисы по которым не хотим отслеживать подключения.
:local removeThese {"telnet";"192.168.88.27"}
# smtp сервер
:local smtpserv [:resolve "smtp.yandex.ru"];
# мыло с которого будет все отправляться
:local email "mikrotik@yandex.ru";
# пароль к мылу
:local pass SuperPass;
# END SETUP
# проверяем существует ли запись в планировщике, если нет - выдаем ошибку в лог
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
  /log warning "[LOGMON] ERROR: Schedule does not exist. Create schedule and edit script to match name"
}
# определяем последнее время запуска скрипта
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message

# вводим переменную output
:local output
:local keepOutput false
# if lastTime is empty, set keepOutput to true
:if ([:len $lastTime] = 0) do={
  :set keepOutput true
}

:local counter 0
# loop through all log entries that have been found
:foreach i in=$startBuf do={

# loop through all removeThese array items
  :local keepLog true
  :foreach j in=$removeThese do={
#   if this log entry contains any of them, it will be ignored
    :if ([/log get $i message] ~ "$j") do={
      :set keepLog false
    }
  }
  :if ($keepLog = true) do={
 
   :set message [/log get $i message]
#   LOG DATE
#   depending on log date/time, the format may be different. 3 known formats
#   format of jan/01/2002 00:00:00 which shows up at unknown date/time. Using as default
    :set currentTime [ /log get $i time ]
#   format of 00:00:00 which shows up on current day's logs
   :if ([:len $currentTime] = 8 ) do={
     :set currentTime ([:pick [/system clock get date] 0 11]." ".$currentTime)
    } else={
#     format of jan/01 00:00:00 which shows up on previous day's logs
     :if ([:len $currentTime] = 15 ) do={
        :set currentTime ([:pick $currentTime 0 6]."/".[:pick [/system clock get date] 7 11]." ".[:pick $currentTime 7 15])
      }
   }
   
#   if keepOutput is true, add this log entry to output
   :if ($keepOutput = true) do={
     :set output ($output.$currentTime." ".$message."\r\n")
   }
#   if currentTime = lastTime, set keepOutput so any further logs found will be added to output
#   reset output in the case we have multiple identical date/time entries in a row as the last matching logs
#   otherwise, it would stop at the first found matching log, thus all following logs would be output
    :if ($currentTime = $lastTime) do={
     :set keepOutput true
     :set output ""
   }
  }
#   if this is last log entry
  :if ($counter = ([:len $startBuf]-1)) do={
#   If keepOutput is still false after loop, this means lastTime has a value, but a matching currentTime was never found.
#   This can happen if 1) The router was rebooted and matching logs stored in memory were wiped, or 2) An item is added
#   to the removeThese array that then ignores the last log that determined the lastTime variable.
#   This resets the comment to nothing. The next run will be like the first time, and you will get all matching logs
   :if ($keepOutput = false) do={
#     if previous log was found, this will be our new lastTime entry    
     :if ([:len $message] > 0) do={
        :set output ($output.$currentTime." ".$message."\r\n")
      }
    }
  }
  :set counter ($counter + 1)
}
# If we have output, save new date/time, and send email
if ([:len $output] > 0) do={
  /system scheduler set [find name="$scheduleName"] comment=$currentTime
  /tool e-mail send server=$smtpserv port=587 user=$email password=$pass start-tls=yes to="$emailAddress" from=$email subject="MikroTik alert $currentTime" body="$output"
  /log info "[LOGMON] New logs found, send email"
}
  Сообщения приходят такого вида:

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

11 комментариев:

  1. как убрать из письма сообщения подключения к впн,часть лога с микрота
    07:20:29 - first L2TP UDP packet received from 193.56.114.202
    07:20:31 - Tsun logged in, 192.168.116.60
    07:20:31 - Tsun: authenticated
    07:20:31 - Tsunami: connected

    ОтветитьУдалить
  2. А у меня не работают исключения, например:
    :local removeThese {"telnet";"192.168.0.254"}
    :local removeThese {"winbox";"192.168.0.254"}
    :local removeThese {"192.168.0.254"}
    :local removeThese {"192.168.0.0/24"}
    Все равно получаю сообщения о входе с 192.168.0.254

    И как исключить подключения по l2tp:
    12:52:32 l2tp,info first L2TP UDP packet received from 213.87.145.19
    12:52:33 l2tp,ppp,info,account vpn logged in, 192.168.89.3
    12:52:33 l2tp,ppp,info : authenticated
    12:52:33 l2tp,ppp,info : connected

    ОтветитьУдалить
    Ответы
    1. странно, у меня исключения работали. корректно отрабатывали слова исключения, которые находятся с любом месте строчки лога.

      Удалить
    2. Может опять-таки проблема из-за версий ROS?
      На 6.36 (Current) есть возможность проверить?

      Удалить
  3. У меня проблема такая:
    system,e-mail,error Error sending e-mail : AUTH failed

    ОтветитьУдалить
    Ответы
    1. Почтовый клиент настроен не верно/не нестроен

      Удалить
  4. Как сделать так, что бы еще писало имя микротика
    :local sysname [/system identity get name];

    ОтветитьУдалить
  5. То же самое написал в 4 строчки с уведомлением в telegram:

    :local token "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    :local chatid "XXXXXXXXX";
    :local lstime ([/system scheduler get value-name=next-run [find name="schedule-notify"]] - [/system scheduler get value-name=interval [find name="schedule-notify"]] * 2);
    :foreach i in=[/log find message~"login failure for user" && time>=$lstime] do={/tool fetch url="https://api.telegram.org/bot$(token)/sendMessage\?chat_id=$(chatid)&text=$[/system identity get name]%0A$[/log get $i message]" keep-result=no};

    Немного подредактировав можно добавить исключения

    ОтветитьУдалить
    Ответы
    1. Это его прям в шелудер можно прописать с именем "schedule-notify"?
      И как часто его запускать? Поясните пожалуйста.

      Удалить
  6. Не работает если заходить после 22:00 и до утра (еще не заметил в какое время)
    Подправьте пожалуйста

    ОтветитьУдалить