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

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

Mikrotik RouterOS NAT – Masquerade y Netmap

Existen varios tipos de NAT para diferentes propósitos. Todos conocemos el clásico «Masquerade«, que siempre utilizamos en los mikrotik de nuestros clientes, pero a veces trae algunos problemas extraños en la navegación que por suerte resuelve Netmap.

Además de action=masquerade también existe action=netmap. Los dos son muy similares entre si (hay una linea muy delgada entre uno y otro).

Tipos de NAT a grandes rasgos

  • Masquerade traduce desde 1 sola dirección publica, y permite un WAN con direcciones dinámicas. (también conocida como NAT dinámica).
  • Src-nat traduce de 1 a muchos. (Nat conocido para cuando hacemos port forwarding).
  • Netmap mapea de 1 a 1 Publica:Privada. (Conocida como NAT estatica).

Uno de los usos posibles NETMAP:

En mi escenario, mi proveedor superior routeaba las direcciones públicas a través de un punto a punto privado /29. De esta manera en tu WAN vas a tener una dirección IP Privada, y tu GW también va a ser privado. Entonces para poder tener salida con origen publico (hacia afuera), hay que configurar el GW público de tus abonados en una interfaz Privada. Los ISP que hacen esto realmente piensan en no desperdiciarnos ninguna dirección IP pública.

NOTA: Si el origen de la salida sería privado, muchos proveedores superiores que utilizan BGP, filtran el origen de tráfico en rangos privados.

Algunos ISP que han tenido que NATEAR en el escenario anterior (utilizando action=masquerade simplemente no funciona) lo que hacen es resolverlo agregar otro equipo Mikrotik dedicado al NATEO. Entonces de esa manera, le otorgan una dirección pública al equipo que dedican exclusivamente para NAT utilizando el clasico action masquerade.

Aquí es donde entra en acción NETMAP.

/ip firewall nat add action=netmap chain=srcnat comment="CGNAT rule" out-interface-list=WAN ipsec-policy=out,none src-address-list=nateados to-addresses=public/32

En Este ejemplo, esta habilitado ipsec passthrough para evitar problemas con servicios P2P, VPNs, Juegos (Xbox) etc.

Incluso en to-addresses podes setear por que dirección IP queres que se Nateen.

Para el que quiera profundizar les dejo este enlace que me gustó mucho:

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

Port Forwarding VPN L2TP con Mikrotik

La semana pasada instale un rack para fibra al hogar en Rolon – La Pampa, y me encontre con la particularidad de que el carreir entrega una sola direccion IP Publica, para lo cual tuve que hacer Port Forwarding de la VPN.

Hace mucho tiempo que no escribo y no por que no quiera, siempre es por cuestiones de tiempo. Me siento obligado a tener que postearlo porque la proxima vez que lo necesite se que ademas de compartirlo con los demas, me lo estoy compartiendo conmigo mismo.

En este caso se trata de un Router de Border que presta el servicio de acceso a internet los clientes de fibra al hogar. (es decir que actua como router haciendo NAT, entre otras cosas). Y detras de este, otro router haciendo de VPN. Con lo cual tenemos encadenados un router detras de otro.

Escenario actual, de doble NAT (de Izquierda a Derecha)

Este tipo de setup tiene 1 inconveniente:

Antes de seguir con la configuracion, es fundamental que aclaremos que el estar haciendo hairpinin (o forwarding) de una VPN hace que el origen que ve tu VPN Server es siempre el primer equipo, en este caso el de Border (ver imagen superior). Es decir que si hay un usuario con una VPN activa, otra VPN no deberia poder conectarse, o hasta incluso puede suceder que se caiga el tunel existente y entre el nuevo. Para mitigar este problema pueden probar desactivar el tilde «One session per host» en tu configuracion de VPN Server. En mi caso L2TP Server. No es la mejor de las soluciones pero puede funcionar.

Reglas de NAT para el primer NAT: Border.

add action=dst-nat chain=dstnat comment="VPN L2TP Forwarding" dst-address=[TU IP PUBLICA] dst-port=4500 protocol=udp to-addresses=\
192.168.77.2 to-ports=4500
add action=dst-nat chain=dstnat dst-address=[TU IP PUBLICA] dst-port=1701 protocol=udp to-addresses=192.168.77.2 to-ports=1701
add action=dst-nat chain=dstnat dst-address=[TU IP PUBLICA] dst-port=500 protocol=udp to-addresses=192.168.77.2 to-ports=500
add action=dst-nat chain=dstnat dst-address=[TU IP PUBLICA] dst-port=2218 protocol=tcp to-addresses=192.168.77.2 to-ports=2218
add action=dst-nat chain=dstnat dst-address=[TU IP PUBLICA] protocol=ipsec-esp to-addresses=192.168.77.2

Luego reemplacen [TU IP PUBLICA] por la direccion IP publica que usan para navegar a través de NAT. Y reemplazar 192.168.77.2 por el direccionamiento IP interna que le dieron al equipo que haga de VPN. Se supone que la regla de Masqarade del Pool de IP de los abonados deberia estar puesta si tenes este mismo escenario. (no esta entre estas reglas)

Reglas para el segundo NAT, VPN Server

add action=masquerade chain=srcnat comment="default configuration" src-address=192.168.77.1

Misma aclaracion que anteriormente, siempre que el equipo este en modo router aqui se agrega la regla de masqarede para el pool de IP que usemos en el bridge o LAN. (En este caso no esta).

Realmente desearia poder postear mas seguido, tengo algunas cosas en mi lista, como Domotica, Automatizaciones en casa, Algo de programacion con WordPress, algo de monitoreo con ubiquiti, Etc.
Ahora que estamos en cuarentena deberia poder organizarme y lograr subir algun video.

Mis saludos a todos los hispanos!!.

_____
Primero en tech-nico.com

Winbox en MacOS Catalina (con Wine)

Si actualizaste a la version Catalina (como yo), seguramente te quedaste sin Wine (la aplicacion que emula y ejecuta archivos .exe de windows) para ejecutar winbox.exe.

En Catalina ya no se puede ejecutar aplicaciones de 32 bits, pero podes ejecutarlas todavia en 64.

Descargas winbox64 desde la web oficial de Mikrotik: https://mt.lv/winbox64

En mi caso lo que hice fue:

brew cask install xquartz 
brew cask install wine-stable

Luego para poder ejecutarlo cada vez que encendemos la maquina apuntamos las rutas de wine con variables de entorno:

chsh -s /bin/zsh 
sudo vi ~/.zprofile 

Y le pegamos las rutas:

export PATH="/Applications/Wine Stable.app/Contents/Resources/wine/bin:$PATH"

export FREETYPE_PROPERTIES="truetype:interpreter-version=35"

export DYLD_FALLBACK_LIBRARY_PATH="/usr/lib:/opt/X11/lib:$DYLD_FALLBACK_LIBRARY_PATH"

Para abrir ejecutamos:

wine64 /Applications/winbox64.exe

Finalmente si queremos ejecutarlo desde el escritorio con un acceso directo, abrimos Automator, Utilities, Run AppleScript, pegamos lo siguiente y luego lo exportamos a escritorio.

export PATH="/Applications/Wine Stable.app/Contents/Resources/wine/bin:$PATH"
export FREETYPE_PROPERTIES="truetype:interpreter-version=35"
wine64 /Applications/winbox64.exe

Saludos

Mikrotik [tip] Ojo con los Backups y las mac-address!

No es nada bueno, pero tiene solución:

Si por alguna razón estas configurando tus equipos routerboard, puede que en algún punto necesites acelerar el proceso de configuración y decidas crear un backup de uno de los equipos para luego restaurarlo en el resto de los los routerboard que vayas utilizando. El problema oculto sobre esto es que «Te clona los MAC-Address del primer equipo al que le hiciste el backup». Y eso para equipos que pertenecen al mismo segmento de red, créeme que no es nada bueno.

Ya me había pasado antes que me aparecía eventualmente un mensaje en los logs que decia algo como: received packet with own address as source address. Y por supuesto, tal y como siempre sucede, «En el momento del problema, nunca aparece la solución».

Hace una semana, arme un PHP para poder serializar la configuración de muchos routerboard. Mi problema puntual: No conectaba el VPLS y ademas, volvió este bendito error en el log.

Leyendo en forum.mikrotik.com encontré que la solución es resetear los mac-address a su dirección original. Asi que recuerda!! cada vez que restaures un Backup, ejecuta este comando.

/interface ethernet reset-mac-address 0,1,2,3,4,5,6,7,8,9,10

En este caso, es un RB2011 el cual trae 11 interfaces, 10 ethernet y 1 sfp. Por eso va del 0 al 10. Por ejemplo en un RB 750 (5 ethernet) el comando seria asi:

/interface ethernet reset-mac-address 0,1,2,3,4

Enjoy!!.

solucionar DNS_PROBE_FINISHED_NO_INTERNET

Para resolver este «fucking problem» tenemos que ejecutar unos comandos en la consola con privilegios de administradores;

ALTERNATIVA (A): escribir los comandos manualmente.

Paso 1 ) suponiendo que tenemos windows 7 u 8 vamos a inicio, y en el cuadro de busqueda escribimos «cmd». Luego en los resultados hacemos click derecho y elegimos «ejecutar como administrador«.

 

Paso 2) escribimos: ipconfig /flushdns (y presionamos enter)

Paso 3) escribimos: netsh winsock reset (y presionamos enter)

Paso 4) reiniciamos la PC y cruzamos los dedos.

PASOS ADICIONALES (OPCIONAL por si no funciona lo anterior)

Paso a) escribimos: ipconfig /release (y presionamos enter)

Paso b) escribimos: ipconfig /renew (y presionamos enter)

EDITADO (09/09/2015):
Agrego este video que alguien ha hecho siguiendo mi tutorial. OJO: en el video hay menos pasos y falta el paso 1 «ejecutar como administrador».

ALTERNATIVA (B): Crear y ejecutar un script:

En escritorio, creamos un nuevo Documento de texto en Notepad. Y luego pegamos esto en su interior:

@echo off
cls

echo "limpiando la tabla de dns local..."
ipconfig /flushdns
ping -n 4 localhost > null 

echo "reseteando winsock..."
netsh winsock reset
echo "Reinicie sistema AHORA!!!!......."
pause

Guardamos el archivo, luego cerramos el Notepad y le cambiamos la extencion «.txt» por «.bat». Finalmente, click derecho ejecutar como administrador.

Espero que les sirva tanto como a mi, que perdi 4 valiosas horas de mi vida hasta que logre que funcione.
____________________
Publicado por Nicolas
Primero en www.tech-nico.com

Como bootear tus antiguas aplicaciones para Ms-DOS en CD o USB «Bien Facil»

En este paso a paso, vamos a ver como crear un disco booteable en CD para levantar tu viejo sistema hecho para correr en DOS.

Tendremos el beneficio de que emularemos el floppy disk «driver A» por medio del BIOS (unidad 0). Utilizaremos un software que se llama BCD/BFD con el agregado de algunos driver de CDROOM para que permita ademas bootear en dispositivos SCSCI.

Paso 1, descomprimimos esto (descargar).

Paso 2, pegamos los archivos y/o carpetas de nuestro viejo software en la ruta: tech-nico_boot\cds\cdromsi\files\

Paso 3, vamos a la consola de windows. —- Inicio – Ejecutar – cmd

Paso 4, nos movemos con «cd» a la carpeta «tech-nico_boot»

command

Paso 5, Ejecutamos el comando «bcd cdromsi»

Paso 6, si queremos grabar el ISO en un CD presionamos «Enter» y ponemos un CD en blanco (el mismo software se ocupa de grabarlo), y si no lo queremos quemar en CD y solo nos interesa el ISO, miramos cual es la ruta del ISO y lo buscamos antes de presionar cualquier tecla, ya que al presionar «A-abort» nos elimina el ISO.

iso_path

Ya tenemos nuestro disco listo para bootear. Facil no?.
Con el ISO podriamos crear un USB boot. (No lo probe pero deberia funcionar).

Como tip adicional. Si queremos que se auto ejecute un exe o bat al iniciar el CD tenemos que editar el archivo tech-nico_boot\cds\cdromsi\files\autorun.bat

Fuente: http://www.nu2.nu/

Este post se publico primero en tech-nico.com

Template Cacti AirOS 5.5 para cacti version: 0.8.7g (hash version)

Para los que no lo saben, en el firmware 5.5 de ubiquiti dejaron de funcionar los graficos del Cacti. Por suerte un colaborador del foro oficial forum.ubnt.com publico un template que funciona de maravillas.

El unico inconveniente que se presenta al importar el archivo cacti_host_template_airos-ubnt_5_5.xml en el panel de control de cacti es que arroja el error:

Error: XML: Hash version does not exist

Este error es porque dentro del archivo xml tiene un tag llamado hash, que se forma con la version de cacti y unos numeros aleatorios. Por lo tanto si tu version no coincide con la del hash, arroja el error de arriba.

ejemplo: hash_0200248f0dcc6cc49fee26220bfeb7ae781802

0024 es la version de Cacti, que si miramos en la siguiente tabla de versiones corresponde a la 0.8.8 o 0.8.8a

"0.8.4"  => "0000",
"0.8.5"  => "0001",
"0.8.5a" => "0002",
"0.8.6"  => "0003",
"0.8.6a" => "0004",
"0.8.6b" => "0005",
"0.8.6c" => "0006",
"0.8.6d" => "0007",
"0.8.6e" => "0008",
"0.8.6f" => "0009",
"0.8.6g" => "0010",
"0.8.6h" => "0011",
"0.8.6i" => "0012",
"0.8.6j" => "0013",
"0.8.7"  => "0014",
"0.8.7a" => "0015",
"0.8.7b" => "0016",
"0.8.7c" => "0017",
"0.8.7d" => "0018",
"0.8.7e" => "0019",
"0.8.7f" => "0020",
"0.8.7g" => "0021",
"0.8.7h" => "0022",
"0.8.7i" => "0023",
"0.8.8"  => "0024",
"0.8.8a" => "0024"

En mi caso tengo la version 0.8.7g. Por lo tanto tendria que modificar el 24 por 21. :).
Lo que hice fue usar Adobe Dreamweaver para buscar y reemplazar mediante una expresion regular:  (lo vamos a hacer en 2 pasos).

Paso 1:

Buscar:

(hash_)([0-9]{2})(00)(24)

y reemplazarlo con:

$1$2$3{loquequieras}21

Paso 2:

Buscar:

{loquequieras}

y reemplazarlo por NADA. (dejar vacio).

Este paso ultimo paso es necesario porque si no, dreamweaver se confunde y piensa que $3 es $321, entonces separamos $3__algo__21 con algo que quieras y finalmente quitamos ese «algo» con el paso 2.

El archivo finalmente queda asi: descargar aqui

Recuerda situar el archivo AirOS5_5.xml en la ruta:
<path_cacti>/resource/snmp_queries/AirOs5_5.xml

__________________
Nicolas
tech-nico.com

Mikrotik script para recorrer lista de secrets pppoe y reemplazar IP’s

PPPoE Secrets: Migrar de IP privada «fija» a IP publica «fija»
Algo muy puntual que tuve que hacer cuando migre de IP Privadas a IP Publicas fue mantener la terminación de las IP de los clientes PPPoE de mi Red. Se preguntarán.. para que?. Bueno en mi caso tengo un sistema de gestión que maneja el servidor usando el API mediante PHP y Mysql. Entonces me tiene que quedar sincronizadas las IP del Mysql con las del Mikrotik. Por otro lado, siempre fui de la idea de que todos los secrets tengan una IP fija asignada, ya que cuando me reportan un problema, de virus, ataque o violación de derechos de autor, puedo identificar con velocidad de quien se trata.

Ejemplo 192.168.100.8     por 201.250.45.8

Para ello, elabore un script que me recorra la lista y reemplace lo que quiero.

El Script es el siguiente:

       :local BUSCA "192.168.100";
       :local REMPL "201.250.45";
       # recorro todos los secrets
       :foreach i in=[/ppp secret find] do={
       # guardo remote IP
          :local tmpIP [/ppp secret get $i remote-address];
       # guardo la primera parte
          :local ipfirst [pick $tmpIP 0 11];
       #guardo la ultima parte
          :local iplast [pick $tmpIP 12 15];
       #busco los secrets que tienen el rango de Ip a reemplazar
            :if ($ipfirst=$BUSCA) do={
                  :log info ($REMPL .".".  $iplast);
                 /ppp secret set $i remote-address="$REMPL.$iplast"
            }
       }

Solo tienes que editar las primeras 2 variables «BUSCA» por la IP actual que vas a buscar, y «REMPL» por la IP nueva que quieres asignar a cada secret. Si tienes 4 clases C tendras que ejecutar el script 4 veces.

Para importarlo hay que copiar y pegar lo siguiente en la consola:

sys scr add name=recorro_ppp_remoteAddress policy=\
    ftp,reboot,read,write,policy,test,winbox,password,sniff,sensitive,api source=":local\
    \_BUSCA \"192.168.100\";\r\
    \n:local REMPL \"201.250.45\";\r\
    \n# recorro todos los secrets\r\
    \n:foreach i in=[/ppp secret find] do={\r\
    \n# guardo remote IP\r\
    \n   :local tmpIP [/ppp secret get \$i remote-address]; \r\
    \n# guardo la primera parte\r\
    \n   :local ipfirst [pick \$tmpIP 0 11];\r\
    \n#guardo la ultima parte\r\
    \n   :local iplast [pick \$tmpIP 12 15];\r\
    \n#busco los secrets que tienen el rango de Ip a reemplazar\r\
    \n     :if (\$ipfirst=\$BUSCA) do={ \r\
    \n           :log info (\$REMPL .\".\".  \$iplast);\r\
    \n          /ppp secret set \$i remote-address=\"\$REMPL.\$iplast\"\r\
    \n     }\r\
    \n}"

Salutes

_________
Nicolas Daitsch
tech-nico.com

Publicar Imagen de Ubiquiti Aircam en un sitio web (sin login) de manera automática

Esta webcam, mas precisamente la Aircam de Ubiquiti no tiene muchos parámetros para configurarla. Solo se acceden via login. Otras camaras tienen la opcion de desactivar el login o bien configurar un servidor FTP y publicar la imagen de la cámara cada x tiempo.
Nosotros lo que haremos es ingresarle por SSH y copiar la imagen /tmp/snap.jpeg (que es la ruta donde publica ubiquiti la imagen en vivo) dentro de nuestro sitio web de apache.

Para ello deberemos primero crear las Keys que requiere el acceso SSH.

Crear el par de claves públicas y privadas:

$ sudo ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):

Damos enter, para que las llaves se guarden en ~/.ssh

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Le ponen el password que quieran. Luego vamos a la carpeta home del usuario root o bien al home del usuario logeado y veremos 2 archivos: id_rsa e id_rsa.pub.

Publicamos la llave publica id_rsa.pub en nuestra cámara desde el navegador. Como esta en la imagen.

Para testear que ingresas bien a la cámara puedes correr la siguiente linea desde la consola de linux donde se hospeda tu sitio web:

$ sudo /usr/bin/scp -qv «ubnt@IPdeAircam:/tmp/snap.jpeg» /var/www/tusitio/webcam.jpg.
Si todo va bien te tiene que solicitar la contraseña de la cámara. Luego revisa que se haya generado el archivo webcam.jpg en tu sitio.  :). Perfecto!, Ahora si queremos que la foto se publique sola, tenemos que lograr que esta linea de comandos no nos pida la contraseña. Para ello necesitamos instalar «expect», un programa para automatizar tareas que va a encargarse del login.

sudo apt-get install expect

Luego vamos a armar 2 script; uno que hara el trabajo de ingresar a la camarita, con lo siguiente:   webcam_image_get.sh

#! /usr/bin/expect
set hostName [lindex $argv 0]
 ### Modificar ubnt por el usuario, y /var/... por la ruta de tu sitio.
spawn /usr/bin/scp -q "ubnt@$hostName:/tmp/snap.jpeg" /var/www/tusitio/webcam.jpg

set timeout 10
expect {
  ### Modificar ubnt por la contraseña de tu camara
 -re ".*passphrase.*" { send "ubnt\n"; expect eof exit }
  eof { exit }
  timeout { puts "\n--TIMEOUT!--\n";exit}
}
exit

Modificar «ubnt ubnt» por el usuario y contraseña de tu camara y la ruta que tiene que apuntar a la de tu sitio web.

Y el otro script ejecutara el anterior cada cierto tiempo en segundos, y ademas usaremos «convert» para reescribir la imagen con un texto personalizado.

Para poder usar «convert» instalamos:  $ sudo apt-get install imagemagick

Y aqui el script: webcam_cron.sh

#! /bin/sh

while [ true ]; do
        sleep 2   # espearmos 2 segundos
 /home/tu_usario/webcam_image_get.sh 190.100.100.5 # ip de tu camara
        sleep 1  # esperamos 1 segundo mas
        convert -family Arial -pointsize 16 -fill "#ffffff"  -draw "text 20,20 'Tech-Nico.com Live'" /var/www/tusitio/webcam.jpg/var/www/tusitio/webcam.jpg
done

En rojo las cosas que tenes que modificar para tu caso.
Le damos permisos de ejecución a los 2 scripts con: $ sudo chmod +x

Finalmente para ejecutar «webcam_cron.sh» como trabajo en background y re-direccionamos la salida estándar a un archivo de texto llamado output para esconder los mensajes.

$  sudo ./webcam_cron.sh >>output 2>&1 &

Ahora si! ya tenemos nuestra imagen publicandose automaticamente. Solo tenemos que armar un archivito HTML y ponerle la etiqueta Refresh para que refresque cada cierto tiempo.

La única desventaja de esto es que «no vamos a ver la imagen como un video» Es mas lento porque hasta que se logea por ssh, intercambia las llaves.. ingresa la contraseña… copia el archivo..  todo eso le demora unos 2 segundos. Asi que lo mas rapido que puede publicar va a ser en 3 o 4 segundos como maximo.

Resultado

Espero que les guste y.. lo mas importante.. «les sirva».

________________
Nicolas Daitsch
tech-nico.com/blog

Clonar Mac-Address en AirOS Ubiquiti

Un colaborador del foro ISPARG (David Aldret) nos resolvió el gran problema de poder clonar un Mac address en AirOS y que se mantenga el cambio luego de reiniciar.

Por que clonar un mac?. Se quema un equipo; y muchos clientes tienen fijado el mac del AP. Si hubiera tenido este tip no habria ido casa por casa 😛

Hay que entrar al equipo por SSH o bien por el admin.cgi y pegarle este codigo

echo «ifconfig ath0 down; ifconfig ath0 hw ether MAC; ifconfig ath0
up» > /etc/persistent/rc.poststart; chmod +x /etc/persistent/
rc.poststart; cfgmtd -w -p /etc/; reboot

___________________
Nicolas tech-nico.com

Como refrigerar un Azbox HD Bravoo

Hoy decidí modificar mi equipo de FTA (Free to Air).

Al parecer en lugares donde corre poco aire los equipos levantan temperatura y terminan apagándose o destellando la pantalla.

Lo que hice fue comprar un Cooler de PC marca NogaNet ($ 15 pesos). Mientras sean de 12v. Cualquier marca sirve.

Aqui va el resultado en imagenes:

Feliz Navidad!!!!! 😀
______________________
Nicolas Tech-nico.com

Native instrument Audio 8 DJ | micro cortes y ruidos raros

Esto va para todos aquellos que sufren problemas con la placa Audio 8 y Traktor.
El problema esta en los drivers que son bastante inestables, probé:

  • 3.0.1
  • 3.0.0
  • 2.9.8 beta (ya no están mas en el sitio de NI)
  • 2.0.15
Y para mi sorpresa los únicos que reproducen sin micro pausas en el audio son casi los mas viejos, la version 2.0.15; pero tampoco son perfectos. En mi caso se escuchan unos pequeños ruidos aleatorios, son ruidos bastante sutiles pero en fin ruidos que no debería hacer por el valor del equipamiento. Hoy encontré ademas algunos tips interesantes en el foro oficial de Native Instrument, que consisten en modificar la prioridad de los IRQ (interrupciones) para dar prioridad al IRQ10 que es la interrupción que maneja la parte de audio. También es conveniente desactivar interfaces Wireless, Ethernet, Bluethoot. Usar la Notebook con el mayor rendimiento posible de energía. (No usar dispositivos USB innecesarios). Etc.
A continuación, editar el registro para Windows 7 o Vista
1. Ir a Inicio -> Ejecutar -> Escribir "Regedit" (sin comillas) -> Press Enter

Esto abrirá el registro

2. Ahora en la izquierda del Regedit muévase hasta: 

HKEY_LOCAL_MACHINE\SYSTEM\Curr entControlSet\Control\Priority Control

Aquí debería ver 2 filas: "Predeterminado" y "Win32PrioritySeparation"

3. Click derecho en el area blanca de la derecha y click en

Nuevo -> Valor de DWORD (32-bit) |  (como podrás ver)

Ahora veras una nueva fila!

4. Click derecho en esta nueva fila y elegir renombrar.

Renombrar como "IRQ10Priority" sin comillas (escribir Exactamente como esta!)

Presionar <Enter>.

5. Ahora que lo has renombrado, hacer doble click en este y veras una área de texto con el valor 0 en su interior.  

Cambiar el 0 por 1, <dejar el resto igual, y click en ACEPTAR>

6. Cierre el registro y reinicie la computadora!
Luego en el administrador de dispositivos, hay que destildar una opcion en los puertos USB, haciendo doble click en cada dispositivo llamado «Controlador raíz USB».
Nos movemos a la solapa «Administración de Energía» y finalmente destildar la opción «Permitir que el equipo apague este dispositivo para ahorrar energía«.
Todavía sigo con esos pequeños ruidos. Espero que alguien tenga un tip para eliminarlos o bien salga un driver como la gente. :P. Eso fue todo amigos.
Que tengan una muy Feliz Navidad y prospero año nuevo!!!_____________________
Nicolas tech-nico.com/blog 

Embeber Objetos Audio y Video con Ajax usando swfobject

Algo realmente curioso e interesante es ver que el wp-standalone-player utiliza la
funcion Javascript para embeber Objetos Flash usando DOM creado por «Geoff Stearns, Michael Williams, y Bobby van der Sluis»
Casualmente es muy util para los que quieran embeber Objetos Flash mediante AJAX.
Es un problema muy tipico el querer embeber video de youtube y que el innerHTML no funcione. (Sinceramente da muchos dolores de cabeza).
Pero con este pequeño include llamado player.js de tan solo 11kb solucionamos todos nuestros problemas y podemos embeber indistintamente Objetos Flash (SWF) Locales, como URL de Objetos, como es el caso de los videos de Youtube.

Vamos a aclarar que salio una version de «WordPress Audio Player» version standalone. Por lo tanto podemos customizarla y usarla en cualquiera de nuestros sitios webs (aunque no tengan WP instalado).

Entonces hasta aca tenemos:
– Funcion JS para embeber objetos flash con DOM de 11 Kb.
– Reproductor de audio WordPress Audio Player (Standalone)
– Y una funcion para incluir Objetos Flash (mas especificamente Videos Youtube)

Aqui abajo les muestro como implementarlo:

<!– HEADER –>
<script src=»player/player.js» type=»text/javascript»></script>

<script type=»text/javascript»>  
 // VIDEO DE YOUTUBE
 function show_video(element_descripcion, video_objeto, video_descripcion){
     var div_element_descrip = document.getElementById(element_descripcion); 
     audioplayer_swfobject.embedSWF(video_objeto, «main_video», «295», «237», «9.0.0»);
     div_element_descrip.innerHTML = video_descripcion;
 }

 // WP_STANDALONE_PLAYER ( la siguiente linea, invoca el audioPlayer )
       
AudioPlayer.setup(«
http://<?php echo $tudominio; ?>/player/player.swf», {  
                width: 290  
        });   
</script>

 Son 2 funciones totalmente distintas; la primera, show_video( ), es la que usaremos para embeber video.  Y AudioPlayer.setup( ), es la que invoca al reproductor de audio. Lo que tienen en comun, es que ambas funciones utilizan el mismo Include player.js con el que embeben los tags usando DOM.

En el Body:

<!– BODY –>
 <!– audio player –>
<p id=»audioplayer_1″>Alternative content</p>  
<script type=»text/javascript»> 
                 AudioPlayer.embed(«audioplayer_1», {soundFile: «
http://<?php echo $tudominio;?>/<?php echo $ruta_de_tu_audio .’/’. $nombre_archivo; ?>»,transparentpagebg: «yes»,titles: «descripcion del audio»});   
</script>
                                   

 <!– video player –>
<script type=»text/javascript»> 
          show_video(‘video_descripcion’, ‘http://www.youtube.com/v/codigovideo’,  ‘la descripcion del video desde la base de datos’);
</script>
 <div id=»main_video»></div>
 <div id=»video_descripcion»></div>
 

Multiples Instancias:

Los contenedores para cada reproductor son los que estab en negrita.
Para agregar multiples reproductores de audio, solo basta con cambiar el ID del contenedor y duplicar el codigo. Para el caso del reproductor de video habria que hacer unas minimas modificaciones en la funcion show_video( ), y pasandole como parametro el identificador del DIV podriamos tener multiples reproductores de video.

Bien!. veran que es muy facil!!!

UN TIP > USAR YOUTUBE COMO SERVIDOR DE VIDEO STREAM:
Esto es para los que ahorramos ancho de banda. (Hoy en dia los que tienen reproductores de video propios insertados en su sitio web, estimo que es porque el sitio les da mucha ganancia)  🙂
Lo que yo hice fue guardar toda las rutas de los videos de youtube en mi base de datos. Para ello, se me presento un inconveniente; las URL’s de los videos son diferentes a la URL de publicacion que estan en los tags.. se entiende?.

Ejemplo: esta es la URL del video que esta en la barra de direcciones del navegador, http://www.youtube.com/watch?v=Mxo9D_aTrx4. (Esta URL NO FUNCIONA!).
pero si miramos la URL del objeto a insertar:

<object width="425" height="344"><param name="movie" value="
http://www.youtube.com/v/G8whC4Me8d4&hl=en&fs=1«></param> <param name=»allowFullScreen» value=»true»></param><param name=»allowscriptaccess» value=»always»></param> <embed src=»http://www.youtube.com/v/G8whC4Me8d4&hl=en&fs=1» type=»application/x-shockwave-flash» allowscriptaccess=»always» allowfullscreen=»true» width=»425″ height=»344″></embed></object>

Ja, si!  es totalmente distinta; en mi caso, necesitaba guardar solo la URL en el campo de la Base de datos, entonces lo que hice fue armar una expresion regular que me devuelva la URL del video de forma limpia.

function validate_youtube(text_element) {
if (text_element.value != ""){
var matches = "";
var expression = /((http:\/\/)|(www\.[^ \[\]\(\)\n\r\t]+)|(([012]?[0-9]{1,2}\.){3}[012]?[0-9]{1,2})\/)([^ \[\]\(\),;\"'<>\n\r\t]+)([^\. \[\]\(\),;\"'<>\n\r\t])|(([012]?[0-9]{1,2}\.){3}[012]?[0-9]{1,2})/gi;
var rx = new RegExp(expression);
var str = text_element.value;
matches = str.match(rx);
text_element.value=matches[0];
}
}

La podes agregar en el textfield con el evento onChange, entonces cuando hagas «Copy/Paste» del codigo <object…/object> en el textbox de tu CMS, obtendras la URL on the fly.

Esto ultimo tambien podria hacerce mucho mejor con el API de google para Youtube, y se podrian obtener hasta los comentarios de los videos (estuve viendo el codigo y no es para nada dificil). Pero yo necesitaba una solucion sencilla y rapida, asi que dejamos el API para el Upgrade del sitio.

descargar archivos

Nicolas. tech-nico.com/blog