Publicado por & archivado en PHP, Programación.

En uno de mis proyectos, un chat bastante conflictivo, me encontré con el problema de detectar cuando los usuarios utilizaban un proxy para acceder, así como la IP real de los usuarios para introducirla en una base de datos.

 

Lo más sencillo es cargar la IP declarada en la variable REMOTE_ADDR:

$ip = $_SERVER['REMOTE_ADDR']; 

Pero es buena idea comprobar también otras variables utilizadas por distintos tipos de proxies.

 

Si existe la variable “HTTP_CLIENT_IP”, lo más probable es que el usuario esté tras algún NAT o router dentro de una red privada.


$_SERVER['HTTP_CLIENT_IP'];

Si existe las variables “HTTP_X_FORWARDED_FOR” o “HTTP_VIA”, con toda seguridad el usuario utiliza un proxy, que declara la IP de origen con esta variable.


$_SERVER['HTTP_X_FORWARDED_FOR'];
$_SERVER['HTTP_VIA'];

En los proxies transparentes, “HTTP_VIA” y “REMOTE_ADDR” declaran la misma IP (la que conecta con el servidor), y “HTTP_X_FORWARDED_FOR” declara la IP del cliente original.

 

Este tipo de proxy no trata de esconder al usuario, si no que le da paso desde una red local (empresas, organismos, universidades, etc), de redes o países con censura, o de servicios de caché como Opera Turbo.

 

En el caso del proyecto para el que utilizo esto, es importante saber si la IP es de un proxy y además saber si la IP de origen es de una red privada.

 

La “Autoridad de Números Asignados en Internet”, Internet Assigned Numbers Authority (IANA), ha reservado los tres siguientes bloques de direcciones IP para el uso en internets privadas:

127.0.0.0       -   127.255.255.255 (loopback 127/8)
10.0.0.0        -   10.255.255.255  (prefijo 10/8)
172.16.0.0      -   172.31.255.255  (prefijo 172.16/12)
192.168.0.0     -   192.168.255.255 (prefijo 192.168/16)

 

Además hay otros rangos de direcciones restringidas para ser enrutadas de forma pública por diversos motivos, hay un listado aquí:
http://en.wikipedia.org/wiki/Reserved_IP_addresses

 

En el proceso, asigno también un array $proxy con el nombre del tipo de proxy detectado, si es una IP no rutable en Internet (direcciones restringidas), y la IP declarada por el proxy.

 

Estos valores van luego a una base de datos que utilizo para determinar si los usuarios tratan de ocultar sus IPs, cargando las IPs declaradas y las reales y los marcadores que indican si se utiliza o no un proxy.

 

Se pueden usar estas funciones para detectar las IPs y proxies:


/**
 * @name Ejemplo de detección de proxy
 * @copyright (c)2015 Intervia IT
 * @link http://intervia.com/doc/detectar-conexiones-desde-proxy-y-la-ip-real/
 * @license MIT http://opensource.org/licenses/MIT
 */

//Valida una IP para que coincida con 123.123.123.123
//No admite IPs parciales, por ejemplo 123.123 dará error
function valida_ip($ip){
 $ip = preg_replace("/[^0-9 .]/i","",$ip);
 $divideip = explode(".", $ip);
 if (count($divideip) != 4) $ip = 0;
 $ip = sprintf("%u",ip2long($ip));
 if ($ip == 0){
 return false;
 }else{
 return true;
 }
}

//Detecta si una IP es restringida (no enrutable públicamente en Internet)
function detecta_ip_restringida($ip){

$restringida = 0;

//Si la IP tras un proxy es restringida, activa un marcador
//Estos rangos no sirven para uso público
//http://en.wikipedia.org/wiki/Reserved_IP_addresses

$ipl = sprintf("%u",ip2long($ip));
if (substr($ip, 0, 2) == '0.') $restringida = 1; //0.0.0.0/8
if ($ipl >= 167772160 && $ipl <= 184549375) $restringida = 1; //10.0.0.0/8
if ($ipl >= 1681915904 && $ipl <= 1686110207) $restringida = 1;//100.64.0.0/10
if ($ipl >= 2130706432 && $ipl <= 2147483647) $restringida = 1;//127.0.0.0/8
if ($ipl >= 2851995648 && $ipl <= 2852061183) $restringida = 1;//169.254.0.0/16
if ($ipl >= 2886729728 && $ipl <= 2887778303) $restringida = 1;//172.16.0.0/12
if ($ipl >= 3221225472 && $ipl <= 3221225479) $restringida = 1;//192.0.0.0/29
if ($ipl >= 3221225984 && $ipl <= 3221226239) $restringida = 1;//192.0.2.0/24
if ($ipl >= 3227017984 && $ipl <= 3227018239) $restringida = 1;//192.88.99.0/24
if ($ipl >= 3232235520 && $ipl <= 3232301055) $restringida = 1;//192.168.0.0/16
if ($ipl >= 3323068416 && $ipl <= 3323199487) $restringida = 1;//198.18.0.0/15
if ($ipl >= 3325256704 && $ipl <= 3325256959) $restringida = 1;//198.51.100.0/24
if ($ipl >= 3405803776 && $ipl <= 3405804031) $restringida = 1;//203.0.113.0/24
if ($ipl >= 3758096384 && $ipl <= 4026531839) $restringida = 1;//224.0.0.0/4
if ($ipl >= 4026531840 && $ipl <= 4294967294) $restringida = 1;//240.0.0.0/4
if ($ip == '255.255.255.255') $restringida = 1; //255.255.255.255/32

return $restringida;

}

//Función para detectar IPs y proxys
//Necesita las funciones: 
//detecta_ip_restringida y valida_ip
function detecta_ip(){

 //Carga la IP pública (declarada)
 $ip = $_SERVER['REMOTE_ADDR'];

 //Por defecto no hay proxy, inicializo array
 $proxy = array();

 /*
 * Normalmente sólo se declara un tipo de proxy y una IP
 * La deteccion va del tipo menos probable al más probable
 * Sólo se guarda una IP de proxy en $ip_proxy, pero se carga
 * un array con (tipo|restringida|ip) para separar con explode
 * que puede usarse para comprobar si hay más de un proxy declarado
 * en la misma conexión. En esos casos seguramente sean todas falsas.
 * tipo: (nombre del proxy detectado)
 * restringida: 0=Ip rutable en Internet, 1=IP NO rutable en Internet
 * ip: La IP declarada por el proxy
 */

 //Detecta Proxy tipo HTTP_VIA
 if (!empty($_SERVER['HTTP_VIA'])){
 $r = detecta_ip_restringida($_SERVER['HTTP_VIA']);
 $ip_proxy = $_SERVER['HTTP_VIA'];
 if ($ip == $ip_proxy) $ip_proxy = '';
 $proxy[] = 'HTTP_VIA|'.$r.'|'.$ip_proxy;
 }

 //Detecta si hay Proxy tipo HTTP_X_FORWARDED_FOR
 if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
 $r = detecta_ip_restringida($_SERVER['HTTP_X_FORWARDED_FOR']);
 $ip_proxy = $_SERVER['HTTP_X_FORWARDED_FOR'];
 if ($ip == $ip_proxy) $ip_proxy = '';
 $proxy[] = 'HTTP_X_FORWARDED_FOR|'.$r.'|'.$ip_proxy;
 }

 //Detecta si hay Proxy tipo HTTP_CLIENT_IP
 if (!empty($_SERVER['HTTP_CLIENT_IP'])){
 $r = detecta_ip_restringida($_SERVER['HTTP_CLIENT_IP']); 
 $ip_proxy = $_SERVER['HTTP_CLIENT_IP'];
 if ($ip == $ip_proxy) $ip_proxy = '';
 $proxy[] = 'HTTP_CLIENT_IP|'.$r.'|'.$ip_proxy;
 }

 //Si la IP no es válida porque un proxy declaró algo erróneo 
 //deja la IP declarada en REMOTE_ADDR y vacía la del proxy
 if (valida_ip($ip) == false){
 $ip = $_SERVER['REMOTE_ADDR'];
 }
 if (valida_ip($ip_proxy) == false){
     $ip_proxy = '';
 }

 //Comprueba si la IP del proxy es restringida
 $restringida = detecta_ip_restringida($ip_proxy);

 //Obtiene los nombres de host
 $host = gethostbyaddr($ip);
 if ($ip_proxy && !$restringida) $host_proxy = gethostbyaddr($ip_proxy);

 //Obtiene el user_agent
 $ua = trim($_SERVER['HTTP_USER_AGENT'],'\'');

 //Si el UA o host contienen uno de los nombres de redes anónimas, es un proxy
 if (stristr($ua,'Anonymouse')) $proxy[] = 'Anonymouse||';
 if (stristr($host,'tor')) $proxy[] = 'Tor||';
 if (stristr($host,'Anonymizer')) $proxy[] = 'Anonymizer||';
 if (stristr($host,'anonymous')) $proxy[] = 'Anonymous||';
 if (stristr($host,'anonine')) $proxy[] = 'Anonine||';

 //Devuelve el array con los datos
 return array($ip,$ip_proxy,$proxy,$restringida,$host,$host_proxy);
}

 

Esta función se puede llamar vacía como $ip = detecta_ip(); y devolverá un array con:


$ip[0] //Dirección IP pública (declarada)
$ip[1] //Dirección IP tras el proxy (pueden ser direcciones privadas)
$ip[2] //Array con todos los proxies detectados y las IPs declaradas
$ip[3] //La ip declarada por el proxy es restringida
$ip[4] //Nombre del host
$ip[5] //Nombre del host del proxy (si lo hay)

 

Para obtener la IP real, siempre que no sea restringida, se puede hacer esto (la IP real quedaría en $ip):


$ipd = detecta_ip();

//No hay proxy
if (!$ipd[2]) $ip = $ipd[0];

//Hay proxy y declara una IP NO restringida
if ($ipd[2] && !$ipd[3]) $ip = $ipd[1]; 

Con esto tendríamos la IP real del usuario, siempre que sea una IP enrutable, por ejemplo, un usuario que navega con Opera Turbo conectado muestra la IP de Opera si se usa para detectar la IP la variable  $_SERVER[‘REMOTE_ADDR’]. Con este código de arriba, la IP detectada será la real del usuario y no la del proxy de Opera Turbo.

 

Si se quiere la IP privada para algo, típico en redes empresariales y gubernamentales donde conectan con proxy, pero los equipos tienen IPs privadas:


if ($ipd[2] && $ipd[3]) $ip_privada = $ipd[1];

Se puede mostrar la IP declarada y la información sobre proxys con este código:


//Llama a la función para detectar la IP
$ipd = detecta_ip();

echo '<b>Dirección IP declarada: </b>'.$ipd[0].'<br>';

if($ipd[2]){
 echo '<hr align="left" width="500">';
 echo '<h3>PROXY DETECTADO</h3>';
 foreach($ipd[2] as $i){
 $infop = explode("|", $i);
 echo 'Tipo de proxy: <b>'.$infop[0].'</b><br>';
 echo '<b>IP tras el proxy: </b>';
 echo ($infop[2]) ? $infop[2] : 'No declarada';
 if ($infop[1]) echo ' (IP no enrutable en Internet)';
 echo '<br><br>';
 }
 echo '<hr align="left" width="500">';

}

En los proxies anónimos, todas las variables, incluida “HTTP_X_FORWARDED_FOR”, dan la misma IP, por lo que no es posible conocer la IP de origen, pero si que se está usando un proxy, lo que permite utilizar otras técnicas para identificar a los usuarios.

 

Hay un tipo de proxy anónimo que en vez de declarar la misma IP en “HTTP_X_FORWARDED_FOR”, declara una IP falsa generada aleatoriamente, esto es difícil de verificar y puede dificultar la detección de los usuarios, por lo que esta variable nunca la podemos tomar en consideración como totalmente fiable.

 

Queda pendiente la detección, mucho más difícil, de los proxies invisibles.   En un proxy invisible no es posible conocer la IP real del que conecta, pero saber si alguien utiliza uno de estos proxies puede ser interesante, especialmente cuando tienes un chat lleno de trolls.

 

La privacidad se ha vuelto algo muy importante, pero es como un cuchillo de doble filo, ya que se puede usar también para actos ilegítimos, como evitar que te puedan bloquear en un chat y seguir haciendo en vándalo.

 

Los proxies de la red de Tor son de los más problemáticos, ya que no sólo ocultan la IP real, si no que alteran otros datos de la conexión que pueden ser utilizados para detectar a los usuarios, por lo que en este caso opté por impedir la entrada desde esta red utilizando una clase de PHP para este propósito, escrita por Alexander Over: http://www.phpclasses.org/package/7214-PHP-Check-if-an-IP-is-TOR-network-exit-address.html


//Inicia detección de Tor
include_once "tor.class.php";
$tor = Tor::getInstance();

//Detección de Tor
$tor_detectado = var_dump($tor->setTarget($host)->isTorActive());

Para el resto de proxies invisibles utilizo varias fases de detección.

 

1.- Comparo la IP que conecta contra una lista conocida de proxies. Tengo una base de datos que he obtenido de fuentes públicas.

 

La coincidencia con una de esas IPs supone la detección fiable del uso de proxy. En esa misma base de datos se van añadiendo automáticamente los nuevos proxies invisibles detectados, así en cada nueva conexión que utilice uno de ellos, el tiempo de detección es mucho menor.

 

2.- Busco cadenas de redes de proxies conocidas como “Anonymouse”, “tor” y “Anonymizer” en el “USER_AGENT”. Esto es simple de hacer y efectivo (está incluido en la función de detección, publicada arriba, para los tipos más conocidos).

 

3.- Para detectar otros proxies invisibles he utilizado técnicas, que tienen como inconveniente que toman gran cantidad de tiempo y no pueden utilizarse en tiempo real, por lo que he puesto un archivo que cargo en el crontab cada 5 minutos y va analizando las IPs.

 

NOTA: Para evitar analizar dos veces la misma IP voy escribiendo un flag en cada registro.

 

Lo primero que hago es buscar los puertos abiertos de la IP que conecta con @fsockopen, busco los típicos puertos que usan estos proxies y otros que indican que puede tratarse de un servidor (21, 22, 23, 53, 80, 81, 88, 443, 554, 808, 1080, 3124, 3127, 3128, 3246, 6588, 8000, 8008, 8082, 8085, 8088, 8090, 8118, 8123, 8888, 8909, 9188, 36673).


//Carga los puertos en un array
$ports = array(21, 22, 53, 81, 88, 443, 554, 808, 1080, 3124, 3127, 3128, 3246, 
 6588, 8000, 8008, 8082, 8088, 8090, 8118, 8123, 8888, 8909, 9188, 36673);

//Recorre todos los puertos por cada IP
foreach($ports as $port) {

 //Comprueba si los puertos del array están abiertos
 if (@fsockopen( $ip, $port, $errno, $errstr, 1)){

 //Carga una lista separada por comas de puertos detectados
 if ($puertos) $puertos = $puertos.','.$port;
 }
}

La detección de los puertos abiertos podría hacerse también con nmap. Estuve probando una clase de Tomasz Malewski que permite entre otras cosas usar nmap:
http://www.phpclasses.org/package/4988-PHP-Analyze-the-local-network-with-nmap.html

 

Es posible que usando este sistema se puedan detectar algunos puertos filtrados o que tienen los ICMPs bloqueados, pero finalmente opté por usar @fsockopen porque nmap es demasiado lento.

 

La presencia de los puertos 21, 22, 53, 80 y 443, suele ser síntoma de que la conexión no pertenece a un ordenador doméstico, aunque esto no es 100% fiable es un buen indicador, por lo que marco la IP como sospechosa si los detecto.

 

Los puertos 23, 80 y 8085 están abiertos en muchos routers ADSL por lo que no es seguro basar una detección de proxy en ellos, sólo deben tenerse en cuenta como una puntuación o para hacer otras detecciones posteriores.

 

Si detecto alguno de estos puertos típicos de proxies, trato de cargar una página de mi propio servidor a través de ellos usando CURL, en cada uno de los puertos detectados.

 

Si lo consigo se con un 100% de probabilidad que es un proxy. Claro que si el proxy utiliza contraseña o tiene una IP de entrada distinta de la de salida, esto no funciona, pero son muy pocos los que hacen esto.

 

Algunas de las rutinas de detección que estoy usando aun las estoy probando, pero las publicaré en esta página cuando vea que funcionan bien.

 

————————————-
(16/12/2014) NOTA:
Las rutinas de detección tienen un problema, que estoy trabajando para solucionar hace un tiempo. Lo he detectado en un web de alto tráfico del que tratan de abusar redes mafiosas, en su mayoría desde IPs de China. Están enviado cabeceras con información falsa que indican que la conexión proviene de un proxy, del que entregan una IP inventada.  Esto puede hacerse fácilmente instalando el complemento “Secret Agent” de Firefox.

 

Este complemento no evita revelar la IP correcta, que aparece en la variable REMOTE_ADDR, pero si tienes un sistema de detección de proxies, se equivocará al tomar la IP falsa como la buena. Discernir entre ambas es muy difícil y si además el usuario usa un proxy de verdad, la cosa se vuelve aun más complicada.

 

Cualquier sistema automatizado para discernir entre la IP real y la falsa, pasaría por detectar si la IP es real y si la conexión proviene realmente de esa IP, algo que es bastante lento e impide usarlo en sistemas donde se necesite actuar en tiempo real.

 

He probado “Secret Agent” en varios webs de esos que te muestran la IP real tras el proxy y se la ha colado a todos, ni uno acierta, ya que se dejan engañar por las cabeceras falsas de proxy, como sucede con mis rutinas. Cuando tenga un método que pueda lidiar con esto actualizaré la información aquí.
————————————-

 

Hay una versión para pruebas de las funciones de esta página aquí:
http://intervia.com/ip

 

Si tienes alguna idea más que aportar a la detección de proxies, por favor deja tu comentario.

 

 

15 Comentarios para “Detectar conexiones desde proxy y la IP real”

  1. Sony Garcia

    Este tipo de informacion o comentarios siempre me parece muy interesante, te agradezco tu amabilidad por ponerlo en conocimiento de todos. Gracias

    Responder
  2. Chris

    Seria grandioso que nos puedas brindar la base de datos de las ips yo tambien ando en un problema similar, gracias por la informacion

    Responder
  3. HackHades

    Simplemente genial… Excelente! Gracias. Espero poder implementarlo pronto y probarlo pero sobre todo poder contar contigo para futuras dudas o inquietudes :)

    Responder
  4. juan

    hola no entiendo mucho de esto, pero me estan ostigando por mail y quisiera saber si existe un soft que pemirta saber que ip es???? y con eso el usuario.
    gracias

    Responder
    • Juan

      No, no hay ningún software que haga eso.

      Se puede conocer el servidor que entregó el correo, pero haría falta acceder a los registros del servidor de origen (el que entregó el email a nuestro servidor), y en último término a que usuario de ese servidor pertenece, para lo que probablemente haría falta la colaboración de los administradores de ese servidor.

      Si el que envió el email utiliza algún sistema anónimo y conecta camuflado su identidad, por ejemplo desde la red Tor, averiguar quien es el autor podría ser muy difícil incluso con una orden judicial, de todas formas, en caso de acoso la única solución viable es denunciarlo a las autoridades.

      Responder
  5. Polymeric falcighol derivation

    La red TOR es actualmente la única forma que la gente tiene de escapar al control del poder en internet, y librarse de las mordazas puestas a la libre expresión. Cuándo aprendereis que bloquear a los usuarios anonimos es hacerle el caldo gordo a los tiranos que quieren tener a los internautas sometidos a sus caprichos?

    Responder
    • Juan

      Polymeric,

      Primero, aquí no trato de temas políticos, no es el lugar adecuado, esto es un blog para tratar cuestiones técnicas.

      Dicho esto, comprendo muy bien lo que dices, pero la red Tor tiene dos caras, una la de permitir la libre expresión, y otra la de delinquir y hacer el troll con impunidad.

      En este caso el desarrollo fue encargado para un chat de una asociación de ateos, un chat privado de acceso libre, donde no se guardan registros de conversaciones y donde cualquiera puede conectar sin más que escribir un nick y sin registros ni contraseñas y sobre una conexión SSL, diseñado con la idea de proteger la privacidad y libertad de expresión de los usuarios, algunos de países donde ser ateo es un problema grave.

      Por desgracia, esto propició que personas sin escrúpulos usaran esa libertad para insultar, amedrentar y tratar de inutilizar el chat mediante ataques al sistema y flooding, sólo porque era usado por personas con una forma de pensar diferente.

      Así que este desarrollo impide el acceso usando proxies, incluidos los de Tor y registra los nicks y las IPs para detectar desde un panel a los atacantes, para que el moderador pueda detectarlos y expulsarlos con facilidad, objetivo que logramos cuando la asociación ya habían decidido cerrar el chat por la imposibilidad de usarlo.

      Por desgracia, el uso de proxies, y no sólo de Tor, sino muchos otros, hacía imposible detectar a estos pocos usuarios que casi consiguen destruir el servicio, por tanto, se tomaron estas medidas para impedir justamente que se vulnerara el derecho de libre expresión de los usuarios del chat.

      Esto, además, se hizo por consenso con la mayoría de usuarios legítimos del servicio, que estaban hartos de los constantes ataques.

      No obstante, el servicio permite conectar mediante proxy a usuarios que lo necesiten, previa solicitud de registro, ya que estas medidas de bloqueo se aplican sólo a usuarios, precisamente, anónimos.

      Es decir, es todo lo contrario de lo que afirmas en este caso, donde lo que estamos haciendo es propiciar el uso anónimo del servicio, aconsejando no usar nombre reales ni información personal para salvaguardar la privacidad de los usuarios.

      Creo es un error que vayas a un lugar dedicado a la programación a hacer juicios éticos, pero además, en este caso concreto te has equivocado por completo al juzgar los motivos.

      La información que ofrezco puede ser usada de forma correcta o incorrecta, pero no soy quien para juzgar los motivos de cada uno.

      Lo que está claro es que si alguien no quiere que accedas a sus servicios mediante proxies, tendrá sus motivos, pero eso no te obliga a acceder sin ellos, es bien sencillo, el que quiera acceder al chat que lo haga desde su IP, si quiere usar un proxy que se registre y si no, es bien fácil, nadie le obliga a conectarse a ese chat.

      Por cierto, para que veas que esto no es nada raro, prueba a crear una cuenta en Gmail desde un proxy o desde Tor, para activar la cuenta, Google te pedirá que introduzcas un número de teléfono al que enviarte un mensaje o hacerte una llamada con un código, porque este sistema se ha usado para crear cuentas y usarlas para enviar spam.

      No siempre está la privacidad detrás del uso de sistemas de acceso anónimo.

      Responder
  6. Jose Luis

    Hola Juan.

    Lo primero de todo, muchas gracias por compartir el codigo. Parece ser de mucha utilidad y ademas bien construido.

    Unicamente queria hacerte un comentario y una pregunta.

    El comentario es que en la función “detecta_ip()”, haces uso de la variable “$ip_config” pero al no declarar ésta al principio de la función no siempre queda definida. En ocasiones (si el usuario no navega a traves de un proxy), saltará un error de variable no definida. Por otro lado, si “valida_ip($ip_proxy)” es false, te cargas la variable, por lo que mas adelante saltará de nuevo un error. Ocurre lo mismo en la parte final del codigo con la variable “$host_proxy” (solo se declara si entra en un if). Podría solucionar esto simplemente declarando ambas variables como cadenas vacias al principio de la funcion (aunque entiendo algo de PHP no soy muy versado con esto de las IP’s, proxies y demas). Es decir, no se si con esto bastaría o haría falta una modificación mas “fina” de la funcion. También,…el unset bastaría con cambiarlo por un $ip_proxy = ”??

    Es que no se si al hacer estas modificaciones voy a “joder” algo de la función y tirar por tierra alguna parte de su funcionalidad.

    En cuanto a la pregunta….comentas al final de tu entrada que estabas intentando mejorar el codigo. ¿Conseguiste algun avance significativo? Es decir, yo la funcion en general la veo muy completa, pero no se si a dia de hoy la habrías mejorado.

    Un saludo y de nuevo gracias tanto por tu tiempo en compartirla como por tu interes. ;)

    Responder
    • Juan

      Lo que sugieres está perfecto, tienes razón que no es buena idea borrar la variable ya que vuelve con el array de respuesta y podría causar problemas, lo he cambiado.

      Sobre las mejoras, lo tengo en espera en mi gestor Kanban, pero tengo una avalancha de trabajo y esto ahora mismo no es lo más urgente, aunque he hecho algunas pruebas.

      Si un usuario está usando un plugin como el de “Secret Agent” enviará junto a la IP correcta en REMOTE_ADDR, otras falsas como si fueran proxies. Lo que hay que hacer es guardar un registro y hacer comparaciones, si lo declarado es siempre la misma IP en REMOTE_ADDR y varias distintas en las otras variables, habrá que marcar que se están manipulando las variables y tomar la IP de REMOTE_ADDR como la correcta.

      Otra cosa que se puede hacer es verificar si las IPs declaradas en HTTP_VIA, HTTP_X_FORWARDED_FOR y HTTP_CLIENT_IP son reales, estos módulos generan IPs aleatorias, por lo que si una de esas IPs no existe, está claro que se está haciendo trampa.

      El código que verifica los puertos abiertos es también útil, muchos proxies tienen abiertos puertos como el SSH o FTP que son mucho más raros en equipos domésticos.

      En cualquier caso, lo que se haga supondrá siempre analizar las IPs, por lo que podría ser necesario un proceso en segundo plano o habría que hacer esperar al usuario, según la aplicación será más conveniente una cosa u otra.

      En un chat conflictivo que mantengo hay un proceso en background que va analizando las IPs en segundo plano, el administrador va viendo como los datos se van actualizando, primero aparece información básica y según se escanean puertos, se mira el propietario de la red y se analizan datos del equipo, la información se va cruzando.

      Así por ejemplo un usuario que dice conectar desde Argentina, si tiene una IP de Australia o usa una zona horaria de México, es detectado como una anomalía.

      De todas formas no usamos estos factores para rechazar directamente una conexión, sino para darle una puntuación y cruzar con otros datos y es el administrador quién decide.

      Esto lo estoy desarrollando también dentro de una serie de clases que estoy programando para hacer pagos en la pasarela de Redsys, las clases de ejemplo que dan me dieron ganas de sacarme los ojos, así que lo reescribí desde cero y ahora lo estoy mejorando entre otras cosas con un sistema de puntuaciones para tratar de detectar pagos fraudulentos.

      La propia plataforma tiene ya alguna detección, pero aun así estoy añadiendo varios análisis de las IPs para generar puntuaciones, junto a datos que devuelve Redsys, como el país emisor de la tarjeta.

      Así, si un usuario paga con una tarjeta emitida en Alemania desde Nigeria y además la IP usa un proxy o sale por alguna red anónima, entonces detengo la operación hasta que se verifique que es legítima.

      Responder
  7. Jose Luis

    Hola Juan. El otro dia deje un comentario (un poco extenso) pero veo que sigue sin estar publicado. No te ha llegado? Ha llegado pero no lo publicas por algun motivo?

    Un saludo

    Responder
    • Juan

      No se que regla ha saltado, pero fue al spam y me ha costado encontrarlo entre esa basura de miles de mensajes, por suerte llevo unos días sin vaciarlo.

      Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada.