Desde 1994 en la Red. La pagina de los aficionados a la electronica, informatica y otras curiosidades de la vida. No dudes en visitarnos.
Ahora 2 visitas.| 3408505 Visitas (desde Dic. 2011), hoy: 280 Visitas 698 Pag. Vistas , ultimos 36 dias: 10109 Visitas. 43984 Pag. Vistas. Tu IP: 18.119.213.235
Que ando curioseando:
AutosuficienciaCosas de casaElectronicaEn InternetInformáticaMundo MisticoSin categoríaSociedadTe lo recomiendo

Obtención de la IP real de una visita web en PHP

La forma más sencilla de obtener la dirección IP de un usuario en PHP es mediante la utilización de $_SERVER['REMOTE_ADDR'], sin embargo este valor no siempre es el que estamos buscando, hay veces en que las visitas llegan a nuestro web a través de proxys de que ocultan su dirección IP.

En la mayoría de los casos es aún posible obtener la dirección IP del usuario en estas situaciones, utilizando determinadas cabeceras. Pero antes conviene tener en cuenta las cabeceras que llegan al servidor web y los diferentes tipos de proxy que existen, para saber cómo funcionan y cómo obtener la dirección IP.

Cuando pedimos una página web el navegador se encarga de realizar la petición enviando una serie de cabeceras HTTP al servidor web. Estas cabeceras se hacen disponibles en el servidor web mediante variables de entorno que se añaden a las propias del servidor web, haciendo que tengamos disponibles variables como DOCUMENT_ROOT, HTTP_USER_AGENT, HTTP_ACCEPT_ENCODING, SERVER_ADDR, SERVER_PROTOCOL, HTTP_HOST… entre otras.

Aparte de estas variables de entorno provenientes tanto del cliente como del servidor, puede haber otras variables generadas a partir de cabeceras cuyo origen no es el cliente, si no algún sistema intermedio como proxys. En estos casos, cuando la petición web de un usuarios pasa a través de un proxy o anonimizador, estos pueden modificar las cabeceras del cliente o añadir nuevas, dependiendo del tipo de sistema que sea como veremos más adelante.

Para lo que nosotros necesitamos las siguientes son las variables de entorno más importantes:

REMOTE_ADDR: dirección ip del cliente
HTTP_X_FORWARDED_FOR: si no está vacío indica que se ha utilizado un proxy. Al pasar por el proxy lo que hace éste es poner su dirección IP como REMOTE_ADDR y añadir la que estaba como REMOTE_ADDR al final de esta cabecera. En el caso de que la petición pase por varios proxys cada uno repite la operación, por lo que tendremos una lista de direcciones IP que partiendo del REMOTE_ADDR original irá indicando los proxys por los que ha pasado.
Respecto al funcionamiento de los proxys y su interacción con la cabecera que genera la variable HTTP_X_FORWARDED_FOR, hay que tener en cuenta un par de cosas más. Por un lado la forma en la que los proxys concatenan la dirección del REMOTE_ADDR anterior al final de la cabecera no es siempre igual ya que en algunos casos se utiliza una coma y en otros un espacio. Por otro lado hay que tener en cuenta también que la primera dirección IP que viene en la variable HTTP_X_FORWARDED_FOR en algunas ocasiones es una dirección IP de las pertenecientes a los rangos de utilización privada. En estos casos partiendo de estas direcciones hay que continuar mirando el resto de direcciones disponibles hasta encontrar una del rango público.

Una vez vistas estas dos variables de entorno, conviene entender también, al menos de manera resumida, los diferentes tipos de proxy que existen.

Proxies transparentes
No ocultan la información IP de los clientes, únicamente la añaden a HTTP_X_FORWARDED_FOR dejando la suya en REMOTE_ADDR. El objetivo de estos proxys no es el de proporcionar anonimicidad en la red, sino la de cachear información o servir de punto de acceso común a Internet para varios equipos.

REMOTE_ADDR = IP-proxy
HTTP_X_FORWARDED_FOR = IP-cliente
Proxies anónimos
Estos proxies ocultan la dirección ip del cliente proporcionando una forma de navegar anónima. La forma en que ocultan la dirección ip del cliente hace que un proxy se clasifique en una de las siguientes categorías:

Simples
No se oculta el hecho de que se está utilizando un proxy, únicamente se guarda la dirección ip del proxy en ambos cabeceras, sin que aparezca por ningún sitio la del cliente.

REMOTE_ADDR = IP-proxy
HTTP_X_FORWARDED_FOR = IP-proxy
Proxys ruidosos
Son similares al anterior caso con la salvedad de que en vez de guardar su dirección ip HTTP_X_FORWARDED_FOR, guardan una generada aleatoriamente.

REMOTE_ADDR = IP-proxy
HTTP_X_FORWARDED_FOR = IP-aleatoria
Proxys de alta anonimicidad
Este tipo de proxys oculta el hecho de que se esté utilizando un proxy para realizar la petición. Para ello sustituyen la dirección IP existente en REMOTE_ADDR por la suya y no lo indican mediante ninguna otra cabecera, por lo que no es posible saber que se está utilizando un proxy.

REMOTE_ADDR = IP-proxy
HTTP_X_FORWARDED_FOR = sin-determinar
Código PHP
Una vez explicados esta serie de conceptos ya estamos en disposición de poder entender el siguiente código, cuyo objetivo es el de obtener la dirección IP real del usuario.

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;

}

Básicamente lo que hace la función es partiendo de la dirección indicada en REMOTE_ADDR obtener la dirección IP real. Si HTTP_X_FORWARDED_FOR es vacío la dirección que hemos obtenido previamente es la real (a no ser que se esté utilizando un proxy de alta anonimicidad). En caso contrario lo que se hace es obtener la lista de direcciones IP almacenada en HTTP_X_FORWARDED_FOR y buscar la primera que sea del rango público

Comentarios (1)

Penney27 marzo 2019 at 10:27

Gracias por cualquier otro weblog informativo. ¿Exactamente en qué otro sitio puedo estar escribiendo ese tipo de información de manera tan perfecta?
Tengo un proyecto que ahora simplemente estoy ejecutando, y he estado buscando esa información. ¡Volveré,
puesto que he marcado esta página como preferida y lo he twitteado a mis seguidores!

Escribe un comentario

Tu comentario