MikroTik Script: Notification of successful login to device or simple MikroTik log parser

The article will be more interesting for specialists using a small fleet of devices (not using a separate server for a monitoring or logging system), home users, those who are first starting to write device scripts and those who do not have the time / desire to figure it out.





Example email with user login / logout events
Example email with user login / logout events

I was prompted to write my own script by the desire to simplify the monstrous scripts that can be found for this request on the Internet, performing this simple action ( an example of a script from the MikroTik Wiki), as well as to show why MikroTik engineers made a simple parsing method impossible if you are not a resident of London. :)





The article parses an example of a notification about user login and logout from a MikroTik device, but also shows examples:





  1. Organization of time in the device log;





  2. Parsing the device log, searching for events by criteria;





  3. Sending email notifications;





  4. Sending a Telegram message.





Background. Why are MikroTik log parsing scripts "monstrous"?

By monstrosity we mean a large amount of script logic and construction of the form:





: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 message example
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).





PS This is my first article on Habré, you can judge strictly, but fairly. The article will not give anything new to specialists using monitoring systems or separate log servers. But for beginners, home users, administrators with a small fleet of network devices - I hope it will be useful.








All Articles