最新新闻:

反向代理软件获取客户端IP地址的方法和方法获取方法

时间:2022-06-08 14:00:52来源:网络整理

在JSP中,获取客户端IP地址的方法是:request.getRemoteAddr(),大部分情况下有效。但是通过Apache、Squid等反向代理软件后,无法获取客户端的真实IP地址。

如果使用反向代理软件服务端获取客户端ip,使用request将192.168.1.110:2046/的URL反向代理为/的URL获取到的IP地址.getRemoteAddr() 方法为:127.0.0.1 or 192.168.1.110,且不是真实IP客户。

通过代理后,由于在客户端和服务之间增加了一个中间层,服务端无法直接获取客户端的IP,服务器端应用也无法通过转发请求直接将地址返回给客户端。但是,在转发请求的 HTTP 头信息中添加了 X-FORWARDED-FOR 信息。用于跟踪原始客户端IP地址和原始客户端请求的服务器地址。

当我们访问/index.jsp/时,并不是我们的浏览器真正访问了服务器上的index.jsp文件,而是代理服务器访问了192.168.1.@ >110:2046/index.jsp,代理服务器会将访问结果返回给我们的浏览器,因为是代理服务器访问index.jsp,所以在index.jsp中通过request.getRemoteAddr()方法获得的IP实际上是代理服务器的地址,而不是客户端的IP地址。

外界流通的JAVA/PHP服务器获取客户端IP是这样的:

伪代码:

1)ip = request .getHeader("X-FORWARDED-FOR")

2)如果值为空或者数组长度为0或等于“未知”,则:\ip = request.getHeader("Proxy -Client-IP")

3)如果值为空或数组长度为0或等于“未知”,则:\ip = request.getHeader("WL-Proxy-Client-IP")

4)如果值为空或数组长度为0或等于“未知”,则:\ip = request.getHeader("HTTP_CLIENT_IP")

5)如果值为空或者数组长度为0或等于“unknown”,则:\ip = request.getHeader("X-Real-IP")

6)@ >如果值为空或者数组长度为0或等于“未知”,则:\ip = request.getRemoteAddr()

先说一下这些请求头的含义

这是squid开发的字段,只有通过HTTP代理或者负载均衡服务器时才会添加。

格式为 X-Forwarded-For:client1,proxy1,proxy2。一般情况下,第一个ip是客户端的真实ip,后一个是经过的代理服务器的ip。现在大多数代理都添加了这个标头。

这通常只能通过 apache http 服务器的请求获得。使用apache http做代理的时候,通常会加上Proxy-Client-IP请求头,而WL-Proxy-Client-IP是他的weblogic插件添加的头。

某些代理服务器会添加此标头。

以下是获取客户端IP地址的参考:

public static String getIpAddress(HttpServletRequest request) {
    String ip = request.getHeader("x-forwarded-for");
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
    }
    if (ip.contains(",")) {
        return ip.split(",")[0];
    } else {
        return ip;
    }
}

如果你使用的是Druid连接池,可以参考:com.alibaba.druid.util.DruidWebUtils#getRemoteAddr方法,但这是经过多级代理的​​IP地址,需要自己处理以获得第一个。

有几点需要注意

这些请求头不是http协议中的标准请求头,也就是说,这是各个代理服务器指定的代表客户端地址的请求头。如果有代理服务器软件使用oooo-client-ip请求头来表示客户端请求,上面的代码就不行了。

这些请求头不一定是代理服务器带来的。网络上很多匿名代理没有这些请求头,所以获取到的客户端IP不一定是真实的客户端IP。代理服务器一般可以自定义请求头设置。

即使请求经过的代理会按照自己的规范附加代理请求头,但上面的代码并不能保证获取到客户端ip。不同的网络架构对请求头的顺序判断不同。

最重要的一点是请求头是可以伪造的。如果一些客户端验证严格(比如投票)的应用想要获取客户端ip服务端获取客户端ip,应该直接使用ip=request.getRemoteAddr(),虽然获取的ip可能是proxy的ip而不是客户端的ip,但是这个ip获得的基本不可能伪造,这就排除了刷票的可能。 (有分析说arp spoofing + syn可能会伪造这个ip,如果可能的话,这是所有基于TCP的协议都存在的漏洞。)这个ip就是tcp连接中的ip。

参考\ /sgx425021234/article/details/19043459\ /fengwind1/article/details/51992528

声明:文章仅代表原作者观点,不代表本站立场;如有侵权、违规,可直接反馈本站,我们将会作修改或删除处理。

猜您喜欢

图文推荐

热点排行

精彩文章

热门推荐