AddThis Social Bookmark Button
AddThis Feed Button
Bio
Mi avatar Blog de un pequeño informaticú y sus ocurrencias y pequeñas notas de ayuda.
Citas
Loading Quotes...
100_9939
100_9938
100_9937
100_9936
100_9935
Categorias
links
16
Abr

PHP : Identificar la IP Real del Usuario

(QR Code)

PHP

Cuando estaba haciendo el sistema de estadísticas de la web, me vino a la mente que muchos usuarios de los que tengo constancia que visitan o iban a visitar en un futuro la página navegan habitualmente tras un proxy. Yo quería almacenar las IPs de cara a una futura ampliación de las estadísticas en las que añadiera una localización geográfica, además de distinguir y eliminar mis propias visitas para una mayor transparencia dichas estadísticas.

Buscando información acerca de obtener la IP real (en los casos en los que fuera posible) me tropecé con un artículo interesante sobre como los distintos proxies alteran los datos del navegador para enmascarar su propia IP.

Por lo general el navegador envía la cabecera $_SERVER[\'REMOTE_ADDR\'] al servidor con la IP original del usuario. Si este no estuviera detrás de un proxy, esa sería la IP deseada, pero… ¿Cómo altera el proxy esta cabecera para ocultar los datos reales?

Todo depende del tipo de proxy que se esté utilizando. Un proxy Transparente, copia el contenido de $_SERVER[\'REMOTE_ADDR\'] en la cabecera $_SERVER[\'HTTP_X_FORWARDED_FOR\'] para justo a continuación colocar la suya propia en el $_SERVER[\'REMOTE_ADDR\'] confundiendo en el mayor de los casos a las páginas visitadas.

El resto de proxies son bastante más seguros, y no dan lugar a la obtención de la IP original (lo que en principio es lógico, ya que la mayoría de la gente los utiliza para ello). Los proxies Anónimos pueden ser de varios tipos, y cada uno de ellos oculta la información de una manera característica. Los simples, añaden su IP en ambas cabeceras, los ruidosos van un paso mas lejos, tratan de engañar aún más generando de forma aleatoria una IP para el \'HTTP_X_FORWARDED_FOR\' y ponen la suya en el \'REMOTE_ADDR\' ergo a los ojos de la página seria difícil discernir de un proxy de tipo transparente.

Los mas complejos son los de alta anonimicidad, ya que únicamente cambian la cabecera \'REMOTE_ADDR\' con su propia IP y dejan \'HTTP_X_FORWARDED_FOR\' en blanco, por lo que es prácticamente imposible determinar si se esta usando un proxy o no.

Después de esto ya estamos listos para enfrentarnos al código que comparte con nosotros Patxi Echarte en su página y que en encontrado de lo más útil.

function getRealIP()
{
         if ( $_SERVER['HTTP_X_FORWARDED_FOR'] != '' )
    {
        $client_ip =
            ( !empty($_SERVER['REMOTE_ADDR']) ) ?
                $_SERVER['REMOTE_ADDR']
                :
                ( ( !empty($_ENV['REMOTE_ADDR']) ) ?
                    $_ENV['REMOTE_ADDR']
                    :
                    "unknown" );
    
        // los proxys van añadiendo al final de esta cabecera
        // las direcciones ip que van "ocultando". Para localizar la ip real
        // del usuario se comienza a mirar por el principio hasta encontrar
        // una dirección ip que no sea del rango privado. En caso de no
        // encontrarse ninguna se toma como valor el REMOTE_ADDR

    
        $entries = split('[, ]', $_SERVER['HTTP_X_FORWARDED_FOR']);
    
        reset($entries);
        while (list(, $entry) = each($entries))
        {
            $entry = trim($entry);
            if ( preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/", $entry, $ip_list) )
            {
                // http://www.faqs.org/rfcs/rfc1918.html
                $private_ip = array(
                        '/^0\./',
                        '/^127\.0\.0\.1/',
                        '/^192\.168\..*/',
                        '/^172\.((1[6-9])|(2[0-9])|(3[0-1]))\..*/',
                        '/^10\..*/');
    
                $found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]);
    
                if ($client_ip != $found_ip)
                {
                    $client_ip = $found_ip;
                    break;
                }
            }
        }
    }
    else
    {
        $client_ip =
            ( !empty($_SERVER['REMOTE_ADDR']) ) ?
                $_SERVER['REMOTE_ADDR']
                :
                ( ( !empty($_ENV['REMOTE_ADDR']) ) ?
                    $_ENV['REMOTE_ADDR']
                    :
                    "unknown" );
    }
    
    return $client_ip;
    
}

Espero que os sea de utilidad y gracias de nuevo a Patxi por su artículo.


Nadie ha comentado (aun...)

No hay comentarios

Quieres dejar un comentario?