RouterOS – Controlar / Filtrar contenido por DNS 2023

En muchas ocasiones he tenido que controlar mediante QoS algunas cuestiones como las actualizaciones de windows, o las redes sociales, y en otros casos filtra Whatsapp.
OpenDNS de Cisco permite mediante un dashboard poder ir tildando y destildando contenidos a filtrar.
Anda bien pero no te deja discriminar. Por ejemplo filtra «Redes Sociales» pero el termino es muy grande y termina cometiendo errores. Si tildas por ejemplo «File Sharing» los audios de Whatsapp no se envian.
Entonces para evitar este tipo de problemas lo que hacemos es armar nuestro script que marque por nombre de dominio.

Te deja utilizar los filtros de manera gratuita para 1 direccion IP por cuenta. Es decir que para 1 red nateada andaria bien. Tiene para tildar por defecto redes bogon, sitios que propagan malware, pornografia, etc.

OpenDNS

El script

Para que funcione correctamente tenemos que habilitar el cache de DNS de nuestro router y hacer resolver a nuestos clientes con los DNS del router. Luego siempre dropear el DNS input en el firewall para que no nos ataquen los DNS desde afuera.

Lo que hace el script es buscar una palabra que coincida en el nombre del dominio.

# Use DNS Entrys and add Address to the Firewall Address-list #
:foreach i in=[/ip dns cache all find where ( (name~"instagram") || (name~"facebook") || (name~"twitter") || (name~"twitch") ) && (type="A") && (data!=0.0.0.0) ] do={
:local tmpAddress [/ip dns cache get $i data];
delay delay-time=10ms;
# prevent script from using all cpu time #
:if ( [/ip firewall address-list find where address=$tmpAddress] = "") do={ 
:local cacheName [/ip dns cache get $i name] ;
#:log info ("added entry: $cacheName $tmpAddress");
/ip firewall address-list add address=$tmpAddress list=RedesSociales comment=$cacheName timeout=6d;
}
}

Si se fijan donde dice:

(name~»instagram«) || (name~»facebook«) || (name~»twitter«) || (name~»twitch«)

Modificamos a nuestro antojo.

Y mas abajo le damos el nombre al Address-List:

/ip firewall address-list add address=$tmpAddress list=RedesSociales comment=$cacheName timeout=6d;

Tambien pueden modificar el timeout: Todas las direcciones nuevas que resuelva las va agregando al AddressList (en este caso las mantiene por 6 dias), esto hace que tengamos un segundo cache que se vaya limpiando cada 6 dias y las direcciones IP viejas se vayan eliminando automaticamente.

Luego solo nos queda hacer algo con ese address list. Podemso dropearlo en el firewall.
O bien crear un mangle que marque la conexion con destino a esas IP y luego usarlo en Queues.

Por ejemplo:

/ip firewall filter
add action=drop chain=forward dst-address-list=RedesSociales in-interface=bridge_alumnos
add action=drop chain=output dst-address-list=RedesSociales out-interface=bridge_alumnos

Ojo que en mi caso ademas le digo en que interfaz eliminar las redes sociales. Elijan la interfaz para su caso.

origen: tech-nico.com

Mikrotik Script para bloquear intentos de login

Leyendo en el foro de mikrotik me encontre con este script que monitorea el log en busca errores , Y bloquea en base a la cantidad de intentos de acceso. Lo interesante es que podemos configurarlo para detectar distintos tipos de acceso. Por ejemplo los famosos intentos de acceso por VPN Ipsec que dicen «phase1 negotiation failed…». O los accesos erroneos por winbox nos dirian «login failure for user», etc.

Paso 1, importar script pegando esto en la terminal.

/sys script 
add dont-require-permissions=no name=LoginAttempBlocker owner=usuario policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="# Check if exist drop \
    firewall rule and add\r\
    \n/ip firewall raw\r\
    \n:if ([:len [find where src-address-list=\"blockedUsers\"]] = 0) do={\r\
    \n    add action=drop chain=prerouting src-address-list=blockedUsers\r\
    \n}\r\
    \n\r\
    \n:global lastLogLogin\r\
    \n:if ([:typeof \$lastLogLogin] != \"num\") do={:set lastLogLogin 0}\r\
    \n\r\
    \n/log\r\
    \n:global maxattampt 3\r\
    \n:global errorArray [:toarray \"\"]\r\
    \n:global failmsg    \"login failure for user \"\r\
    \n:global frommsg    \" from \"\r\
    \n:global viamsg     \" via \"\r\
    \n:global listfail   \"blockedUsers\"\r\
    \n:local  id2num     do={:return [:tonum \"0x\$[:pick \$1 1 [:len \$1]]\"]}\r\
    \n\r\
    \n:foreach rlog in=[find where (([\$id2num \$\".id\"] > \$lastLogLogin) \\\r\
    \n                             and \\\r\
    \n                             (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={\r\
    \n    \r\
    \n    :set lastLogLogin [\$id2num \$rlog]\r\
    \n    :local rmess [get \$rlog message]\r\
    \n    :if ((\$rmess~\$failmsg) and (\$rmess~\$frommsg) and (\$rmess~\$viamsg)) do={\r\
    \n         :local userinside [:pick \$rmess ([:find \$rmess \$failmsg -1] + [:len \$failmsg]) [:find \$rmess \$frommsg -1]]\r\
    \n         :local ipinside   [:pick \$rmess ([:find \$rmess \$frommsg -1] + [:len \$frommsg]) [:find \$rmess \$viamsg -1]]\r\
    \n         :local intinside  [:pick \$rmess ([:find \$rmess \$viamsg -1] + [:len \$viamsg]) [:len \$rmess]]\r\
    \n         :if ([:typeof ((\$errorArray)->\$ipinside)] = \"nothing\") do={\r\
    \n             :set ((\$errorArray)->\$ipinside) 1\r\
    \n         } else={\r\
    \n             :set ((\$errorArray)->\$ipinside) (((\$errorArray)->\$ipinside) + 1) \r\
    \n         }\r\
    \n         :if (((\$errorArray)->\$ipinside) > (\$maxattampt - 1)) do={\r\
    \n             /ip firewall address-list\r\
    \n             :if ([:len [find where list=\$listfail and address=\$ipinside]] = 0) do={\r\
    \n                 add list=\$listfail address=\$ipinside comment=\"\$rmess\" timeout=24h\r\
    \n             }\r\
    \n         }\r\
    \n         \r\
    \n    }\r\
    \n}"

Paso 2, configurar el script editando las variables globales:

:global maxattampt 3
:global failmsg    "login failure for user "
:global frommsg    " from "
:global viamsg     " via "
:global listfail  "blockedUsers"

3 serian la cantidad de intentos que toleramos. (para bloquear en un cuarto intento).

login from user, from y via van a depender del mensaje en el log que querramos capturar. Si quieren filtrar intentos de acceso por winbox entonces dejarlo como esta.

blockedUsers es la lista del firewall que se crea dinamicamente con la/s IP del usuario que intenta acceder.

Paso 3, agregar tu script al calendario para que se ejecute cada 5 minutos o menos.

Esto hara que nuestro script lea el log cada 5 minutos. Mas ajustemos el tiempo, mas eficiente sera el chequeo de acceso. Si dentro de estos 5 minutos, hubo 3 o mas intentos, automaticamente se creara una regla en el Firewall Raw, y borrara todo el input desde la direccion IP dinamica detectada en la lista blockedUsers. Se entiende que en las proximas 24 hs caducara la direccion y volvera a tener acceso.

______________

origen: tech-nico.com

RouterOS DHCP Server Automático con Queues Dinámicas

Esto esta pensado para lugares de mucha «mucha» concurrencia, para no derrochar recursos. Direcciones IP y Ancho de Banda. Por supuesto que esto tiene que estar acompañado de un buen CPU (para mi caso con un equipo 2011, me fue suficiente), y también debería estar acompañado de un caudal de ancho de banda suficiente dependiendo de cada caso y el factor simultaneidad.

Funcionamiento

Se crea un DHCP server como siempre, pero en la solapa Script se le dice que a cada Lease dinamico lo convierta en estatico, y que ademas le otorgue un RATE-LIMIT de Upload y Download. (En nuestro caso configure 1 mega de subida y 3 de bajada). Esto es lo que hace toda la magia.

#tech-nico.com  CONTACTO: administracion@tech-nico.com  01-01-2022
/ip dhcp-server lease make-static [/ip dhcp-server lease find dynamic && active-server="dhcp-invitados"];
/ip dhcp-server lease set [find where active-mac-address=$leaseActMAC] rate-limit="2M/3M" insert-queue-before="bottom";

Luego deben agregar un script que limpie los Leases que queden en estado «waiting». (son clientes que no pudieron obtener direccion IP por mala señal, o bien al renovar el Lease ya no estaba ese dispositivo en el sitio).

/ip dhcp-server lease remove [/ip dhcp-server lease find status="waiting" && server="dhcp-invitados"];

Nicolas Daitsch
Tech-nico.com

Automatizacion de Backups con Mikrotik y Google Drive Parte 2

En la primera parte, te enseñe como automatizar mediante un script el envio de tus backups. Ahora viene la parte divertida, «donde el google drive cobra vida». Esta segunda parte no tiene nada de Mikrotik, para ello leer la primera parte.

Esta «segunda» parte consiste en recibir el correo con un archivo adjunto (El backup), y dependiendo del asunto del email organizarlo en distintas carpetas y documentar todo en una planilla de calculo.

Como logramos esto?

Con Scripts de Google App Scripts que son muy muy poderosos y te permitirian mejorar funcionalidades en todo esto:

Nosotros lo que haremos es darle funcionalidades especiales dentro de una planilla de calculo «Sheet» que tendra funciones para:

  1. Leer el Gmail,
  2. Manipular el G.Drive
  3. y finalmente escribir el resultado en una planilla de calculo.

Pasos a seguir para implementarlo:

  1. Nos logueamos en la misma cuenta de gmail que utilizamos en la primera parte (donde estarian llegando los backups). Yo les recomiendo que lo hagan en una ventana de incognito.
  2. Luego como se muestra en la imagen, click en aplicaciones, y finalmente en Hojas de calculo. O bien, luego de loguearnos vamos a esta direccion: https://docs.google.com/spreadsheets/

3. Creamos una hoja de calculo nueva. Le damos el nombre que mas nos guste:

4. Usar la primer fila para crear los encabezados para cada columna

IDFECHA SUBIDACARPETAARCHIVOURLTIPOHORA ESCRITURA

5. Ahora iremos al menu «Herramientas» > Editor de secuencias de comandos tal como muestro en la siguiente imagen:

Es lo mismo que acceder a script.google.com, con la diferencia de que aqui queda el codigo ligado a esta planilla

6. Aqui pegaremos el siguiente codigo:


/*
 * Script por Nicolas Daitsch www.tech-nico.com/blog
   30 de septiembre de 2020
 */

// GLOBALS
//Filtro de extenciones de los archivos adjuntos
var fileTypesToExtract = ['backup', 'rsc', 'gz'];
//Carpeta de google drive donde los archivos seran movidos
var folderName = 'MIS-BACKUPS';
//Etiqueta que le pondremos a los correos ya procesados
var labelName = 'read_label';
// ID de la carpeta definida en la variable "folderName"
var DocsfolderID='1kLOIsv1Co_4SA6oE838kskfPXvZUuXcZg4fH';

function GmailToDrive(){
    var query = '';
    for(var i in fileTypesToExtract){
      query += (query === '' ?('filename:'+fileTypesToExtract[i]) : (' OR filename:'+fileTypesToExtract[i]));
    }
    query = 'in:inbox has:nouserlabels ' + query;
    var threads = GmailApp.search(query);
    var label = getGmailLabel_(labelName); // Get Label ID
    var parentFolder,parentMyFolder,parentMySubFolder; 
    if(threads.length > 0){
      parentFolder = createFolder(folderName,DocsfolderID); // Si la carpeta existe, traer el ID
    }
    var root = DriveApp.getRootFolder();
    for(var i in threads){
        var mesgs = threads[i].getMessages();
        for(var j in mesgs){
              var subject = mesgs[j].getSubject();
              var subject_array = subject.split("//");
              if(subject_array.length<2) { 
                 threads[i].addLabel(label); 
              }else{ 
                  var subject_folder = subject_array[0];
                  var subject_subfolder = subject_array[1];
                
                  var attachments = mesgs[j].getAttachments();
                  for(var k in attachments){
                      var attachment = attachments[k];
                      var isDefinedType = checkIfDefinedType_(attachment);
                      if(!isDefinedType) continue;
                      var attachmentBlob = attachment.copyBlob();
                      var file = DriveApp.createFile(attachmentBlob);
                      var nom_archivo="";
                      nom_archivo = attachment.getName();

                      parentMyFolder = createFolder(subject_folder,parentFolder.getId());
                      parentMySubFolder = createFolder(subject_subfolder,parentMyFolder.getId());

                      parentMySubFolder.addFile(file);
                      var files = [];
                      files.push({ id:file.getId(), fecha:file.getDateCreated(), carpeta: subject, archivo: file.getName(), url:file.getUrl(), tipo:file.getMimeType()});
                      printInSheet2(files[0])

                      root.removeFile(file);
                  }
              }
            
        }
        threads[i].addLabel(label); // set as just read
    }
}

function getGmailLabel_(name){
  var label = GmailApp.getUserLabelByName(name);
  if(!label){
	label = GmailApp.createLabel(name);
  }
  return label;
}

function checkIfDefinedType_(attachment){
  var fileName = attachment.getName();
  var temp = fileName.split('.');
  var fileExtension = temp[temp.length-1].toLowerCase();
  if(fileTypesToExtract.indexOf(fileExtension) !== -1) return true;
  else return false;
}


function createFolder(Name,folderID){
  
  var PF = DriveApp.getFolderById(folderID);
  if(Name==folderName){ return PF; }
  
  var subFolders = PF.getFolders();
  var doesntExists = true;
  var newFolder = '';
  
  while(subFolders.hasNext()){
    var folder = subFolders.next();
    if(folder.getName() === Name){
      doesntExists = false;
      newFolder = folder;
      return newFolder;
    };
  };
  
  if(doesntExists = true){
    newFolder = PF.createFolder(Name);
    return newFolder;
  };
};



function printInSheet2(objeto) {
  var today = (Utilities.formatDate(new Date(), "GMT-3", "dd-MM-yyyy")).toString();
  var today_hora = (Utilities.formatDate(new Date(), "GMT-3", "HH:mm")).toString();
  var ss = SpreadsheetApp.getActiveSpreadsheet();  
  var sheet = ss.getSheetByName(today);
  if (!sheet){
    SpreadsheetApp.setActiveSheet(ss.getSheets()[0]); 
  
    ss.duplicateActiveSheet(); 
    ss.renameActiveSheet(today); 
    ss.moveActiveSheet(1); 
    // Prepares tab (clears old content)
    var sheet = ss.getSheetByName(today); 
    sheet.getRange('A2:G200').clearContent(); // clean
    sheet.getRange('A2:G200').setBackground(null);
  }

  var found = sheet.getRange(1,1,sheet.getLastRow()).createTextFinder(objeto["id"]).matchCase(false).findNext(); 
  if ( found==null ){ // only write if any cell content not match with de file ID
      var data, sheet = SpreadsheetApp.getActiveSheet();
      data = [
        objeto["id"],
        objeto["fecha"],
        objeto["carpeta"],
        objeto["archivo"],
        objeto["url"],
        objeto["tipo"],
        today_hora
      ];
      sheet.appendRow(data);
   }
};

La Magia:

Nos quedaria algo asi:

7. Solo tendremos que editar primeras 4 variables, y son obligatorias la creacion de la carpeta MIS-BACKUPS o como quieras llamarla. Al crearla, obtenemos el ID de la carpeta que necesitamos definir en la ultima variable (tambien obligatoria), como muestro a continuacion:

En una nueva solapa vamos a https://drive.google.com/

Presionamos NUEVO:

Elegimos Carpeta:

Finalmente le damos click derecho «Obtener Enlace»

Copiamos el ID, Asegurense de que este completo porque es mas largo de lo que se ve en la captura:

8. Ahora ya podemos ejecutar el codigo y probar si funciona: Volver a la ventana de script.google.com y ejecuta el codigo eliguendo la funcion GmailToDrive y seguidamente presionar el boton Play

Finalmente les va a pedir que le den permisos de lectura para acceder al gmail, drive, etc.

Por supuesto que si no hay correos en tu casilla no va a procesar nada. Y ademas que si el asunto no respeta la doble barra para separar el nombre de la carpeta con la fecha, el mail no va a ser procesado. Si el correo es procesado lo marca con la etiqueta de leido «read_label»:

Finalemente revisamos en nuestro drive la creacion de las carpetas y en la planilla que deberia aparecer el resumen del archivo en solapas por fecha, para que si buscamos entre muchos backusp de una fecha especifica, lo podamos encontrar super rapido!.

9. Para agregar el script a un calendario de ejecucion y que corra el proceso de manera automatica, lo que tenemos que hacer es crear un nuevo Trigger o Activador:

Añadir Activador:

Yo lo configure asi: (Ustedes pueden setearlo a su gusto)

No hace falta que les diga que pueden utilizar este mismo script para recibir backups de Linux, Mikrotik, Windows, o cualquier dispositivo que sea capaz de enviar un mail con un archivo adjunto.

Espero que les haya gustado tanto como a mi, y cualquier cosa que no se entienda puedo armar un video-tutorial.

Saludos
_______________
Por Nicolas en tech-nico.com/blog

Mikrotik: Como direccionar trafico PPPoE por interfaz (sin balancear): 3 WAN / 3 LAN

No quiero extenderme explicando por que tuve que elegir esta configuracion, pero si quiero decir que fue una solucion muy buena en su momento. Por supuesto que tienen que darse condiciones muy similiares para que te sirva hacer lo mismo. Pero somos tantos en el mundo que seguro mi aporte puede ayudar a otros. 🙂

Escenario

3 LAN (OLT), cada una en una VLAN distinta, los usuarios conectan por PPPoE a cada VLAN y se routean a un WAN especificio.
Son 3 WAN de 100 Mb c/u. Los clientes hacen NAT en cada interfaz LAN. La clave de todo es generar dinamicamente listas de direcciones IP de los abonados en el momento que conectan y se desconectan.

A continuación paso a detallar cada bloque de comandos

A cada una de mis salidas las voy a nombrar Fortinet 1,2 y 3. (Asi se llaman los firewall que suele instalar telefonica en uno de sus servicios)

/ip firewall mangle
add action=mark-connection chain=input comment=UPLOAD in-interface=vlan_fortinet1 new-connection-mark=input1_connection passthrough=yes
add action=mark-routing chain=output connection-mark=input1_connection new-routing-mark=route_fortinet1 passthrough=no
add action=mark-connection chain=input in-interface=vlan_fortinet2 new-connection-mark=input2_connection passthrough=yes
add action=mark-routing chain=output connection-mark=input2_connection new-routing-mark=route_fortinet2 passthrough=no
add action=mark-connection chain=input in-interface=vlan_fortinet3 new-connection-mark=input3_connection passthrough=yes
add action=mark-routing chain=output connection-mark=input3_connection new-routing-mark=route_fortinet3 passthrough=no
add action=mark-routing chain=prerouting comment="ROUTING OLT 3 por FOTINET 3" new-routing-mark=route_fortinet3 passthrough=no src-address-list=\
OLT_service3
add action=mark-routing chain=prerouting comment="ROUTING OLT 2 por FOTINET 2" new-routing-mark=route_fortinet2 passthrough=no src-address-list=\
OLT_service2
add action=mark-routing chain=prerouting comment="ROUTING OLT 1 por FOTINET 1" new-routing-mark=route_fortinet1 passthrough=no src-address-list=\
OLT_service1

Estas son las rutas de cada salida. Deberas reeemplazar el gateway por los tuyos. Cada salida tiene su propia tabla de routeo.
Esto hace que puedas hacer traceroute desde afuera o desde adentro y no se confunda de ruta.

Hay una ruta que no tiene marca. Es la que yo elijo por defecto. (Es decir que nuestro router va a preferir esa ruta).

/ip route
add comment="gw fortinet 2" distance=3 gateway=200.2.2.105 routing-mark=route_fortinet2
add comment="gw fortinet 1" distance=2 gateway=200.1.1.137 routing-mark=route_fortinet1
add comment="gw fortinet 3" distance=4 gateway=200.3.3.97 routing-mark=route_fortinet3
add comment="default gw fortinet 2" distance=10 gateway=200.2.2.105
/ip route rule
add action=lookup-only-in-table routing-mark=route_fortinet1 table=route_fortinet1
add action=lookup-only-in-table routing-mark=route_fortinet3 table=route_fortinet3
add action=lookup-only-in-table routing-mark=route_fortinet2 table=route_fortinet2

Esta es la parte de de NAT, no hay mucho para ver. Cada interfaz LAN hace mascarade con las direcciones que se almacenan con el Script -PPP-On_up On_down. Veras mas abajo como se crean.

/ip firewall nat
add action=masquerade chain=srcnat comment="mascarading RED LOCAL" out-interface=vlan_fortinet1 src-address-list=OLT_service1 src-address-type=""
add action=masquerade chain=srcnat comment="mascarading RED LOCAL" out-interface=vlan_fortinet2 src-address-list=OLT_service2 src-address-type=""
add action=masquerade chain=srcnat comment="mascarading RED LOCAL" out-interface=vlan_fortinet3 src-address-list=OLT_service3 src-address-type=""

Cada PPPoE server tiene un nombre de servicio especifico: mas abajo se van a dar cuenta por que. En este caso son: «service1», «service2», y «service3». (Recordar esos nombres)

/interface pppoe-server server
add authentication=pap disabled=no interface=sfp-sfpplus1_olt1 keepalive-timeout=5 one-session-per-host=yes service-name=service1
add authentication=pap disabled=no interface=sfp-sfpplus2_olt2 keepalive-timeout=5 one-session-per-host=yes service-name=service2
add authentication=pap disabled=no interface=sfp-sfpplus3_olt3 keepalive-timeout=5 one-session-per-host=yes service-name=service3

Para poder routear los clientes correctamente necesitamos separar las direcciones IP de los tuneles PPP que se conecten, en 3 listas (address-lists) distintas. (una por cada LAN o en este caso OLT).
En PPP Profile (solapa) Scripts On-UP / On-DOWN. Esto hace que cuando conecta el PPPoE ponga su direccion remota en una lista con el nombre de la interfaz por donde esta conectando. En este caso OLT1, 2 o 3.
A continuacion, estos 2 pequeños comandos, se fijan de que pppoe server esta pidiendo este usuario conectar o desconectar. Entonces con la variable «caller-id» traemos el nombre del servicio desde donde se conecta. Como mencionamos anteriormente, «service1», «service2», y «service3».

La parte donde ocurre la magia

En cada perfil de ancho de banda tienes que ingresar a editar en las solapas donde dice On_up y On_Down y pegar los siguientes 2 scripts: (Tiene partes con comillas dobles, dejarlas tal cual).

ON UP
/ip firewall address-list add list="OLT_$"called-id"" address=$"remote-address"

ON DOWN
/ip firewall address-list remove [find list="OLT_$"called-id"" address=$"remote-address"]

No se por que algunas veces el On-UP Script faya, entonces la direccion IP de ese cliente no queda dentro de la lista OLT_serviceX y eso hace que ese cliente no tenga navegacion, ya que en Firewall NAT hacemos masqarading por listas. Realmente no tuve tiempo de descubir por que lo hacia. Entonces decidi hacer un script al que denomine PPP-SYNC-FIXER compara las direcciones IP de los tuneles PPP conectados con las listas de IP. Si no encuentra alguna de las direcciones, pateo el usuario para obligarlo a reconectar. El script se ejecuta cada 2 minutos en el calendario de ejecucion. (Bajarle el tiempo en equipos con poco procesador).

Para importar el script pegar esto en la consola y presionar enter.

/system script add dont-require-permissions=no name=PPP_SYNC_FIXER owner=soporte1 policy=\
read,write,policy,test,password,sniff,sensitive source=":log info message=\"*** comienza\
_a buscar usuarios PPP sin routeo \";\r\ \n:local arrnoestan [:toarray \"\"];\r\ \n:local pppactivos value=[/ppp active find];\r\ \n:local indice 1;\r\ \n:foreach usuario in=\$pppactivos do={\r\ \n :local direccionip value=[/ppp active get \$usuario value-name=address];\r\ \n :local busqolt1 value=[/ip firewall address-list print count-only where list=\"O\ LT_service1\" address=\$direccionip];\r\ \n :local busqolt2 value=[/ip firewall address-list print count-only where list=\"O\ LT_service2\" address=\$direccionip];\r\ \n :local busqolt3 value=[/ip firewall address-list print count-only where list=\"O\ LT_service3\" address=\$direccionip];\r\ \n :if ((\$busqolt1=0) && (\$busqolt2=0) && (\$busqolt3=0)) do={\r\ \n# :set arrnoestan ( \$arrnoestan, \$direccionip );\r\ \n :log info message=\"I \$indice IP \$direccionip - no encontrada --- PATEAN\ DO\";\r\ \n /ppp active remove \$usuario;\r\ \n }\r\ \n :set indice (\$indice + 1);\r\ \n}\r\ \n#:log info message=\" fin de script ***\";\r\
\n#:log info message=\"\$arrnoestan\";\r\
\n"

Para importar el scheduler pegar esto en la consola:

/system scheduler
add interval=2m name=Corro_fixer_PPP on-event="/sys script run PPP_SYNC_FIXER" policy=read,write,policy,test,password,sniff,sensitive \
start-date=dec/30/2019 start-time=21:38:15

Automatizacion de Backups con Mikrotik y Google Drive Parte 1

1) CONFIGURAR sNTP Client

Para que nuestro backup se ejecute correctamente lo primero es que nuestro RouterOS se mantenga siempre con la hora correcta por mas que se reinicie. Entonces pegamos esto en la consola:

/system ntp client
set enabled=yes primary-ntp=216.239.35.12

Solo aceptaremos en nuestro firewall el servidor NTP de google, ya que estos puertos suelen estar dentro de los mas atacados. Para ellos pegamos nuevamente lo siguiente en la consola:

/ip firewal filter
add action=accept chain=input comment="NTP Admitir solo a time.google.com" dst-port=123 protocol=tcp src-address=\
216.239.35.12
add action=accept chain=input dst-port=123 protocol=udp src-address=216.239.35.12
add action=drop chain=input dst-port=123 protocol=udp

2) CONFIGURAR E-MAIL

Las siguientes lineas corresponden al seteo del servicio de correo. La direccion IP es de smtp.google.com: Lo editas en tu notepad reemplazando tu contraseña y la direccion de correo y lo pegamos en la consola:

/tool e-mail
set address=172.217.192.109 from= password="TU_CONTRASEÑA_FUERTE" port=587 start-tls=yes user=\
TUMAIL@GMAIL.com

NOTA IMPORTANTE: recorda que Gmail bloquea el envio de mails de cualquier aplicacion externa (que se considera poco segura) como por ejemplo Outlook, (y cualquier otros), y por supuesto el envio de mails a traves de RouterOS. Para resolverlo loggearse con la cuenta que usaran para backups y luego hacen click en el siguiente este enlace: https://myaccount.google.com/lesssecureapps

Cambiar de NO a SI

3) PROBAR EL ENVIO DE EMAIL

Para saber si el envio es correcto probamos el envio desde consola con la siguiente linea:

/tool e-mail send to="TUMAIL@GMAIL.com" subject="soy tech-nico backups"

4) IMPORTAR SCRIPTS DE BACKUPS

A continuacion tenemos 2 scripts que debemos pegar en la consola (previo a editar la direccion de e-mail). El primer script envia el binario completo. «.backup» y el segundo script envia un export completo «.rsc». Por ahora no editen el asunto porque es importante mantener el doble slash «//». (en la parte 2 te daras cuenta del por que). Recueden que al pegar en la consola hay que presionar enter.

/system script add name=backup_binary source={/system backup save name=([/system identity get name] . "-" . \
[:pick [/system clock get date] 7 11] . [:pick [/system clock get date] 0 3] . [:pick [/system clock get date] 4 6]); \
/tool e-mail send to="TUMAIL@GMAIL.com" subject=([/system identity get name] . "_BACKUP//" . \
[/system clock get date]) file=([/system identity get name] . "-" . [:pick [/system clock get date] 7 11] . \
[:pick [/system clock get date] 0 3] . [:pick [/system clock get date] 4 6] . ".backup"); :delay 10; \
/file rem [/file find name=([/system identity get name] . "-" . [:pick [/system clock get date] 7 11] . \
[:pick [/system clock get date] 0 3] . [:pick [/system clock get date] 4 6] . ".backup")]; \
:log info ("System Backup emailed at " . [/sys cl get time] . " " . [/sys cl get date])}

Y este otro:

/system script add name=backup_export source={/export file=([/system identity get name] . "-" . \
[:pick [/system clock get date] 7 11] . [:pick [/system clock get date] 0 3] . [:pick [/system clock get date] 4 6]); :delay 2; \
/tool e-mail send to="TUMAIL@GMAIL.com" subject=([/system identity get name] . "_BACKUP//" . \
[/system clock get date]) file=([/system identity get name] . "-" . [:pick [/system clock get date] 7 11] . \
[:pick [/system clock get date] 0 3] . [:pick [/system clock get date] 4 6] . ".rsc"); :delay 10; \
/file rem [/file find name=([/system identity get name] . "-" . [:pick [/system clock get date] 7 11] . \
[:pick [/system clock get date] 0 3] . [:pick [/system clock get date] 4 6] . ".rsc")]; \
:log info ("System Backup emailed at " . [/sys cl get time] . " " . [/sys cl get date])}

5) AGREGARLO AL CALENDARIO DE EJECUCION

Y finalmente lo ejecutamos cada 5 dias. O como ustedes prefieran. Esto hara que se envien 2 mails. 1 con el .backup y el otro con el export .rsc.

/system scheduler
add interval=5d name=backup_binary on-event="/sys script run backup_binary" policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=aug/03/2020 start-time=16:35:00
add interval=5d name=backup_export on-event="/sys script run backup_export" policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=aug/03/2020 start-time=16:35:00


En la segunda parte de este post te enseñare como volcar estos mails a un Google Drive.

Scripts Mikrotik | 2 esenciales para un sys admin: Ether state and Speedtest

2 Scripts que yo denomino «Criminales»

Hola amigos,  disculpen la ausencia, estamos con muchas implementaciones, pero no queria dejar pasar esta oportunidad de dejarles 2 script que trabajan de la mano y para mi gusto son increibles.

Script 1: Chequear el estado de un puerto ethernet

Este script esta pendiente del estado de un puerto de red que le configuremos. Es decir que esta atento a si el estado del puerto esa con link o sin link. Cuando el puerto hace link chequea que tenga salida a internet haciendo un ping a www.tech-nico.com.
Si tiene salida a internet, entonces ahi entra en juego el script nro 2.

[PHP]
# Nicolas: Tech-nico.com/blog
# CHEQUEAMOS ESTADO DE ETHERNET
:global etherNET;
:set $etherNET value=»ether1″;
:global «ether-state»;
:global «ether-laststate»;
/interface ethernet monitor $etherNET once do={:set «ether-state» $status};
:if ($»ether-state» != $»ether-laststate») do={
:log info («Interface $etherNET – link status cambio a: » . $»ether-state»);
:set «ether-laststate» $»ether-state»;
:do {
:put [:resolve www.tech-nico.com];
:if ($»ether-state»=»link-ok») do { :log warning («HACER TEST!!»); /system script run speedtest; }
} on-error={ :put «resolver failed»};
}
[/PHP]

Script 2: Hacer un test de velocidad descargando un archivo

En principio enciende la pantalla LCD del equipo (tenemos que usar algún equipo como un RB-2011) para mostrar la velocidad de download reflejada en la pantalla. Fíjense que tienen que editar la url donde dice archivo_pesado.tif y setear el servidor y nombre de archivo que ustedes tengan, y usen como prueba. Se recomienda algún video AVI pesado, (algo que pueda almacenar nuestro RB).

[PHP]
{
# Nicolas: Tech-nico.com/blog
# HACEMOS UN SPEEDTEST
/lcd backlight state=on;
local startTime [/system clock get time];
:global myurl «http://www.tech-nico.com/archivo_pesado.tif»;
/tool fetch url=$myurl mode=http;
local endTime [/system clock get time];
# subtract startTime from endTime to get time elapsed
local finalTime ( $endTime – $startTime );
# convert hours to seconds, add to sum
:local sum ( $sum + ( [ :pick $finalTime 0 2 ] * 60 * 60 ));
# convert minutes to seconds, add to sum
:set sum ( $sum + ( [ :pick $finalTime 3 5 ] * 60 ));
# add seconds to sum
:set sum ( $sum + [ :pick $finalTime 6 8 ] );
:local sise [[/file get [/file find name=archivo_pesado.tif] size] /1024];
:local sdonspped ((($sise / $sum ) * 8 ) /1024);
:local ddow ((($sdonspped *1000) /8) / 1024);
:global speedtest $sdonspped;
:log warning («My connection Speed «.[:pick $sdonspped 0 1] .».». [:pick $sdonspped 1 3] . » Mbps» );
:log error («My Speed Download = «. $ddow .» Kbps»);
}
[/PHP]

Casos de uso

La idea de estos 2 script es la siguiente:  Crear una herramienta para mostrarle al cliente «sin encender ninguna computadora», cual es el rendimiento de su conexion a internet. Por eso es un requisito fundamental usarlo con modelos de hardward que tengan pantalla LCD. Tambien porque en el mercado no existe ningun tester o appliance que haga algo tan basico como un testspeed y lo entregue de manera elegante en una pantallita LCD, Sin paracticamente configurar nada. Loco no?

Funcionamiento

En mi caso tengo configurado un usuario PPPoE en el ether1. El mismo puerto esta seteado en el Script 1 para chequear el estado de red. Una vez que es detectado el estado del ethernet como UP, hacemos un ping, y si el PPPoE client alcanzo a conectar, el ping a tech-nico.com nos va a dar OK, con lo cual finalmente se va a ejecutar el download.

Pd: Aclaro que la foto fue «gestionada» con google. Aclaro por si aparece el dueñ0.  😀

____________________
Primero en tech-nico.com/blog

Script Mikrotik – Enviar mail cuando ping es mayor a 200ms

Minientrada

Algo para agregar a la navaja suiza de tus script (sysadmin only): 

Hola Amigos, hace mucho que no escribo, y en este caso, me pareció que vale la pena repostear. Este script de mikrotik hecho por un chino te envia un mail cuando el ping a cierta dirección supera los 200 ms; por ejemplo, si tenemos algun enlace o cliente que queremos monitorear cuando estamos durmiendo. Si sos nerd (como yo), No dejes escapar este script, es justo para vos.

#Mikrotik Ping more than 200ms to send mail
#https://ros.ac
#By:Ali
#From:China
:local Asunto "Alarma! Monitor de ping a IP"
#Configurar la IP a monitorear
:local addre 192.168.88.1;
#Configurar el Delay maximo tolerado
:local ms 200;
:local avgRtt;
/tool flood-ping $addre count=10 do={
  :if ($sent = 10) do={
    :set avgRtt $"avg-rtt"
}}
:if ($avgRtt &gt;= $ms) do={
#Send mail
/tool e-mail send server=&lt;Server IP&gt; port=25 user=&lt;user&gt; password=&lt;pass&gt; to=to@mail.com from=from@mail.com subject=$Asunto body=("Monitoreando IP:$addre\ndelay:$avgRtt ms")
:log err "La alarma ha sido enviada.";
}

Atencion, configurar las siguientes variables para que funcione correctamente el script:

:local addre 192.168.88.1; —- Aqui setear la direccion IP a la que queremos monitorear.

:local ms 200; ———- Aqui los ms. Solo cambiar el nro 200 por el valor deseado.

Email Settings: ———– No Olvides configurar server, port, user, password, to y from.
________
Primero en tech-nico.com

API MIKROTIK – Eliminar una dirección del firewall address-list

Te interesa saber como agregar una direccion IP a una lista?.

Exactamente hace 1 año atrás, el armamos un ejemplo para agregar una direccion IP una lista determinada del firewall; pero nunca dijimos como eliminarla y por eso aquí esta la solución.

Aquí va el código de como hacerlo:

Requisito: Descargar la librería api_mt_include2.php (podes hacerlo en uno de nuestros primeros ejemplos)

<?php require_once('api_mt_include2.php'); ?>
<?php
/*
/// AUTOR: Tech-Nico.com ///
/// admin@tech-nico.com /////
/// API: Firewall Address-list: Elimino una direccion IP a un address-list
/// Fecha: 10/08/2016 
  
//////// configura tus datos
$ServerList ="192.168.100.1"; //ip_de_tu_API
$Username ="api"; //usuario_API
$Pass ="#pass"; //contraseña_API
$Port ="8727"; //puerto_API
*/
/// VARIABLES DE FORMULARIO
$address= "5.4.3.1";  // direccion que borraremos en el address-list
$list=    "FACEBOOK";  // nombre de la lista  que borraremos 
if( $address !="" && $list!=""  ){
    $API = new routeros_api();
    $API->debug = false;
    if ($API->connect($ServerList, $Username, $Pass, $Port)) {
       $API->write("/ip/firewall/address-list/getall",false);
       $API->write('?address='.$address,false);
       $API->write('?list='.$list,true);       
       $READ = $API->read(false);
       $ARRAY = $API->parse_response($READ); // busco si ya existe
        if(count($ARRAY)>0){ 
            $ID = $ARRAY[0]['.id'];
            $API->write('/ip/firewall/address-list/remove', false);
            $API->write('=.id='.$ID, true);
       		$READ = $API->read(false);
        }else{ // si no existe lo creo
            echo 'La IP "'.$address.'" No existe en el address-list "' . $list .'" del firewall L3, no se hará nada!';
        }
        $API->disconnect();
    }
}
?>              

Primero en tech-nico.com: Por favor, pongan la fuente si van a copiar y pegar en otro sitio.!!.

Script Mikrotik para LIMITAR dispositivos móviles con DHCP con QUEUEs Dinamicas

Bloquear / Limitar

En las 3 versiones anteriores de este script podiamos «bloquear» un dispositivo movil tanto por DHCP como en el firewall del Bridge (capa 2) y en firewall capa 3.

Tal vez te interesen los scripts anteriores:
Version 1: Filtrar en Bridge Filter
Version 2: Filtrar en Firewall Filter
Version 3: Filtrar con DHCP Block

Ahora con una mínima modificación podemos controlarles el ancho de banda a cada uno de ellos. En este caso el script permite setear el RATE-LIMIT en una variable para todos los dispositivos.

########## INICIO DEL SCRIPT
:local DHCPSERVER "dhcp1";
:local LIMITE "256k";
# # www.tech-nico.com 
 
:foreach i in=[/ip dhcp-server lease find active-server=$DHCPSERVER] do={
log warning "Hola";
    :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 set $i block-access=no  rate-limit="$LIMITE" insert-queue-before=first  mac-address="$DhcpDynMAC" use-src-mac=yes comment="$DhcpDynHOST" server="$DHCPSERVER" client-id="$DhcpDynCLIENTID";
    }
}
############## FIN DEL SCRIPT

La forma de limitar del script (sincronizando con queues) es como lo hacen algunos servidores radius.

El script recorre la lista de Leases DHCP y busca los dispositivos que comienzan con Host_name «iPad», «andr», etc. Luego lo edita, agregandole el limite de velocidad. Esto instantaneamente agrega un Queue dinamico en la lista de queues, controlando asi en el acto a cada Lease. Si el lease caduca, el queue se elimina solo, y si el lease por alguna razon renueva con otra direccion IP, tambien lo hace el queue de manera sincronizada. Es tal y como lo manejan los Servidores Radius.

Espero que lo disfruten de estas utilidades tan sencillas pero al mismo tiempo tan brillantes.

A pedido de Leonardo Jung. (excelente idea).

Saludos.

[Actualizado] Script Mikrotik para bloquear dispositivos móviles en bridge – Muy Efectivo!

Bloqueando Celulares desde Mikrotik con Bridge filter (Efectividad 80%)

NOTA: Esta es la version para filtrar por bridge, tambien podes filtrar en firewall o bloquear directamente en dhcp-server.

Me toco en un colegio tener que dejar sin navegación a los celulares. En este caso opte por armar un script que recorra la lista de Leases del DHCP Server y filtre a los hosts llamados «Android» o «Windows Phone», «Blackberry». Con lo cual podríamos estar filtrando la mayoría de los dispositivos. Creo que se van a escapar los teléfonos chinos que suelen venir con sistemas operativos bastante raros. Tambien se estan escapando los celulares con SO  de Apple (no lo pude setear porque no se cual es su Host Name). Pero bueno, no queremos llegar a la perfección.. al menos con esto he quitado de circulación unos 50 dispositivos en el primer dia. No solo me ha bajado el consumo del CPU del RB 2011 si no que ademas ha mejorado mucho el rendimiento del ancho de banda ya que los celulares están todo el tiempo bajando actualizaciones, hasta incluso estando en el bolsillo del pantalón.

¿Como los bloqueamos?

Cuando abrimos la lista de Leases en «IP — DHCP-Server» veremos un listado de todas las IP dinamicas entregadas en la red. Uno de los campos es «HOST-NAME». Ese es el que nos interesa. Vean la imagen:

leases cossettini

Lista de nombres de mobiles a filtrar:  (que yo detecte y filtre) (AMPLIAREMOS)

  • android-8d0a00d6eddf7787
  • Android_356434048181508
  • Windows-Phone
  • BLACKBERRY-8A8D
  •  (nombre en blanco)

Entonces esto es lo que vamos a usar para detectarlos.
El primero y segundo, «android, Android» estan porque con mikrotik scripting no encontré un comando para hacer Upper o Lower Case de los caracteres. BLACKBERRY me aparece 2 veces en mayusculas (en otro router) asi que por ahora lo mantendremos asi. Y buscando en los mac-address vendors pude descubrir que muchos de los dispositivos celulares que vienen con el Host-Name en blanco son Samsung, Nokia, etc. Por lo que opte por dropearlos y cuando mucho, si es una laptop… «que le ponga el nombre de equipo». jeje.

Vamos a lo nuestro:
Para que el script funcione, debemos configurarle el nombre de nuestro DHCP-Server y ademas el nombre del Bridge en el cual vamos a filtrar (Son las primeras 2 variables). Esta parte es interesante porque si tambien es tu caso, puede ser que en el mismo equipo tengas mas de un DHCP Server o mas de 1 bridge, (uno para directivos y otro para alumnos). Por lo tanto, si esto no seria seteable, estaríamos quitándote navegación a TODOS, y no queremos que los directivos se enojen porque no pueden revisar el facebook en su android. :D.

# # SCRIPT: FILTRAR CELULARES EN BRIDGE

:local DHCPSERVER "dhcp_alumnos";
:local BRIDGEFILTER "bridge-alumnos";

# # AUTOR: NICOLAS DAITSCH
# # www.tech-nico.com

:foreach i in=[/ip dhcp-server lease find dynamic=yes active-server=$DHCPSERVER]  do={
   :local DhcpDynIP [/ip dhcp-server lease get $i address];
   :local DhcpDynMAC [/ip dhcp-server lease get $i mac-address];
   :local DhcpDynHOST [/ip dhcp-server lease get $i host-name];
   :local IfMacExist [/interface bridge filter find src-mac-address="$DhcpDynMAC/FF:FF:FF:FF:FF:FF"];
   :local phoneNAME [:pick $DhcpDynHOST 0 4];

:if ( ($phoneNAME="iPad") || ($phoneNAME="S410") || ($phoneNAME="Andr") || ($phoneNAME="LANI") || ($phoneNAME="Ipho") || ($phoneNAME="S220") || ($phoneNAME="S120") || ($phoneNAME="BLUS") || ($phoneNAME="iPod") || ($phoneNAME="andr") || ($phoneNAME="Wind") || ($phoneNAME="iPho") || ($phoneNAME="BLAC") || ([:len $DhcpDynHOST]=0) ) do={
          :if ($IfMacExist != "") do={
#               :log error ("Filtrando telefono... ".$DhcpDynMAC. " Ya existe")
          } else= {
               /interface bridge filter add action=drop chain=input in-bridge=$BRIDGEFILTER src-mac-address="$DhcpDynMAC/FF:FF:FF:FF:FF:FF" comment=$DhcpDynHOST;
                 :log warning ("Se filtro un nuevo dispositivo " . $phoneNAME . " MAC: " .  $DhcpDynMAC);
          }
     }
}

Muy bien el script recoje los mac-adddress de este listado (leases), y si coinciden con alguno de los nombres que dijimos, se filtra automáticamente sin retorno.
Y digo sin retorno porque si ya lo filtro, por mas que cambie el hostname YA ESTA!!!.
Lo bueno de este script es que estamos filtrando por MAC-Address en el Bridge, cosa que resulta MUY Efectiva.

La linea que dice:

($phoneNAME="androi") || ($phoneNAME="Window")

Esta tomando los primeros 6 caracteres del hostname. Entonces podríamos seguir agregando nombres de dispositivos seteados de fabrica con un nombre por default. Ejemplo: «Iphone»   —  justo 6.  Que yo estimo, «rara vez se modifica».

ATENTOS: Si alguien sabe como aparece el hostname del IPhone u algun otro dispositivo que no este contemplado, por favor deje un comentario y vamos actualizando el script.

Frecuencia de ejecucion del script y leases dhcp:
Lo tengo seteado en el Scheduler cada 10 minutos, Cosa que por mas que el «Lease dhcp» quede activo, ese dispositivo ya no navega. Lo que pueden hacer es setear los Leases del DHCP en 10 minutos (menos tiempo), o bien agregarle al script que tambien patee el lease. Pero ya no es necesario… cuando caduca su tiempo, ya no vuelve a aparecer mas.

Saludos! ! ! .

________________________
Este post se escribio primero en Tech-nico.com

Script Mikrotik para hacer parpadear un led del router.

Vos dirás.. y para que lo quiero?. Tal como dice el creador del script (foro Mikrotik) podría servir para señalar remotamente (al tecnico in-situ) cual es el equipo que tiene que supervisar. Lo acabo de probar y me anduvo bien. Es una pabada, pero a mi me encantó. 🙂

Importar por consola

add name=ParpadearLed policy=read,write,policy,test,sensitive source="# CONFIGURAR CANTIDAD DE PARPADEOS\r\
\n:local count 10\r\
\n# SETEAR EL LED QUE QUREMOS MANEJAR a) wlan-led b) led1 c) user-led\r\
\n:local led led1\r\
\n# NO EDITAR DE ACA PARA ABAJO\r\
\n:local numb 0\r\
\n:local test [ /system leds find leds~\"\$led\" ]\r\
\n:if (\$test = \"\") do={ /system leds add leds=\$led type=on }\r\
\n:local test2 [ /system leds find leds~\"\$led\" ]\r\
\n:local state [ /system leds get value-name=type number=\$test2 ]\r\
\n:while (\$numb &lt; \$count) do={\r\
\n :set \$numb (\$numb + 1)\r\
\n /system leds set numbers=\$test2 type=on\r\
\n :delay 0.5\r\
\n /system leds set numbers=\$test2 type=off\r\
\n :delay 0.5\r\
\n}\r\
\n/system leds set type=\$state numbers=\$test2"

Script Mikrotik para bloquear dispositivos moviles en Firewall

Bloqueando Celulares desde Mikrotik con Firewall (Efectividad 80%)

NOTA: Esta es la version para filtrar por firewall, tambien podes filtrar en bridge filter o bloquear directamente en dhcp-server.

Me toco en un colegio tener que dejar sin navegación a los celulares. En este caso opte por armar un script que recorra la lista de Leases del DHCP Server y filtre a los hosts llamados «Android» o «Windows Phone», «Blackberry». Con lo cual podríamos estar filtrando la mayoría de los dispositivos. Creo que se van a escapar los teléfonos chinos que suelen venir con sistemas operativos bastante raros. Con esto he quitado de circulación unos 50 dispositivos en el primer dia. No solo me ha bajado el consumo del CPU del RB 2011 si no que ademas ha mejorado mucho el rendimiento del ancho de banda ya que los celulares están todo el tiempo bajando actualizaciones, hasta incluso estando en el bolsillo del pantalón. Quizas te interese saber como bloquear las actualizaciones de android.

¿Como los bloqueamos?

Cuando abrimos la lista de Leases en «IP — DHCP-Server» veremos un listado de todas las IP dinamicas entregadas en la red. Uno de los campos es «HOST-NAME». Ese es el que nos interesa. Vean la imagen:

leases cossettini

Lista de nombres de mobiles a filtrar:  (que yo detecte y filtre) (AMPLIAREMOS)

  • android-8d0a00d6eddf7787
  • Android_356434048181508
  • Windows-Phone
  • BLACKBERRY-8A8D
  •  (nombre en blanco)

Entonces esto es lo que vamos a usar para detectarlos.
El primero y segundo, «android, Android» estan porque con mikrotik scripting no encontré un comando para hacer Upper o Lower Case de los caracteres. BLACKBERRY me aparece 2 veces en mayusculas (en otro router) asi que por ahora lo mantendremos asi. Y buscando en los mac-address vendors pude descubrir que muchos de los dispositivos celulares que vienen con el Host-Name en blanco son Samsung, Nokia, etc. Por lo que opte por dropearlos y cuando mucho, si es una laptop… «que le ponga el nombre de equipo». jeje.

Vamos a lo nuestro:
Para que el script funcione, debemos configurarle el nombre de nuestro DHCP-Server y ademas el nombre de la interfaz de tu LAN en el cual vamos a filtrar (Son las primeras 2 variables). Esta parte es interesante porque si tambien es tu caso, puede ser que en el mismo equipo tengas mas de un DHCP Server o mas de 1 LAN, (una red para directivos y otro para alumnos). Por lo tanto, si esto no seria seteable, estaríamos quitándote navegación a TODOS, y no queremos que los directivos se enojen porque no pueden revisar el facebook en su android. :D.

Muy bien el script recoje los mac-adddress de este listado (leases), y si coinciden con alguno de los nombres que dijimos, se filtra automáticamente sin retorno.
Y digo sin retorno porque si ya lo filtro, por mas que cambie el hostname YA ESTA!!!.
Lo bueno de este script es que estamos filtrando por MAC-Address en el Bridge, cosa que resulta MUY Efectiva.

La linea que dice:

($phoneNAME="androi") || ($phoneNAME="Window")

Esta tomando los primeros 6 caracteres del hostname. Entonces podríamos seguir agregando nombres de dispositivos seteados de fabrica con un nombre por default. Ejemplo: «Iphone»   —  justo 6.  Que yo estimo, «rara vez se modifica»..

Frecuencia de ejecucion del script y leases dhcp:
Lo tengo seteado en el Scheduler cada 10 minutos, Cosa que por mas que el «Lease dhcp» quede activo, ese dispositivo ya no navega. Lo que pueden hacer es setear los Leases del DHCP en 10 minutos (menos tiempo), o bien agregarle al script que tambien patee el lease. Pero ya no es necesario… cuando caduca su tiempo, ya no vuelve a aparecer mas.

# # SCRIPT: FILTRAR CELULARES EN FIREWALL (SIN BRIDGE)

:local DHCPSERVER "dhcp_alumnos";
:local INTERFACEFILTER "bridge-alumnos";

# # AUTOR: NICOLAS DAITSCH
# # www.tech-nico.com

:foreach i in=[/ip dhcp-server lease find dynamic=yes active-server=$DHCPSERVER]  do={
   :local DhcpDynIP [/ip dhcp-server lease get $i address];
   :local DhcpDynMAC [/ip dhcp-server lease get $i mac-address];
   :local DhcpDynHOST [/ip dhcp-server lease get $i host-name];
   :local IfMacExist [/ip firewall filter find src-mac-address="$DhcpDynMAC"];
   :local phoneNAME [:pick $DhcpDynHOST 0 6];

    :if ( ($phoneNAME="androi") || ($phoneNAME="Window") || ($phoneNAME="Androi")  || ($phoneNAME="BLACKB") || ([:len $DhcpDynHOST]=0) ) do={
          :if ($IfMacExist != "") do={
#               :log error ("Filtrando telefono... ".$DhcpDynMAC. " Ya existe")
          } else= {
               /ip firewall filter add action=drop chain=input in-interface=$INTERFACEFILTER src-mac-address="$DhcpDynMAC" comment=$DhcpDynHOST;
                 :log warning ("Se filtro un nuevo dispositivo " . $phoneNAME . " MAC: " .  $DhcpDynMAC);
          }
     }
}

Saludos! ! ! .

________________________
Este post se escribio primero en Tech-nico.com

Script Mikrotik para bloquear dispositivos móviles con DHCP

El script nacio por un comentario de nuestro colaborador «Felix Serrato» que NO vio la necesidad de bloquear los dispositivos celulares usando firewall o bridge filter. Es decir, bloquearlos directamente en los «leases» del dhcp-server y ademas que el board Mikrotik utilice menos recursos (si es que hay muchos dispositivos para bloquear en tu red).

Efectividad: 

Si bien el script es muy efectivo, probando me encontré con la particularidad de que no bloquea al instante. Te bloquea el lease (para que, A tu mac-address ya no le pueda entregar nunca mas una direccion IP), pero al filtrar por DHCP, no te quita la navegacion hasta que tu dispositivo vuelva a pedir una nueva solicitud DHCP. Una vez que apago y enciendo el Wifi de mi celular queda en «Obteniendo una direccion IP». Sin embargo los 2 scripts mencionados al principio (por bridge y por firewall), filtran en el acto.

Funcionamiento:

El 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 1 servidor dhcp para no filtrar en todos. Busca el host-name 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 direccion IP.

Solo hay que definirle el nombre del DHCP-server.

########## INICIO DEL SCRIPT
:local DHCPSERVER "dhcp1";
# # www.tech-nico.com 

: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*"]
############## FIN DEL SCRIPT

Mikrotik Script: Marcar y controlar trafico de whatsapp por DNS

whatsappSi queremos controlar el ancho de banda de whatsapp por QoS o dropear o simplemente dejar pasar este trafico, podemos ejecutar este maravilloso script desde nuestro RouterOS, que recolecta las IP que usa esta aplicación de mensajería.

Las IP que recolecta realmente son MUCHAS!.

whatsapp_ips

 
Entonces, pegamos este codigo en la consola de comandos de routerOS y luego lo configuramos en el scheduler para que se ejecute cada 2 minutos. (o menos, dependiendo del procesador de tu equipo).
 

/system script add name=whatsapp policy=read,write,policy source="# chequear las entradas al \
    DNS\r\
    \n:foreach i in=[/ip dns cache find] do={\r\
    \n:local bNew \"true\";\r\
    \n:local cacheName [/ip dns cache all get \$i name] ;\r\
    \n# Revisar el DNS si contiene cadenas whatsapp\r\
    \n:if ([:find [/ip dns cache get \$i name] \"whatsapp\"] > 0) do={\r\
    \n:local tmpAddress [/ip dns cache get \$i address] ;\r\
    \n#---- Si address list esta vacio, no lo chequeo ( add address directly )\
    \r\
    \n:if ( [/ip firewall address-list find ] = \"\") do={\r\
    \n/ip firewall address-list add address=\$tmpAddress list=whatsapp_dns_ips\
    \_disabled=no comment=\$cacheName; \r\
    \n} else={\r\
    \n#------- chequeo cada entrada del address-list para no repetir las ips\r\
    \n:foreach j in=[/ip firewall address-list find ] do={\r\
    \n#---------- set bNew variable to false if address exists in address list\
    \r\
    \n:if ( [/ip firewall address-list get \$j address] = \$tmpAddress ) do={\
    \r\
    \n:set bNew \"false\";\r\
    \n}\r\
    \n}\r\
    \n#------- Si la direccion (IP) es nueva, la agrego al ADDRESS-LIST\r\
    \n:if ( \$bNew = \"true\" ) do={\r\
    \n/ip firewall address-list add address=\$tmpAddress list=whatsapp_dns_ips\
    \_disabled=no comment=\$cacheName; \r\
    \n}\r\
    \n}\r\
    \n}\r\
    \n}"

Script Mikrotik, mandar backup por FTP

Un usuario del foro oficial de mikrotik publico un pequeño script para enviar un backup de nuestro RouterOS por FTP. Muy bueno para automatizar nuestros routers y enviar todos los backups a una caja NAS.

/system backup save name="filename"

/tool fetch address="ftpaddress" src-path="filename.backup" \
user="ftpuser" mode=ftp password="ftppassword" \
dst-path="Path of your ftp(/Mt-Backup/filename.backup)<--example" upload=yes

delay 10;
/file remove filename.backup

_________
publicado en tech-nico.com

API MIKROTIK – Crear queues simples con PHP (con validacion)

Hola señores, el codigo para agregar un Queue Simple validando que no se duplique ningún cliente seria asi:

ACTUALIZADO: agrega un queue si no existe el nombre, y si existe, lo edita.

<?php require_once('api_mt_include2.php'); ?>
<?php

/// AUTOR: Tech-Nico.com ///
/// admin@tech-nico.com /////
///  API: agrega un queue simple y si este existe lo edita.
/// Editado: 03/05/2015 

//////// configura tus datos
$ServerList ="192.168.100.1"; //ip_de_tu_API
$Username ="api"; //usuario_API
$Pass ="#pass"; //contraseña_API
$Port ="8727"; //puerto_API
/// VARIABLES DE FORMULARIO
$target= "192.168.0.5";  // IP Cliente
$name=    "nicolas222";
$maxlimit=    "5M/5M";
$comment= "Este es un ejemplo.";
if( $target !="" ){
    $API = new routeros_api();
    $API->debug = false;
    if ($API->connect($ServerList, $Username, $Pass, $Port)) {
       $API->write("/queue/simple/getall",false);
       $API->write('?name='.$name,true);
       $READ = $API->read(false);
       $ARRAY = $API->parse_response($READ);
        if(count($ARRAY)>0){ // si el nombre de usuario "ya existe" lo edito
			$API->write("/queue/simple/set",false);
			$API->write("=.id=".$ARRAY[0]['.id'],false);
            $API->write('=max-limit='.$maxlimit,true);   //   2M/2M   [TX/RX]
			$READ = $API->read(false);
			$ARRAY = $API->parse_response($READ);
            echo "Error: El nombre no puede estar duplicado, el queue fue editado.";
            echo '<img src="../images/icon_error.png" />';
        }else{
            $API->write("/queue/simple/add",false);
            $API->write('=target='.$target,false);   // IP
            $API->write('=name='.$name,false);       // nombre
            $API->write('=max-limit='.$maxlimit,false);   //   2M/2M   [TX/RX]
            $API->write('=comment='.$comment,true);         // comentario
            $READ = $API->read(false);
            $ARRAY = $API->parse_response($READ);
            echo "El Usuario $name, ha sido creado con exito!.";
            echo '<img src="../images/okicon.png" />';
        }
        $API->disconnect();
    }
}
?>

Descargar el Descargar_ejemplo_actualizado_03-05-2015

No hay mucho que explicar porque esta comentado el codigo y explicado en los post anteriores.

API MIKROTIK – Como optimizar tu administracion con un poco de PHP (introduccion)

API MIKROTIK Segunda parte – Usando el API con PHP

API MIKROTIK Tercera parte – Nuestro primer ejemplo (codigo abierto)

_________________
Nicolas
Primero en Tech-nico.com

Mikrotik bloquear actualizaciones de Android en firewall

Estoy implementando algunas reglas para mejorar el ancho de banda de un colegio. Esta me parece una muy buena practica. Aquí la dejamos anotada por si acaso.

Ir a la consola y ejecutar esto.

/ip firewall filter add action=drop chain=forward port=5228 protocol=tcp
/ip firewall filter add action=drop chain=forward port=5228 protocol=udp

Luego, si sos tan amable, arrastra las reglas para arriba de tu firewall y tener la seguridad de que se ejecuten.
_______________________
Este post se publico primero en Tech-nico.com

Script Mikrotik para patear un cliente registrado con mala señal

Hola amigos, bueno, este script no es muy nuevo que digamos. Pero lo voy a postear porque le hice un agregado para mi gusto bastante importante.
En este caso, se trata de un routerboard 2011 con Wifi, y va a instalarse en un colegio. Como hay muchos celulares y netbooks, la clave del funcionamiento esta en patear cada 1 minuto los clientes que tienen muy mala señal. Y ademas, dentro del mismo script, tambien eliminaremos el «lease» del DHCP-Server.

Esto sirve para darle mucho mas rendimiento al AP, ya que si hay muchos dispositivos (celulares, tablets, netebooks de «conectar igualdad») con baja señal, el radio tiene que manejar demasiadas peticiones con re-transmicion de paquetes y llegado a un punto hasta se puede plantar.

Veran que donde dice «-86» es el tope de señal que yo configure para cuando el cliente este conectado con -87 o mas… lo saque de circulación. Ustedes pueden setear el que mas les guste.

/system script
add name=station-check-signal policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive source="/interfac\
    e wireless registration-table;\r\
    \n:foreach i in=[ /interface wireless registration-table find ap=no] do={\r\
    \n   :local SIGNAL ([:pick ([get \$i signal-strength]) 0 3]);\r\
    \n   :if (\$SIGNAL < \"-86\") do={\r\
    \n           :local MAC [get \$i mac-address];\r\
    \n           :log warning (\$MAC . \" fue desconectado por baja se\F1al:  \"\
    \_.\$SIGNAL );\r\
    \n           /interface wireless registration-table remove \$i;\r\
    \n# PATEO EL DHCP DEL CLIENTE CON MALA SE\D1AL\r\
    \n          /ip dhcp-server lease;\r\
    \n           :foreach s in=[find] do={\r\
    \n                  /ip dhcp-server lease;\r\
    \n                   :if ([get \$s active-mac-address] = \$MAC) do={\r\
    \n                           :log warning (\"DHCP pateado por script de mala\
    \_se\F1al:  \" .\$MAC );\r\
    \n                           /ip dhcp-server lease remove \$s;\r\
    \n                   }\r\
    \n           }\r\
    \n           :delay 5s;\r\
    \n     }\r\
    \n}"

Solución al script de DuckDNS en Mikrotik RouterOS

Cuando quisiste usar DuckDNS.org en tu RouterOS tuviste problemas con la instalación?. Bueno a mi me paso que el script «corría»  pero no me devolvía nunca el resultado deseado (mas claro: NO ANDABA). Depurando linea por linea me di cuenta que el problema no era el script si no la vesion de mi RouterOS.

¿para que uso DuckDNS?
Para el que no lo conoce, se usa para cuando tenes un sitio remoto con IP publica Dinamica y queres accederlo desde afuera. Tambien podes usarlo para una camara IP.
En este caso, el script del routerOS se encarga de que cuando la IP cambie… el sistema de duckDNS guarde la nueva IP. Entonces cada vez que accedas a tudominio.duckdns.org vas a entrar a tu routerOS sin problemas.

Para el que no lo usa, la instalación es super sencilla:
La instalacion del script es muy sencilla solo basta con copiar y pegar y tan solo modificar «domains» por tu dominio y el «token» por el que te de al hacer login y «agregar un dominio».

domains=exampledomain&token=a7c4d0ad-114e-40ef-ba1d-d217904a50f2

Aqui abajo el script completo:

:global currentIP;
:local newIP [/ip cloud get public-address];
:if ($newIP != $currentIP) do={
    :log info "IP address $currentIP changed to $newIP";
    :set currentIP $newIP;
    /tool fetch mode=https url="https://www.duckdns.org/update?domains=exampledomain&token=a7c4d0ad-114e-40ef-ba1d-d217904a50f2&ip=$newIP" dst-path=duckdns.txt;
    :local result [/file get duckdns.txt contents];
    :log info "Duck DNS update result: $result";
}

Conclusión y forma de resolverlo:
RouterOS agrego el «https»del comando fetch en la version 6.0, es por eso que el script no corre. Lo unico que hay que hacer es actualizar el RouterOS a la version 6.X.

Escribir Scripts para Mikrotik con el editor Sublime Text

Ahora es mucho mas fácil poder escribir código usando el famoso editor gratuito «Sublime Text» que permite entre otras cosas el highlight de los comandos, funciones, variables, comentarios, etc., para que todo sea mas legible y eficaz.
Un ayudante del foro de Mikrotik nos hizo este gran aporte que realmente es de gran ayuda para nosotros los fanáticos.

El paquete esta disponible para instalarlo desde el administrador de paquetes de Sublime o bien descargarlo desde Github.

mikrotik sublime text

Mikrotik Script: ejecutar un script si aparece cierta palabra o frase en el Log.

En el foro de Mikrotik un participante ha posteado algo interesante!!

Creo que el titulo esta bastante claro, es un script que detecta cierto contenido en el log, y luego ejecuta «otro script».

Script:

:global lastTime;

:local currentBuf [ :toarray [ /log find message~"wrong peer state" || message~"master flag=false" ] ] ;
: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={
      :set lastTime $currentTime ;
      /system script run myScript
   }
}

ver el post completo en el foro de Mikrotik

Primero en tech-nico.com

Mikrotik Script: Buscar en PPP las IP libres no asignadas en una Clase C

Bueno, este es un script muy rebuscado que arme para listar las IP Libres de un /24. Es muy util ya que hay escasos bloques IPv4. En mi caso doy pppoe con IP fija, entonces es muy facil a veces (por error) saltearnos alguna IP y quede en desuso.

Antes de ejecutarlo hay que editar una variable que contiene nuestro rango de IP a buscar.

:global BUSCA "210.100.200";
/ip firewall address-list remove [/ip firewall address-list find list="pool_ip_libres"];
:for i from= 1 to= 254 do={
:local DIREC ($BUSCA . "." . $i);
:local VAR [:put [/ppp secret find where remote-address=$DIREC]];
:if ($VAR!="") do={
:log info (" Existe " . $DIREC );
} else={
/ip firewall address-list add list=pool_ip_libres address=$DIREC;
}
}

Luego de ejecutarlo vamos a ver que se crea una nueva lista llamada «pool_ip_libres».
Cada vez que ejecutamos el script, se limpia primero esa lista para que no queden ips duplicadas.

Se puede mejorar, se aceptan modificaciones. El que modifique también comparta su versión asi ampliamos el post.

___________
Primero en Tech-nico.com
Nicolas