获取用户的真实ip

常见的坑有两个:

一、获取的是内网的ip地址。nginx作为代理层,转发请求到php,java等应用容器上。结果php获取的是nginx代理服务器的ip,表现为一个内网的地址。

二、获取的是攻击者伪造的ip地址。攻击者可以随便伪造一个头部信息,随便填写一个ip放到头部发过来,php获取到HTTP_CLIENT_IP。为避免伪造,不要使用discuz原来的获取ip函数,里面的判断优先级会使得攻击者容易伪造ip。

php代码:


function getIP() {

if (getenv("HTTP_X_FORWARDED_FOR")) {

//这个提到最前面,作为优先级,nginx代理会获取到用户真实ip,发在这个环境变量上

$ip = getenv("HTTP_X_FORWARDED_FOR");

} else if (getenv("REMOTE_ADDR")) {

//在nginx作为反向代理的架构中,使用REMOTE_ADDR拿到的将会是反向代理的的ip,即拿到是nginx服务器的ip地址。往往表现是一个内网ip。

$ip = getenv("REMOTE_ADDR");

} else if ($_SERVER[‘REMOTE_ADDR‘]) {

$ip = $_SERVER[‘REMOTE_ADDR‘];

} else if (getenv("HTTP_CLIENT_IP")) {

//HTTP_CLIENT_IP攻击者可以伪造一个这样的头部信息,导致获取的是攻击者随意设置的ip地址。

$ip = getenv("HTTP_CLIENT_IP");

} else {

$ip = "unknown";

}

return $ip;

}

说明

不能通过REMOTE_ADDR来获取用户的真实ip!

因为反向代理架构: nginx作为一个前端代理,转发请求到php,java等应用程序上去,nginx和php不在同一台物理服务器上。

在nginx作为反向代理的架构中,php的REMOTE_ADDR(其他语言也是类似的名称)拿到的将会是nginx代理的ip地址。拿不到用户的真实ip。

REMOTE_ADDR本意就是远程的地址,nginx是代理层,转发请求到php,php获取到的远程地址是nginx的服务器地址,这是符合常理的。

但是,可以让nginx帮助我们拿到用户的真实ip,然后转发给我们,只要按照某个约定的名称即可,比如预定HTTP_X_FORWARD_FOR。

nginx配置类似于这样:

fastcgi_param  HTTP_X_FORWARD_FOR  $remote_addr;

$remote_addr是nginx的内置变量,这个变量它得到是用户真实的ip地址(用户使用了代理,则就是代理的ip地址)。

上一句的目的是,将HTTP_X_FORWARD_FOR的值设置为$remote_addr的值。也就是将用户真实的ip放到HTTP_X_FORWARD_FOR中去。

于是在php端通过getenv("HTTP_X_FORWARDED_FOR")就可以获取到真实的ip地址。

注:

1、getenv(‘HTTP_X_FORWARD_FOR‘);等价于$_SERVER[‘HTTP_X_FORWARD_FOR‘]; getenv也是获取环境变量的值的。

2、nginx作为反向代理时,统一使用 HTTP_X_FORWARD_FOR来重置用户的真实ip,遵循统一的风格。以保证所有系统的开发,都可以通过"HTTP_X_FORWARD_FOR"获取到用户真实的ip地址。

时间: 2024-10-06 22:32:17

获取用户的真实ip的相关文章

PHP获取用户的真实IP地址

本文出至:新太潮流网络博客 PHP获取用户的真实IP地址,非代理IP function getClientIP(){ global $ip; if(getenv("HTTP_CLIENT_IP")){ $ip = getenv("HTTP_CLIENT_IP"); }else if(getenv("HTTP_X_FORWARDED_FOR")){ $ip = getenv("HTTP_X_FORWARDED_FOR"); }e

IpUtils获取用户请求真实ip工具类

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; /** * IP工具类 * @author justin.zheng * @date 2020/2/12 15:08 */ public class IpUti

如何获取用户的真实IP

在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了 Apache,Nagix等反向代理软件就不能获取到客户端的真实IP地址了.如果使用了反向代理软件,用 request.getRemoteAddr()方法获取的IP地址是:127.0.0.1或 192.168.1.110,而并不是客户端的真实IP. 经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的 IP,服务器端应用也无法直接通过

怎么使用PHP获取用户客户端真实IP的解决方案呢?

function getIp(){if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))$ip = getenv("HTTP_CLIENT_IP");else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv(

使用CDN后,PHP如何获取用户的真是IP?

在统计访问日志参数的时候IP是一个重要的参数,所有索取客户端的IP就至关重要. 在log_format配置中有两个变量是获取IP地址的: remote_addr:客户端IP x_forwarded_for:客户端的IP 从上面来看两个都是客户端IP,那这两个变量有什么不同? 首先当你访问某个网站,假设你中间不经过任何代理,那么webserver就会把remote_addr当成你客户端的IP,但是你使用代理了或者服务端有代理的情况下webserver获取的remote_addr就不准确了,这时候就

安装mod_rpaf让apache获取访客真实IP

安装mod_rpaf让apache获取访客真实IP 安装mod_rpaf让apache获取访客真实IP 作者:朱 茂海 /分类:Apache 字号:L M S mod_rpaf是apache的一个模块,目的是为了获取访客的真实IP,下面是安装方法: wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz tar xvfz mod_rpaf-0.6.tar.gz cd mod_rpaf-0.6 /usr/local/apach

获得用户的真实IP地址

/** * 获得用户的真实IP地址 * * @access public * @return string */if (!function_exists('get_real_ip')){ function get_real_ip() { static $realip = NULL; if ($realip !== NULL) { return $realip; } if (isset($_SERVER)) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])

使用nginx反向代理时,如何正确获取到用户的真实ip

在记录日志的的时候,获取用户的信息,比如用户的ip,浏览器等等信息是十分重要的. 但是在使用nginx反向代理的时候,可能经过转发无法获取到用户的真实的ip, 在此情况下需要配置nginx,让其在转发的时候在header 带上用户的真实的ip. 举个例子: server { listen 80; server_name xxx.lenny.net; root D:\soft\nginx-1.11.4\html; index index.php index.html index.htm; add_

php中获取用户登陆的IP地址以及常规处理

本文为原创,转载请注明!  在我们开发多站点业务网站中,经常需要获取客户端的ip地址来给用户推荐其所在地址的信息的业务,用php获取客户端的ip地址,我们一般用到的PHP内置方法是$_SERVER['REMOTE_ADDR']. 但是这个函数只能获取访问者本地连接中设置的IP,局域网网关出口的IP地址,如果访问者使用代理服务器,将不获取代理服务器的IP,而是获取访问者网关的真实IP.如果将这个函数应用到限IP访问的网页中,别人即使通过限IP访问段中的代理服务器,也不能访问该页面. 所以我们一般为