首页 > 其他分享 >多级反向代理[Squid]下获取客户端真实IP地址

多级反向代理[Squid]下获取客户端真实IP地址

时间:2023-08-21 17:02:55浏览次数:46  
标签:ip Squid request 192.168 IP地址 IP 客户端


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

  这段时间在做IP统计的程序设计,由于服务器作了集群,使用了反向代理软件,将http://192.168.1.110:2046/的URL反向代理为http://www.xxx.com/的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。这是什么原因呢?

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

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


1 
   
 public 
  String getIpAddr(HttpServletRequest request)  
 {
2      String ip = request.getHeader("x-forwarded-for");
3      if(ip == null || ip.length() == 0) {
4            ip = request.getRemoteAddr();
5        }
6        return ip;
7    }


  可是当我访问http://www.xxx.com/index.jsp/时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问http://192.168.1.110:2046/index.jsp时,则能返回客户端的真实IP地址,写了个方法去验证。

1 
 <% 
 @ page import="java.util.*"  
 %> 
 
 
  2 
 < 
 table  
 border 
 =1  
 cellspacing 
 =0  
 cellpadding 
 =0  
 align 
 =center 
 > 
  
 
  3 
 < 
 tr 
 > 
  
 
  4 
 < 
 th 
 > 
 Name 
 </ 
 th 
 > 
  
 
  5 
 < 
 th 
 > 
 Value 
 </ 
 th 
 > 
  
 
  6 
 </ 
 tr 
 > 
  
 
  7 
 <% 
  
 8Enumeration enumNames; 
 9String strName,strValue; 
10
11enumNames = request.getHeaderNames(); 
12while(enumNames.hasMoreElements()){ 
13    strName = (String)enumNames.nextElement(); 
14    strValue = request.getHeader(strName); 
15     
 %> 
  
 
 16 
      
 < 
 tr 
 > 
  
 
 17 
      
 < 
 td 
 > 
 <% 
 = 
 strName 
 %> 
 </ 
 td 
 > 
  
 
 18 
      
 < 
 td 
 > 
 <% 
 = 
 strValue 
 %> 
 </ 
 td 
 > 
  
 
 19 
      
 </ 
 tr 
 > 
  
 
 20 
      
 <% 
  
21} 
22 
 %> 
 
 
 23 
 < 
 tr 
 > 
 
 
 24 
 </ 
 table 
 > 
 
 
 25

  出来的结果:X-Forwarded-For: unknown 。X-Forwarded-For确实存在,但其值却为unknown,继续找原因。上网搜了搜,原因出在了Squid上。

squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:

X-Forwarded-For: unknown

一查,发现forwarded_for 项设为了off,原因找到了,把forwarded_for 项设为了on,重启后,访问http://www.xxx.com/index.jsp/ 获得的IP是客户端的真实IP。

  于是可得出获得客户端真实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    } 
 
 
 14

  可是,如果通过了多级反向代理的话,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

 

标签:ip,Squid,request,192.168,IP地址,IP,客户端
From: https://blog.51cto.com/u_16230604/7177291

相关文章

  • ora.erp61.vip FAILED OVER 或者故障节点vip地址查询不到了
    [root@erp61~]#crsctlstatusres-t--------------------------------------------------------------------------------NAMETARGETSTATESERVERSTATE_DETAILS-------------------------------------------------------......
  • 解决Windows远程桌面“由于安全设置错误, 客户端无法连接到远程计算机”
    用windows2008远程桌面连接Ubuntu系统,出现如下错误: 但我用win10可以进入登录界面,查了一下,需要修改安全策略,设置为如下: 参考资料:https://it.cha138.com/python/show-1249300.html ......
  • TWCMS您的IP地址已改变,为了安全考虑,请重新登录
    twcms您的IP地址已改变,为了安全考虑,请重新登录,很多人在群里重复问这个问题的解决方案,决定写篇文章帮大家解决直接进入主题:第一步:找到并打开admin/control/admin_control.class.php第二步:找到下面这段代码:<preclass="brush:php;toolbar:false">if(empty($this->_group)){$e......
  • Squid代理服务之反向代理模式
    为公网用户做加速访问1)实验拓扑2)web服务器配置参考传统模式中的web服务器配置,这里不再重复记录操作。网关需要指向squid服务器的内网ipecho"GATEWAY=10.10.10.13">>/etc/sysconfig/network-scripts/ifcfg-ens333)安装squid服务安装步骤这里不再赘述,参考传统模式中的安装步骤。(1)开......
  • MQTTnet4入门(二)实现客户端
    上一篇写服务端的文章《MQTTnet4入门(一)实现服务端》已经是去年年底,现在MQTTnet的版本是4.2.1.781,总的来说改动不大。下面以新版为例实现一个客户端。varmqttClientOptions=newMqttClientOptionsBuilder().WithTcpServer("地址",端口).Wit......
  • Squid代理服务之透明模式部署
    为内网用户做加速访问,客户端无需手动设置代理即可访问公网中的web服务器。1)实验拓扑2)修改squid配置文件指定squid为透明模式vim/etc/squid/squid.confhttp_port10.10.10.12:3128transparent(透明模式)visible_hostnamelvs_backup(不添加也可以)3)配置iptables策略vim......
  • 让SignalR客户端回调支持强类型
    几天写一个小程序的时候用到了SignalR,发现现在SingalRServer支持强类型了,也就是说,我们可以定义一个客户端的通知契约:    public interface IClient    {        void SayHello(string message);    }然后Hub就可以这么写了:    public class Me......
  • MySQL客户端工具 phpMyAdmin MySQL Workbench HeidiSQL Sequel Pro DBeaver
    MySQL是一种流行的关系型数据库管理系统,它被广泛用于Web应用程序和企业级应用程序的开发中。目前,市面上有不少好用的MySQL客户端工具,如Navicat,SQLyog等。但这些产品虽然功能强大,却都是收费的,而且费用还不低。幸运的是,收费产品并不是你的唯一选择,目前也有不少开源的工具。如果你不想......
  • SignalR 客户端源生成器 客户端强类型方法
     SignalR客户端源生成器根据您定义的接口生成强类型的发送和接收代码。您可以在客户端上重用来自强类型SignalR集线器的相同接口来代替松散类型的.On("methodName",...)方法。同样,您的集线器可以为其方法实现一个接口,并且客户端可以使用该相同接口来调用集线器方法。要使......
  • 25、DHCP动态获取IP地址
    DHCP动态获取IP地址的过程:DHCP通过法师部分广播报文,发现DHCP服务器;DHCP服务器分配一个IP地址通过单播报文;DHCP客户端发送广播报文,请求IP地址;DHCP服务器收到请求报文后,服务器向DHCP客户端发送单播确认报文,包含iIP地址相关信息。DHCP常见的部署方法有interface与global两种模......