Mostrando entradas con la etiqueta PHP. Mostrar todas las entradas
Mostrando entradas con la etiqueta PHP. Mostrar todas las entradas

[PHP] Creando una firma dinamica


Introduccion

Buenas he estado sin tiempo para postear pero en esta ocasion les mostraré como crear una firma dinamica de manera que obtengan algunos datos, muchos ya saben como realizarlo por que no tiene tanta dificultad mas que nada se trata de utilizar la libreria de PHP GD.

Un buen tutorial que recomiendo mucho sobre PHP GD es el siguiente: http://wiki.elhacker.net/programacion/php/libreria-gd el cual esta muy bien explicado.
Tratare de ser breve colocando solo los pasos.

Estructura a realizar

La estructura con la que trabajaremos sera la siguiente:



Explicando un poco que hace cada archivo.

.htaccess - Con este archivo interpretaremos imagenes png (con su extension .png) como archivos php y bloquearemos cualquier intento de acceso al archivo logs.txt

firma.php - Con este archivo generamos la imagen dinamica (pronto le cambiaremos la extension a .png)

KeepCalm-Medium.ttf - Es el tipo de letra que utilizaremos para la firma dinamica.

logs.txt - Aqui guardaremos los logs, en este caso IP, Sistema, Si usa proxy.

rVJgsdx.png - Es la imagen que utilizaremos para la firma dinamica.

view_logs.php - Este es un archivo para ver los logs online. Con un simple formulario que tiene que ingresar una clave.

Nota importante: Nada de aqui es guardado en una base de datos. Y esto es facilmente explotable haciendo peticiones desde la misma IP un sin fin de veces cargaria todo el archivo logs.txt haciendolo demasiado pesado (Esa idea la hizo un amigo JhonJhon_123) entonces lo unico que podemos realizar en este caso es:

1.- Denegar las ips que realizen demasiadas peticiones
2.- No insertar IPS repetidas en el archivo logs.txt
3.- Cambiar el nombre de la carpeta para que no hagan mas peticiones.

Cualquiera de estos tres puntos no se ven en este tutorial.

Creando la firma

En este caso crearemos el archivo PHP para realizar la firma dinamica, no entrare en detalles de explicaciones ya que comente el codigo lo mas posible para que se entendiera, de todas maneras si no entienden algo, arriba deje una buena documentacion con la que pueden guiarse.

Código: PHP
  1.  <?php
  2.  // no reportamos errores
  3.  // el nombre de la imagen a poner como firma
  4.  $im_name = "rVJgsdx.png";
  5.  // los datos de la imagen
  6.  $data_im = getimagesize($im_name);
  7.  // el tipo de imagen
  8.  header("Content-type: {$data_im['mime']}");
  9.  // creamos la imagen en este caso png
  10.  $im = imagecreatefrompng($im_name);
  11.  // creamos un color para usarlo en el texto
  12.  $color = imagecolorallocate($im, 45, 196, 236);
  13.  // obtenemos la IP
  14.  $ip = $_SERVER['REMOTE_ADDR'];
  15.  // obtenemos los datos del navegador
  16.  $user_agent = $_SERVER['HTTP_USER_AGENT'];
  17.  // vemos si existe algun proxy (no es 100% fiable), y lo agregamos a la variable ip
  18.  $proxy_headers = array(
  19.         'HTTP_VIA',
  20.         'HTTP_X_FORWARDED_FOR',
  21.         'HTTP_FORWARDED_FOR',
  22.         'HTTP_X_FORWARDED',
  23.         'HTTP_FORWARDED',
  24.         'HTTP_CLIENT_IP',
  25.         'HTTP_FORWARDED_FOR_IP',
  26.         'VIA',
  27.         'X_FORWARDED_FOR',
  28.         'FORWARDED_FOR',
  29.         'X_FORWARDED',
  30.         'FORWARDED',
  31.         'CLIENT_IP',
  32.         'FORWARDED_FOR_IP',
  33.         'HTTP_PROXY_CONNECTION'
  34.     );
  35.     foreach($proxy_headers as $x){
  36.         if (isset($_SERVER[$x])) {
  37.          $ip .= "/Estas usando proxy!";
  38.          break;
  39.         }
  40.     }
  41.  
  42.     // reemplazamos los datos del navegador en caso de que sea firefox por firefox o chrome por chrome, la lista es corta se pueden agregar mas
  43.  $navegador = preg_replace('/.*(firefox|chrome).*/i', '$1', $user_agent);
  44.  // lo mismo que arriba en este caso con el sistema, igual podemos hacer la lista personalizable
  45.  $sistema = preg_replace('/.*(windows|mac|linux).*/i', '$1', $user_agent);
  46.  // guardamos los datos en una variable para usarla en el texto
  47.  $string = " Tu IP: $ip \n Tu navegador: $navegador \n Tu sistema: $sistema \n Te estoy vigilando!\n";
  48.  // asignamos una variable con la fuente para usarla en el texto
  49.  $fuente = "KeepCalm-Medium.ttf";
  50.  // en caso de que no se haya detectado nada mostramos el navegador, aunque nos trolleen xD :P
  51.  if($navegador == ''){
  52.   $navegador = $_SERVER['HTTP_USER_AGENT'];
  53.  }
  54.  // what? :3, Guardamos logs
  55.  $manejador = fopen("logs.txt", 'a+');
  56.  fwrite($manejador, "$string\n\n\n");
  57.  fclose($manejador);
  58.  // magia is here! Mostramos el texto en las coordenadas dadas
  59.  imagettftext($im, 10, 0, 300, 10, $color, $fuente, $string);
  60.  // png transparency, para la transparencia en la imagen sino se veria desfigurada
  61.  imagealphablending($im, true);
  62.  imagesavealpha($im, true);
  63.  imagepng($im);
  64.  // destroy image, liberamos la memoria
  65.  imagedestroy($im);
  66. ?>
  67.  
  68.  

Asignar formato a la imagen y denegar acceso a los logs

En este apartado crearemos el archivo .htaccess el cual denegara acceso a los logs y interpretara nuestro archivo png como php.

Citar
AddType application/x-httpd-php .png
<FilesMatch "\.(txt)$">
  Order Deny,Allow
  Deny from all
</FilesMatch>

Creando archivo para ver los logs

Por ultimo creamos nuestro archivo view_logs.php con el cual veremos los logs.

Código: PHP
  1.  <?php
  2.  if (isset($_POST['pass']) && !empty($_POST['pass']) && $_POST['pass'] == 'tucontraseñae.e') {
  3.   $gestor = fopen('logs.txt', 'r');
  4.   $contenido = fread($gestor, filesize('logs.txt'));
  5.   fclose($gestor);
  6.   echo "<pre>" . $contenido . "</pre>";
  7.  }
  8. ?>
  9. <form method="post" action="">
  10.  <p><input type="text" name="pass" /></p>
  11.  <p><input type="submit" name="enviar" /></p>
  12. </form>
  13.  

En este caso solo hay que cambiar tucontraseñae.e por la contraseña que le quieras asignar a la entrada.

Finalizando

Le cambiamos la extension al archivo firma.php y le ponemos el nombre que queramos en mi caso firma.png
Lo abrimos en el navegador para ver los resultados.


En este caso mi ip es ::1 ya que es una ip local.

Les dejo por ultimo los archivos por si quieren probarlo, igual pueden realizar el suyo propio cambiando algunas funciones como dependiendo del tipo de imagen que sea JPEG, PNG, etc. el tipo de letra, sus datos, etc. De igual manera con esto podrian crearse hasta generadores de firmas, saludos!

Archivos: http://www.mediafire.com/download/wr4yeydjyoyc397/firma_dinamica.rar

Redis como Session Handler en PHP


En este articulo se configurara dos Apache Server para que guarden las sesiones de los cliente en un Servidor Redis. De esta forma ambos servidores pueden acceder a las sesiones de los cliente.

La configuración es la siguiente:

Tengo 2 nodos:
  • Nodo A IP: 192.168.0.3
  • Nodo B IP: 192.168.0.12
En el Nodo A, esta corriendo los siguientes servicios:
  • Nginx Server
  • Redis Server
  • Apache Server

Nodo B:
  • Apache Server

Nodo A corre sobre Fedora 21, Nodo B corre sobre Fedora 20.



  • Los clientes realizan petición contra el servidor de Nginx
  • El Servidor Nginx enruta las peticiones hacia el Servidor Apache en el Nodo A. En caso de que el Servidor Apache del Nodo A no este disponible, entonces Nginx enrutara las peticiones hacia el Servidor Apache del Nodo B
  • Las sesiones que se crearan en el Servidor de Redis, y cada vez que se necesite leer la data de una sesion se realizara contra el Servidor de Redis


Como funcionan las sesiones.


Es necesario instalar y configurar en ambos Apache Server la extensión PHP-Redis que permite la comunicación con un servidor Redis: http://pecl.php.net/package/redis

Ambos Apache Server están corriendo sobre el puerto 8080. Nginx estará corriendo sobre el puerto 80 en el Nodo A. Utilizare el servidor de Nginx como Load Balancer para los Apache Server configurados en los dos nodos. El Apache Server del Nodo A, sera configurado como primario, y recibirá todas las conexiones entrantes. El Apache Server del Nodo B, sera configurado como Failover, osea que cuando el Apache Server del Nodo A no responda, entonce Nginx enrutará todas las conexiones hacia el Apache Server del Nodo B.

Configuración de NGINX
Código: INI
  1. upstream httpbackendserver {
  2.     server 192.168.0.3:8080;
  3.     server 192.168.0.12:8080 backup;
  4.  
  5.     }
  6.  
  7.     server {
  8.         listen       80 default_server;
  9.         server_name  localhost;
  10.  
  11.         # Load configuration files for the default server block.
  12.         include /etc/nginx/default.d/*.conf;
  13.  
  14.         location / {
  15.             proxy_pass http://httpbackendserver;
  16.         }
  17.  
    Directivas importantes:
    • upstream: sirve para definir un grupo de server. La usaremos para definir nuestro HTTP Server.
    • server: sirve para definir un servidor y sus parámetros. En este caso definimos el servidor del nodo B, con el parámetro backup.

    Luego de instalar la extensión de Redis para PHP, de haber reiniciado el servidor Apache, entonces hay que configurar PHP para que almacenes las sesiones en el servidor de Redis. De esta forma cada vez que se vaya a utilizar sesiones, hay que utilizar Redis como repositorios de las sesiones. Para indicar que Redis maneje la sesiones guardada, hay que configurar las directivas
session.save_handler y session.save_path del php.ini, de esta forma:
Código: INI
  1. session.save_handler = redis
  2. session.save_path    = tcp://redis-host:redis-port

En mi caso lo hice un poco mas portable, modifico las directivas desde un archivo PHP (teniendo en cuenta que la modificación solo tendrá efecto siempre y cuando se ejecute el mismo archivo PHP).

Código: PHP (brief)
  1. <?php
  2.  
  3. ini_set('session.save_handler', 'redis');
  4. ini_set('session.save_path',    'tcp://192.168.0.3:6379');
  5.  
  6.  
  7.  
  8. echo "Server 1,  ";
  9. if(!empty($_GET['set'])) {
  10.     $_SESSION['data'] = $_GET['set'];
  11. }
  12.  
  13. if(!empty($_GET['show']) && $_GET['show'] == 1) {
  14.  echo "Session data: ".$_SESSION['data'];
  15. }
  16.  
  17.  
  18. echo "Hola mundo";
  19. ?>

Tengo las siguientes URL:
  • 192.168.0.3/test.php?set=data_a_setear
  • 192.168.0.3/test.php?show=1
La primera URL se utiliza para setear información a la sesión data. La segunda URL se utiliza para ver la información que contiene la sesión data.




Bajo el servidor Apache del Nodo 1, para que Nginx enrute todas las peticiones hacia el servidor de Apache del nodo 2.



De esta forma se puede ver que Nginx ha enrutado todas las peticiones hacia el Servidor Apache en el Nodo B, y el Servidor Apache en el Nodo B utiliza la data de la sesiones creada en el Servidor Apache en el Nodo A.

Data de la sesion guardada en el Servidor de Redis:
Código: Bash
  1. [yoya@127 ~]$ redis-cli
  2. 127.0.0.1:6379> KEYS *
  3. 1) "PHPREDIS_SESSION:n30kep1lkgnks7knlkppps6c10"
  4. 127.0.0.1:6379> get "PHPREDIS_SESSION:n30kep1lkgnks7knlkppps6c10"
  5. "data|s:9:\"Underc0de\";"
  6. 127.0.0.1:6379>
  7.  


Este tipo de configuración se puede utilizar en ocasiones en la que es posible que no siempre el mismo servidor maneje la comunicación  con el mismo cliente. También en ocasiones en que se esta trabajando una mejora de la misma aplicación y se desea que los cliente no tengan ningún tiempo de inactividad en la transferencia de la aplicación vieja a la aplicación nueva.

También hay que tener en cuenta el acceso a la sesiones en Redis sera mas rápido que acceder a la información de la sesiones almacenadas en archivos en el sistema operativo, ya que la información en Redis reside en la memoria. Pero esta afirmación dependerá del contexto donde se encuentre los servidores.

Existe configuraciones similares para el manejo de sesiones como realizar un shared disk para almacenar los archivos de sesiones generados en los servidores.

Saludos!

URLs:
http://php.net/manual/en/session.configuration.php#ini.session.save-handler
http://php.net/manual/en/session.configuration.php#ini.session.save-path
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server
http://www.if-not-true-then-false.com/2011/install-nginx-php-fpm-on-fedora-centos-red-hat-rhel/
http://pecl.php.net/package/redis
http://phpave.com/installing-php-redis-a-php-extension-for-redis/

PHPSocketMaster 1.1 Sockets en PHP y Websockets de forma fácil!



Buenas tardes, la idea de esta librería es permitirle a los desarrolladores utilizar sockets en php, ésto puede servir para realizar conexiones a servidores, por ejemplo creando un bot irc, o para crear una librería como cURL pero completamente en php usando el protocolo HTTP y sockets. Por otra parte también les permite crear servidores, poniendo sockets a la escucha y recibiendo conexiones, para por ejemplo programar un servidor de IRC, o un servidor de chat. Tiene soporte para websockets, por lo que pueden crear un servidor para recibir conexiones desde un navegador, entre muchas cosas más (Hasta incluye la posibilidad de usar los sockets en hilos paralelos), en realidad los sockets nos permiten hacer mucho, hasta podríamos crear un servidor de http (como apache) hecho en php. Las posibilidades son infinitas.

¿Por qué usar PHPSocketMaster?
phpsocketmaster incluye la solución a muchisimos problemas que surgen en la creación de sockets en php, y te ahorran muchos problemas, además de llevar casi un año de desarrollo, que es exactamente el tiempo que te ahorras, está desarrollada para poder solventar cualquier necesidad que usted tenga.

Desde el inicio estamos desarrollando para tratar de hacer PHPSocketMaster completo, pero simple, los ejemplos son sencillos y fáciles de entender, y la documentación es extensa, en español.

Incluimos el protocolo de websocket completo, con la dificultad de definir una constante, y con esa constante automáticamente se activa todo el protocolo websocket.

Con la dificultad de definir una constante como "true" para activar todos los mecanismos de multihilos de los sockets.

Pero no incluye un mecanismo de gestión
Es verdad que PHPSocketMaster por si sola, no provee de los mecanismos para gestionar los sockets, y programarlos puede resultar engorroso y llevar a un monton de errores y problemas, como antes lo era manejar los sockets nativos de php sin la librería. Como sabíamos que te encantaría que te solucionemos todos estos problemas, te traemos la otra mitad de las soluciones! para ello desarrollamos una librería aparte complementaria de PHPSocketMaster llamada ServerSocket, que te provee de todos los mecanismos necesarios para gestionar con un código simple y rápido, con ejemplos y documentación, y crear tu servidor. (Repo aquí)

Desde ahora ya no tendrás problemas, en un par de minutos tendrás un servidor de sockets corriendo y solo tendrás que programar lo que sea que deseabas programar sin preocuparte por el funcionamiento, problemas, y dolores de cabeza que te hubiesen dado los sockets!

Para terminar
En fin vengo a publicar la nueva versión de PHPSocketMaster, en esta nueva versión traemos un par de novedades, un trait útil para ejecutar funciones cada cierto tiempo, o pasado cierto tiempo. Traemos muchisimos nuevos ejemplos actualizados a las ultimas funcionalidades de PHPSocketMaster (multihilos, websockets, sockets, etc.), también se mejoró la compatibilidad de las distintas formas de utilizar la librería porque en algunos casos resultaba ser bastante confuso.

Por supuesto se arreglaron varios errores de la versión anterior.

Pueden ver el repositorio, o ver la página de descarga, pueden ver la wiki, o los ejemplos. (Changelog aquí)

Autor: Alexander1712