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 = preg_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.
Más información
Pues poco te puedo ayudar con esto… creo que OpenSSL te servirá para generar y validar las claves, y lo único que se me ocurre que te pueda aportar, es que quizás no necesites el textarea para la llave pública, quizás te valga con generar un certificado, instalarlo en el navegador y configurar el servidor de forma acorde, aunque como te digo, poco más te puedo decir, no me ha tocado nunca hacer nada de esto, así que te hablo sólo de lejos.
Hola Patxi.
Mi nombre es Jose y te felicito por la web.
Tengo dudas con respecto el código web para poder saber las ip de los visitantes.
Aquí tienes el código que le he puesto a mi web:
$ip = getRealIp(log.txt)
El caso es que quiero ver las IP de los visitantes a través de un archivo
(log.txt). Me lo descargo del servidor y está totalmente en blanco.
¿Qué está mal en el código?
Hola Jose, estás pasando log.txt a la función pero ésta no acepta ningún parámetro. Si lo que quieres es escribir la ip que te devuelve getRealIp en el archivo log.txt lo que tendrías que hacer es ejecutar $ip = getRealIp(); y luego abrir el archivo log.txt en modo escritura (append) y escribir una línea con el valor de la variable $ip. Para ello mira en php.net/fwrite y php.net/fopen.
¿ Como puedo saber la direccion IP de un cliente ?
Les agradeceria mucho si me ayudaran es de suma urgencia ..
ahaha y muy buena esta pagina ..
Felicitaciones..
como puedo saber la direccion ip de un cliente? y con eso sabre mas informacion del cliente y de su equipo?
la dirección ip del cliente la puedes obtener (en algunos casos) con el código que se indica arriba. Con eso sabrás la dirección ip, otra cosa es lo que hagas con ella, por supuesto hay cosas que se pueden obtener a partir de ella, pero eso queda fuera de este post 😉
Saludos, disculpa, estoy empezando con esto de php y tengo instalado el easyphp en ambiente windows xp, bueno el chiste es que copie el script del post para probralo, pero resulta que no me aparece nada al momento de ejecutarlo, me podrias decir por favor como hago para que me aparezca en pantalla la ip o lo k tenga k aparecerme, de antemano te agradezco, gracias, nos vemos.
Adrian, lee los comentarios anteriores, está explicado en uno de ellos.
Hola, estoy comenzando en php, esto de como guardar las ip pues no lo entiendo muy bien, ?si alguien pudiera explicarme brevemente esto se lo agradeseria.
La dirección IP de la pagina Hotmail es 216.74.180.189
La dirección IP de la página http://www.meebo.com es 65.19.140.246
buena la intencion.. pero he probado la funcion en una pagina de prueba para ver si funciona correctamente..
Separando el tama de proxys, he tratado de ponerla a prueba en uso comun, nmandando el enlace a mi pagina por MSNMessenger y no captura la IP real, sino la IP del mismo MSN.. al igual, con tan solo enviar el enlace por email, con captura el Ip del router del cliente. incluso lo he probado conmigomismo, y solo funciona si se accede directamente a la web.
Hola, soy nueva programando y necesito que me ayuden en el tema de incluir este código a la página. Yo he hecho lo siguiente
y me sale error. Bueno, en realidad me gustaria guardarlo en un txt, pero no se como hacer esto…podrías ayudarme :S
Lo que hice fue incluir hacer include(‘ip.php’); y luego a una valiable $ip le asigne el valor getIPReal(); por ultimo echo «Su ip es $ip»;
Alisha, la función se llama getRealIP, no getIPReal, quizás sea eso.
no, me equivoque al escribir aquí, porque no me funciona con copy/paste :O, pero quisiera que me digas como podría hacer para guardar ese dato en un txt, donde crearlo, etc. Gracias !!
Saludos
En un comentario de más arriba explico en unas pocas líneas qué es lo que habría que hacer. Básicamente es abrir un fichero en modo append y luego escribir en él con fwrite. Mira el comentario y la documentación de php sobre fwrite en http://www.php.net/fwrite
Espero que te sirva, un saludo
saludos,
les comento mi situacion, tengo un formulario simple para capturar datos de contacto con HTML hecho en frontpage, para capturar los datos del formulario y enviarlos a un correo utilizo PHP, como puedo hacer para que ademas de los datos que las persona digitan, automaticamente el formulario me envie la IP publica de donde se genero el envio, GRACIAS
Manuel, si lees el artículo y los comentarios obtendrás la respuesta a la duda que planteas.
El script es excelente. Pero no logro solucionar el problema. En una base de datos Mysql guardo la ip de los que votan en mi encuesta, pero el registro que guarda es la ip de conexión y me pierdo de muchos votos. Existe alguna forma de detectar ip del cliente y no solo de conexión?.
Gracias!
si te refieres a que puede haber varios usuarios accediendo a tu web con la misma ip pública, y que por lo tanto todos parecen un único usuario, puedes probar varias cosas. Lo más sencillo por ejemplo sería añadir un tiempo de prohibición de repetición de voto más corto, pero podrías utilizar también un identificador de sesión o una cookie generada aleatoriamente, bien por tí manualmente o por algún modulo de apache
Disculpen que mi pregunta no sea de este tema específicamente, pero estoy tratando de hacer una Intranet donde necesito el uso de sesiones de usuarios. Una forma podría ser evaluando el «usuario», «contraseña» y «IPdelcliente» (ESTE ARTICULO) como número de sesión, pero con los problemas que se pueden presentar con los Proxys y un futuro acceso por VPN no lo veo conveniente. He escuchado que también se puede por cookies o asignándole un número de sesión a un usuario una vez que se leguee, pero hasta el momento no he encontrado ayuda de estas 2 opciones adicionales para enviar a todas las páginas un usuario resgistrado (logueado). Les agradezco cualquier ayuda.
Aclaro que los parámetros de «usuario», «contraseña» y «sesión» deben ser ocultos para evitar que personal cualquiera entre cambiando datos en la ruta ó URL. Gracias
Tienes información de cómo funcionan las sesiones en php en http://es2.php.net/manual/es/ref.session.php
¿como puedo saber las personas q visitan mi fotolog??, me dijeron q es mediante le ip, pero no tengo ni idea. gracias
Muchas gracias Patxi, me fue de mucha ayuda tu link sobre sesiones.
Muy interesante, si bien, he leído por otros sitios, que utilizar HTTP_X_FORWARDED_FOR no es seguro, porque es una variable que puede ser modificada por el usuario. También creo haber leído que el phpbb la utilizaba y tuvo que cambiar de método porque era inseguro. ¿Alguna información al respecto?
Por otro lado, si alguien es tan amable, me gustaría saber algún ejemplo de proxy anónimo. No entiendo muy bien el concepto, ya que aunque un proxy pudiera cambiar la ip aleatoriamente, el propio proxy no tendría una ip?? Si tuviéramos problemas con un usuario conectándose a través de un proxy. ¿no habría forma de bloquear todo ese proxy?
me parece interesante el tema…gracias yo estudio servidores.y diseño de paginas web no tenia mucha idea como funcionaban los proxys..solo se qeu ocultaban el IP.
Hola, he usado a perfección tu código… muchas gracias por la ayuda
Hola, a todos espero alguien pueda ayudarme, mi problema esta relacionado con las IP de los equipos que entran en un site para votar en una encuesta, tengo que lograr que solo puedan votar una vez en cada encuesta, soy nueva en estos menesteres asi es que ojalá la explicación sea sencilla.
Saludos y espero su ayuda.
Estoy usando la funcion getRealIp , bajo la intranet haciendo pruebas y solo me da la ip local en unos casos y en otros(desde linux) solo me da 127.0.0.1, he probado otras paginas y haciertan on mis 2 direcciones la publica y la privada, lo que asumo que mi proxy esta dejandole obtener esas cabeceras… En resumen la funcion no me funciona bajo mi intranet!
Supongo que el paquete no lleva las cabeceras simplemente por q no
sale del proxy ya que estan en intranet…
Corrijame si estoy errado… Gracias
En efecto Jose Luis, la función está pensada para su uso en internet. Si quieres obtener la dirección en una intranet local «sencilla» debería bastarte con utilizar REMOTE_ADDR. De todas formas yo encapsularía el acceso a esa variable en una función por si luego tienes que cambiar algo, para tocar solo un sitio.
El caso en el que te da 127.0.0.1, ¿es cuando accedes al web desde el propio servidor que lo contiene?. Si es así tiene sentido ya que estaría accediendo a él a través del interfaz loopback.
Desde Argentina, fenomenal el artículo, la función y el trabajo de contestar todas las preguntas!!!!
Grande Patxi!!!
Hola .. (tambien desde ARG.) muy bueno el articulo Patxi. De muchisima utilidad!. muy bien explicado. sos un fenomeno!
Excelente. solo lo copie y pegue y funciono inmediatamente. Gracias.
Hola patxi, por lo que veo tu eres lo mejor que hay en el site, y yo soy el peor, necesito ayuda, soy extremadamente nuevo en esto del php, tengo php y mysql5, quiero guardar en mysql las dirección ip que visitan mi sitio, y despues manipularlo para presentar reportes,, pero no tengo idea, aqui psan muchas opiniones, pero no se cual me sirve a mi en especifico !! ya tengo un contadoy y escribe la ip de donde se conectan, pero no se como guardarla!! gracias!!
Hola, me gustaria saber como encontrar el ip de un usuario en un foro? por favor ayudenme. GRACIAS
Hola a todos!
Solo me gustaria saber como pudo hacer para ver el numero de IP de los usuarios desde el msn messenger (windows live messenger)
Gracias!
Espero poder obtener la respuesta correcta!
Saludos!!
Buen trabajo el q realiza esta funcion , felicitaciones!!.
Creo q esto tambien se puede hacer capturando la direccion MAC del cliente de la siguiente manera:
$remoteIp = rtrim($_SERVER[‘REMOTE_ADDR’]);
$location = rtrim(`arp -a $remoteIp`);
print_r($remoteIp.$location);//display
$location = preg_replace(‘/\s+/’, ‘s’, $location);
$location = split(‘\s’,$location);//
$num=count($location);//get num of array elements
$loop=0;//start at array element 0
while ($loopClient MAC Address:- «.$location[$loop].»»;
$_SESSION[‘MAC’] = $loop;
return;
}
else {$loop=$loop+1;}
}
quizas este codigo le sirva a alguien q al igual q yo desea la direecion mac.
aunque si estas trabajando en una red bajo un servidor proxy creo q pasara lo mismo q en la funcion getRealip en donde si el servidor proxy es de alta confidencialidad solo se vera la dierccion mac de dicho proxy.
Muy bueno y muchas gracias
Muy buen articulo
En verdad que me parecio de mucha utilidad, me aclaro algunos conceptos que no tenia muy claros
Se agradece
SL2
Felicitaciones por el artículo, de verdad muy bueno!
Salu!2
Me pueden decir como hago para consegir el IP de una página web
javier:
desde una consola de msdos pon el comando
ping «pagina web»
ejemplo: ping http://www.yahoo.com
al indicar los paquetes enviados propios del comando ping, te dara el IP de la direccion web , en este ejemplo la de yahoo….
disculpen una preganta como puedo ocultar mi IP. = me lo detecta en la pagina, no se que hacer.
E usado diferentes proxis tor, hide ip ani…
ayuda porfavor q de debo hacer
la pagina q bloqueo es cabal online no permite q me resgistre
Una pregunta como puedo saber el IP de un correo recibido desde un correo de Yahoo hay forma??
Mil gracias me urge la información porque alguien esta acosando a mi novia y queremso saber la identidad de esta persona
el correo de la otra persona es de hotmail
Yo ya tengo la IP pero se puede saber quien lo envio?? como puedo saber quien es la persona?? me urge esta informacion si alguien pudiera ayudarme por favor!!!
Hola Roberto, si se puede!! no se muy bien como se logra, alguien me ayudo a mandar mis correos de yahoo a outlook y ahi de alguna manera se ve la IP, espero esto te ayude.. aunque lo importante es saber como hacer para saber de quien es esa IP, si logras tenerla y saber como, te agradeceria me informaras, gracias!