miportaljuvenil
Usuario (Argentina)
En esta oportunidad crearemos un sistema de registro de usuarios utilizando a PHP. ¿En que consiste? y ¿para que sirve? muy sencillo, en algunas webs como por ejemplo esta, queremos interactuar con los usuarios, deseamos que estos puedan enviar scripts al sistema para ayudar a crecer la coleccion de scripts que disponemos, pero deseamos llevar un control sobre los autores de los scripts asi que no cualquiera puede enviar scripts, para hacerlo tienes que registrarte y hacer el respectivo "ingreso" para que el sistema te reconosca y te deje enviar scripts, archivos y articulos como este, de otra manera no puedes hacer ninguna de estas acciones. ¿Pero como se logra esto?, se hace teniendo en una base de datos una tabla de usuarios(Podria hacerse con archivos, aunque seria un poco inseguro) y por medio de archivos PHP y manejo de sesiones(session) o por "cukis"(cookies). En este articulo explicare como crear un sistema de registro y reconocimiento de usuarios teniendo una tabla en una base de datos MySql y por medio de "cukis"(COOKIES) para nuestra web de una manera sencilla. A la hora de crear un sistema de registro de usuarios siempre pensamos en lo mismo: registro + login + reconocimiento Queremos que los usuarios se registren dejando sus datos y puedan acceder a algunas zonas de la pagina y sea reconocido por nuestra pagina(por ejemplo "bienvenido jlmm" o "bienvenido visitante" en caso de no estar ingresado (o registrado) en el sistema). Muchos piensan en crear un sistema de usuarios por que les parece "bonito", pero hay pocos que realmente lo necesitan(lo digo por experiencia con dichas personas), y cuando les haces las dos preguntas: 1- ¿que beneficios tienen los usuarios registrados con respecto a los demas? 2- ¿que zonas de tu web quieres que sean de acceso restringido y PORQUE? La mayoria no es capaz de responder la primera pregunta, y es que antes de aventurarnos a crear un sistema de usuarios para nuestra web debemos de pensar si realmente vale la pena, ya que las tematicas de la web y sus contenidos no siempre son adecuados para tener un sistema de registro de usuarios. Para ello respondemos las 2 preguntas, en el caso de misCODIGOS.com serian: 1- ¿que beneficios tienen los usuarios registrados con respecto a los demas? R://Posibilidad de enviar scripts, articulos y archivos al sistema, al igual que disponibilidad de un panel de control entre otros. 2- ¿que zonas de tu web quieres que sean de acceso restringido y PORQUE? R://Quiero que solo los usuarios que esten registrados puedan enviar scripts/articulos/archivos, ya que asi puedo llevar un mejor cotrol sobre los mismos y prevenir el envio indiscriminado de scripts/articulos/archivos al sistema por parte de los usuarios. Ya tenemos nuestras razones para crear nuestro sistema de registro de usuarios, claro que pueden haber muchas razones dependiendo del tipo de web, podrian ser por ejemplo para que solo usuarios registrados puedan bajar software/musica/videos/etc, para restringir el acceso a ciertas zonas de la web "obligando" al usuario a registrarse para poder "ver" dicha zona, etc… Siempre teniendo en cuenta que las razones sean validas y que no molesten al usuario, ya que en mi caso hace algunos meses me encontre con una web de "scripts" la cual para poder ver los "scripts" tenias que registrarte, obviamente lo que hice fue salir de esa web y olvidarla (por ello no les puedo dar la direccion), tenemos que tener muy en cuenta que zonas restringir a usuarios registrados ya que el usuario en general prefiere la comodidad y en este caso que les comento de webs con recursos y scripts para webmasters hay muchas (pero ninguna como esta :-P ) y hay que buscar siempre la comodidad de los usuarios. Ahora a lo que vinimos, crearemos nuestro sistema de registro de usuario, lo primero que debemos pensar es que datos debera introducir el usuario para registrarse, como siempre deberan de haber aunque sea dos campos basicos: * nick * password Lo mas común para identificar a los usuarios es por medio de nick/password, aunque también podria ser email/password, para este articulo utilizare el primero(nick/password). Ya sabemos que nuestra tabla de "usuarios" tendra esos dos campos: CREATE TABLE usuarios ( id bigint(7) NOT NULL auto_increment, nick char(100) NOT NULL, password char(100) NOT NULL, KEY id (id)) ¿Pero son suficientes?, tambien seria bueno tener el email de los usuarios en caso de querer enviar informacion a los usuarios registrados y tener el nombre de dichos usuarios para personalizar dichos emails o mensajes que le demos al usuario en la pagina(ejemplo "hola jorge luis", entonces nuestra tabla creceria un poco: CREATE TABLE usuarios ( id bigint(7) NOT NULL auto_increment, nick char(100) NOT NULL, password char(100) NOT NULL, nombre char(255) default NULL, email char(100) default NULL, KEY id (id)) Listo, ya tenemos la estructura de nuestra tabla de usuarios, es pequeña y sencilla pero para efectos prácticos y de aprendizaje es perfecta (eso depende de ti, según lo que desees saber de tus usuarios). Ahora viene lo sencillo, crear el sistema de registro de usuarios, un formulario y una aplicacion que agregue al nuevo usuario a la base de datos, para ello crearemos un formulario del tipo: FORM ACTION="registrar.php" METHOD="post"> Nick : <INPUT TYPE="text" NAME="nick" SIZE=20 MAXLENGTH=20> <BR> Email: <INPUT TYPE="text" NAME="email" SIZE=28 MAXLENGTH=100> <BR> Password: <INPUT TYPE="password" NAME="password" SIZE=28 MAXLENGTH=20> <BR> Nombre: <INPUT TYPE="text" NAME="nombre" SIZE=28 MAXLENGTH=255> <BR> <INPUT TYPE="submit" CLASS="boton" VALUE="Registrar"> </FORM> Y ahora necesitamos una aplicacion que lo procese (registrar.php), por motivos practicos haremos algo sencillo sin demasiadas comprobaciones (dependera de ti mejorarlo si quieres algo mas personalizado), primero el codigo luego la explicacion: <?php //AQUI CONEXION O include() DE ARCHIVO DE CONEXION CON BASE DE DATOS. function quitar($mensaje) { $mensaje = str_replace("<","<",$mensaje); $mensaje = str_replace(">",">",$mensaje); $mensaje = str_replace("'","'",$mensaje); $mensaje = str_replace('"',""",$mensaje); $mensaje = str_replace("\\","",$mensaje); return $mensaje; } if(trim($HTTP_POST_VARS["nick"]) != "" && trim($HTTP_POST_VARS["email"]) != "" { $sql = "SELECT id FROM usuarios WHERE nick='".quitar($HTTP_POST_VARS["nick"])."'"; $result = mysql_query($sql); if($row = mysql_fetch_array($result)) { echo "Error, nick escogido por otro usuario"; } else { $sql = "INSERT INTO usuarios (nick,password,nombre,email) VALUES ("; $sql .= "'".quitar($HTTP_POST_VARS["nick"])."'"; $sql .= ",'".quitar($HTTP_POST_VARS["password"])."'"; $sql .= ",'".quitar($HTTP_POST_VARS["nombre"])."'"; $sql .= ",'".quitar($HTTP_POST_VARS["email"])."'"; $sql .= ""; mysql_query($sql); echo "Registro exitoso!"; } mysql_free_result($result); } else { echo "Debe llenar como minimo los campos de email y password"; } mysql_close(); ?> Al principio no he echo conexion con la base de datos pero he puesto el comentario "//AQUI CONEXION O include() DE ARCHIVO DE CONEXION CON BASE DE DATOS.", ya que la conexion depende de ti, si no sabes como hacer una conexion te aconsejo buscarte un manual antes de estar queriendo hacer un sistema como este. Vemos que he declarado una funcion, llamada quitar($mensaje), la cual recibe el parametro "mensaje", esta funcion se encargara de deshabilitar el codigo html("<" y ">" al reemplazarlos por su respectivo codigo("<" y ">", ademas de reemplazar el apostrofe(‘) y las comillas dobles(" por sus respectivos codigos HTML, esto para no tener conflictos con la instruccion sql, y al final retorna la cadena con las nuevas modificaciones en caso de haberlas: function quitar($mensaje) { $mensaje = str_replace("<","<",$mensaje); $mensaje = str_replace(">",">",$mensaje); $mensaje = str_replace("'","'",$mensaje); $mensaje = str_replace('"',""",$mensaje); $mensaje = str_replace("\\","",$mensaje); return $mensaje; } Ahora comprobaremos que los campos de nick y password que seran los "requeridos" como minimo para completar el registro no esten vacios, para ello utilizamos la funcion "trim()" la cual quita los espacios al comienzo y al final de la cadena, por lo que en caso de ser una cadena vacia o con solo espacios en blanco retornara "", en caso de ser valido continuamos con el registro, de lo contrario retornamos un mensaje de error: if(trim($HTTP_POST_VARS["nick"]) != "" && trim($HTTP_POST_VARS["password"]) != "" Ahora suponiendo que las cadenas estaban correctas comprobaremos que el nick seleccionado por el usuario no exista en la base de datos, para ello hacemos una instruccion sql para pedirle a la base de datos que nos retorne la fila donde el nick sea igual al nick introducido con el usuario(quitandole el apostrofe, html y demas con la funcion quitar()): $sql = "SELECT id FROM usuarios WHERE nick='".quitar($HTTP_POST_VARS["nick"]."'"; $result = mysql_query($sql); En caso de existir dicho nick, osea que nos devuelve una fila: if($row = mysql_fetch_array($result)) Mostraremos un mensaje de error al usuario informandole del "incidente", de lo contrario continuaremos con el proceso de registro. Ahora lo que hacemos es simplemente una instruccion sql donde insertamos en la tabla usuarios el nick, password, nombre y email introducidos por el usuario en el formulario, a todos estos les quitamos el html, apostrofe y demas haciendo uso de nuestra instruccion "quitar()", y mostramos un mensaje de "exito" al usuario: $sql = "INSERT INTO usuarios (nick,password,nombre,email) VALUES ("; $sql .= "'".quitar($HTTP_POST_VARS["nick"])."'"; $sql .= ",'".quitar($HTTP_POST_VARS["password"])."'"; $sql .= ",'".quitar($HTTP_POST_VARS["nombre"])."'"; $sql .= ",'".quitar($HTTP_POST_VARS["email"])."'"; $sql .= ""; mysql_query($sql); echo "Registro exitoso!"; Notaor efectos practicos hemos echo esto muy sencillo, podrian agregar más comprobaciones como la del email o manejo de errores mysql. Tambien podria hacerse más seguro mediante el uso de la funcion de encriptacion md5() para el password, aunque se esta haciendo lo mas sencillo posible ya que la finalidad de este articulo es la de enseñar como reconocer a los usuarios, de ustedes dependen estos "detalles" a la hora de "depurar" este codigo. Bien, listo ya tenemos la aplicacion de registro, ¿pero y ahora que?, que hago con todos esos usuarios, ahora necesitamos que los usuarios ingresen y sean "reconocidos" y como lo dije lo haremos por medio de cookies. Crearemos un formulario HTML para que los usuarios introduscan su nick y password al igual que deberemos de realizar una aplicacion ingresar.php que sera la encargada de procesar si el usuario es valido y darle "ingreso" al sistema por medio de una cookie. Es recomendable tener este archivo en la carpeta raiz de nuestra web, el formulario html seria algo asi: <FORM ACTION="ingresar.php" METHOD="post"> Nick : <INPUT TYPE="text" NAME="nick" SIZE=20 MAXLENGTH=20> <BR> Password: <INPUT TYPE="password" NAME="password" SIZE=28 MAXLENGTH=20> <BR> <INPUT TYPE="submit" CLASS="boton" VALUE="Ingresar"> </FORM> Y ahora el codigo de nuestra aplicacion ingresar.php, luego la explicacion: <?php //AQUI CONEXION O include() DE ARCHIVO DE CONEXION CON BASE DE DATOS. function quitar($mensaje) { $mensaje = str_replace("<","<",$mensaje); $mensaje = str_replace(">",">",$mensaje); $mensaje = str_replace("'","'",$mensaje); $mensaje = str_replace('"',""",$mensaje); $mensaje = str_replace("\\","",$mensaje); return $mensaje; } if(trim($HTTP_POST_VARS["nick"]) != "" && trim($HTTP_POST_VARS["password"]) != "" { $nickN = quitar($HTTP_POST_VARS["nick"]); $passN = quitar($HTTP_POST_VARS["password"]); $result = mysql_query("SELECT password FROM usuarios WHERE nick='$nickN'"; if($row = mysql_fetch_array($result)) { if($row["password"] == $passN) { //90 dias dura la cookie setcookie("usNick",$nickN,time()+7776000); setcookie("usPass",$passN,time()+7776000); ?> Ingreso exitoso, ahora sera dirigido a la pagina principal. <SCRIPT LANGUAGE="javascript"> location.href = "index.php"; </SCRIPT> <? } else { echo "Password incorrecto"; } } else { echo "Usuario no existente en la base de datos"; } mysql_free_result($result); } else { echo "Debe especificar un nick y password"; } mysql_close(); ?> Bien, arriba ya explique que debes de realizar la conexion y explique el funcionamiento de la funcion quitar($mensaje), asi que saltemos hasta el primer "if". Lo primero que hacemos es comprobar que los campos de "nick" y "password" para que no esten vacios, ya sabemos para que sirve trim() asi que no lo repetire: if(trim($HTTP_POST_VARS["nick"]) != "" && trim($HTTP_POST_VARS["password"]) != "" Asi que continuamos suponiendo que todo este bien, ahora lo que hacemos es quitarle el html, apostrofe comillas y demas al nick y password enviados por el usuario para su comprobacion con la base de datos, para ello utilizamos la funcion quitar($mensaje) que explicamos antes, y guardamos las nuevas cadenas en dos nuevas variables: nickN = quitar($HTTP_POST_VARS["nick"]); $passN = quitar($HTTP_POST_VARS["password"]); Ahora ejecutamos una instruccion sql, en la cual le pedimos a la base de datos que de la tabla usuarios nos devuelva la fila cuyo nick corresponda por el enviado por el usuario: $result = mysql_query("SELECT password FROM usuarios WHERE nick='$nickN'"; Si devuelve una columna quiere decir que el nick SI existe en la base de datos, de lo contrario devolvemos un mensaje de error: if($row = mysql_fetch_array($result)) { ... } else { echo "Usuario no existente en la base de datos"; } Ahora continuamos con el proceso suponiendo que el usuario exista en la base de datos ahora debemos comprobar que el password sea correcto, para ello hacemos una simple comparacion, si es correcto continuamos de lo contrario mostramos el mensaje de password incorrecto: if($row["password"] == $passN) { ... } else { echo "Password incorrecto"; } Ahora suponiendo que el password es correcto continuamos y lo proximo a hacer es establecer las cookies de nick y password (Las cuales nombramos "usNick"/"usPass" y contienen el nick y password respectivamente) en la maquina del usuario, informamos que se ha realizado correctamente el login y lo enviamos a la pagina principal, una vez mas recalco que estamos haciendo esto lo mas sencillo posible, de ti depende personalizar y mejorar los mensajes : setcookie("usNick",$nickN,time()+7776000); setcookie("usPass",$passN,time()+7776000); ?> <SCRIPT LANGUAGE="javascript"> alert("Ingreso exitoso"; location.href = "index.php"; </SCRIPT> <? Listo, el usuario ya tiene las cookies en su sistema, ¿pero ahora que?, como hacemos para comprobar en las paginas que queramos si el login es correcto, osea que el usuario posee las cookies y son validas?. Para ello crearemos un ultimo archivo, lo llamaremos login.php, este se encargara de leer las cookies y decirnos si el usuario es un usuario registrado y que ha echo el respectivo "ingreso" al sistema, el contenido de dicho archivo seria el siguiente: <?php $loginCorrecto = false; $idUsuarioL; $nickUsuarioL; $emailUsuarioL; $nombreUsuarioL; if(isset($HTTP_COOKIE_VARS["usNick"]) && isset($HTTP_COOKIE_VARS["usPass"])) { $result = mysql_query("SELECT * FROM usuarios WHERE nick='".$HTTP_COOKIE_VARS["usNick"]."' AND password='".$HTTP_COOKIE_VARS["usPass"]."'"; if($row = mysql_fetch_array($result)) { setcookie("usNick",$HTTP_COOKIE_VARS["usNick"],time()+7776000); setcookie("usPass",$HTTP_COOKIE_VARS["usPass"],time()+7776000); $loginCorrecto = true; $idUsuarioL = $row["id"]; $nickUsuarioL = $row["nick"]; $emailUsuarioL = $row["email"]; $nombreUsuarioL = $row["nombre"]; } else { //Destruimos las cookies. setcookie("usNick","x",time()-3600); setcookie("usPass","x",time()-3600); } mysql_free_result($result); } ?> Lo primero que hacemos es declarar unas variables que utilizaremos para guardar los datos del usuario en caso de tener las cookies en su sistema y de estas ser correctas: $loginCorrecto = false; $idUsuarioL; $nickUsuarioL; $emailUsuarioL; $nombreUsuarioL; Hay una variable boleana que tenemos que mirar de cerca y es la de $loginCorrecto ya que esta sera la que utilizaremos para comprobar el login en nuestros archivos, mas adelante veremos como. Seguidamente lo que hacemos es comprobar que las cookies existan, si no existen pues no hay problema simplemente no hay "ingreso" : if(isset($HTTP_COOKIE_VARS["usNick"]) && isset($HTTP_COOKIE_VARS["usPass"])) Ahora lo que hacemos es una sentencia sql, en la cual le pedimos a la base de datos que nos devuelva la fila donde el nick y password correspondan al nick y password guardado en las cookies: $result = mysql_query("SELECT * FROM usuarios WHERE nick='".$HTTP_COOKIE_VARS["usNick"]."' AND password='".$HTTP_COOKIE_VARS["usPass"]."'"; Si ese nick y password corresponden a una fila en la base de datos esto quiere decir que son correctos de lo contrario la informacion de las cookies esta mal y debemos destruirlas: if($row = mysql_fetch_array($result)) { ... } else { //Destruimos las cookies. setcookie("usNick","x",time()-3600); setcookie("usPass","x",time()-3600); } Si la informacion es correcta procedemos con el ingreso, establecemos de nuevo las cookies con lo que se actualiza el tiempo de destruccion a otros noventa dias apartir de ahora: setcookie("usNick",$HTTP_COOKIE_VARS["usNick"],time()+7776000); setcookie("usPass",$HTTP_COOKIE_VARS["usPass"],time()+7776000); Seguido de esto establecemos la variable $loginCorrecto a "true", y las otras variables las llenamos con la informacion del usuario: $loginCorrecto = true; $idUsuarioL = $row["id"]; $nickUsuarioL = $row["nick"]; $emailUsuarioL = $row["email"]; $nombreUsuarioL = $row["nombre"]; Listo ya tenemos nuestro archivo "login.php", ahora ¿como lo utilizamos?, bien supongamos que queremos en nuestro "index.php" darle la bienvenida al usuario en caso de estar ingresado en el sistema deseamos saludarlo por su nick o nombre en caso contrario lo saludaremos como visitante, para ello tendriamos que incluir el archivo "login.php" al comienzo de nuestro archivo "index.php" asi: Nota:Antes de incluir el "login.php" debe recordar realizar la conexion con la base de datos, de lo contrario obtendra errores. <?php //AQUI CONEXION O include() DE ARCHIVO DE CONEXION CON BASE DE DATOS. include("login.php"; ... Con eso el "login.php" se encargara de realizar las acciones que vimos arriba, ahora en nuestro "index.php" donde queramos saludar al visitante ponemos lo siguiente: ... if($loginCorrecto) { echo "Estas identificado en el sistema como ".$nickUsuarioL; } else { echo "Bienvenido visitante, el sistema no te ha reconocido"; } ... Como ven, hicimos uso de la variable $loginCorrecto la cual sera "true" en caso de que el usuario fuera reconocido por el sistema, de lo contrario sera "false". Y asi podemos usarlo en muchas areas, supongamos que tenemos una seccion donde solo pueden accesar los usuarios registrados, la llamaremos "restringida.php", entonces lo que hariamos para prevenir que usuarios no registrados vean el contenido seria algo asi: <?php //AQUI CONEXION O include() DE ARCHIVO DE CONEXION CON BASE DE DATOS. include("login.php"; if($loginCorrecto) { echo "Aqui el contenido solo para usuarios registrados"; } else { echo "El sistema no lo ha identificado, solo los usuarios registrados tienen acceso a esta area"; } ?> Eso es todo, espero haya quedado claro. PD: Sobre el proceso de "logout" o "salir" no lo explico ya que es algo muy sencillo, simplemente se "borran" las cookies. Bueno espero que le hayas gustado adios!!!! SAludos taringueros!!!
Moderación con el tamaño de lo que publicamos Y es precisamente por la limitación de ancho de banda que debemos de ser contenidos en lo que publicamos en nuestra web. Por ejemplo, una imagen de 300KiB que se muestre en todas las página de nuestro sitio puede suponer una verdadera bofetada a nuestros visitantes que tendrán que esperar segundos y segundos a que la página acabe de cargar… y eso si finalmente esperan y no la cierran antes. Por eso, cuidado con lo que hospedamos y seamos muy tacaños con el escaso ancho de banda con el que contamos. Antes hacía referencia a entradas previas que trataban de la compresión y cacheo de las páginas web. Con dicha técnica podremos reducir al mínimo el volumen de los ficheros HTML, CSS y JavaScript, pero el objetivo de mantener a un tamaño razonable las imágenes no debe de perderse nunca de vista. Un poco de SEO para ahorrar ancho de banda Unos visitantes tan pesados como necesarios son los robots de los buscadores. Los necesitamos para existir en Internet, pero sus visitas constantes consumen ancho de banda y no poco, ya que recordemos que recorren periódicamente toda nuestra web. Una solución para aliviar el problema es usar un fichero robots.txt y bloquear todo aquello que no necesitemos que sea encontrado. En el caso de un blog, podemos bloquear las páginas de categorías, las de etiquetas, los archivos… al fin y al cabo, es sólo contenido duplicado que lo único que puede hacer es confundir al buscador a la hora de decidirse por la mejor página. Pero la jugada maestra para ahorrar ancho de banda es prohibir a los buscadores que indexen las imágenes de nuestro sitio (Remove an image from Google Image Search). La gente que busca imágenes, raramente estará interesada por el contenido de nuestra página en sí mismo. Por ello, prohibiendo la búsqueda de imágenes, evitamos por un lado el gasto de ancho de banda de servir nuestras imágenes a los buscadores de imágenes y por otro, el de aquellos que acceden a nuestra página buscando imágenes, e incluso el de aquellos que, una vez encontrada la imagen que buscaban, decidan hacer hotlinking a nuestra imagen. Otra cosa es que te pueda interesar mucho el tráfico proveniente de buscadores de imágenes. En mi caso, el número de visitas procedente de images.google.com llegó a ser muy alto hasta que prohibí la búsqueda de imágenes en mi sitio, ya que analizando las búsquedas origen de las visitas, llegue a la conclusión de que no eran visitantes interesados en el contenido de mis páginas. Si tenemos un feed por RSS o Atom, tenemos que tener en cuenta que los diferentes agregadores de noticias suelen acceder con cierta frecuencia para ver si hay nuevas entradas, así que puede ser muy útil para ahorrar ancho de banda servir el feed a través FeedBurner de forma que FeedBurner sea el único que acceda a nuestro feed y que sea él el que use su ancho de banda para alimentar al resto de agregadores. Para analizar los logs, Debian nos ofrece varias aplicaciones ya preempaquetadas: Visitors, WebDruid, AWFFull y el veterano wwwstat. Apache HTTP server benchmarking tool Por último, no podemos dejar de mencionar el ab (Apache HTTP server benchmarking tool), una utilidad incluida en el paquete apache2-utils con la que podremos hacerle pruebas de carga a nuestro servidor web. Puede resultarnos útil para comparar el rendimiento de un Apache 1.3 con el de un Apache 2.2 o con el de un lighttpd o para probar las mejoras de la caché o de la compresión o para estudiar las consecuencias que los cambios en el código pueden suponer (por ejemplo, tras introducir un trozo de código PHP muy complejo de ejecutar y que tal vez resulte muy lento). En esta prueba de ejemplo, le lanzo a mi servidor a través de la LAN peticiones de 5 en 5 (-c 5) durante un tiempo máximo de 60 segundos (-t 30), y veo que es capaz de atender 23 peticiones (los fallos “Length: 21” son porque las páginas devueltas no tienen todas el mismo tamaño, algo que no es un problema en este caso), pero que algunas han tenido que esperar hasta 40 segundos: # ab -c 5 -t 60 http://www.vicente-navarro.com/blog/ This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking www.vicente-navarro.com (be patient) Finished 23 requests Server Software: Apache/2.2.3 Server Hostname: www.vicente-navarro.com Server Port: 80 Document Path: /blog/ Document Length: 63231 bytes Concurrency Level: 5 Time taken for tests: 60.523663 seconds Complete requests: 23 Failed requests: 21 (Connect: 0, Length: 21, Exceptions: 0) Write errors: 0 Total transferred: 1510651 bytes HTML transferred: 1505035 bytes Requests per second: 0.38 [#/sec] (mean) Time per request: 13157.318 (mean) Time per request: 2631.464 (mean, across all concurrent requests) Transfer rate: 24.37 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 2319 11847 9921.7 9117 40440 Waiting: 1251 5547 7283.9 2763 30366 Total: 2319 11847 9921.7 9117 40440 Percentage of the requests served within a certain time (ms) 50% 8977 66% 14074 75% 15522 80% 18804 90% 27300 95% 29838 98% 40440 99% 40440 100% 40440 (longest request) Volvamos a repetir la prueba tras habilitar el plugin para WordPress WP Super Cache, del que ya hablamos en Comprimir y cachear las páginas generadas por Wordpress y veremos que de las decepcionantes 23 peticiones servidas pasamos a nada menos que 8193 peticiones con un tiempo de espera máximos de 71ms: # ab -c 5 -t 60 http://www.vicente-navarro.com/blog/ This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking www.vicente-navarro.com (be patient) Completed 5000 requests Finished 8193 requests Server Software: Apache/2.2.3 Server Hostname: www.vicente-navarro.com Server Port: 80 Document Path: /blog/ Document Length: 63301 bytes Concurrency Level: 5 Time taken for tests: 60.358 seconds Complete requests: 8193 Failed requests: 0 Write errors: 0 Total transferred: 520941496 bytes HTML transferred: 518752897 bytes Requests per second: 136.55 [#/sec] (mean) Time per request: 36.617 (mean) Time per request: 7.323 (mean, across all concurrent requests) Transfer rate: 8478.80 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 3 2.5 3 26 Processing: 13 32 4.1 33 69 Waiting: 2 8 4.4 8 49 Total: 18 36 4.1 36 71 Percentage of the requests served within a certain time (ms) 50% 36 66% 37 75% 38 80% 39 90% 41 95% 43 98% 45 99% 46 100% 71 (longest request) ¡Ah! Y si permitimos la compresión con la opción -H "Accept-Encoding: gzip", el resultado es incluso más espectacular, llegándose a las 16122 peticiones servidas, aunque ahora la diferencia ya era previsible, ya que es debida sólo a que ahora se sirven menos datos: # ab -c 5 -t 60 -H "Accept-Encoding: gzip" http://www.vicente-navarro.com/blog/ [...] Complete requests: 16122 [...] Por supuesto, lo ideal es hacer estas pruebas desde otro sistema de Internet, donde el cuello de botella del ancho de banda se note, pero estas pruebas desde la LAN también pueden ser muy ilustrativas y útiles para entender por dónde cojea nuestre servidor web. El servidor de correo Los dos servicios básicos de un hosting son el servidor web y el servidor de correo, así que de nuestro HC también podríamos esperar que fuera un buen servidor de correo. Sin embargo, quitando la parte de que un servidor de correo como sendmail o exim puede ser realmente difícil de configurar, la realidad es que en la actualidad, siendo el spam un problema tan grande en Internet, un servidor de SMTP funcionando desde una red de usuarios finales con IPs dinámicas es candidato seguro a ser ignorado por casi todos los servidores de correo de Internet. E incluso aunque nuestra IP fuera fija, al no ser la IP conocida de un ISP profesional, lo más probable es que nuestros correos también fueran rechazados por un alto porcentaje de servidores destino. Además, no podremos cambiar la resolución inversa de la IP, algo que muchos servidores de correo verifican. Por ejemplo, imaginemos que instalo el paquete exim4, y lo configuro con “dpkg-reconfigure exim4-config” como servidor SMTP del dominio hostingcasero.homelinux.org (para direcciones como [email protected]). Elegimos que el “General type of mail configuration” sea “internet site“: En “System mail name” ponemos hostingcasero.homelinux.org: En “IP-addresses to listen on for incoming SMTP connections” lo podemos dejar vacío para que el servidor acepte conexiones SMTP por todos los interfaces de red: En “Other destinations for which mail is accepted“, pondremos el hostname de nuestro servidor, así como hostingcasero.homelinux.org: El “Domains to relay mail for” en principio lo podemos dejar vacío, así como el “Machines to relay mail for“. El “Keep number of DNS-queries minimal (Dial-on-Demand)?” no tiene mayor importancia en nuestra configuración, así como el “Delivery method for local mail” y el “Split configuration into small files?“, que ya van según las preferencias de cada uno. Pues bien, a finalizar me encuentro con que si intento enviar un e-mail a Hotmail me dice que no acepta mi correo porque mi IP no es de fiar: # mail [email protected] < /tmp/correo.txt delivering 1JY4zH-0001ym-VM R: dnslookup for [email protected] T: remote_smtp for [email protected] Connecting to mx2.hotmail.com [65.54.244.168]:25 ... connected SMTP<< 220 bay0-mc2-f2.bay0.hotmail.com Sending unsolicited commercial or bulk e-mail to Microsoft's computer network is prohibited. Other restrictions are found at http://privacy.msn.com/Anti-spam/. Violations will result in use of equipment located in California and other states. Sat, 8 Mar 2008 11:45:44 -0800 SMTP>> EHLO localhost SMTP<< 250-bay0-mc2-f2.bay0.hotmail.com (3.5.0.22) Hello [81.39.245.151] 250-SIZE 29696000 250-PIPELINING 250-8bitmime 250-BINARYMIME 250-CHUNKING 250-AUTH LOGIN 250-AUTH=LOGIN 250 OK SMTP>> MAIL FROM:<[email protected]> SIZE=1367 SMTP>> RCPT TO:<[email protected]> SMTP>> DATA SMTP<< 550 DY-001 Mail rejected by Windows Live Hotmail for policy reasons. We generally do not accept email from dynamic IP's as they are not typically used to deliver unauthenticated SMTP e-mail to an Internet mail server. http://www.spamhaus.org maintains lists of dynamic and residential IP addresses. If you are not an email/network admin please contact your E-mail/Internet Service Provider for help. Email/network admins, please visit http://postmaster.live.com for email delivery information and support SMTP>> QUIT LOG: MAIN ** [email protected] R=dnslookup T=remote_smtp: SMTP error from remote mail server after MAIL FROM:<[email protected]> SIZE=1367: host mx2.hotmail.com [65.54.244.168]: 550 DY-001 Mail rejected by Windows Live Hotmail for policy reasons. We generally do not accept email from dynamic IP's as they are not typically used to deliver unauthenticated SMTP e-mail to an Internet mail server. http://www.spamhaus.org maintains lists of dynamic and residential IP addresses. If you are not an email/network admin please contact your E-mail/Internet Service Provider for help. Email/network admins, please visit http://postmaster.live.com for email delivery information and support LOG: MAIN <= <> R=1JY4zH-0001ym-VM U=Debian-exim P=local S=1777 LOG: MAIN Completed Pero en cambio, GMail sí que me lo acepta: # mail [email protected] < /tmp/correo.txt delivering 1JY51y-0001yu-LW R: dnslookup for [email protected] T: remote_smtp for [email protected] Connecting to gmail-smtp-in.l.google.com [216.239.59.27]:25 ... connected SMTP<< 220 mx.google.com ESMTP g11si5603645gve.6 SMTP>> EHLO localhost SMTP<< 250-mx.google.com at your service, [81.39.245.151] 250-SIZE 28311552 250-8BITMIME 250 ENHANCEDSTATUSCODES SMTP>> MAIL FROM:<[email protected]> SIZE=1363 SMTP<< 250 2.1.0 OK SMTP>> RCPT TO:<[email protected]> SMTP<< 250 2.1.5 OK SMTP>> DATA SMTP<< 354 Go ahead SMTP>> writing message and terminating "." SMTP<< 250 2.0.0 OK 1205005717 g11si5603645gve.6 SMTP>> QUIT LOG: MAIN => [email protected] R=dnslookup T=remote_smtp H=gmail-smtp-in.l.google.com [216.239.59.27] LOG: MAIN Completed aunque según mi experiencia, dependiendo de la IP dinámica que te haya tocado, es muy posible que también se te rechacen los correos si alguna vez la ha tenido alguien sospechoso de mandar spam. En definitiva, es un servicio nada fiable. Si tenemos un dominio propio con Custom DNS, crear un registro SPF en el DNS puede ayudar para que no rechacen los correos de tu servidor. En openspf.org tienen un formulario que nos ayuda a confeccionar uno adecuado para nuestro servidor. Las MSN Hotmail Guidelines son un buen sitio donde contrastar todos estos requisitos, que suelen ser bastante comunes: 1. Sender is expected to comply with all technical standards for the transmission of Internet e-mail, as published by The Internet Society’s Internet Engineering Task Force (IETF), including RFC 2821, RFC 2822, and others. 2. After given a numeric SMTP error response code between 500 and 599 (also known as a permanent non-delivery response), the sender must not attempt to retransmit that message to that recipient. 3. After multiple non-delivery responses (see #2), the sender must cease further attempts to send e-mail to that recipient. 4. Sender must not open more than 500 simultaneous connections to MSN Services inbound e-mail servers without making prior arrangements. 5. Messages must not be transmitted through insecure e-mail relay or proxy servers. 6. The mechanism for unsubscribing, either from individual lists or all lists hosted by the sender, must be clearly documented and easy for recipients to find and use. 7. Connections from dynamic IP space may not be accepted. 8. E-mail servers must have valid reverse DNS records. Y fijémonos además en lo que nos decía el mensaje de rechazo de Hotmail: Mail rejected by Windows Live Hotmail for policy reasons. We generally do not accept email from dynamic IP’s as they are not typically used to deliver unauthenticated SMTP e-mail to an Internet mail server. http://www.spamhaus.org maintains lists of dynamic and residential IP addresses. If you are not an email/network admin please contact your E-mail/Internet Service Provider for help. Email/network admins, please visit http://postmaster.live.com for email delivery information and support. Esa lista que menciona de Spamhaus no sólo la usa Microsoft, sino que muchas otras empresas e ISPs se basan en ella para descartar los correos desde determinados rangos de IPs en función de la lista. Con los correos entrantes no tendremos ningún problema siempre que nuestro servidor esté arriba. Los servidores SMTP que nos quieran mandar correo buscarán el registro MX (o el A si no hay MX) en elDNS y salga la IP que salga, ahí se mandará el correo. Para recuperar los correos recibidos en el servidor, puede ser suficiente el clásico comando mail, o con un simple “apt-get install qpopper“, podemos tener un servidor de POP3 listo en pocos segundos. Sin embargo, si nuestro servidor no está arriba por algún problema cuando otro servidor SMTP quiera conectarse al nuestro para enviarle un e-mail, el servidor remoto tendrá que decidir si reintenta el envío más tarde o si lo descarta, por lo que el servicio de recepción de correos tampoco es fiable. Si realmente queremos tener un servidor de correo fiable en nuestro sistema, la solución definitiva puede venir por contratar el servicio de DynDNS MailHop Relay (42.5$/año), específicamente pensado para estos problemas. El servidor SMTP de DynDNS es el que da la cara y nosotros lo usamos como smarthost para mandar los correos a través de él y viceversa, para que él nos los envíe de vuelta, guardándolos temporalmente si nuestro servidor está caído. Bytecoders también trató estos temas hace poco en Aviso de actualizaciones en Debian por e-mail y SMTP: la lacra del SPAM. Correo con nuestro propio dominio con Google Apps Para mí, todos estos problemas con el correo se acabaron cuando apareció el Google Apps y pude usar el equivalente a GMail (con su POP3 y su IMAP) pero creando diferentes direcciones sobre mi propio dominio (vicente-navarro.com). Para ello, lo único que tuve fue darme de alta en el servicio y apuntar los registros MX de mi dominio a los servidores de Google (Configuring Your MX Records): # nslookup > set querytype=MX > vicente-navarro.com Server: 80.58.61.250 Address: 80.58.61.250#53 Non-authoritative answer: vicente-navarro.com mail exchanger = 10 alt1.aspmx.l.google.com. vicente-navarro.com mail exchanger = 15 alt2.aspmx.l.google.com. vicente-navarro.com mail exchanger = 5 aspmx.l.google.com. Authoritative answers can be found from: alt1.aspmx.l.google.com internet address = 72.14.215.114 alt1.aspmx.l.google.com internet address = 72.14.215.27 alt2.aspmx.l.google.com internet address = 64.233.179.27 aspmx.l.google.com internet address = 216.239.59.27 Tras esto, creé buzones de correo (o alias) para cada una de las cuentas que iba a usar y reconfiguré mi servidor para que usara un smarthost: Y para que usara smtp.google.com como smarthost: el resto de la configuración, puede quedar igual que estaba antes. Bueno, igual pero no se nos tiene que olvidar poner nuestro dominio en el apartado de “System mail name“. Lo único que tendremos que tener en cuenta es que ahora los correos no se reciben localmente sino en la cuenta de Google Apps (lo que en realidad es más cómodo), pero si aún así fuera necesario traer esos correos a nuestro servidor, siempre podríamos configurarlo para que se los trajera de Google usando POP3. Por supuesto, Google requiere autentificación para mandar correos a través de él, por lo que en el fichero /etc/exim4/passwd.client tendremos que asociar nuestro usuario y contraseña de Google Apps al servidor SMTP: # password file used when the local exim is authenticating to a remote # host as a client. # # see exim4_passwd_client(5) for more documentation # # Example: ### target.mail.server.example:login:password gmail-smtp.l.google.com:[email protected]:contrasenya Independientemente de que vayamos a usar el servidor de HC para enviar y recibir correos en serio o no, es indudable que necesitamos tenerlo bien configurado como servidor de correo para que podamos mandarnos advertencias sobre problemas que pueda haber en el servidor desde nuestros scripts de monitorización. O, simplemente, porque aplicaciones como WordPress mandan correos cada vez que llega un nuevo comentario, por ejemplo. Si el servidor de correo no está bien configurado, las aplicaciones que envían correos como parte de su funcionamiento normal, no podrán hacerlo. Otras cuestiones Backups #!/bin/bash while ! queda_claro do insistir_en_el_backup done no_se_puede_insistir_bastante Creo que no hace falta decir más. Tenemos todo el trabajo invertido en configurar nuestro servidor casero, las bases de datos con los comentarios de nuestros visitantes, nuestras imágenes, nuestro trabajo ahí. ¿De verdad nos vamos a arriesgar a que el disco duro falle o a que inadvertidamente hagamos un “rm -rf *” y desaparezca todo de un plumazo? Para esta tarea, rysnc es nuestro mejor amigo (Backups con rsync), aunque herramientas como tar o cpio también pueden ayudar. Yo recomendaría una copia de todos los ficheros importantes en algún directorio del propio servidor casero y otra/s copia/s en otro/s sistema/s que tengamos a través de de la red con rsync. Para exportar todas las bases de datos MySQL del sistema e incluirlas en el backup, podemos hacer un: mysqldump -uroot -ppassword --all-databases > backup_mysql.bak y lo podríamos recuperar con un: mysql -uroot -ppassword < backup_mysql.bak Más detalles sobre cómo usar el mysqldump en “mysqldump — A Database Backup Program“. El sistema de respaldo Durante el año habrá algunos días, semanas o meses que pases fuera de tu casa. Seguramente esos días te querrás dejar la luz, el agua y el gas de casa cerrados para prevenir incidentes. ¿Qué haces con el servidor casero? ¡Tiene que seguir dando servicio! Si tienes la suerte, como yo, de contar con algún otro ordenador que pueda servir también de servidor casero y de tener algún familiar/amigo con conexión a Internet y que consienta en tenerlo en su casa, una especie de “housing casero”, lo tenemos muy fácil: * Instalamos la misma versión de sistema operativo que en el servidor “oficial” y lo llevamos a su nuevo destino. * Creamos un nuevo nombre para el otro sistema en DynDNS y lo configuramos para que el ddclient del nuevo sistema lo actualice, pero muchísimo mejor si podemos configurar el router de “la otra casa” para que lo haga automáticamente. * Opcional: Preparamos el router y el sistema “hospedado en casa ajena” para arrancar con Wake on Lan. Tenemos que tener en cuenta que si no es el router el que se encarga de actualizar la IP en DynDNS, podemos tener el problema de no saber la IP de destino para enviarle el paquete mágico. * Le ponemos una IP fija al sistema o configuramos el router para que le asigne por DHCP siempre la misma y abrimos los puertos necesarios en el router. * Creamos una batería de scripts basados en rsync y SSH para sincronizar todos los ficheros de configuración necesarios y adaptar los que varían en el nuevo sistema (por ejemplo, el /etc/ddclient.conf). También deberían actualizar las bases de datos y reiniciar los procesos necesarios tras modificar la configuración. * Tener previstos otros scrips para pasar el servicio de un sistema a otro. Al final, esto sólo consiste en que el sistema que sea el primario actualice los registros DNS con su IP y el secundario deje de hacerlo. * Tras la estancia en el otro sistema, tendremos que sincronizar los cambios de vuelta al sistema principal y probablemente querramos recoger los logs que se hayan generado allí. Este sistema de respaldo no sólo nos puede servir en caso de tener que apagar nuestro servidor habitual. También lo podemos utilizar mientras hacemos tareas de mantenimiento o si en tenemos problemas con la conexión a Internet o estamos sufriendo un apagón. Los cortes de corriente Otro de los problemas con los que nos tendremos que enfrentar serán los cortes de corriente. Aunque no son muy frecuentes, de vez en cuando tendremos uno y tenemos que tener previsto qué hacer cuando ocurran. Si se trata de un breve corte, lo más importante es que el servidor arranque sólo cuando vuelva a recibir corriente. Para ello, tenemos que buscar el parámetro de nuestra BIOS que lo permite. Por ejemplo, en una VIA EPIA SP8000E, el parámetro se llama AC Loss Auto restart y podemos hacer que la máquina se encienda siempre cuando vuelva la luz, que no se encienda nunca o que vuelva al estado anterior: AC Loss Auto restart The field defines how the system will respond after an AC loss during system operation. Off: Keeps the system in an off state until the power button is pressed On: Restarts the system when the power is back Former-Sts: Restores the system to its previous state En una placa Asus A8N-SLI, el parámetro se llama Restore on AC Power Loss y sólo tiene dos valores posibles, activado o desactivado: Pero si queremos estar prevenidos de verdad ante cortes de corriente, la mejor opción es tener un SAI al que conectar el servidor y el router que da acceso a Internet. Si el servidor es un sistema de bajo consumo, tendremos bastante tiempo de margen para esperar a que vuelva la luz, o al menos, el tiempo suficiente para actualizar nuestro servidor de respaldo por si tiene que entrar en acción. Mantenimiento remoto La posibilidad de conectarnos por SSH a nuestro servidor casero siempre tiene que estar abierta. En mi experiencia, un servidor SSH abierto en Internet trae infinidad de intentos de conexión con reiteradas pruebas con distintos usuarios. Sin ir más lejos, hoy mismo, alguien ha probado 1520 combinaciones diferentes de usuario/contraseña en mi sistema # grep "Invalid user" auth.log.0 | grep "Mar 9" | wc -l 1520 Algunos ejemplos: Mar 9 06:15:05 telemaco sshd[6028]: Invalid user ibm from 61.250.91.34 Mar 9 06:15:09 telemaco sshd[6032]: Invalid user informix from 61.250.91.34 Mar 9 06:40:08 telemaco sshd[7742]: Invalid user stevie from 61.250.91.34 Mar 9 06:40:11 telemaco sshd[7746]: Invalid user kelly from 61.250.91.34 Mar 9 06:40:15 telemaco sshd[7750]: Invalid user rasoul from 61.250.91.34 Es por eso que lo mejor es deshabilitar completamente el acceso con usuario/contraseña y permitir exclusivamente la autentificación por clave pública/privada: Autentificación trasparente por clave pública/privada con OpenSSH. Cambiar el puerto del servidor SSH (por defecto 22) a otro también puede ser una medida útil para evitar algunos de estos insistentes intentos de acceso. Otra herramienta de mucha utilidad para el mantenimiento remoto es conectar un módem a nuestro servidor casero, tal y como vimos en: Configurar Linux para permitir el acceso remoto por módem a la consola y por RAS/PPP. En casos en que el router haya perdido la conexión a Internet, podemos tratar de conectarnos por módem y a través del interfaz de configuración por telnet del router tratar de reiniciarlo. Otra situación útil es en caso de una avalancha de peticiones en la que tú mismo no puedes acceder por el router por la absoluta falta de ancho de banda y, en ese caso, la entrada “por la puerta de atrás” nos puede servir para llegar al sistema sin usar Internet. ¿P2P y hosting casero? Supongamos que necesitamos bajarnos el último DVD de Knoppix por Bittorrent. ¿Es compatible el P2P con sus altas necesidades de ancho de banda con el HC? Pues en principio, puede serlo -en función del número de visitas que recibamos- siempre que limitemos el ancho de banda de subida disponible para P2P a un límite que permita servir los contenidos hospedados a una velocidad razonable. En el mejor de los casos, el uso de P2P en la misma conexión de un HC irá completamente en detrimento de la experiencia de nuestros visitantes, aunque sólo tengamos uno en ese momento, pero que notará que la página descarga más lenta. El mejor consejo al respecto es que si activamos el P2P, deberíamos de estar pendientes de que el tiempo de respuesta sea un mínimo aceptable probando nosotros mismos a conectarnos desde otro sistema de Internet. Si vemos que va muy lento, deberíamos desactivar el P2P. Por supuesto, en caso de un pico de visitas, deberíamos de desactivar el P2P inmediatamente. Scripting Cualquier administrador que se encargue de un servidor UNIX tiene que estar continuamente creándose scripts para no realizar las mismas tareas una y otra vez. Para nosotros, como administradores de nuestro HC no va a ser distinto. Deberíamos de tener unos conocimientos mínimos de scripting que nos serán muy útiles para hacer backups, para analizar logs, para monitorizar el estado de algún proceso, para enviar e-mails con advertencias, etc. A lo largo de este año, yo me he llegado a crear un buen número de scripts. La mayoría son muy específicos de mis necesidades particulares, pero me gustaría dejar aquí uno muy sencillito que nos manda un e-mail cada vez que el ISP nos cambia la dirección IP dinámica: #!/bin/bash cd /root/scripts_ip mv -f ippublica ippublica.old ./ippublica.sh > ippublica if ! diff ippublica ippublica.old > /dev/null then cat cabecera ippublica | mail -s "La IP del servidor ha cambiado - `date +\"%g/%m/%d %H:%M\"`" [email protected] fi El ippublica.sh puede ser, bien una petición por SNMP al router para ver cuál es la IP del interfaz de WAN: snmpwalk -c comunidad -v 1 192.168.1.1 IP-MIB::ipAdEntAddr|egrep -v '0\.0|192\.168' | awk '{print $4}' bien un acceso a checkip.dyndns.org: /usr/bin/wget -q -O - http://checkip.dyndns.org/index.html | /usr/bin/fromdos | /bin/sed 's_<html><head><title>Current IP Check</title></head><body>Current IP Address: __' | /bin/sed 's_</body></html>__' El fichero cabecera es algo como: La IP del servidor es ahora: Conclusión En esta entrada he tratado de recopilar lo más importante de lo que me ha sido necesario conocer durante un año completo de autohospedaje en el que creo que el resultado ha sido bastante satisfactorio. Por carambolas del destino, ahora ya he pasado a un hosting profesional, pero la travesía ha valido la pena y la repetiría tantas veces como hiciera falta. Si alguien tiene intención de adentrarse en esta aventura ha de saber que aprenderá mucho y espero que en estas líneas encuentre consejos que le sean de utilidad, como creo que me hubieran sido a mí. También hay que tener en cuenta que también es posible tener un hosting casero sin tomárnoslo muy en serio, de forma que no nos importe en absoluto si tenemos la página caída varios días seguidos, pero creo que si nos ponemos, vale la pena hacerlo lo mejor posible. No hay nada que dé peor impresión en Internet que una página que tarda en cargar o que cada dos por tres esté caída. Esa no es la forma de fidelizar a nuestros lectores. El HC es un poco como tener un perro en casa. Puede ser divertido, te dará muchas satisfacciones, pero a cambio ganas muchas obligaciones: Tienes que estar pendiente de él, te da trabajo y no puedes irte de vacaciones sin buscarle un acomodo. :wq
Te has preguntado como unir 2 CPU y trabajen como una sola bueno este proceso se llama cliustering, y en este tutorial voy explicar como hacerlo asi que por favor sigan los siguientes pasos y no se salten ninguno plis!!! Tutorial de un Cluster Beowulf Casero - Primera Parte Cuando hablamos de clusters, se nos viene inmediatamente a la mente NASA, universidades y lugares con muchos recursos y conocimientos. Pero un cluster es solo dos o mas computadores funcionando como uno para desempeñar tareas de forma mas rá pida y eficiente. Generalmente no tenemos la necesidad de correr aplicaciones en paralelo como individuos ya que no hacemos cosas que requieran grandes velocidades; de todas formas, para nosotros los curiosos, es interesante ver como contruimos y corremos un "supercomputador" en nuestra casa. 1. Requerimientos En mi caso, hice un cluster con 2 computadores, el primero (y mas poderoso) lo llame unix.oz, mientras que el otro se llamo billy.oz: unix.oz: AMD ATHLON K7 600 mhz 256 mb RAM 4.1 Gigabytes de DD SiS 900 PCI (Tarjeta de Red) Red Hat Linux 7.2 Kernel 2.4.7-14 billy.oz CYRIX 233 mhz 32 mb RAM 2 Gigabytes de DD Fast Ethernet 10/100 Genius Red Hat Linux 7.2 Kernel 2.4.7-14 Como sólo tenía 2 computadores, no necesite un hub o switch, los conecte mediante un cable cruzado... 2. Configurando el cluster Un cluster tipo Beowulf funciona con uno de dos librerías de trasnferencia de mensajes: MPI (Message Passing Interface) o con PVM (Parallel Virtual Machine). Cuando son compiladas, estas librerías pasan información o data entre las má quinas (o nodos) del cluster. Ambos usan el protocolo de comunicacion TCP/IP. Tambié n usan el programa rsh (esto es muy inseguro desafortunadamente pero en un cluster casero no importa tanto) para iniciar las sesiones entra las má quinas. Este comando (rsh) permite correr comandos UNIX remotamente. Yo preferi tratar con PVM, y lo siguiente se debe hacer para cada computador que se desee paralelizar, voy a usar unix.oz: 1. Entrar como root al sistema 2. En /etc/hosts 192.168.1.1 unix.oz unix 192.168.1.2 billy.oz billy 3.Crear el archivo /etc/hosts.equiv. Este contiene el nombre de las máquinas al que rsh puede acceder unix.oz billy.oz 4. Reiniciar y entrar como un usuario "normal". 5.Probar la red: desde unix.oz hice ping billy.oz. Si no funciona, deben arreglar la configuracion de su red, si funciona, pasar a paso número 6. 6.Ahora a probar rsh: desde unix.oz hice rsh usuario_de_billy "ls-l". Si funciona debería mostrar una lista del directorio de un usuario del otro computador. De lo contrario,es VITAL resolver ese problem.a 7. ***Si algo no funciona, no hay que continuar hasta arreglarlo **** 3. Instalar y configurar PVM Yo usé la versión 3.4 de Parallel Virtual Machine (descargable de http://www.epm.ornl.gov/pvm/pvm_home.html). 1.La bajé a /home/unixoz y como uso Bash, añadí lo siguente a .bashrc PVM_ROOT=$HOME/pvm3 PVM_DPATH=$PVM_ROOT/lib/pvmd export PVM_ROOT PVM_DPATH *** Ojo: Esto puede variar dependiendo de la distro, kernel, etc. Si no usas Bash, ve en el README al descomprimir PVM**** 2. Salir del sistema y entrar nuevamente a $HOME (/home/unixoz) 3. tar zxvf pvm-3.4.tgz 4. cd pvm3 y luego en $HOME/pvm3 correr make 5. Si todo sale bien hay que ejecutar pvm Deberías ver pvm> (para salir solo hay que poner halt) 6. Repetir el proceso con cada computador 7.Luego puse pvm y para ver cuantos computadores tengo en el cluster puse conf (solo me salió uno, ya que aun debemos agregar los otros) 8.Para agregar a billy.oz puse add billy.oz y ahora al poner conf me salen unix.oz y billy.oz AHORA YA TENEMOS UN CLUSTER DE TIPO BEOWULF!!!!!!!! 4. Recursos Ahora debes aprender a escribir programas en paralelo o usar PVMPOV, un programa para crea imá genes "super" digitales y diseñado para clusters (http://www.povray.orghttp://www.povray.org) Pronto publicaré un tutorial para este, ya que aun no lo manejo del todo bien. Tutorial de un Cluster Beowulf Casero [2da parte] En la primera parte de este tutorial vimos como crear y configurar un cluster beowulf para usar una herramienta llamada PVM. En este artículo veremos que cosas podemos hacer con nuestro recié n creado cluster. Una de las principales utilidades son las librerías para la programación en C, y FORTRAN. En este artículo solo veremos la parte de C, ya que FORTRAN es un lenguaje que no manejo. Es importante adelantar que lo que viene es para personas que ya tienen un nivel intermedio o avanzado de la programación en C, esto NO es un tutorial de C. 1. Tecnicas Basicas de la Programación Paralela Creando aplicaciones para PVM continúa con lo tradicional de la programación de memoria distribuida de multiprocesadores, como es el nCUBE de Intel. La computación en paralelo puede ser visto desde tres aspectos bá sicos, todas basadas en la organización de las tareas que requieran el uso de nuestro cluster. El modelo má s común para programar con PVM es el crowd o multitud; es un conjunto de procesos similares (tienen el mismo código) pero que ejecutan distintas fracciones de un todo, o la tarea total. El segundo es el té rmino llamado tree o á rbol, aquí los procesos son copiados de forma tripartita, creando una relación padre e hijo. Esta té cnica, aunque no es muy usada, permite encajar aplicaciones de las que no sabemos nada apriori. La tercera es el hybrid o híbrido, y es una combinación de las dos anteriores; en cualquier punto de la ejecución de una aplicación la relación entre los procesos de carga puede cambiar. Estas tres clasificaciones nos pueden ayudar con la topología de nuestro cluster, en mi caso, gracias a esto puedo añadir un tercer nodo fá cilmente, sin afectar la configuración de unix.oz y billy.oz. A continuación está n las dos primeras de forma má s detallada. 2. Cómputos CROWD Estas generalmente usan tres fases. El primero es la inicialización del grupo; el segundo es el cómputo mismo; y el tercero es el conjunto del output (lo que devuelve el programa al usuario), durante esta fase el grupo de nodos pueden terminar una sesión. A continuación se puede ver a travé s de un programa de multiplicación de matrices el uso de esto por medio del algoritomo de Pipe Multiply Roll: {Matrix Multiplication Using Pipe-Multiply-Roll Algorithm} {Processor 0 starts up other processes} if (<my processor number> = 0) then for i := 1 to MeshDimension*MeshDimension pvm_spawn(<component name>, . .) endfor endif forall processors Pij, 0 <= i,j < MeshDimension for k := 0 to MeshDimension-1 {Pipe.} if myrow = (mycolumn+k) mod MeshDimension {Send A to all Pxy, x = myrow, y <> mycolumn} pvm_mcast((Pxy, x = myrow, y <> mycolumn),999) else pvm_recv(999) {Receive A} endif {Multiply. Running totals maintained in C.} Multiply(A,B,C) {Roll.} {Send B to Pxy, x = myrow-1, y = mycolumn} pvm_send((Pxy, x = myrow-1, y = mycolumn),888) pvm_recv(888) {Receive B} endfor endfor 3. Cómputos TREE Para mostrar mejor como esto crea un proceso parecido a la estructura de un á rbol podemos usar un algoritmo de Parallel Sorting del MIT donde un proceso procesa, para luego compilar un segundo proceso. Ahora hay dos procesos, y ambos se copian nuevamente para generar dos má s y así sucesivamente, creando una estructura de un á rbol. Cada proceso es independiente del otro. Este es el código desarrollado por la MIT: { Spawn and partition list based on a broadcast tree pattern. } for i := 1 to N, such that 2^N = NumProcs forall processors P such that P < 2^i pvm_spawn(...) {process id P XOR 2^i} if P < 2^(i-1) then midpt: = PartitionList(list); {Send list[0..midpt] to P XOR 2^i} pvm_send((P XOR 2^i),999) list := list[midpt+1..MAXSIZE] else pvm_recv(999) {receive the list} endif endfor endfor { Sort remaining list. } Quicksort(list[midpt+1..MAXSIZE]) { Gather/merge sorted sub-lists. } for i := N downto 1, such that 2^N = NumProcs forall processors P such that P < 2^i if P > 2^(i-1) then pvm_send((P XOR 2^i),888) {Send list to P XOR 2^i} else pvm_recv(888) {receive temp list} merge templist into list endif endfor endfor 4. C Para Aplicaciones con PVM Ahora que ya conocemos lo bá sico de la programación en paralelo, podemos comenzar a explorar las librerías que nos oferece PVM. Cada programa de PVM debe incluir la librería está ndard, o sea debemos añadir al comienzo de nuestro programa: #include <pvm3.h> Las funciones de PVM generalmente se llaman con: info=pvm_mytid() info es un int (número entero) que devuelve esa funcion, si pvm_mytid() devolverá una número negativo si ocurre un error. Cuando finaliza un programa PVM, es recomendable usar la función pvm_exit(). Para poder escribir un programa en paralelo, las tareas deben ser ejecutados en diferentes procesadores, para esto se usa pvm_spawn(). Esa función se usa de referencia para los computos tree. Se llama: numt=pvm_spawn(mi_tarea, NULL, PvmTaskDefault, 0, n_task, tids) La pvm_spawn() copia mi_tarea en el nodo que elige PVM. PVM tiene mucha información a la que podemos acceder, como con pvm_parent(), pvm_config(), pvm_tasks(), etc. 5. Compilando Nuestros Programas Para compilar mi_programa.c, se usa las siguentes extensiones gené ricas que nos ofrece PVM: gcc -L directorio/donde esta pvm3/lib/ARQUITECTURA mi_programa.c -lpvm3 -o foo Donde ARQUITECTURA generalmente sera LINUX, al no ser que estemos usando otro sistema operativo como BSD, DARWIN, MACINTOSH, etc. Despué s de compilar debemos poner el ejecutable en el /directorio donde esta pvm3/bin/ARQUITECURA. La compilación se debe hacer separadamente en cada arquitectura de los nodos de nuestro cluster. Luego debemos dejar corriendo el demonio de PVM (pvmd) en cada nodo, con el comando pvm y luego ponemos quit para acceder a la consola: pvm> quit Finalmente podemos correr nuestra aplicación en paralelo. Aún queda mucho que ver sobre la programación de C en paralelo y PVM, en la tercera parte y final de este tutorial veremos como se comunican nuestras tareas, balanceo de carga, etc. Para poder ver ejemplos de código fuente estan en /directorio donde esta pvm3/examples Tutorial de un Cluster Beowulf Casero [3ra parte] 1. Comunicación entre Tareas Ya es la hora de ponerse a programar aplicaciones que realmente valen la pena. Para esto es imprescindible conocer las distintas formas de ponder hacer que las tareas se puedan comunicar entre si; con PVM, esto se hace por medio de las message-passing. Para poder mandar un mensaje de A a B, A debe llamar pvm_initsend(). Esto limpia el buffer y especifca un mensaje; bufid=pvm_initsend(PvmDataDefault) es generalmente usado para esto. Despué s del inicio, la tarea para mandar debe tomar toda la información que se quiera mandar y convertirla a un buffer especial para distribuirlo entre las taras (ie: A & B); esto se hace con la función pvm_pack() (la cual es muy parecida a la famosa printf()). Tambié n hay funciones para arreglos (arrays en inglé s) de tipos de datos únicos; como la pvm_pkdbl(). Para mayor información recomiendo buscar en las pá ginas man. Cuando ya esta todo esto listo, la tarea esta preparada para ser enviada, esto se hace por medio de pvm_send(). info=pvm_send(tid, msgtag) Esta función enviará el mensaje en el buffer a la tarea con la task id (ver 2da parte) de la tid. Esta nombra la tarea con la variable (tipo int) msgtag. Un mensaje tag es útil para decirle a la tarea cual recibirá el mensaje que tipo de dato va a recibir. Por ejemplo, un mensaje de tag 9 puede significar la suma de los números en el mensaje, mientras que un tag 3 puede significar la su división. pvm_mcast() es una función bastante parecida ya que hace los mismo que la pvm_send(), solo que la pvm_cast() toma varios tids en vez de uno. Conviene usarla cuando se envien varios mensajes a un conjunto de tareas. La tarea que recibe el mensaje llama a la función pvm_recv() para recibirlo. bufid=pvm(tid,msgtag) esperará que la tarea llame a la función anterior. Con la nueva PVM3.3 se añadió la pvm_trecv(), la cual se deja de esperar a la tarea que reciba en un periodo de tiempo determinado, así permitiendo mayor fluidez en los programas. Tambié n esta la pvm_probe(), esta sólo le dice a la tarea que ha llegado un mensaje, y luego se termina. Ya cuando la tarea ha recibido un mensaje, debe desempacar la información con pvm_unpack() (la opuesta a pvm_pack()). 2. Balanceo de Carga El balanceo de carga es muy importante para las aplicaciones. Asegurarse que cada nodo esta haciendo la tarea que debe y como lo debe hacer puede hacer o deshacer un cluster beowulf. La forma má s fá cil se llama balance de carga está tica. Este mé todo consiste en la división de tareas para ser procesadas sólo una vez. La división es mejor hacerla antes que comience el trabajo. Otra forma de balancear la carga de tareas es la Pool of Task Paradigm o el paradigma del Conjunto de Tareas. Consiste en un programa maestro / esclavo (donde el maestro es el administrador de tareas); el maestro manda a los esclavos trabajos. Este sistema no se recomienda implementarlo en clusters con programas que requieren una comunicación entre tareas, ya que las tareas paran y comienzan en tiempos determinados. 3. Consideraciones en Cuanto a Rendimiento La programación en paralelo puede ser una actividad entretenida e interesante para todo aficionado de la programación, pero hay algunas cosas que pueden hacer que nuestros programas fallen o no funcionen como nosotros queramos. La granularidad. Es decir la proporción entre la cantidad de bytes recibidos por un proceso a el número decimal de operaciones o tareas que realiza. int NumeroBytesRecibidos() : float NumeroOperacionesRealizadas() Cantidad de mensajes enviados. Se demora menos el enviar pocos mensajes pesados o con mucha información que enviar varios mensajes con poca información. Esto es cierto, excepto cuando hay programas en donde se especifica lo contrario. De todos modos, la cantidad de mensajes es específico para cada plataforma y programa. Algunas aplicaciones funcionan mejor con paralelismo funcional, mientras que otras para paralelismo de datos. En la primera, distintas má quinas hacen distintas tareas (dependiendo de su capacidad). Por ejemplo un supercomputador puede resolver un problema de matemá tico o de física vectorial, una estación de trabajo grá fico puede usarse para visualizar datos en tiempo real. En el paralelismo de datos la información es distribuida a todas las tareas del cluster (o má quina virtual). Las operaciones son pasadas entre procesos hasta que el problema se resuelva. Tomar encuenta la red tambié n es importante en un cluster. El poder de procesamiento depende de cada computador (hay diferencias mínimas hasta en procesadores de la misma marca y misma velocidad). Esto puede alterar el dinamísmo de las cargas de las má quinas o nodos. Para solucionar esto, recomiendo usar un programa de balance de carga. 4. Recursos 4.1 Depuradores Xmdb - Depurador para programas paralelas (recomendado para principiantes) http://www-c8.lanl.gov/dist_comp2/mdb/mdb.html P2D2 - Depurador portable, creado por la NASA http://www.nas.nasa.gov/NAS/Tools/Projects/P2D2 4.2 Balances de Carga & Organizadores de Tareas CONDOR - http://www.cs.wisc.edu/condor CraySoft NQE - http://www.cray.com/craysoft Para terminar... ...cluster Beowulf en casa de unixOZ Aca un video tutorial sobre la medicion de consumo del cluster: link: http://www.videos-star.com/watch.php?video=U8bZsoGa1Lo Por favor comenten comentar no cuesta nada!!!

[b] EL MEJOR MANUAL PARA CONSTRUIR GUITARRA ELÉCTRICA [/b] Con este manual serás capaz de construir tu propia guitarra eléctrica a un precio accesible. En este manual vienen técnicas básicas y avanzadas de diseño de guitarra eléctrica. Curso Construye tu Guitarra Electrica - Construir una guitarra no solo puede ser un hobby o una profesión, sino también un arte. ¿Alguna vez quisiste modificar algunos detalles tecnicos de tu propia guitarra y encontraste dificultades por falta de conocimientos? ¿o tener una guitarra eléctrica de calidad y economica a su vez? No es necesario que seas un luthier profesional para para que te animes y puedas retocar, armar, o aprender a construir tu guitarra eléctrica. - Con este curso aprenderas a fabricar tu propia guitarra eléctrica, basado en el plano de un diseño incluido en el mismo. La plantilla incluida, te permitirá realizar el molde del diseño base para la construcción de la guitarra. El curso detalla una lista de materiales, aunque también podremos seleccionar los accesorios y materiales económicos que deseemos y que esten a nuestro gusto y alcance. - ¿Te Gustaria Construir Esta Misma Guitarra Electrica? Quizas te parezca imposible hacerlo pero no es así. este curso que te enseñará como construir una guitarra eléctrica con todos los detalles técnicos demostrados paso a paso. - Todo sobre Materiales necesarios, herramientas, el cuerpo, el diapasón, los trastes, pruebas técnicas, terminado de la guitarra y seteo final. El curso incluye el plano del modelo de guitarra a diseñar con gran definición y resolución, junto con toda la información para armarla. - Además si eres aficionado a las guitarras, no solo te servirá para construir una, sino también para poder saber como modificar algunos de los detalles técnicos de la guitarra que ya tienes. La unica guia completa totalmente en español. - CONTENIDO DEL MANUAL - INTRODUCCIÓN Madera - Materiales - Plunge Router - Pegamento - Presentación - Plantilla - EL CUERPO Cortar el cuerpo - Limpiar Ajustar - Lijar Costados - Lijar Cuerpo - Redondear Bordes - Perforaciones - Empernar Cuello - Encajar Tremolo - Cavidades - EL DIAPASON Cortar Clavijero - Preparar Superficie - Reducir Diapason - Pegar Diapason - Canal del Alma - Tapa del Clavijero - Marcar Trastes - Limpiar / Ajustar - Forma del Cuello - Puntos del Costado - Lijar el Radio - TERMINAR / SETEAR Lijado Final - Aplicar Aceite - Aplicar Cera - Ensamblaje - Setear la Guitarra - Guitarra de Jazz ¿QUE DISEÑO DE GUITARRA? Tu eliges el diseño de tu preferencia. Si sigues al pie de la letra lo que dice este manual serás capaz de construir tu propia guitarra eléctrica y serás la envidia de tus amigos. Tambien aqui tienes un video por las dudas: link: http://www.videos-star.com/watch.php?video=skCZCCUWtHk Saludos taringueros. Espero que les guste mi post
Configurando mi Cuenta Email en Domain Live para abrirlo en hotmail.com 1. Ingresar a http://domains.live.com/ , 2. Click sobre el botón Sign In que está bajo de Already using this service? 3. Logueate con una cuenta hotmail que tengas 4. Click sobre Add Domain 5. Escriba el dominio que quieres asociar a Windows Live y presiona Continue 6. Presiona I Accept 7. Baja la nueva pantalla hasta ubicar los datos que necesitarás modificar en tu panel de domino: 8. Ahora, ingresa a tu panel de control de tu dominio. 9. En el lado izquierda, bajo la sección My Products, click sobre Domains 10. Click sobre el nombre del dominio listado que estás asociando con Windows Live 11. Ubica la sección Total DNS: (Available) , luego click sobre Total DNS Control and MX Records 12. Ubica la sección MX (Mail Exchange) 13. Borra los parámetros que allí se muestran, presionando sobre la imagen X, al final de la fila de cada parámetro. Al presionar la X te pedirá confirmación, presiona Aceptar. 14. Luego en la misma sección MX (Mail Exchange), aparecerán los parámetros como Pending Removal. 15. Presiona sobre el botón Add New MX Record 16. Y llena los espacios del formulario tal como muestran los datos del paso 7, (sección MX Record Configuration: (required) en los datos que te provee Domainslive). 17. Y presione OK, luego confirma de nuevo presionando OK. 18. Luego ubica la sección TXT (Text) que se encuentra más abajo y cliceka sobre Add New TXT Record. 19. Llena las cajas de texto con los datos provisto en Windows Live en la sección Sender ID Configuration (recommended) 20. Y presione OK, luego confirma de nuevo presionando OK. 21. Los parámetros nuevos agregados aparecerán Pending Setup, luego de unos minutos aparecerán sus opciones con la imagen de un lápiz para modificar y X para eliminar, y estará completo la configuración. 22. Regresa a la página de Domains Live y dale click sobre Refresh, esto actualizará las configuraciones hechas en tu panel de dominio, 23. Ahora para agregar correos en Windows Live , presiona sobre el botón Add 24. En la ventana que se abre escribe los datos correspondientes según tú elijas, tales como nombre de tu correo, nombre y apellido del propietario del correo y contraseña; luego presiona OK. 25. En la imagen de arriba, si tú marcas Require password change at first login, significa que la primera vez que te loguees a tu cuenta email através de hotmail.com, te pedirá cambiar tu password, si no lo marcas entonces seguirá siendo el mismo que pusiste al principio. 26. Tú podrás ver tus correos y acceder a tu cuenta desde http://mail.live.com ó hotmail.com Sino te funciona avisa a: [email protected] Yo te ayudo