多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合


在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为 http://www.javapeixun.com.cn / 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.javapeixun.com.cn /index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110:2046/index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。

于是可得出获得客户端真实IP地址的方法一:

  
  
  1. public String getRemortIP(HttpServletRequest request) { 
  2.   if (request.getHeader("x-forwarded-for") == null) { 
  3.    return request.getRemoteAddr(); 
  4.   } 
  5.   return request.getHeader("x-forwarded-for"); 
  6.  } 

可是当我访问http://www.5a520.cn /index.jsp/ 时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问http://192.168.1.110:2046/index.jsp 时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:X-Forwarded-For: unknown

于是可得出获得客户端真实IP地址的方法二:

  
  
  1. public String getIpAddr(HttpServletRequest request) { 
  2.        String ip = request.getHeader("x-forwarded-for"); 
  3.        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
  4.            ip = request.getHeader("Proxy-Client-IP"); 
  5.        } 
  6.        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
  7.            ip = request.getHeader("WL-Proxy-Client-IP"); 
  8.        } 
  9.        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
  10.            ip = request.getRemoteAddr(); 
  11.        } 
  12.        return ip; 
  13.    } 

可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串Ip值,究竟哪个才是真正的用户端的真实IP呢?

答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。

如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110

以上方法还不行的话就采用如下方法:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 获取当前网络ip 
  3.      * @param request 
  4.      * @return 
  5.      */  
  6.     public String getIpAddr(HttpServletRequest request){  
  7.         String ipAddress = request.getHeader("x-forwarded-for");  
  8.             if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
  9.                 ipAddress = request.getHeader("Proxy-Client-IP");  
  10.             }  
  11.             if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
  12.                 ipAddress = request.getHeader("WL-Proxy-Client-IP");  
  13.             }  
  14.             if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  
  15.                 ipAddress = request.getRemoteAddr();  
  16.                 if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){  
  17.                     //根据网卡取本机配置的IP  
  18.                     InetAddress inet=null;  
  19.                     try {  
  20.                         inet = InetAddress.getLocalHost();  
  21.                     } catch (UnknownHostException e) {  
  22.                         e.printStackTrace();  
  23.                     }  
  24.                     ipAddress= inet.getHostAddress();  
  25.                 }  
  26.             }  
  27.             //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割  
  28.             if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15  
  29.                 if(ipAddress.indexOf(",")>0){  
  30.                     ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));  
  31.                 }  
  32.             }  
  33.             return ipAddress;   
  34.     }  

以上内容均来自网络。鄙人只是对其整合。望对大家帮助!
多级Nginx反向代理的架构中,确保后端服务器能够获取客户端真实IP的关键在于前端Nginx的正确配置以及后端Nginx对`NginxHttpRealIpModule`模块的支持。首先,前端Nginx需要在`location`块中设置`proxy_set_header X-Real-IP`和`proxy_set_header X-Forwarded-For`,这样可以确保HTTP请求头中包含了客户端真实IP信息。具体操作如下: 参考资源链接:[Nginx多级反向代理客户端IP转发与RealIP模块配置详解](https://wenku.csdn.net/doc/64531cebea0840391e76e44d?spm=1055.2569.3001.10343) ```nginx location / { proxy_pass *** *** $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_redirect off; } ``` 在这个配置中,`$remote_addr`变量包含了客户端IP地址,`$proxy_add_x_forwarded_for`则包含了经过所有代理的客户端IP信息。通过这些设置,后端服务器可以从HTTP头中提取到真实客户端IP。 接着,后端Nginx服务器需要启用`NginxHttpRealIpModule`模块。如果该模块未启用,需要通过编译Nginx时添加`--with-http_realip_module`选项来启用。然后在后端Nginx配置文件中使用`set_real_ip_from`指令来指定可信任的前端Nginx代理服务器或Squid服务器的IP地址范围,以及使用`real_ip_header`指令来指定哪个头信息字段包含真实IP地址: ```nginx set_real_ip_from ***.***.*.***; # 指定前端代理服务器IP real_ip_header X-Real-IP; # 使用X-Real-IP头字段 ``` 这样配置后,后端Nginx能够从HTTP头信息中提取并识别出真实客户端IP地址,而不是仅仅获得代理服务器的IP地址。 为了进一步理解这些配置的细节和应用场景,建议阅读《Nginx多级反向代理客户端IP转发与RealIP模块配置详解》。该资料详细讲解了Nginx在多级代理环境下的IP转发机制,并提供了丰富的配置示例和深入的故障排查技巧。这将帮助你更好地理解Nginx的反向代理功能,特别是在复杂的多级代理架构中,确保后端应用能够正确获取客户端真实IP地址。 参考资源链接:[Nginx多级反向代理客户端IP转发与RealIP模块配置详解](https://wenku.csdn.net/doc/64531cebea0840391e76e44d?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值