时间: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
声明:文章仅代表原作者观点,不代表本站立场;如有侵权、违规,可直接反馈本站,我们将会作修改或删除处理。
图文推荐
2022-06-08 14:00:32
2022-06-08 12:01:21
2022-06-08 12:01:06
2022-06-08 11:00:42
2022-06-05 11:00:50
2022-06-05 10:01:11
热点排行
精彩文章
2022-06-06 11:01:13
2022-06-06 09:00:28
2022-06-05 12:00:43
2022-06-05 11:01:02
2022-06-05 10:01:04
2022-06-03 12:02:10
热门推荐