MANUAL: Mikrotik, colección de scripting

El motivo de meterme en "berenjenales" es el siguiente. Desde hace unos días vengo observando en logs intentos de conexión denegados a través de winbox/dude, desde diversas IP's.
Eso es porque tienes un agujero en el firewall. Las conexiones de winbox no deberían venir nunca desde internet. Y Dude, a menos que lo uses, desinstálalo.

Corrige eso primero antes de meterte con el scripting. Lo primero es partir de una base segura, luego ya metes white/black list o lo que quieras.

Saludos!
 
@pokoyo, no, dude no lo utilizo y no lo tengo instalado (salvo que venga "de fábrica" en el MK). Supongo que el mensaje de intento de login que recibo será genérico:

denied winbox/dude connect from XXX.XXX.XXX.XXX

Efectivamente, acabo de darme cuenta que tengo el firewall hecho unos zorros...voy a revisarlo antes de nada y os paso pantallazo para ver si lo veis correcto, una vez lo modifique.


Saludos!!
 
@pokoyo, adjunto estado del firewall después de darle un repaso.

Por el motivo que fuese (por manazas) me faltaban un montón de reglas, incluso la de aceptar los puertos de WG (y aún así me funcionaba WG ¿?)

Qué os parece el orden? faltaría alguna regla importante?


Saludos!
 

Adjuntos

  • InkedNueva imagen_LI.jpg
    InkedNueva imagen_LI.jpg
    164.9 KB · Visitas: 121
@pokoyo, adjunto estado del firewall después de darle un repaso.

Por el motivo que fuese (por manazas) me faltaban un montón de reglas, incluso la de aceptar los puertos de WG (y aún así me funcionaba WG ¿?)

Qué os parece el orden? faltaría alguna regla importante?


Saludos!
Te funciona porque, por defecto y a menos que lo bloquees, todo tráfico está aceptado si no hay regla de firewall que lo prohíba.

Si quieres ver el original, puedes ver el script de auto-configuración con este comando. De ahí puedes sacar las reglas por defecto que trae el equipo:

Código:
/system/default-configuration/print

Saludos!
 
@pokoyo, gracias! Ya he dejado el firewall bastante más curioso, observaré si cesan los intentos de conexión..., faltaban muchas reglas (importantes)

No obstante, voy a echar a andar el script que comentaba anteriormente del compi @diamuxin, me parece sumamente interesante. Voy a pelearme con las variables a ver si puedo agregarle el módulo de telegram (me parece más cómodo que por correo).


Saludos!
 
@pokoyo, gracias! Ya he dejado el firewall bastante más curioso, observaré si cesan los intentos de conexión..., faltaban muchas reglas (importantes)

No obstante, voy a echar a andar el script que comentaba anteriormente del compi @diamuxin, me parece sumamente interesante. Voy a pelearme con las variables a ver si puedo agregarle el módulo de telegram (me parece más cómodo que por correo).


Saludos!
Muy buenas, verás que no es difícil solo tienes que cambiar el módulo E-mail por el de Telegram en la misma posición del script y utilizar las variables que necesitas ser informado (toma como referencia otro script que utilice Telegram y te haces una idea).

Ahora estoy fuera de casa, en cuanto tenga el portátil entre manos le echo un vistazo.

Respecto a "los intrusos" recientemente he habilitado una VPN tipo L2TP/IPSec road-warrior como respaldo de la Wireguard y de vez en cuando los rastreadores de Internet como Shadow Server intentan acceder por los puertos ipsec. Los avisos de error son del tipo: XXX.XXX.XXX.XXX phase1 negotiation failed.

Esos intentos, con un script extraigo la IP del mensaje y la mando a una lista de direcciones que la bloqueo por RAW durante 7 días.

Inténtalo y vas probando, es lo divertido del scripting.

S@lu2.
 
No obstante, voy a echar a andar el script que comentaba anteriormente del compi @diamuxin, me parece sumamente interesante. Voy a pelearme con las variables a ver si puedo agregarle el módulo de telegram (me parece más cómodo que por correo).

Supongo que te refieres a este script (mod de v.7)

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

Bash:
# Creamos un script con el nombre: CheckFailureLoginUser
# 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 timeout=86400
 
    # START Send Email
    /tool e-mail send to="destinatario@gmail.com" subject="\E2\9A\A0 MikroTik alert on $datetime" body="Your Router ($DeviceName) is attempt login by: $attackiparray at $GTime. Now it has been add to block list." file="";
    # END Send Email

   }
:set ($attackcountarray->$z) 0
:set z ($z+1)
}

Cambias la parte de E-mail

Bash:
# START Send Email
    /tool e-mail send to="destinatario@gmail.com" subject="\E2\9A\A0 MikroTik alert on $datetime" body="Your Router ($DeviceName) is attempt login by: $attackiparray at $GTime. Now it has been add to block list." file="";
# END Send Email

Por:

Bash:
# START Send Telegram Module
    :local MessageText "\E2\9A\A0 $DeviceName: Attempt login by: $attackiparray at $GTime. Now it has been add to block list.";
    :local SendTelegramMessage [:parse [/system script get MyTGBotSendMessage source]];
    $SendTelegramMessage MessageText=$MessageText;
# END Send Telegram Module

S@lu2.
 
Hola!

Estoy con un script que me vale para algo en concreto, pero me quedo un poco mosca, que no sea lo más eficiente, elegante, etc.

En concreto tengo varias rutas definidas en mi mikrotik para que las saque por una VPN. Tengo alguna web alojada en Amazon AWS y los dominios cambian de IP regularmente, por lo que quiero ponerme un script que me actualice la tabla de rutas hacia esas IPs dinamicas que va cambiando en Amazon, para que mi tabla de rutas esté actualizada y acceda a esas IPs desde la VPN.

Código:
#Cabe destacar, que tengo ese dominio lo tengo añadido en:
/ip firewall address-list add address=Web_alojada_en_AWS comment=Web_alojada_en_AWS

Y el propio Mikrotik me resuelve ese dominio en varias IPs


El script seria:

#Borra las IPs actuales

/ip route/ remove [find comment="Web_alojada_en_AWS"]

#Añade las nuevas IPs

:foreach i in=[/ip firewall address-list find comment=Web_alojada_en_AWS] do={
    /ip/route add dst-address=[/ip firewall address-list get $i address] gateway=Tunel_VPN comment=Web_alojada_en_AWS;
}
Código:

Como veis, uso el truco que Firewall address-list ya me resuelve ese dominio de AWS en las IPs, por lo que me lo ahorro en el script.

¿Qué os parece?
 
Última edición:
Hola!

Estoy con un script que me vale para algo en concreto, pero me quedo un poco mosca, que no sea lo más eficiente, elegante, etc.

En concreto tengo varias rutas definidas en mi mikrotik para que las saque por una VPN. Tengo alguna web alojada en Amazon AWS y los dominios cambian de IP regularmente, por lo que quiero ponerme un script que me actualice la tabla de rutas hacia esas IPs dinamicas que va cambiando en Amazon, para que mi tabla de rutas esté actualizada y acceda a esas IPs desde la VPN.

Código:
#Cabe destacar, que tengo ese dominio lo tengo añadido en:
/ip firewall address-list add address=Web_alojada_en_AWS comment=Web_alojada_en_AWS

Y el propio Mikrotik me resuelve ese dominio en varias IPs


El script seria:

#Borra las IPs actuales

/ip route/ remove [find comment="Web_alojada_en_AWS"]

#Añade las nuevas IPs

:foreach i in=[/ip firewall address-list find comment=Web_alojada_en_AWS] do={
    /ip/route add dst-address=[/ip firewall address-list get $i address] gateway=Tunel_VPN comment=Web_alojada_en_AWS;
}
Código:

Como veis, uso el truco que Firewall address-list ya me resuelve ese dominio de AWS en las IPs, por lo que me lo ahorro en el script.

¿Qué os parece?
Pues veo que sabes aprovechar los recursos del equipo, enhorabuena. Una solución muy elegante, muy parecida a la del hairpin nat para resolver la IP pública.

Saludos!
 
Pues veo que sabes aprovechar los recursos del equipo, enhorabuena. Una solución muy elegante, muy parecida a la del hairpin nat para resolver la IP pública.

Saludos!
Muchas gracias! Si lo ves bien me fio :p

Al final le doy vueltas, porque lo suyo sería comparar si las que ya existen estan actualizadas o no y solo cambiarlas cuando detecte un cambio en la IP, pero como dices, esto ya lo tiene implementado Mikrotik en address-list, asi que deja el script bastante simple.
 
@diamuxin, muchas gracias, efectivamente ese es, estaba dándole vueltas a cómo implementar el módulo de Telegram, ya que lógicamente las variables eran distintas para el módulo de e-mail y telegram. Ya lo he dejado apañado, espero que no tenga que activarse demasiado xD

@pokoyo, desde que modifiqué el firewall, ni un sólo intento de conexión, gracias!


Saludos!
 
Crear el backup en cloud, con un script en /system scripts
Código:
/log info message="Cloud backup started"
/system backup cloud upload-file action=create-and-upload password=MySup3rb4ckUp! replace=[find name]
/tool e-mail send to=pokoyo@pericoplaotes.com subject="New cloud backup created for $[/system identity get name] router" body="A new cloud backup has been created at $[/system clock get time] on $[/system clock get date]."
/log info message="Cloud backup finished"

Hacerlo de manera periódica, todas las semanas a las 5 de la mañana
Código:
/system scheduler
add interval=1w name=backups on-event=cloud-backup policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=jan/01/2021 start-time=05:00:00
Hola,

Por algún oscuro motivo ese replace a mí no me funciona. Mi solución ha sido:

Código:
/log info message="Cloud backup started";
:local ficheros;
:set ficheros [/system backup cloud print count-only];
:if ($ficheros=1) do={
    /log info "Hay un fichero. Lo borro!";
    /system backup cloud print
    /system backup cloud remove-file 0;
}
/system backup cloud upload-file action=create-and-upload password=xxxxxxxx;
/log info message="Cloud backup finished";

Que, desde fuera, funciona pero no me acaba de gustar. Ah! Y una curiosidad el "remove-file 0" debe ir precedido de un "cloud print" ya que de lo contrario el comando falla y aborta el script (y no borra el fichero). Lo dicho, me parece una chapuza. Soy el único en el mundo en el que la solución propuesta por el maestro Pocoyo no le funciona? Quizás he hecho algo mal. Gracias!
 
Te falla porque, si es la primera ejecución, no hay fichero. Crea un backup a mano, con el botoncito de crear el cloud backup, y ya lo tienes listo para correr.

Saludos!
 
Te falla porque, si es la primera ejecución, no hay fichero. Crea un backup a mano, con el botoncito de crear el cloud backup, y ya lo tienes listo para correr.

Saludos!
Gracias, Pocoyo. Pero, claro, la idea era hacer un script de backup que no dependa de si hay o no fichero. Porque si, por error o por lo que sea, borras el fichero, la ejecución del script original fallaría en sucesivas ocasiones y no te darías cuenta...hasta el día en que necesitas el backup. La versión que postee funciona pero lo veo chapuza sobretodo por el hecho de tener que hacer el "cloud print" antes que el "remove-file 0" ... que parece que debería funcionar sí o sí (mientras el fichero exista en el slot 0, que es lo que se verifica unas lineas más arriba). Pero resulta que a veces falla...aún existiendo el fichero en la nube. Parece que hay un bug que hace que routerOS "se olvide" de que tiene algo en la nube y que el "cloud print" le refresca la memoria, por así decirlo. Bueno, nada, era para contrastar si era una paranoia mía :)

Gracias!
 
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

Interesante script.

A qué posición habría que mover esta regla partiendo de las creadas con el Quit Set:

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

Si usamos IPv6 habría que crear esta otra regla y a qué posición moverla.

/ipv6 firewall filter
add action=drop chain=input comment="Drop Attempt Login User" disabled=yes src-address-list=Lst_AttemptLoginIP

Saludos!
 
¿Para IPv4 habría que moverla aquí?

Ver el adjunto 90927

¿Y para IPv6 aquí?

Ver el adjunto 90930

Saludos!
Entiendo que esa lista tienes usuarios de tu LAN, a los que tampoco quieres permitir el acceso, no? Porque sino, la que tienes debajo, ya hace eso. Con la config por defecto, sólo tu LAN tiene acceso al chain de input del router. Y, si quieres restringirlo aún más, puedes poner que sólo una IP tenga acceso a los servicios de http y winbox.

Saludos!
 
Lo que quiero hacer es detectar y bloquear los intentos fallidos de acceso al router desde wan y lan.
He cambiado los puertos de los servicios www y winbox y desactivado Discovery Neighborts.

Saludos!
 
Arriba