MikroTik logs are valuable on their own, but they are even more useful when paired with Telegram notifications.
Receiving notifications on Telegram when someone is trying to log in to your MikroTik router can help to detect suspicious login attempts, including potential hacking attempts, allowing you to take appropriate action in a timely manner.
In this article, I will guide you through the process of configuring a separate log file on your MikroTik router that will only contain authentication log entries.
And also I will show how to set up a scheduled script that will be sending a notification about each login attempt to Telegram.
Cool Tip: Setup a guest WiFi network on MikroTik hAP ax³ (WifiWave2)! Read more →
Telegram Notification on MikroTik Login Attempt
1. Separate Log File for Authentication Events
By default, MikroTik keeps only last 1000 log entries stored in the router’s memory (RAM).
Firstly, configure MikroTik to write authentication logs to a dedicated log file on a disk.
For this, create a new logging action named auth that will be recording, for example, the last 5000 log entries to a file auth.log:
[admin@MikroTik] > /system logging action add disk-file-count=1 \ disk-file-name=auth.log \ disk-lines-per-file=5000 \ name=auth \ target=disk
Instruct MikroTik to apply the auth action to any logs assigned to the account topic, so they are saved to auth.log:
[admin@MikroTik] > /system logging add action=auth topics=account
⚠️ Warning! The above configuration will log only successful authentication events, such as login and logout. To log authentication failures, it is required to add the critical topic. However, since the critical topic includes not only authentication-related events, they may also be recorded to auth.log.
To log failed login attempts, apply the auth action to log entries marked as critical (these log entries are printed to console each time you log in):
[admin@MikroTik] > /system logging add action=auth topics=critical
The auth logs can now be printed as follows:
[admin@MikroTik] > /log print where buffer="auth" - sample output - 20:08:15 system,info,account user admin logged in from 192.168.88.251 via web 20:17:20 system,info,account user admin logged out from 192.168.88.251 via web 20:23:57 system,error,critical login failure for user admin from 192.168.88.251 via ssh
2. MikroTik Telegram Script
As Telegram may be used for notifications by different scripts, instead of hardcoding credentials and a connection string in each of them, I propose to create a special function for this, let’s say $tgSendMessage and store it as a :global environment variable from where it can be called by the other scripts.
Cool Tip: How to configure MikroTik to send messages to Telegram! Read more →
Create a script named telegram-config-global and open it in an editor:
[admin@MikroTik] > /system script add name=telegram-config-global [admin@MikroTik] > /system script edit telegram-config-global source
Write a source code of the script:
#!rsc by ShellHacks # RouterOS script: telegram-config-global # Copyright (c) 2011-2024 www.ShellHacks.com <mail@shellhacks.com> # # Telegram Bot API global settings # Documentation: https://www.shellhacks.com/mikrotik-send-message-to-telegram # Source: https://github.com/shellhacks/MikroTik/blob/main/src/telegram-config-global.rsc # # Tested on RouterOS, version=7.12 (stable) # Version: 1.0.0 # BEGIN SETUP :global tgBotToken "0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi" :global tgChatID "012345678" # END SETUP # Send message to Telegram # Usage: $tgSendMessage $tgChatID "" :global tgSendMessage do={ :global tgBotToken :local url ("https://api.telegram.org/bot$tgBotToken" . "/sendMessage\?chat_id=" . $1 . "&text=" . $2 . "&parse_mode=html") /tool fetch keep-result=no url="$url" }
Press Ctrl + O to save the script and close the editor.
The latest version of this script can be found on GitHub.
Now it is required to configure this script to run on MikroTik startup using a scheduler.
This is required to keep these variables persistent, since by default they are not saved after reboot:
[admin@MikroTik] > /system scheduler add name=telegram-config-global \ on-event=telegram-config-global \ start-time=startup [admin@MikroTik] > /system script run telegram-config-global
3. MikroTik Login Attempts Monitoring Script
Create a script named auth-logs-monitoring and open it in an editor:
[admin@MikroTik] > /system script add name=auth-logs-monitoring [admin@MikroTik] > /system script edit auth-logs-monitoring source
Write a source code of the script:
#!rsc by ShellHacks # RouterOS script: auth-logs-monitoring # Copyright (c) 2011-2024 www.ShellHacks.com# # Monitor authentication events and send notifications on login attempts to Telegram # Documentation: https://www.shellhacks.com/mikrotik-telegram-notification-on-login-attempt # Source: https://github.com/shellhacks/MikroTik/blob/main/src/auth-logs-monitoring.rsc # # Requires: # - telegram-config-global # https://github.com/shellhacks/MikroTik/blob/main/src/telegram-config-global.rsc # # Tested on RouterOS, version=7.12 (stable) # Version: 1.0.0 # tgSendMessage is set by tgSetEnvironment script which runs at startup by the scheduler, # contains Telegram BotAPI string for sendMessage method. # BEGIN SETUP # Set by 'telegram-config-global' script which runs on startup using a scheduler # and contains Telegram Bot API settings / connection string :global tgSendMessage :global tgChatID # Log IDs to parse through :local logIDs [/log find where buffer=auth] # END SETUP # Used to track already shown log entries :global lastLogID :local skip :local buffer "" # Check if last ID is not set and trigger the skip flag :if ([:typeof $lastLogID]="nothing") do={ :set buffer ("🤷‍♂️ Last log ID is not found. The router may have rebooted.%0A⏰ Uptime: ".[/system resource get uptime]) :set skip true } else={ :set skip true } # Run through the log buffer and parse entries :foreach logID in=$logIDs do={ :if ($skip = false) do={ :local logTopics [/log get $logID topics] :local logTime [/log get $logID time] :local logMessage [/log get $logID message] ## Critical error events :if ($logTopics="system;error;critical") do={ :set buffer ($buffer.$logTime." ⚠️ ".$logMessage."%0A") } ## Logins to the router :if ($logTopics="system;info;account" && $logMessage~"logged in") do={ :set buffer ($buffer.$logTime." 🔓 ".$logMessage."%0A") } # Logouts from the router :if ($logTopics="system;info;account" && $logMessage~"logged out") do={ :set buffer ($buffer.$logTime." 🔒 ".$logMessage."%0A") } } # Have reached an unshown logMessage, so don't skip then :if ($logID=$lastLogID) do={ :set skip false } } # Remember last log ID :set lastLogID [:pick $logIDs ([:len $logIDs]-1)] # Consider the buffer for sending out only if it isn't empty :if ($buffer!="") do={ :local message "" # Replace URL-unsafe characters with ASCII (UTF-8) :for i from=0 to=([:len $buffer]-1) do={ :local char [:pick $buffer $i] :if ($char="&") do={ :set char "%26" } :if ($char="\$") do={ :set char "%24" } :if ($char="+") do={ :set char "%2B" } :if ($char=",") do={ :set char "%2C" } :if ($char="/") do={ :set char "%2F" } :if ($char=":") do={ :set char "%3A" } :if ($char=";") do={ :set char "%3B" } :if ($char="=") do={ :set char "%3D" } :if ($char="?") do={ :set char "%3F" } :if ($char="@") do={ :set char "%40" } :if ($char="#") do={ :set char "%23" } :if ($char=" ") do={ :set char "%20" } :if ($char="<") do={ :set char "%3C" } :if ($char=">") do={ :set char "%3E" } :if ($char="[") do={ :set char "%5B" } :if ($char="]") do={ :set char "%5D" } :if ($char="{") do={ :set char "%7B" } :if ($char="}") do={ :set char "%7D" } :if ($char="|") do={ :set char "%7C" } :if ($char="\\") do={ :set char "%5C" } :if ($char="^") do={ :set char "%5E" } :if ($char="\"") do={ :set char "%22" } :set message ($message . $char) } # The maximum length of a Telegram message is 4096 characters # Split into several messages if the data to send is > 4096 characters :if (([:len $message]-1) < 4096) do={ $tgSendMessage $tgChatID $message } else={ :for i from=0 to=([:len $message]-1) step=4096 do={ $tgSendMessage $tgChatID [:pick $message $i ($i+4096)] :set i ($i+4096) } } }
Press Ctrl + O to save the script and close the editor.
The latest version of this script can be found on GitHub.
Finally, it is required to configure this script to run each minute:
[admin@MikroTik] > /system scheduler add name=auth-logs-monitoring on-event=auth-logs-monitoring interval=1m
That’s it! Here’s how the Telegram notifications from MikroTik will look like:

Very useful! Thanks for effort!
Please fix your RSS feed so I can add it to NewsBlur.
I got the link from the bottom of the page to work with a couple of retrys.
https://www.shellhacks.com/feed/
I appreciate your posts and look forward to many more.