MANUAL: Mikrotik, colección de scripting

Hola, buenos días.
Estuve viendo la API de Telegram y no encuentro o no se que parámetro usar para enviar archivos mediante script, ¿Sabéis algo si es posible y como? Muchas gracias.

Saludos
Hola!

Parece ser que en la API de Telegram aún no está habilitado el envío de ficheros, sobre todo desde la llamada de una variable en Mikrotik. Puedes comprobarlo en la doc: https://core.telegram.org/bots/api#sending-files

Para el envío de ficheros, utiliza la opción que te ofrece el módulo de E-mail que trabaja correctamente.

Bash:
# Módulo para utilizar una cuenta Gmail para enviar emails.
# Variables
:local SendFrom "Router Mikrotik";
:local PasswordMail "MyStrongPassword";
:local SmtpServer 173.194.76.108;
:local UserName "mi-usuario-gmail";
:local SmtpPort 587;
:local UseTLS "yes";

# Main script code
/tool e-mail send to=$SendTo server=$SmtpServer port=$SmtpPort start-tls=$UseTLS user=$UserName \
password=$PasswordMail from=$SendFrom subject=$Subject body=$TextMail file=$FileName;

Y dentro de cualquier script, el envío de información, por ejemplo:

Bash:
# Test para enviar Emails
# Variables
:local DeviceName [/system identity get name];
:local Time [/system clock get time];
:local Date [/system clock get date];
:local SendTo "destinatario@gmail.com";
:local Subject "\F0\9F\9F\A2 INFO: $DeviceName [$Date $Time]";
:local MessageText "This informational message indicates the successful execution of the script \
on device $DeviceName";

/export file=some_file.txt.rsc
:delay 2s

# Main script code
:local FileName "some_file.txt.rsc";
:local SendEmail [:parse [/system script get SendEmailFunction source]];
$SendEmail SendTo=$SendTo TextMail=$MessageText Subject=$Subject FileName=$FileName;

:delay 2s
/file remove some_file.txt.rsc

S@lu2.
 
Última edición:
Hola!

Parece ser que en la API de Telegram aún no está habilitado el envío de ficheros, sobre todo desde la llamada de una variable en Mikrotik. Puedes comprobarlo en la doc: https://core.telegram.org/bots/api#sending-files

Para el envío de ficheros, utiliza la opción que te ofrece el módulo de E-mail que trabaja correctamente.

Bash:
# Módulo para utilizar una cuenta Gmail para enviar emails.
# Variables
:local SendFrom "Router Mikrotik";
:local PasswordMail "MyStrongPassword";
:local SmtpServer 173.194.76.108;
:local UserName "mi-usuario-gmail";
:local SmtpPort 587;
:local UseTLS "yes";

# Main script code
/tool e-mail send to=$SendTo server=$SmtpServer port=$SmtpPort start-tls=$UseTLS user=$UserName \
password=$PasswordMail from=$SendFrom subject=$Subject body=$TextMail file=$FileName;

Y dentro de cualquier script, el envío de información, por ejemplo:

Bash:
# Test para enviar Emails
# Variables
:local DeviceName [/system identity get name];
:local Time [/system clock get time];
:local Date [/system clock get date];
:local SendTo "destinatario@gmail.com";
:local Subject "\F0\9F\9F\A2 INFO: $DeviceName [$Date $Time]";
:local MessageText "This informational message indicates the successful execution of the script \
on device $DeviceName";

/export file=some_file.txt.rsc
:delay 2s

# Main script code
:local FileName "some_file.txt.rsc";
:local SendEmail [:parse [/system script get SendEmailFunction source]];
$SendEmail SendTo=$SendTo TextMail=$MessageText Subject=$Subject FileName=$FileName;

:delay 2s
/file remove some_file.txt.rsc

S@lu2.
Buenos días, creía que se podría hacer. Muchas gracias por la ayuda.
 
Script similar al publicado por @pokoyo para backup en la Cloud de Mikrotik (Latvia) con algunos añadidos interesantes.

Nos envía un email con información completa del fichero generado en la Cloud y su "Secret Download Key" para ser restaurado si fuera necesario en otro equipo.

Bash:
:log info "Automated Cloud Backup Started"
:local DeviceName [/system identity get name];

/system backup cloud upload-file action=create-and-upload password=MyPasSwOrD! replace=[find name]
:delay 2s
/system backup cloud print

# START Send Email Module
:local numCloud "0";
:local nameCloud [/system backup cloud get 0 name];
:local sizeCloud ([/system backup cloud get 0 size]/1024);
:local rosCloud [/system backup cloud get 0 ros-version];
:local dateCloud [/system backup cloud get 0 date];
:local statusCloud [/system backup cloud get 0 status];
:local secretCloud [/system backup cloud get 0 secret-download-key];
:local SendTo "destinatario@gmail.com";
:local Subject "\F0\9F\92\BE Cloud Backup $DeviceName";
:local MessageText "Se ha creado un nuevo Backup en la Cloud de Mikrotik:\n\nBackup number: \
$numCloud\nName: $nameCloud\nSize: $sizeCloud KiB\nRouterOS Version: $rosCloud\nDate: \
$dateCloud\nStatus: $statusCloud\nSecret Download Key: $secretCloud\n\nPara descargar el backup en otro \
equipo, copiar el siguiente comando:\n/system backup cloud download-file action=download \
secret-download-key=$secretCloud\n\nPara descargarlo en el propio equipo, copiar el siguiente \
comando:\n/system backup cloud download-file action=download number=0\n\nSi queremos borrar el fichero en \
los Servidores de Mikrotik, copiar el siguiente comando:\n/system backup cloud remove-file 0";
:local FileName "";
:local SendEmail [:parse [/system script get SendEmailFunction source]];
$SendEmail SendTo=$SendTo TextMail=$MessageText Subject=$Subject FileName=$FileName;
# END Send Email Module

:log info "Automated Cloud Backup Completed"

Lo programamos para que realice el backup cada día a las 02:00 h

Bash:
/system scheduler
add interval=1d name=cloud-backup on-event=cloud-backup \
policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
start-date=apr/14/2021 start-time=02:00:00

Y como resultado, obtenemos un email similar a este:

fi2LljYPvV.png

S@lu2.
 
Última edición:
Script similar al publicado por @pokoyo para backup en la Cloud de Mikrotik con algunos añadidos interesantes.

Nos envía un email con información completa del fichero generado en la Cloud y su "Secret Download Key" para ser restaurado si fuera necesario en otro equipo.

Bash:
:log info "Automated Cloud Backup Started"
:local DeviceName [/system identity get name];

/system backup cloud upload-file action=create-and-upload password=MyPasSwOrD! replace=[find name]
:delay 2s
/system backup cloud print

# START Send Email Module
:local numCloud "0";
:local nameCloud [/system backup cloud get 0 name];
:local sizeCloud ([/system backup cloud get 0 size]/1024);
:local rosCloud [/system backup cloud get 0 ros-version];
:local dateCloud [/system backup cloud get 0 date];
:local statusCloud [/system backup cloud get 0 status];
:local secretCloud [/system backup cloud get 0 secret-download-key];
:local SendTo "destinatario@gmail.com";
:local Subject "\F0\9F\92\BE Cloud Backup $DeviceName";
:local MessageText "Se ha creado un nuevo Backup en la Cloud de Mikrotik:\n\nBackup number: \
$numCloud\nName: $nameCloud\nSize: $sizeCloud KiB\nRouterOS Version: $rosCloud\nDate: \
$dateCloud\nStatus: $statusCloud\nSecret Download Key: $secretCloud\n\nPara descargar el backup en otro \
equipo, copiar el siguiente comando:\n/system backup cloud download-file action=download \
secret-download-key=$secretCloud\n\nPara descargarlo en el propio equipo, copiar el siguiente \
comando:\n/system backup cloud download-file action=download number=0\n\nSi queremos borrar el fichero en \
los Servidores de Mikrotik, copiar el siguiente comando:\n/system backup cloud remove-file 0";
:local FileName "";
:local SendEmail [:parse [/system script get SendEmailFunction source]];
$SendEmail SendTo=$SendTo TextMail=$MessageText Subject=$Subject FileName=$FileName;
# END Send Email Module

:log info "Automated Cloud Backup Completed"

Lo programamos para que realice el backup cada día a las 02:00 h

Bash:
/system scheduler
add interval=1d name=cloud-backup on-event=cloud-backup \
policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
start-date=apr/14/2021 start-time=02:00:00

Y como resultado, obtenemos un email similar a este:

Ver el adjunto 85146
S@lu2.
Qué bonico está quedando este hilo, sí señor. Cuando llegue a casa lo meto en el índice, sustituyendo el mío o complementándolo.

Saludos!
 
Como siempre, genial @pokoyo!

Os paso un script que conseguí hace tiempo (no recuerdo donde) que crea un reporte de IP's para posteriormente crear una regla en RAW que bloquee la citada lista, por si puede ser de utilidad:

Código:
delay 15
ip firewall address-list
:local update do={
:do {
:local data ([:tool fetch url=$url output=user as-value]->"data")
:local array [find dynamic list=blacklist]
:foreach value in=$array do={:set array (array,[get $value address])}
:while ([:len $data]!=0) do={
:if ([:pick $data 0 [:find $data "\n"]]~"^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}") do={
:local ip ([:pick $data 0 [:find $data $delimiter]].$cidr)
:do {add list=blacklist address=$ip comment=$description timeout=1d} on-error={
:do {set ($array->([:find $array $ip]-[:len $array]/2)) timeout=1d} on-error={}
}
}
:set data [:pick $data ([:find $data "\n"]+1) [:len $data]]
}
} on-error={:log warning "Address list <$description> update failed"}
}
$update url=http://feeds.dshield.org/block.txt description=DShield delimiter=("\t") cidr=/24
$update url=http://www.spamhaus.org/drop/drop.txt description="Spamhaus DROP" delimiter=("\_")
$update url=http://www.spamhaus.org/drop/edrop.txt description="Spamhaus EDROP" delimiter=("\_")
$update url=https://sslbl.abuse.ch/blacklist/sslipblacklist.txt description="Abuse.ch SSLBL" delimiter=("\r")
$update url=https://raw.githubusercontent.com/ktsaou/blocklist-ipsets/master/firehol_level2.netset description="FireHOL Level2" delimiter=("\n")
$update url=https://lists.blocklist.de/lists/all.txt description="BlockList.de" delimiter=("\n")

Saludos!
esto no consume muchos recursos? la lista con tantas fuentes tiene que ser enorme...
 
esto no consume muchos recursos? la lista con tantas fuentes tiene que ser enorme...
Mucho. Aunque, en raw, casi no se nota, puesto que descarta los paquetes antes de que entren en el flujo normal de routing, descartándolos en una de las primeras fases. Mirad los flujos del tráfico que hay en la wiki, y veréis donde descarta ese tráfico. Si lo mismo lo haces en el filtro del firewall, le metes un calentón a la cpu de órdago.

Saludos!
 
Ahora que se acerca una ola de calor de las potentes, os paso este sencillo script para avisarnos por Telegram en el momento que el router alcance el umbral de temperatura que configuremos. *Importante, sólo funcionará en aquellos Mikrotiks que dispongan de sonda de temperatura.

Bash:
:global tempSystem [/system health get temperature]
:local DeviceName [/system identity get name]
:local tempMax "50";

:if ($tempSystem >= $tempMax) do={
:log error "Alerta de Temperatura ALTA: $tempSystem ºC";

# START Send Telegram Module
:local MessageText "\E2\9A\A0 <b>Router Mikrotik $DeviceName</b>%0AAlerta Temperatura ALTA: $tempSystem C";
:local SendTelegramMessage [:parse [/system script  get MyTGBotSendMessage source]];
$SendTelegramMessage MessageText=$MessageText;
# END Send Telegram Module

} else={
:log warning "La temperatura está dentro de los valores normales: $tempSystem ºC"
}

Nos avisará de esta forma:

1628592341539.png

*Los 35ºC ya sabemos que no es temperatura alta, solo es a efectos para estas pruebas.

Otro script similar:

Bash:
:global "tempstatus"
:global "templaststatus"
:global "systemtemp" [/system health get temperature]
:local DeviceName [/system identity get name]

:if (systemtemp > "40") do={:set "tempstatus" "La temperatura del sistema es ALTA"}
:if (systemtemp > "50") do={:set "tempstatus" "La temperatura del sistema es MUY ALTA"}
:if (systemtemp > "60") do={:set "tempstatus" "La temperatura del sistema es CRITICA"}
:if (systemtemp < "40") do={:set "tempstatus" "Temperatura del sistema dentro de la normalidad"}

:if ($"tempstatus" != $"templaststatus") do {

# START Send Telegram Module
:local MessageText "\E2\9A\A0 <b>Router Mikrotik $DeviceName</b>%0A$tempstatus: $systemtemp C";
:local SendTelegramMessage [:parse [/system script  get MyTGBotSendMessage source]];
$SendTelegramMessage MessageText=$MessageText;
#END Send Telegram Module

:log info "Aviso: $tempstatus $systemtemp C"
:set "templaststatus" $"tempstatus"
}

Resultado:

1628639639357.png


S@lu2.
 
Última edición:
*Los 35ºC ya sabemos que no es temperatura alta, solo es a efectos para estas pruebas.
Gracias por los scripts. La verdad es que son de gran utilidad. Voy a poner este en práctica también.

Ahora mismo mi hEX-S.

Captura de pantalla_2021-08-10_12-57-26.png


Según Mikrotik para el hEX-S = Tested ambient temperature : -40°C to 70°C

Saludos.
 
Ahora que se acerca una ola de calor de las potentes, os paso este sencillo script para avisarnos por Telegram en el momento que el router alcance el umbral de temperatura que configuremos. *Importante, sólo funcionará en aquellos Mikrotiks que dispongan de sonda de temperatura.

Bash:
:global tempSystem [/system health get temperature]
:local DeviceName [/system identity get name]
:local tempMax "50";

:if ($tempSystem >= $tempMax) do={
:log error "Alerta de Temperatura ALTA: $tempSystem ºC";

# START Send Telegram Module
:local MessageText "\E2\9A\A0 <b>Router Mikrotik $DeviceName</b>%0AAlerta Temperatura ALTA: $tempSystem C";
:local SendTelegramMessage [:parse [/system script  get MyTGBotSendMessage source]];
$SendTelegramMessage MessageText=$MessageText;
# END Send Telegram Module

} else={
:log warning "La temperatura está dentro de los valores normales: $tempSystem ºC"
}

Nos avisará de esta forma:

Ver el adjunto 85152
*Los 35ºC ya sabemos que no es temperatura alta, solo es a efectos para estas pruebas.

S@lu2.
Hola, primeramente gracias por tus scripts. Por otro lado quería preguntar dos cosas, en los hAP AC^2 se puede saber la tamperatura? y con que frecuencia se puede poner la ejecución de un script para no dañar y colapsar el mikrotik. Muchas gracias.

Saludos
 
Hola, primeramente gracias por tus scripts. Por otro lado quería preguntar dos cosas, en los hAP AC^2 se puede saber la tamperatura? y con que frecuencia se puede poner la ejecución de un script para no dañar y colapsar el mikrotik. Muchas gracias.

Saludos
Hola!

El ac2 no tiene sensor de temperatura. Una pena.

Yo tengo bastantes scripts funcionando con el Scheduler y sin problema. Tirale sin miedo.

S@lu2.
 
Los dichos modulos donde van? en sl script?
SendEmailFunction es el módulo para el envío de correos y MyTGBotSendMessage es el módulo para los mensajes de Telegram, ambos se crean como simples scripts y el resto de scripts hacen las llamadas a estos para su uso. Los creas en system -> scripts y ya está.

En este post tienes los módulos/scripts mencionados:
https://www.adslzone.net/foro/mikrotik.199/manual-mikrotik-coleccion-scripting.575217/#post-3581607

S@lu2.
 
Última edición:

Script para bloqueo de dispositivos móviles.​

Este script busca en la lista de dhcp-server leases todos los clientes conectados con el flag dynamic=yes y donde el dhcp server sea el que definimos en la variable DHCPSERVER. Esto es por si tenemos mas de un servidor dhcp para no filtrar en todos. Busca el host-name que coincida con Android, iPad, etc, entonces agrega un nuevo lease con el flag block-access=yes para ese mac. Finalmente libera a todos los leases con ese nombre para no ocupar una dirección IP.

Solo hay que definirle el nombre del DHCP-server.

Bash:
:local DHCPSERVER "dhcp1";
 
:foreach i in=[/ip dhcp-server lease find dynamic=yes active-server=$DHCPSERVER] do={
    :local DhcpDynMAC [/ip dhcp-server lease get $i mac-address];
                :local DhcpDynCLIENTID [/ip dhcp-server lease get $i active-client-id];
    :local DhcpDynHOST [/ip dhcp-server lease get $i host-name];
    :local phoneNAME [:pick $DhcpDynHOST 0 4];
 
    :if ( ($phoneNAME="BLUS") || ($phoneNAME="iPad") || ($phoneNAME="andr") || ($phoneNAME="Andr") || ($phoneNAME="Wind") || ($phoneNAME="iPho") || ($phoneNAME="BLAC") ) do={
        /ip dhcp-server lease add block-access=yes mac-address="$DhcpDynMAC" use-src-mac=yes comment="$DhcpDynHOST" server="$DHCPSERVER" client-id="$DhcpDynCLIENTID";
    }
}
/ip dhcp-server lease remove [find host-name~"BLUS*"]
/ip dhcp-server lease remove [find host-name~"android*"]
/ip dhcp-server lease remove [find host-name~"Android*"]
/ip dhcp-server lease remove [find host-name~"Windows*"]
/ip dhcp-server lease remove [find host-name~"iPad*"]
/ip dhcp-server lease remove [find host-name~"iPhone*"]
/ip dhcp-server lease remove [find host-name~"BLACKBERRY*"]

S@lu2.
 

Script para controlar la carga media de la CPU​

Nos avisa mediante log y enviando un email con la información cuando la carga media alcanza el umbral definido, luego se restablece cuando el promedio vuelve a bajar. Es conveniente configurar el programador en un periodo corto de tiempo. Especialmente indicado para entornos de alto tráfico.

Bash:
# Average CPU Load Notification.
# This will email you once when average CPU Load reaches the set CPU Threshold value.
# When average CPU Load drops back below CPU Threshold the email notification is reset.
# Set up the scheduler to run this at 1-5 second intervals (Sample Rate).
# Original credit goes to rgraham - modified by hartz.

# Threshold is the value that will activate the alert when reached by average CPU Load (1-100)
:local cputhreshold 80;

# Arraysize is the number of CPU Load samples to keep.
# Experiment with this value to incease or decrease the number of samples.
# The greater the value the longer the time that the cpu-load average is calculated for.
:local arraysize 20;

# Misc variables for stuff and things.
:local cpuload 0;
:local arraylen 0;
:local arraypos 0;
:local arraytot 0;
:global avgcpuload 0;
:global cpuarray;
:global highavgcpuload;
:global cpualertemail;

# Get CPU Load samples, limit cpuarray to array size.
:set cpuload [/system resource get cpu-load];
:set cpuarray ( [:toarray $cpuload] + $cpuarray );
:set cpuarray [:pick $cpuarray 0 $arraysize];

# Add up all values in array.
:set arraypos 0;
:set arraylen [:len $cpuarray];
:while ($arraypos < $arraylen) do={
:set arraytot ($arraytot + [:pick $cpuarray $arraypos] );
:set arraypos ($arraypos +1)}

# Divide sum of array values by the number of values in cpuarray.
:set avgcpuload ($arraytot / [:len $cpuarray]);
:if ([:len $highavgcpuload] = 0) do={:set highavgcpuload $avgcpuload}
:if ([$highavgcpuload] < [$avgcpuload]) do={:set highavgcpuload $avgcpuload}

# Display results in Terminal window.
:log info ("CPU Load Captures:");
:delay 1s
:log info $cpuarray;
:log info ("Array Total: $arraytot");
:log info ("Array size: $arraysize");
:log info ("CPU Load – Avg: $avgcpuload High: $highavgcpuload");

# Send alert email.
:if ($avgcpuload >= $cputhreshold) do={
:if ($cpualertemail != "true") do={

# Build message body.
:local body "";
:set body ($body."Uptime: ".[/system resource get value-name="uptime"]."\r\n");
:set body ($body."Memory Total / Free: ".[/system resource get value-name="total-memory"] / "1024" / "1024"."MB / ".[/system resource get value-name="free-memory"] / "1024" / "1024"."MB\r\n");
:set body ($body."CPU Load: ".[/system resource get value-name="cpu-load"]."%\r\n");
:set body ($body."CPU Average: ".$avgcpuload."%\r\n");
:set body ($body."CPU High: ".$highavgcpuload."%\r\n");
:set body ($body."CPU Alert Threshold: ".$cputhreshold."%\r\n");
:set body ($body."Connections: ".[/ip firewall connection print count-only]."\r\n");
:set highavgcpuload;

# Send email and set variable so no further alerts are sent until average goes below threshold.

# START Send Email Module
  :local SendTo "destinatario@gmail.com";
  :local Subject ([/system identity get name]." CPU alert triggered at ".[/system clock get date]);
  :local MessageText $body;
  :local FileName "";
  :local SendEmail [:parse [/system script get SendEmailFunction source]];
  $SendEmail SendTo=$SendTo TextMail=$MessageText Subject=$Subject FileName=$FileName;
# END Send Email Module

:set cpualertemail "true";
}
} else={
# Reset alert if average is less than threshold.
:set cpualertemail "false";
}

S@u2.
 
Última edición:

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:

mNo3ZevDWv.png


Script para informar sobre intentos fallidos de Login y bloquea la IP (2/2)​

Como continuación al anterior script, el siguiente 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:
# By PhallaCCMT (phallaccmt.blogsport.com)
# Modified by @diamuxin

: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 tarea de 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:
/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:

iS3cRa0Wst.png


Efectivamente, desde esa IP ya no se puede acceder, ni vía Winbox ni por SSH.

S@lu2.
 
Última edición:

Script para informar cuando un usuario se ha logueado en el router​

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)

: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]);
  /tool e-mail send to=$emailAddress subject=$msgSubj body=$msgBody;
};

:set TokensOfLoggedUsers [:toarray $tokenList];

Recibimos un email como este:

Ver el adjunto 85332

S@lu2.
Hola diamuxin, gracias por estos scripts, son muy buenos. Por otro lado veo que no este último no usas la función de Email, pero en el código que pones ¿solo se pone el correo y no su configuración? Estaría bien que todos usaran la misma función de Email y Telegram. Gracias.

Saludos.
 
Hola diamuxin, gracias por estos scripts, son muy buenos. Por otro lado veo que no este último no usas la función de Email, pero en el código que pones ¿solo se pone el correo y no su configuración? Estaría bien que todos usaran la misma función de Email y Telegram. Gracias.

Saludos.
Hecho. De todas formas te animo a que los modifiques tú a tu voluntad, solo hay que añadir el módulo y sustituirlo por el original del script, por ejemplo:

Script básico para envío de correos (utilizando la config email de Mikrotik):

Bash:
/tool e-mail send to=$emailAddress subject=$msgSubj body=$msgBody;

Para aplicar el módulo e-mail, se sustituye por:

Bash:
# 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

Lo interesante del scripting es entender como funcionan las variables y los procesos y probar hasta obtener los resultados deseados, si solo te conformas con "copiar/pegar" es muy aburrido.

S@lu2.
 
Hecho. De todas formas te animo a que los modifiques tú a tu voluntad, solo hay que añadir el módulo y sustituirlo por el original del script, por ejemplo:

Script básico para envío de correos (utilizando la config email de Mikrotik):

Bash:
/tool e-mail send to=$emailAddress subject=$msgSubj body=$msgBody;

Para aplicar el módulo e-mail, se sustituye por:

Bash:
# 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

Lo interesante del scripting es entender como funcionan las variables y los procesos y probar hasta obtener los resultados deseados, si solo te conformas con "copiar/pegar" es muy aburrido.

S@lu2.
Hola diamuxin, no es que habitualmente copie y pegue, en temas de scripting se que es un mundo muy abierto pero hay script que poco hay que tocar o casi nada y mejor no tocar algo que funciona. La verdad que en scripting de mikortik no lo llevo muy bien y es por que no se muy bien losa nombres de las variables para coger los datos que me interesan de mikrotik.

Por otro lado me fastidia mucho cuando tengo todo bien y uno cree que todo funciona bien y se despreocupa y resulta que no va algo que no se tocó y antes funcionaba. En concreto lo digo por la función de Email que le tenia una cuenta de Gmail y hoy me fijé y no iba el error es "Error sending e-mail <🚀 Austin System Status>: AUTH failed" al principio pensé que era por la cuenta o la password, pero puse otras cuentas de gmail que tengo varias y pasa igual, me imagino que Google habrá tocado algo o está toqueteando algo. En fin ...

Diamuxin muchas gracias por tus scripts.

Saludos
 
Hola diamuxin, no es que habitualmente copie y pegue, en temas de scripting se que es un mundo muy abierto pero hay script que poco hay que tocar o casi nada y mejor no tocar algo que funciona. La verdad que en scripting de mikortik no lo llevo muy bien y es por que no se muy bien losa nombres de las variables para coger los datos que me interesan de mikrotik.

Por otro lado me fastidia mucho cuando tengo todo bien y uno cree que todo funciona bien y se despreocupa y resulta que no va algo que no se tocó y antes funcionaba. En concreto lo digo por la función de Email que le tenia una cuenta de Gmail y hoy me fijé y no iba el error es "Error sending e-mail <🚀 Austin System Status>: AUTH failed" al principio pensé que era por la cuenta o la password, pero puse otras cuentas de gmail que tengo varias y pasa igual, me imagino que Google habrá tocado algo o está toqueteando algo. En fin ...

Diamuxin muchas gracias por tus scripts.

Saludos
Hola, desde Tools -> Email, si tienes tu cuenta bien configurada, haz una prueba de envío. Si te falla revisa la configuración de tu cuenta de Google a ver si tiene alguna restricción al haber realizado varios envíos muy seguidos, hay que probar, siempre puedes crear una nueva cuenta email de Google y probar desde ésta.

S@lu2.
 
@Universo2021
Además de lo que te comenta @diamuxin, para trabajar con una cuenta de google, crea una contraseña de aplicación. Una vez hecha, tu usuario será tu email de google, y la contraseña que darás de alta en ese menú será la de aplicación que creaste en el primer paso.

Saludos!
 
Arriba