block IP by login failure

Hi,

I have had several attempts to access from the same IP in the Local Network 192.168.1.134 and to all the services of the router (ssh, telnet and ftp), luckily it has not been able to access since I changed user and password at the time.


07-05 13:10:54 system,error,critical login failure for user  from 192.168.1.134 via ssh
07-05 13:10:54 system,error,critical login failure for user admin from 192.168.1.134 via ssh
07-05 13:10:55 system,error,critical login failure for user admin from 192.168.1.134 via ssh
07-05 13:10:55 system,error,critical login failure for user admin from 192.168.1.134 via ssh
07-05 13:10:56 system,error,critical login failure for user  from 192.168.1.134 via ssh
07-05 13:10:57 system,error,critical login failure for user MikroTikSystem from 192.168.1.134 via ssh
07-05 13:10:58 system,error,critical login failure for user dircreate from 192.168.1.134 via ssh
07-05 13:10:58 system,error,critical login failure for user SolucTec from 192.168.1.134 via ssh
07-05 13:10:59 system,error,critical login failure for user EServicios from 192.168.1.134 via ssh
07-05 13:11:00 system,error,critical login failure for user admin from 192.168.1.134 via ssh
07-05 13:11:03 system,error,critical login failure for user  from 192.168.1.134 via telnet
07-05 13:11:04 system,error,critical login failure for user admin from 192.168.1.134 via telnet
07-05 13:11:05 system,error,critical login failure for user admin from 192.168.1.134 via telnet
07-05 13:11:07 system,error,critical login failure for user admin from 192.168.1.134 via telnet
07-05 13:11:08 system,error,critical login failure for user  from 192.168.1.134 via telnet
07-05 13:11:09 system,error,critical login failure for user MikroTikSystem from 192.168.1.134 via telnet
07-05 13:11:11 system,error,critical login failure for user dircreate from 192.168.1.134 via telnet
07-05 13:11:12 system,error,critical login failure for user SolucTec from 192.168.1.134 via telnet
07-05 13:11:13 system,error,critical login failure for user EServicios from 192.168.1.134 via telnet
07-05 13:11:15 system,error,critical login failure for user admin from 192.168.1.134 via telnet
07-05 13:11:16 system,error,critical login failure for user root from 192.168.1.134 via telnet
07-05 13:11:17 system,error,critical login failure for user user from 192.168.1.134 via telnet
07-05 13:11:18 system,error,critical login failure for user sysadm from 192.168.1.134 via telnet
07-05 13:11:19 system,error,critical login failure for user admin from 192.168.1.134 via telnet
...

I want to put a script that runs every 5 minutes and allows to ban the IP for 24h.


# Add firewall drop rule
/ip firewall filter
add action=drop chain=input comment="Drop Attempt Login User" disabled=yes src-address-list=blockedUsers

# script
:local loglist [:toarray [/log find time > ([/system clock get time] - 5m) message~"login failure" topics~"critical"]]
:foreach i in=$loglist do={
	:local logMessage [/log get $i message]
	:local ip [:pick $logMessage ([:find $logMessage "from"]+5) [:find $logMessage " via"]]
	/ip firewall address-list add address=$ip list=blockedUsers timeout=24h
}

I would like if it is possible that the blocking of the IP is by number of attempts, that is to say, that it bans the IP when 3 (or another value) unsuccessful attempts are made in a row.

BR.

I read somewhere on the forum a similar script already working.

This means that with each successful login you have to reset the cunt, otherwise it doesn’t correctly accunt for how many times access has been denied.
07-05 13:14:16 system,error,critical login failure for user root from 192.168.1.134 via telnet
07-05 13:17:16 system,error,critical login failure for user root from 192.168.1.134 via telnet
07-05 13:21:16 user root logged in from 192.168.1.134 via telnet
07-05 13:33:16 system,error,critical login failure for user root from 192.168.1.134 via telnet

OK, I will look for it

Is this?

http://forum.mikrotik.com/t/can-a-script-be-created-if-a-wrong-login-name-is-used/132192/29

EDIT:
Can you add it to your post “:scissors: Rextended Fragments of Snippets”?
so it doesn’t get lost!!! hehe

Ahhh… I’m the author?

Yes is lost, best add to the list :wink:

And once the ip of the variable “$ipinside” is blocked in the address list, how can I delete all the lines in the log that contain that IP?

The lines on the log are not deletable selectively.

At least set the log memory to 1 lines and back to 1000 delete all the 999 old...


This script save the last checked log for start from that point instead to elaborate all list everytime:

:global lastLog
:if ([:typeof $lastLog] != "num") do={:set lastLog 0}

{

[...]

:local id2num do={:return [:tonum "0x$[:pick $1 1 [:len $1]]"]}

[...]

/log
:foreach item in=[find where ([$id2num $".id"] > $lastLog)] do={
:set lastLog [$id2num $item]

[...]

}

[...]

}

I think that's right, isn't it?


# Check if exist drop firewall rule and add
/ip firewall raw
:if ([:len [find where src-address-list="blockedUsers"]] = 0) do={
    add action=drop chain=prerouting src-address-list=blockedUsers
}

:global lastLogLogin
:if ([:typeof $lastLogLogin] != "num") do={:set lastLogLogin 0}

/log
:global maxattampt 3
:global errorArray [:toarray ""]
:global failmsg    "login failure for user "
:global frommsg    " from "
:global viamsg     " via "
:global listfail   "blockedUsers"
:local  id2num     do={:return [:tonum "0x$[:pick $1 1 [:len $1]]"]}

:foreach rlog in=[find where (([$id2num $".id"] > $lastLogLogin) \
                             and \
                             (message~"((25[0-5]|(2[0-4]|[01]\?[0-9]\?)[0-9])\\.){3}(25[0-5]|(2[0-4]|[01]\?[0-9]\?)[0-9])"))] do={
    
    :set lastLogLogin [$id2num $rlog]
    :local rmess [get $rlog message]
    :if (($rmess~$failmsg) and ($rmess~$frommsg) and ($rmess~$viamsg)) do={
         :local userinside [:pick $rmess ([:find $rmess $failmsg -1] + [:len $failmsg]) [:find $rmess $frommsg -1]]
         :local ipinside   [:pick $rmess ([:find $rmess $frommsg -1] + [:len $frommsg]) [:find $rmess $viamsg -1]]
         :local intinside  [:pick $rmess ([:find $rmess $viamsg -1] + [:len $viamsg]) [:len $rmess]]
         :if ([:typeof (($errorArray)->$ipinside)] = "nothing") do={
             :set (($errorArray)->$ipinside) 1
         } else={
             :set (($errorArray)->$ipinside) ((($errorArray)->$ipinside) + 1) 
         }
         :if ((($errorArray)->$ipinside) > ($maxattampt - 1)) do={
             /ip firewall address-list
             :if ([:len [find where list=$listfail and address=$ipinside]] = 0) do={
                 add list=$listfail address=$ipinside comment="$rmess" timeout=24h
             }
         }
         
    }
}

I use fail2ban running on a Linux box, which act as a rsyslog server.

On the moment I can not test it, but apparently it is correct…

Works OK.

The local variables $userinside and $intinside I have eliminated them because I have not seen any use in the script.

Thanks.