Community discussions

MikroTik App
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Is it possible to run a script on login?

Wed Mar 28, 2012 12:34 am

Is there a way to monitor logins to the router and run a script, or send an email?
 
User avatar
Ibersystems
Forum Guru
Forum Guru
Posts: 1686
Joined: Wed Apr 12, 2006 12:29 am
Location: Cabrils, Barcelona - Spain
Contact:

Re: Is it possible to run a script on login?

Fri Mar 30, 2012 10:05 am

hi,


yes, system scripts (create the script)
system scheduler (create the scheduler of the script.) Here you can configure a exact time to run the script. If you click in the time, you can select "startup".
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Sat Mar 31, 2012 7:28 am

I see that there is a way to run a script on router startup, but I am trying to run a script when someone logs into the router.

When I view the logs, I see when someone logs in:
user admin logged in from 192.168.0.1 via web
Can a script be written that allows you to search the logs over the last X minutes to see if anyone has logged in?
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Fri Apr 27, 2012 2:57 am

I got it figured out... This script pointed me in the right direction: http://wiki.mikrotik.com/wiki/Manual:Sc ... _log_entry

The following script I use in conjunction with the scheduler:
# Script to check for specific new logs and send email alerts
# Tested on RouterOS v5.7+

# container to keep track of the last time stamp detected
:global lastTime;

# find log entries where the message contains "logged in" or "login failure"
:local currentBuf [ :toarray [ /log find message~"logged in" || message~"login failure" ] ] ;
# get number of log entries
:local currentLineCount [ :len $currentBuf ] ;

# if any logs were found, proceed
if ($currentLineCount > 0) do={
# based on number of entries, get time of last entry
	:local currentTime "$[ /log get [ :pick $currentBuf ($currentLineCount -1) ] time ]";

# check currentTime length, if length is 15, log is from a previous day and begins with month/day
	:if ([:len $currentTime] = 15 ) do={
# trim currentTime so we are left only with time xx:xx:xx
		:set currentTime [ :pick $currentTime 7 15 ];
	}
	
# the output for the body of the email, includes time stamp and log message
	:local output "$currentTime $[/log get [ :pick $currentBuf ($currentLineCount-1) ] message ]";
	
# email function
	:local sndEmail [:parse "/tool e-mail send to=email@domain.com subject=\"MikroTik alert $currentTime\" body=\"$output\" tls=yes"];

# beep function
	:local doBeep [:parse ":beep;:delay 150ms;:beep;"];


# if the last time stamp has not been set, length will be 0 (after reboot, etc)
	:if ([:len $lastTime] < 1 ) do={ 
# update lastTime to match currentTime
		:set lastTime $currentTime ; 
# send email and beep
		$sndEmail;
		$doBeep;
# if lastTime has been set, continue
	} else={
# if lastTime does not match time stamp of the latest
		:if ( $lastTime != $currentTime ) do={ 
# update lastTime to match currentTime
			:set lastTime $currentTime ; 
# send email and beep
			$sndEmail;
			$doBeep;
		} 
	}
}
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Mon Oct 07, 2013 11:06 pm

v3 - Updated with a few changes:
  • Added a removeThese array to filter out any unwanted log entries from those found. Double quote additional strings and separate them with commas. If you don't want any logs filtered, simply declare the variable :local removeThese, or leave double quotes :local removeThese ("")
  • Optimized the last :if statement block to avoid redundant code
  • Removed the [:parse] functions as they didn't seem to be working on v6.2
  • Time stamp is now saved in the schedule's comment field instead of a global variable, necessary for when logs are saved on disk to avoid duplicate alert after a reboot

ros code

:local scheduleName "mySchedule"
:local emailAddress "myEmail"
:local startBuf [:toarray [/log find message~"logged in" || message~"login failure"]]
:local removeThese ("telnet","whatever string you want")

:local lastTime [/system scheduler get [find name="$scheduleName"] comment]

:local currentBuf ""; :set currentBuf [:toarray $currentBuf]

:foreach i in=$startBuf do={
  :local toggle 1
  :foreach j in=[:toarray $removeThese] do={
    :if ([:typeof [:find [/log get $i message] "$j"]] = "num") do={
      :set toggle 0
    }
  }
  :if ($toggle = 1) do={
    :set currentBuf ($currentBuf , $i)
  }
}

:local currentLineCount [ :len $currentBuf ]
 
if ($currentLineCount > 0) do={
   :local currentTime "$[ /log get [ :pick $currentBuf ($currentLineCount -1) ] time ]"
 
   :if ([:len $currentTime] = 15 ) do={
      :set currentTime [ :pick $currentTime 7 15 ]
   }
    
   :local output "$currentTime $[/log get [ :pick $currentBuf ($currentLineCount-1) ] message ]"
    
   :if (([:len $lastTime] < 1) || (([:len $lastTime] > 0) && ($lastTime != $currentTime))) do={
      /system scheduler set [find name="$scheduleName"] comment=$currentTime
      /tool e-mail send to="$emailAddress" subject="MikroTik alert $currentTime" body="$output"
   }
}
 
hngjared
Frequent Visitor
Frequent Visitor
Posts: 77
Joined: Thu Dec 01, 2011 8:36 pm
Location: NYC USA

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 4:59 pm

Skot, script is very nice and very beneficial! Welll done!

Quick question. Script runs flawlessly on 6.2 as you stated. Any way if you have a free moment you could take a look see and try on 6.13. I can't get the script to complete outside of 6.2.

It would be much appreciated!

Cheers
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 6:42 pm

:local scheduleName value="mySchedule";
:local emailAddress value="myEmail";
:local startBuf value=[:toarray [/log find where message~"logged in" or message~"login failure"] ];
:local removeThese value=[:toarray ("telnet","whatever string you want")];

:local lastTime value=("".[/system scheduler get [find name=$scheduleName] value-name=comment]);

:local currentBuf value=[:toarray ""];

:foreach i in=$startBuf do={
 :foreach j in=$removeThese do={
  :if ([/log get $i value-name=message] ~ $j) do={ } else={
   :set $currentBuf ($currentBuf,$i);
  };
 };
};

:local currentLineCount value=[:len $currentBuf];
 
if ($currentLineCount > 0) do={

 :local currentTime value=[/log get [:pick $currentBuf ($currentLineCount - 1)] value-name=time];

 :if ([:len $currentTime] = 15) do={
  :set $currentTime value=[:pick $currentTime 7 15];
 };

 :local output value=($currentTime." ".[/log get [:pick $currentBuf ($currentLineCount - 1)] value-name=message]);
    
 :if ( ([:len $lastTime] < 1) or ( ([:len $lastTime] > 0) and ($lastTime != $currentTime) ) ) do={
  /system scheduler set [find where name=$scheduleName] comment=$currentTime;
  /tool e-mail send to=$emailAddress subject=("MikroTik alert ".$currentTime) body=$output;
 }

}
 
hngjared
Frequent Visitor
Frequent Visitor
Posts: 77
Joined: Thu Dec 01, 2011 8:36 pm
Location: NYC USA

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 7:27 pm

Rex,

You're the man.

You keep solving my problems I'm going to have to put you on the payroll.

I really appreciate it.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 7:34 pm

Very thanks!

But remeber I fix only the script with standard syntax, the idea is not mine!

Except for this:

From

ros code

:local toggle 1
  :foreach j in=[:toarray $removeThese] do={
    :if ([:typeof [:find [/log get $i message] "$j"]] = "num") do={
      :set toggle 0
    }
  }
  :if ($toggle = 1) do={
    :set currentBuf ($currentBuf , $i)
  }
To
:foreach j in=$removeThese do={
  :if ([/log get $i value-name=message] ~ $j) do={ } else={
   :set $currentBuf ($currentBuf,$i);
  };
 };
 
hngjared
Frequent Visitor
Frequent Visitor
Posts: 77
Joined: Thu Dec 01, 2011 8:36 pm
Location: NYC USA

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 7:48 pm

Very true!

Rex, 1 last thing when/if you have a moment.

The script runs good but the $currentTime resolves to Jan, 1 1970 after the script is run.

Any ideas? The time on my Routerboard shows to be current and correct.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 8:14 pm

I see new version of router os omit date on time if date is the same as actual:

/log> pri
jan/01/2002 02:00:09 system,info router rebooted
jan/01/2002 02:00:20 interface,info ether1 link up (speed 100M, full duplex)
jan/01/2002 02:00:24 dhcp,info dhcp-client on ether1 got IP address 192.168.1.101
19:11:42 system,info,account user admin logged in from 192.168.0.102 via winbox
19:12:34 system,info,account user admin logged in from 192.168.0.102 via telnet


The script must be fixed for this....

I fix the syntax but is like I need to fix how date and time are used...




Also are omitted the year: i try to set time to 21 jul and I obtain this:

/log> pri detail
time=jan/01/2002 02:00:09 topics=system,info message="router rebooted"
time=jan/01/2002 02:00:20 topics=interface,info message="ether1 link up (speed 100M, full duplex)"
time=jan/01/2002 02:00:24 topics=dhcp,info message="dhcp-client on ether1 got IP address 192.168.1.101"
time=jul/11 19:11:42 topics=system,info,account message="user admin logged in from 192.168.0.102 via winbox"
time=jul/11 19:12:34 topics=system,info,account message="user admin logged in from 192.168.0.102 via telnet"
time=19:16:05 topics=system,info message="system time zone settings changed by admin"
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 8:18 pm

I think at this point, the script must be rewrited from scratch....
 
hngjared
Frequent Visitor
Frequent Visitor
Posts: 77
Joined: Thu Dec 01, 2011 8:36 pm
Location: NYC USA

Re: Is it possible to run a script on login?

Fri Jul 11, 2014 8:22 pm

Thanks,

I wrote a quick script to remove the comment from the schedule so the script will still run and I removed the time from the subject of the email.

It will function for the mean time.

Maybe we can get Skot to update the script as it's very beneficial.

I appreciate your time today.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Is it possible to run a script on login?

Sat Jul 12, 2014 1:40 am

I have used search function for you, read this old topic, where I post some script for do what you want.
Rememer to read all!!!

http://forum.mikrotik.com/viewtopic.php ... ilit=login
 
hngjared
Frequent Visitor
Frequent Visitor
Posts: 77
Joined: Thu Dec 01, 2011 8:36 pm
Location: NYC USA

Re: Is it possible to run a script on login?

Sat Jul 12, 2014 1:51 am

Thanks Rex!

I changed up your suggestions from earlier and have the script functioning as I need considering the time is irrelevant to me.

I'll definitely take a look at your link though.

I owe you a drink next time I'm in Italy!
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Is it possible to run a script on login?

Sat Jul 12, 2014 10:00 am

Thanks Rex!

I changed up your suggestions from earlier and have the script functioning as I need considering the time is irrelevant to me.

I'll definitely take a look at your link though.

I owe you a drink next time I'm in Italy!
I count on it ;))
 
rzirzi
Member
Member
Posts: 393
Joined: Mon Oct 09, 2006 2:33 pm

Re: Is it possible to run a script on login?

Sun Dec 14, 2014 8:31 pm

Great script! But why only the last log message is send by e-mail? How to set that script to send all monitored messages from last change?
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Tue Dec 16, 2014 9:18 pm

Quick question. Script runs flawlessly on 6.2 as you stated. Any way if you have a free moment you could take a look see and try on 6.13. I can't get the script to complete outside of 6.2.
I don't know why it didn't work on 6.13. Just now ran it on 6.20 without any problems. Glad rextended's edit got it working for you.

:foreach j in=$removeThese do={
  :if ([/log get $i value-name=message] ~ $j) do={ } else={
   :set $currentBuf ($currentBuf,$i);
  };
 };
This code causes problems when there are multiple removeThese array items. For example, say there are 5 array items, and 1 of them is a match. This code does not add the matching one. But for all of the other ones, it adds this same log entry to the currentBuf array 4 times. My original code prevents this by looping through all items, and if a match is found once, the log entry is ignored. If no matching entries are found, only then is the log entry added.

/log> pri detail
time=jan/01/2002 02:00:09 topics=system,info message="router rebooted"
time=jan/01/2002 02:00:20 topics=interface,info message="ether1 link up (speed 100M, full duplex)"
time=jan/01/2002 02:00:24 topics=dhcp,info message="dhcp-client on ether1 got IP address 192.168.1.101"
time=jul/11 19:11:42 topics=system,info,account message="user admin logged in from 192.168.0.102 via winbox"
time=jul/11 19:12:34 topics=system,info,account message="user admin logged in from 192.168.0.102 via telnet"
time=19:16:05 topics=system,info message="system time zone settings changed by admin"
I was aware of the time format having 2 different formats (00:00:00 and jul/11 00:00:00), and the v3 script checks for these. But I did not know about the other one. I wonder what that's about? I will update the script to check for this.
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Tue Dec 16, 2014 9:42 pm

Great script! But why only the last log message is send by e-mail? How to set that script to send all monitored messages from last change?
This is a good idea. Aside from the benefit of not missing any "inbetween" logs, it also provides more flexibility. If you only want the script to check for new logins, say every 5 minutes, this would return them all.

I will work on a new version to incorporate this.
 
rzirzi
Member
Member
Posts: 393
Joined: Mon Oct 09, 2006 2:33 pm

Re: Is it possible to run a script on login?

Wed Dec 17, 2014 5:41 pm

I will work on a new version to incorporate this.
Are You planning to public taht new script at this topic/forum? It would be great:)
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Thu Dec 18, 2014 2:58 am

v4 - tested on v5.26 and v6.20
  • Script now catches all matching logs since the last detection.
  • Date/time checking updated to look for 3 possible formats.
  • Added comments for easier readability
  • Changed time stamp to now be date/time stamp
NOTE: On the removeThese array, if you don't want any logs filtered, simply declare the variable :local removeThese without any curly braces.
# BEGIN SETUP
:local scheduleName "mySchedule"
:local emailAddress "user@email.com"
:local startBuf [:toarray [/log find message~"logged in" || message~"login failure"]]
:local removeThese {"telnet";"whatever string you want"}
# END SETUP

# warn if schedule does not exist
: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"
}

# get last time
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message
  
# final 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 to="$emailAddress" subject="MikroTik alert $currentTime" body="$output"
  /log info "[LOGMON] New logs found, send email"
}
 
User avatar
spippan
Member
Member
Posts: 334
Joined: Wed Nov 12, 2014 1:00 pm
Location: Austria

Re: Is it possible to run a script on login?

Wed Mar 11, 2015 11:04 am

cheers

first of all ... AWESOME work here! :-D
i'm a rOS Script newbie and wrote only fundamental scripts yet but i'm eager to learn more and more about this great feature

my setup so far, necessary for this:
- firewall rules (all working well so far)
- ACL "whitelist" with local and VPN networks


so my question is:
can i/we use this script (or edit it) to do following steps:
1 check ("realize") when a user logs on to the ROUTER (not hotspot! no hotspot use is intended at all)
2 on succesful login get the IP and name of the active user (as in "/user active get 0 address")
3 add its IP address to the whitelist for a timeout of, let's say 2h (or whatever disired)

i know how to achieve 2 and 3 but i'm completely stuck on point 1 :-(

there are only 2 users which are allowed/able to log in:
[spippan@RB2011_sp-private] /user> print 
Flags: X - disabled 
 #   NAME                                                    GROUP                                                   ADDRESS            LAST-LOGG
 0 X ;;; system default user
     admin_old                                               full                                                                       nov/26/20
 1   spippan                                                 full                                                                       mar/11/20
 2   spippan_ssh                                             full                                                                       mar/11/20
[spippan@RB2011_sp-private] /user>
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Tue May 05, 2015 7:26 pm

1 check ("realize") when a user logs on to the ROUTER (not hotspot! no hotspot use is intended at all)
So, you are using the hotspot, but you don't want any hotspot logins found by the script, only logins directly to the router, right? Generally you would compare the normal login logs with the hotspot login logs to determine what string you can put into the removeThese array to filter out the hotspot logs, but in this case it would be better to filter by the topic rather than the log... but this is not built into the script. It could be easily incorporated, something like this:

Add this near the top:
:local removeTopic {"hotspot"}
Add this after the :local keepLog true line:
:foreach j in=$removeTopic do={
# if this log topic is in the removeTopic array, it will be ignored
  :if ([/log get $i topic] ~ "$j") do={
    :set keepLog false
  }
}
HTH
 
User avatar
spippan
Member
Member
Posts: 334
Joined: Wed Nov 12, 2014 1:00 pm
Location: Austria

Re: Is it possible to run a script on login?

Wed May 06, 2015 10:01 am

1 check ("realize") when a user logs on to the ROUTER (not hotspot! no hotspot use is intended at all)
So, you are using the hotspot, but you don't want any hotspot logins found by the script, only logins directly to the router, right? Generally you would compare the normal login logs with the hotspot login logs to determine what string you can put into the removeThese array to filter out the hotspot logs, but in this case it would be better to filter by the topic rather than the log... but this is not built into the script. It could be easily incorporated, something like this:


HTH
hi and thanks for the reply!

no i'm not using any hotspot-features or hotspot related functions.

i want to check normal logins (ssh, winbox) to the router.
those which appear under
/user print
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Sat May 09, 2015 12:34 am

so my question is:
can i/we use this script (or edit it) to do following steps:
1 check ("realize") when a user logs on to the ROUTER (not hotspot! no hotspot use is intended at all)
2 on succesful login get the IP and name of the active user (as in "/user active get 0 address")
3 add its IP address to the whitelist for a timeout of, let's say 2h (or whatever disired)

i know how to achieve 2 and 3 but i'm completely stuck on point 1 :-(
The script was designed to do #1, and since you're not using the hotspot, that won't matter. If you know how to do 2 and 3, then they would need to be adapted into the script.
 
User avatar
spippan
Member
Member
Posts: 334
Joined: Wed Nov 12, 2014 1:00 pm
Location: Austria

Re: Is it possible to run a script on login?

Mon May 11, 2015 12:05 pm

so my question is:
can i/we use this script (or edit it) to do following steps:
1 check ("realize") when a user logs on to the ROUTER (not hotspot! no hotspot use is intended at all)
2 on succesful login get the IP and name of the active user (as in "/user active get 0 address")
3 add its IP address to the whitelist for a timeout of, let's say 2h (or whatever disired)

i know how to achieve 2 and 3 but i'm completely stuck on point 1 :-(
The script was designed to do #1, and since you're not using the hotspot, that won't matter. If you know how to do 2 and 3, then they would need to be adapted into the script.

AWESOME work dude!! i just pasted this (v4) over to my RB2011 and went through every line to figure out what you are doing here .... AWE-f***ing-SOME ;-)

thanks a lot for this piece of code-cake
 
User avatar
skot
Long time Member
Long time Member
Topic Author
Posts: 584
Joined: Wed Nov 30, 2011 3:05 am

Re: Is it possible to run a script on login?

Wed May 13, 2015 2:47 am

You're welcome, glad you found it useful. :)
 
itmethod
newbie
Posts: 34
Joined: Tue Feb 18, 2014 8:44 pm

Re: Is it possible to run a script on login?

Thu Mar 17, 2016 7:24 am

This Script fails to run on a RB751U-2HnD at all.


The Script fails at the end. when $output is referenced by the email command.
I have Verified this because I remove $output from that one 1 line and only that line and the script works.

So I tried creating a file and putting the contents of $output in it and it fails

This All works just fine on a 951Ui-2HnD including the file and sending the file as an attachement.

Both routers are running 6.34.3

I think this is a Memory issue. Considering the RB751U-2HnD only has 32.0 MiB total Ram.
 
User avatar
k6ccc
Forum Guru
Forum Guru
Posts: 1497
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Is it possible to run a script on login?

Fri Jul 15, 2016 11:30 pm

I found this thread from the Wiki page about this script.  First of all, Thanks for this script!  I'm pretty new with RouterOS and extremely new to scripts for it.  I'm using it on a RB750r2 with 6.35.4 of ROS.  I've got at least part of it figured out what you did (I often learn by seeing what other people did).  However I have one issue I have not figured out.  As I understand the script, it should check for new matching log entries since the last time the script ran.  In other words, if the script ran at 10:00:00 and then again at 10:10:00 with no matching activity in the log, it should not find any new activity and therefore not send the E-mail.  I'm finding that it always searches the entire log and sends every matching log entry for the entire log.  Am I missing something?

Jim
 
User avatar
k6ccc
Forum Guru
Forum Guru
Posts: 1497
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Is it possible to run a script on login?

Fri Jul 15, 2016 11:38 pm

One other thing I noticed is that the subject of the E-Mail is always :  MikroTik alert jul/15/2016 06:52:27
Looking at the code, the time should be from $currentTime, so it would appear that $currentTime is not updating.  Related?

Jim
 
User avatar
k6ccc
Forum Guru
Forum Guru
Posts: 1497
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Is it possible to run a script on login?

Sat Jul 16, 2016 12:17 am

Naturally, right after I post the above messages, I figured it out!  A one character slight typo in how I customized it for my purposes.

And yes, I've learned a few more things about what the script is doing...
Thanks again for writing it!

Jim
 
rzirzi
Member
Member
Posts: 393
Joined: Mon Oct 09, 2006 2:33 pm

Re: Is it possible to run a script on login?

Sat Jun 17, 2017 8:54 pm

Script is GREAT, but there is something wrong with that script at ROS 6.3X :(
At that version of MikroTik Router OS - script is triggering (sending email) at every midnight. So - what I have should to change to work as good as under 5.2X ROS?
 
rzirzi
Member
Member
Posts: 393
Joined: Mon Oct 09, 2006 2:33 pm

Re: Is it possible to run a script on login?

Wed Jun 21, 2017 11:45 pm

Any idea/solution?
 
User avatar
k6ccc
Forum Guru
Forum Guru
Posts: 1497
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Is it possible to run a script on login?

Wed Jun 21, 2017 11:58 pm

Mine works fine on every version 6.x that I have loaded. I will post mine when I get to a computer.


Sent from my phone using Tapatalk, so blame any typos on Android!
 
User avatar
k6ccc
Forum Guru
Forum Guru
Posts: 1497
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Is it possible to run a script on login?

Thu Jun 22, 2017 6:11 am

Thia is mine. This is a variation of the code posted on 17 December 2014 by skot
# BEGIN SETUP
:local scheduleName "Send Login alert"
:local emailAddress1 "<redacted>.com"
:local emailAddress2 "<redacted>.org"
:local startBuf [:toarray [/log find message~"logged in" || message~"login failure" || message~"logged out" || message~"Long Port Knock step x"]]
:local removeThese {"zippo";"whatever string you want"}
# END SETUP

# warn if schedule does not exist
: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"
}

# get last time
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message
 

# final 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={
  /log info "[LOGMON] New login or logout logs found, sending E-Mail."
  /system scheduler set [find name="$scheduleName"] comment=$currentTime
  /tool e-mail send to="$emailAddress1" subject="MikroTik RB750Gr3 #2 Log in or out alert $currentTime" body="Sent from Microtik RB750Gr3 #2 \n \n $output"
  /tool e-mail send to="$emailAddress2" subject="MikroTik RB750Gr3 #2 Log in or out alert $currentTime" body="Sent from Microtik RB750Gr3 #2 \n \n $output"
  /log info "Login / Logout update E-Mail sent."
}
I copied this from my RB750Gr3 running 6.39.1
I have the exact same script on my RB750r2 running 6.38.5

This script runs every one minute. This will send me an E-Mail message when someone logs into the router, logs out, or completes my Port Knock security access.

When I logged into the Gr3 to copy this code, I shortly thereafter received an E-Mail with a subject of:
MikroTik RB750Gr3 #2 Log in or out alert jun/21/2017 19:56:05
And the following text:
Sent from Microtik RB750Gr3 #2

jun/21/2017 19:56:05 user <redacted here> logged in from 192.168.101.42 via winbox
 
User avatar
amt
Long time Member
Long time Member
Posts: 529
Joined: Fri Jan 16, 2015 2:05 pm

Re: Is it possible to run a script on login?

Thu Jun 22, 2017 11:57 am

using this script with telegram ?
 
Shadeofspirit
Member Candidate
Member Candidate
Posts: 203
Joined: Fri May 27, 2016 12:15 am
Location: Minsk
Contact:

Re: Is it possible to run a script on login?

Thu Jun 22, 2017 2:38 pm

using this script with telegram ?
yes, you can add (or replace e-mail) notification to telegram. i use it with my RBs
 
User avatar
amt
Long time Member
Long time Member
Posts: 529
Joined: Fri Jan 16, 2015 2:05 pm

Re: Is it possible to run a script on login?

Thu Jun 22, 2017 3:11 pm

Yes I did... thanks a lot...
 
derekb
just joined
Posts: 14
Joined: Sat Apr 22, 2017 3:38 am
Location: Ontario, Canada

Re: Is it possible to run a script on login?

Sun Jul 16, 2017 10:24 pm

Thank you very much for this script -- I have been looking for something like this for a while. It's working perfectly and was easy enough to modify the output variable to add some text to the email body.

I've chosen to use this script to give me an alert when someone does a port-knock to request access to the network. We have RB750Gr3 on site at customer locations -- we do the port knock and want to see the customer an email with the log so they know when we accessed their network.

I've created a Mangle rule on Prerouting chain to add SRC to address list on port knock -- this is working fine.

I've set the Mangle rule to log with a prefix of "knock" -- again, working fine.

However, when we do the port knock we see 4-5 lines of log each time we knock. Also, sometimes there are logs for "knock" even when we didn't do the knock. Is there any way to reduce the number of lines for this? I think it's from TCP ACKs or something possibly.

Edit: I was also wondering, is it possible to save the output as a txt file and email that as an attachment instead of having he output all in the email body?
Last edited by derekb on Mon Jul 17, 2017 12:05 am, edited 2 times in total.
 
User avatar
k6ccc
Forum Guru
Forum Guru
Posts: 1497
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Is it possible to run a script on login?

Mon Jul 17, 2017 12:04 am

I'll post what I did when I get back to a computer. Essentially what I do is the first step of the port knock sets the source address to a step one list via a firewall rule. That rule logs. Above that rule is a rule that drops packets that meet step one if the source address is already in the step one list. That eliminates the extra log entries. And yes, I also see a random step one port knock in the log once in a while.


Sent from my phone using Tapatalk, so blame any typos on Android!
 
User avatar
k6ccc
Forum Guru
Forum Guru
Posts: 1497
Joined: Fri May 13, 2016 12:01 am
Location: Glendora, CA, USA (near Los Angeles)
Contact:

Re: Is it possible to run a script on login?

Mon Jul 17, 2017 1:38 am

I've chosen to use this script to give me an alert when someone does a port-knock to request access to the network. We have RB750Gr3 on site at customer locations -- we do the port knock and want to see the customer an email with the log so they know when we accessed their network.

I've created a Mangle rule on Prerouting chain to add SRC to address list on port knock -- this is working fine.

I've set the Mangle rule to log with a prefix of "knock" -- again, working fine.

However, when we do the port knock we see 4-5 lines of log each time we knock. Also, sometimes there are logs for "knock" even when we didn't do the knock. Is there any way to reduce the number of lines for this? I think it's from TCP ACKs or something possibly.
I don't do it in Mangle rules. I do it in firewall rules. For each step, there are two rules. The second one sets the source address to the address list Long Knock-x (where x is the step number). Except for the first step, the source address must be in the previous steps source list. Successfully meeting the criteria for each step results in a leg entry. Since the source computer does not get a response, it will continue to send packets which would keep creating log entries. To prevent that, the first rule looks for packets that meet the port knock step one and if the address is in the address list, is simply drops the packet. Obviously the IPs and ports shown are not the actual numbers...
add action=drop chain=input comment="Long Port Knock step 1 log blocker" \
    dst-address=8.7.4.3 dst-port=54321 in-interface=VLAN_200 \
    protocol=tcp src-address-list="Long Knock-1"
add action=add-src-to-address-list address-list="Long Knock-1" \
    address-list-timeout=15s chain=input comment=\
    "Long Port Knock setup step 1" dst-address=8.7.4.3 dst-port=54321 \
    in-interface=VLAN_200 log=yes log-prefix="Long Port Knock step 1" \
    protocol=tcp
    
add action=drop chain=input comment="Long Port Knock step 2 log blocker" \
    dst-address=8.7.4.2 dst-port=45123 in-interface=VLAN_200 protocol=\
    tcp src-address-list="Long Knock-2"
add action=add-src-to-address-list address-list="Long Knock-2" \
    address-list-timeout=15s chain=input comment=\
    "Long Port Knock setup step 2" dst-address=8.7.4.2 dst-port=45123 \
    in-interface=VLAN_200 log=yes log-prefix="Long Port Knock step 2" \
    protocol=tcp src-address-list="Long Knock-1"
    
add action=drop chain=input comment="Long Port Knock step 3 log blocker" \
    dst-address=8.7.4.1 dst-port=32145 in-interface=VLAN_200 \
    protocol=tcp src-address-list="Long Knock-3"
add action=add-src-to-address-list address-list="Long Knock-3" \
    address-list-timeout=15s chain=input comment=\
    "Long Port Knock setup step 3" dst-address=8.7.4.1 dst-port=32145 \
    in-interface=VLAN_200 log=yes log-prefix="Long Port Knock step 3" \
    protocol=tcp src-address-list="Long Knock-2"
    
add action=drop chain=input comment="Long Port Knock step 4 log blocker" \
    dst-address=8.7.4.5 dst-port=14725 in-interface=VLAN_200 protocol=\
    tcp src-address-list=Safe
add action=add-src-to-address-list address-list=Safe address-list-timeout=1m \
    chain=input comment="Long Port Knock setup step 4" dst-address=\
    8.7.4.5 dst-port=14725 in-interface=VLAN_200 log=yes log-prefix=\
    "Long Port Knock step 4" protocol=tcp src-address-list="Long Knock-3"
The script that I posted on June 21st looks for both the log on and off messages in the log, but also the "Long Port Knock step 4" message.
 
derekb
just joined
Posts: 14
Joined: Sat Apr 22, 2017 3:38 am
Location: Ontario, Canada

Re: Is it possible to run a script on login?

Mon Jul 17, 2017 1:41 am

I've chosen to use this script to give me an alert when someone does a port-knock to request access to the network. We have RB750Gr3 on site at customer locations -- we do the port knock and want to see the customer an email with the log so they know when we accessed their network.

I've created a Mangle rule on Prerouting chain to add SRC to address list on port knock -- this is working fine.

I've set the Mangle rule to log with a prefix of "knock" -- again, working fine.

However, when we do the port knock we see 4-5 lines of log each time we knock. Also, sometimes there are logs for "knock" even when we didn't do the knock. Is there any way to reduce the number of lines for this? I think it's from TCP ACKs or something possibly.
I don't do it in Mangle rules. I do it in firewall rules. For each step, there are two rules. The second one sets the source address to the address list Long Knock-x (where x is the step number). Except for the first step, the source address must be in the previous steps source list. Successfully meeting the criteria for each step results in a leg entry. Since the source computer does not get a response, it will continue to send packets which would keep creating log entries. To prevent that, the first rule looks for packets that meet the port knock step one and if the address is in the address list, is simply drops the packet. Obviously the IPs and ports shown are not the actual numbers...
add action=drop chain=input comment="Long Port Knock step 1 log blocker" \
    dst-address=8.7.4.3 dst-port=54321 in-interface=VLAN_200 \
    protocol=tcp src-address-list="Long Knock-1"
add action=add-src-to-address-list address-list="Long Knock-1" \
    address-list-timeout=15s chain=input comment=\
    "Long Port Knock setup step 1" dst-address=8.7.4.3 dst-port=54321 \
    in-interface=VLAN_200 log=yes log-prefix="Long Port Knock step 1" \
    protocol=tcp
    
add action=drop chain=input comment="Long Port Knock step 2 log blocker" \
    dst-address=8.7.4.2 dst-port=45123 in-interface=VLAN_200 protocol=\
    tcp src-address-list="Long Knock-2"
add action=add-src-to-address-list address-list="Long Knock-2" \
    address-list-timeout=15s chain=input comment=\
    "Long Port Knock setup step 2" dst-address=8.7.4.2 dst-port=45123 \
    in-interface=VLAN_200 log=yes log-prefix="Long Port Knock step 2" \
    protocol=tcp src-address-list="Long Knock-1"
    
add action=drop chain=input comment="Long Port Knock step 3 log blocker" \
    dst-address=8.7.4.1 dst-port=32145 in-interface=VLAN_200 \
    protocol=tcp src-address-list="Long Knock-3"
add action=add-src-to-address-list address-list="Long Knock-3" \
    address-list-timeout=15s chain=input comment=\
    "Long Port Knock setup step 3" dst-address=8.7.4.1 dst-port=32145 \
    in-interface=VLAN_200 log=yes log-prefix="Long Port Knock step 3" \
    protocol=tcp src-address-list="Long Knock-2"
    
add action=drop chain=input comment="Long Port Knock step 4 log blocker" \
    dst-address=8.7.4.5 dst-port=14725 in-interface=VLAN_200 protocol=\
    tcp src-address-list=Safe
add action=add-src-to-address-list address-list=Safe address-list-timeout=1m \
    chain=input comment="Long Port Knock setup step 4" dst-address=\
    8.7.4.5 dst-port=14725 in-interface=VLAN_200 log=yes log-prefix=\
    "Long Port Knock step 4" protocol=tcp src-address-list="Long Knock-3"
The script that I posted on June 21st looks for both the log on and off messages in the log, but also the "Long Port Knock step 4" message.
Makes total sence, thanks!

I'm currently modifiying the original script so that the value of $output gets stored in a file called accesslog.txt and THAT gets emailed as an attachment, instead of putting the logs in the email body. I'm planning on setting scheduler for 60 minutes. Hopefully this works...
 
derekb
just joined
Posts: 14
Joined: Sat Apr 22, 2017 3:38 am
Location: Ontario, Canada

Re: Is it possible to run a script on login?

Mon Jul 17, 2017 3:24 am

Alright, I'm completely stuck here...
I thought I had this all working, but I guess not!

I want to have the contents of `$output` printed into a text file `accesslog.txt` whenever scheduler runs the script instead of dumping lots of data into the email body.

Here's the section I've modified:
 If we have output, save new date/time, and send email
if ([:len $output] > 0) do={
/file print file=accesslog
/file set [find name="accesslog"] contents="$output"
  /system scheduler set [find name="$scheduleName"] comment=$currentTime  
  /tool e-mail send to="$emailAddress" subject="$output"" file="accesslog";
  /log info "[LOGMON] New logs found, send email";
  /file remove accesslog.txt;
}
The only lines I have added are the 3 lines above starting with /file

My issues is that the BODY of the email still contains the proper log file data. However the attachment `accesslog.txt` contains this:
# jul/16/2017 20:23:32 by RouterOS 6.39.2
# software id = 9Z71-UNW2
#
 # NAME                   TYPE                        SIZE CREATION-TIME       
 0 flash                  disk                             dec/31/1969 20:00:01
 1 disk1                  disk                             dec/31/1969 20:00:02
 2 flash/skins            directory                        dec/31/1969 20:00:02

From terminal, I can manually run:
/file set [find name="accesslog"] contents="test123"
and it properly writes "test123" into the accesslog.txt, so I know the /file command is accurate.

We also know the $output variable is still intact and working since it gets printed correctly in the email body.

What I am doing incorrectly here?
 
User avatar
CyB3RMX
Member Candidate
Member Candidate
Posts: 148
Joined: Thu May 26, 2011 7:08 am

Re: Is it possible to run a script on login?

Mon Jul 09, 2018 8:55 pm

:local currentBuf [ :toarray [ /log find message~"logged in from" || message~"login failure" ] ] ;


I added "from" on the because i am running a PPPoE Server on this box and when a user connects it sends a false-positive alert (im using telegram instead of email)...

when a pppoe user logs in you get on the log:
user logged in, <ipaddress>
And when you connect to the router, says:
user XXXX logged in from <ipaddress> via winbox or whatever.
 
User avatar
spippan
Member
Member
Posts: 334
Joined: Wed Nov 12, 2014 1:00 pm
Location: Austria

Re: Is it possible to run a script on login?

Thu Oct 18, 2018 4:05 pm

i don't know if this fits in here correctly .... but,
i'm looking for a way to run a comand (or script - in that case with one line) as soon as i login to my MT via SSH

i mean i log in and i see the banner and the "/system note" (see below)
what i want to display here is the output of "/ppp active print" as soon as i log in via SSH SHELL


typical login banner:
  MMM      MMM       KKK                          TTTTTTTTTTT      KKK
  MMMM    MMMM       KKK                          TTTTTTTTTTT      KKK
  MMM MMMM MMM  III  KKK  KKK  RRRRRR     OOOOOO      TTT     III  KKK  KKK
  MMM  MM  MMM  III  KKKKK     RRR  RRR  OOO  OOO     TTT     III  KKKKK
  MMM      MMM  III  KKK KKK   RRRRRR    OOO  OOO     TTT     III  KKK KKK
  MMM      MMM  III  KKK  KKK  RRR  RRR   OOOOOO      TTT     III  KKK  KKK

  MikroTik RouterOS 6.43.2 (c) 1999-2018       http://www.mikrotik.com/

[?]             Gives the list of available commands
command [?]     Gives help on the command and list of arguments

[Tab]           Completes the command/word. If the input is ambiguous,
                a second [Tab] gives possible options

/               Move up to base level
..              Move up one level
/command        Use command at the base level
 
SingleSW
just joined
Posts: 5
Joined: Wed May 27, 2020 11:06 am

Re: Is it possible to run a script on login?

Wed May 27, 2020 11:14 am

Send via Telegram bot. Script have global var - Last Event Id.
# BEGIN SETUP
:local TelegramBotToken "110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw"
:local TelegramChatId   "-1501445581143"
:local RemoveThese {"telnet";"whatever string you want"}
# END SETUP
# final output
:local output
:local EventMessage
:local EventTime
:local KeepOutput false
:local KeepInLog true
#Get id of all log entry
:local StartBuf [:toarray [/log find]]
:global LastId
if ([:len $LastId] < 1) do={
  :set output ("Last log id not found. Maybe Router was rebooted%0A")
  if ([:len $StartBuf] > 0) do={:set LastId [:pick $StartBuf ([:len $StartBuf]-1)]}
}  
:foreach i in=$StartBuf do={
  if ($KeepOutput = true) do={
    :set EventMessage [/log get $i message]
    :set EventTime [/log get $i time]
# loop through all RemoveThese array items. if this log entry contains any of them, it will be ignored
    :set KeepInLog true
    :foreach j in=$RemoveThese do={:if ($EventMessage ~ "$j") do={:set KeepInLog false}}
    if ($KeepInLog = true) do={:set output ($output.$EventTime." ".$EventMessage."%0A")}
  } else={
    if ($i = $LastId) do={:set KeepOutput true}
  }
}
:set LastId [:pick $StartBuf ([:len $StartBuf]-1)]
# If we have output send message
if ([:len $output] > 0) do={
  :set output ([/system clock get date]." log from ".[/system identity get name]."%0A".$output)
  /tool fetch url="https://api.telegram.org/bot$TelegramBotToken/sendmessage\?chat_id=$TelegramChatId&text=$output" keep-result=no
}
 
ZackP
just joined
Posts: 2
Joined: Fri Jul 24, 2020 2:32 pm

Re: Is it possible to run a script on login?

Fri Jul 24, 2020 2:39 pm

Thia is mine. This is a variation of the code posted on 17 December 2014 by skot
# BEGIN SETUP
:local scheduleName "Send Login alert"
:local emailAddress1 "<redacted>.com"
:local emailAddress2 "<redacted>.org"
:local startBuf [:toarray [/log find message~"logged in" || message~"login failure" || message~"logged out" || message~"Long Port Knock step x"]]
:local removeThese {"zippo";"whatever string you want"}
# END SETUP

# warn if schedule does not exist
: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"
}

# get last time
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message
 

# final 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={
  /log info "[LOGMON] New login or logout logs found, sending E-Mail."
  /system scheduler set [find name="$scheduleName"] comment=$currentTime
  /tool e-mail send to="$emailAddress1" subject="MikroTik RB750Gr3 #2 Log in or out alert $currentTime" body="Sent from Microtik RB750Gr3 #2 \n \n $output"
  /tool e-mail send to="$emailAddress2" subject="MikroTik RB750Gr3 #2 Log in or out alert $currentTime" body="Sent from Microtik RB750Gr3 #2 \n \n $output"
  /log info "Login / Logout update E-Mail sent."
}
I copied this from my RB750Gr3 running 6.39.1
I have the exact same script on my RB750r2 running 6.38.5

This script runs every one minute. This will send me an E-Mail message when someone logs into the router, logs out, or completes my Port Knock security access.

When I logged into the Gr3 to copy this code, I shortly thereafter received an E-Mail with a subject of:
MikroTik RB750Gr3 #2 Log in or out alert jun/21/2017 19:56:05
And the following text:
Sent from Microtik RB750Gr3 #2

jun/21/2017 19:56:05 user <redacted here> logged in from 192.168.101.42 via winbox
Hi, first thanks for script im new and i learn with it, but i have a problem. I have RouterOS 6.45.7 and i only change this line:

/tool e-mail send to="$emailAddress" subject="$Missatge" body="$currentTime \n $output"

and i have the same problem than @rzirzi, every midnight script is triggering (sending email).

Any solution or help? thanks :)
 
IntLDaniel
Frequent Visitor
Frequent Visitor
Posts: 56
Joined: Thu Apr 04, 2019 7:21 pm

Re: Is it possible to run a script on login?

Thu Apr 21, 2022 1:45 pm

Hi @skot, thanks a lot for your script, I am using your version V4 viewtopic.php?f=2&t=60616&#p460810 unitl today on 6.49.5 or 7.2.1 mostly with success. Maybe you could help me to resolve probably related issue and one another task. So please if you could assist:

1/ Sometimes (from one to five times a day) I can find such log entries in the main log:
script error: no such item (4)
I bet it is generated by your script, do you have an idea what is wrong? I think if it could be related to situations when another log file is created (because of max log file entries is reached) and the script is just running? Is there a chance to debug somehow your script to be sure what is the reason?

2/ Would it be possible to use your script in the way of export (with append) some messages from log to a file? Currently I am using this simple script (export: security is the preffix added by my to be able search it):
:local date ([:pick [/system clock get date] 7 11] ."-". [:pick [/system clock get date] 0 3]);
/log print append follow-only file="MicroSD/export-security-log-$date" where topics~"firewall" message ~"export: security"
The problem of this script is, that it is adding the same lines multiple times a day. So I could put your searched output limited by last search date/time to the file, but the problem could be the "append" to existing file. In ROS you have to read it first, add data and write again and this is limited by 4096 characters if I remember. So I think the best way is to keep using /log print append function but how to limit searches from specific date/time like your script?

Hope you understand to me and thans for your help.

Who is online

Users browsing this forum: jwrs, woland and 113 guests