Script para informar cuando un usuario se ha logueado en el router (1/2)
Este script recupera las sesiones activas realizadas por cualquier vía, como winbox, ssh, etc. y envía un correo electrónico al administrador informando del número de sesiones activas.
Requiere permisos: read, write, policy, test.
Programar la llamada al script cada 10-15 min (a gusto de cada usuario)
Bash:
# written by Sergei Eremenko (https://github.com/SmartFinn)
# modified by @diamuxin
:global TokensOfLoggedUsers
# :local emailAddress "destinatario@gmail.com"
:local token
:local tokenList
:local newSession
:local msgBody ""
/user active {
:foreach session in=[find via!="api"] do={
:set token ([get $session name]."-".[get $session via]."-".[get $session when]);
:set tokenList ($token.",".$tokenList);
:set newSession true;
:foreach savedToken in=$TokensOfLoggedUsers do={
:if ($savedToken = $token) do={
:set newSession false;
}
};
:if ($newSession) do={
:set msgBody ($msgBody.[get $session name]." logged in from ".[get $session address]);
:set msgBody ($msgBody." via ".[get $session via]." at ".[get $session when]."\r\n");
}
}
};
if ($msgBody != "") do={
:local msgSubj ("New user(s) logged in to ".[/system identity get name]);
:set msgBody ($msgBody."\r\n"."At ".[/system clock get time]);
:set msgBody ($msgBody.", ".[/user active print count-only]." management session(s)");
:set msgBody ($msgBody." is active on ".[/system identity get name]);
# La siguiente línea del script original se sustituye por el módulo Email
# /tool e-mail send to=$emailAddress subject=$msgSubj body=$msgBody;
# START Send Email Module
:local SendTo "destinatario@gmail.com";
:local Subject $msgSubj;
:local MessageText $msgBody;
:local FileName "";
:local SendEmail [:parse [/system script get SendEmailFunction source]];
$SendEmail SendTo=$SendTo TextMail=$MessageText Subject=$Subject FileName=$FileName;
# END Send Email Module
};
:set TokensOfLoggedUsers [:toarray $tokenList];
Recibimos un email como este:
Ver el adjunto 85332
Script para informar sobre intentos fallidos de Login y bloquea la IP (2/2)
Como continuación al anterior script, el siguiente script informa por correo electrónico sobre los intentos fallidos de Login (configurable, en este caso con más de 2 intentos) y acto seguido mete las IPs "atacantes" en una lista de direcciones y se bloquea el acceso al router a través de una regla de firewall.
Creamos una regla específica de Logging que recopila los topics "
critical,system,error" que provocan cada evento de fallo de login.
Bash:
/system logging action
add name=failedauth target=memory
/system logging
add action=failedauth topics=critical,system,error
Creamos un script con el nombre:
CheckFailureLoginUser
Bash:
:local logBuffer "failedauth"
:local failthreshold 2
:local blocklist "Lst_AttemptLoginIP"
:local GTime [:pick [/system clock get time] 0 8]
:local DeviceName [/system identity get name];
# ----------------------------------------------------------------------------------------
:local attackiparray {0}
:local attackcountarray {0}
:local logEntryTopics
:local logEntryTime
:local logEntryMessage
:local clearedbuf
:local lines
:local datetime [/system clock get date]
:set clearedbuf 0
:local i 0
:foreach rule in=[/log print as-value where buffer=($logBuffer)] do={
# Now all data is collected in memory..
# Clear log buffer right away so new entries come in
:if ($clearedbuf = 0) do={
/system logging action {
:set lines [get ($logBuffer) memory-lines]
set ($logBuffer) memory-lines 1
set ($logBuffer) memory-lines $lines
}
:set clearedbuf 1
}
# End clear log buffer
:set logEntryTime ""
:set logEntryTopics ""
:set logEntryMessage ""
:set logEntryTime ($rule->"time")
:set logEntryTopics ($rule->"topics")
:set logEntryMessage ($rule->"message")
:if ($logEntryMessage~"login failure") do={
:local attackip [:pick $logEntryMessage ([:find $logEntryMessage "from "]+5) ([:find $logEntryMessage " via"])]
:local x 0
:foreach ip in=$attackiparray do={
:if ($ip = $attackip) do={
:set ($attackcountarray->$x) (($attackcountarray->$x)+1)
} else={
:set ($attackiparray->$i) $attackip
:set ($attackcountarray->$i) 1
}
:set x ($x+1)
}
}
:set i ($i+1)
# end foreach rule
}
:local z 0
:foreach ip in=$attackiparray do={
:if ($attackcountarray->$z > $failthreshold) do={
:set ($attackcountarray->$z) 0
/ip firewall address-list add address=($attackiparray->$z) list=$blocklist
# START Send Email Module
:local SendTo "destinatario@gmail.com";
:local Subject "\E2\9A\A0 MikroTik alert on $datetime";
:local MessageText "Your Router ($DeviceName) is attempt login by: $attackiparray at $GTime. Now it has been add to block list.";
:local FileName "";
:local SendEmail [:parse [/system script get SendEmailFunction source]];
$SendEmail SendTo=$SendTo TextMail=$MessageText Subject=$Subject FileName=$FileName;
# END Send Email Module
}
:set ($attackcountarray->$z) 0
:set z ($z+1)
}
Creamos la programación del script con el mismo nombre:
CheckFailureLoginUser (aunque puedes llamarlo como quieras)
Bash:
/system scheduler
add interval=20s name=CheckFailureLoginUser on-event=CheckFailureLoginUser \
policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
start-date=aug/18/2021 start-time=12:00:00
Por último la regla de firewall que bloquea los accesos de la address list:
Lst_AttemptLoginIP
Bash:
# in-interface: asignar la interface WAN, en mi caso "pppoe-out1", puede ser también "ether1", etc.
/ip firewall filter
add action=drop chain=input comment="Drop Attempt Login User" disabled=yes src-address-list=Lst_AttemptLoginIP
Cuando el script detecta (se ejecuta cada 20s) que hay varios intentos fallidos de Login (>2) bloquea la IP y nos informa con un correo electrónico como este:
Ver el adjunto 85374