apache代理时java获取IP的问题

现在利用nginx作负载均衡的实例已经不少了,针对不一样的应用场合,还有不少须要注意的地方,本文要说的就是在经过CDN 后到达nginx作负载均衡时请求头中的X-Forwarded-For项到底发生了什么变化。下图为简单的web架构图:php

 

 

 

 

 

先来看一下X-Forwarded-For的定义:
X-Forwarded-For:简称XFF头,它表明客户端,也就是HTTP的请求端真实的IP,只有在经过了HTTP 代理或者负载均衡服务器时才会添加该项。它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中能够找到该项的详细介绍。
标准格式以下:
X-Forwarded-For: client1, proxy1, proxy2
从标准格式能够看出,X-Forwarded-For头信息能够有多个,中间用逗号分隔,第一项为真实的客户端ip,剩下的就是曾经通过的代理或负载均衡的ip地址,通过几个就会出现几个。
html

按照上图的Web架构图,能够很容易的看出,当用户请求通过CDN后到达Nginx负载均衡服务器时,其X-Forwarded-For头信息应该为客户端IP,CDN的IP。但实际状况并不是如此,通常状况下CDN服务商为了自身安全考虑会将这个信息作些改动,只保留客户端IP。咱们能够经过php程序得到X-Forwarded-For信息或者经过Nginx的add header方法来设置返回头来查看。java

下面来分析请求头到达Nginx负载均衡服务器的状况;在默认状况下,Nginx并不会对X-Forwarded-For头作任何的处理,除非用户使用proxy_set_header 参数设置:
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;nginx

$proxy_add_x_forwarded_for变量包含客户端请求头中的"X-Forwarded-For",与$remote_addr用逗号分开,若是没有"X-Forwarded-For" 请求头,则$proxy_add_x_forwarded_for等于$remote_addr。web

$remote_addr变量的值是客户端的IPapache

当Nginx设置X-Forwarded-For等于$proxy_add_x_forwarded_for后会有两种状况发生后端

一、若是从CDN过来的请求没有设置X-Forwarded-For头(一般这种事情不会发生),而到了咱们这里Nginx设置将其设置为$proxy_add_x_forwarded_for的话,X-Forwarded-For的信息应该为CDN的IP,由于相对于Nginx负载均衡来讲客户端即为CDN,这样的话,后端的web程序时死活也得到不了真实用户的IP的。缓存

二、CDN设置了X-Forwarded-For,咱们这里又设置了一次,且值为$proxy_add_x_forwarded_for的话,那么X-Forwarded-For的内容变成 ”客户端IP,Nginx负载均衡服务器IP“若是是这种状况的话,那后端的程序经过X-Forwarded-For得到客户端IP,则取逗号分隔的第一项便可安全

如上两点所说,若是咱们知道了CDN设置了X-Forwarded-For信息,且只有客户端真实的IP的话,那么咱们的Nginx负载均衡服务器能够没必要理会该头,让它默认便可。服务器

其实Nginx中还有一个$http_x_forwarded_for变量,这个变量中保存的内容就是请求中的X-Forwarded-For信息。若是后端得到X-Forwarded-For信息的程序兼容性很差的话(没有考虑到X-Forwarded-For含有多个IP的状况),最好就不要将X-Forwarded-For设置为$proxy_add_x_forwarded_for。应该设置为$http_x_forwarded_for或者干脆不设置!

参考文章:http://en.wikipedia.org/wiki/X-Forwarded-For

转自:http://www.cnblogs.com/yihang/archive/2010/12/19/1910365.html

java获取IP地址的方法:

在个人项目中使用到了apache代理软件,因此最后我通过request.getRemoteAddr()获得都是127.0.0.1,咱们获得的是代理软件的服务器地址。真实的应该是以下:

 public String getIpAddr(HttpServletRequest request) {
 2        String ip = request.getHeader("x-forwarded-for"
);
 3        if(ip == null || ip.length() ==  || "unknown".equalsIgnoreCase(ip)) 
{
 4            ip = request.getHeader("Proxy-Client-IP"
);
 5        }

 6        if(ip == null || ip.length() ==  || "unknown".equalsIgnoreCase(ip)) {
 7            ip = request.getHeader("WL-Proxy-Client-IP"
);
 8        }

 9        if(ip == null || ip.length() ==  || "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

相关文章
相关标签/搜索