Remote IP Valve, X-Forwarded-For等http头字段 http://www.10tiao.com/html/308/201702/2650076434/1.html
http://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html
X-Forwarded-For等http头字段与Tomcat的 Remote IP Valve (Valve源码分析之六)
2017-02-18 16:28 feiying 0 0 阅读 297
Proxies Valve是代理Valve,其作用是可以对负载均衡代理服务器的IP地址与原request的IP地址做请求转换,让服务器端真正识别原IP地址 (如果服务器端有需要的话) ;
本文主要讨论这种地址转换是如何做的;
1.X-Forwarded-For等http头字段
在我们现实的真正的场景中,通常Tomcat直接和用户接触的场景不多,主要是通过代理转发机制进行,如下:
真正的用户客户端是Client1,代理转发服务器采用的是Nginx,Proxy1,那么在此场景下,如果在Tomcat中进行获取客户端的地址:
request.getRemoteAddr,获得的IP地址绝对是Proxy1的,也就是负载均衡的地址;
而如果你想要获取Client1的地址,也是可以获取到的,就是通过X-Forwarded-For字段;
X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。
X-Forwarded-For内置在Http协议头中,一般格式如下:
X-Forwarded-For: client1, proxy1, proxy2, proxy3
其中的值通过一个 逗号+空格 把多个IP地址区分开,;
最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。
在上面这个例子中,这个请求成功通过了三台代理服务器: proxy1, proxy2 及 proxy3。请求由client1发出,到达了proxy3(proxy3可能是请求的终点)。请求刚从client1中发出时,XFF是空的,请求被发往proxy1;通过proxy1的时候,client1被添加到XFF中,之后请求被发往proxy2;通过proxy2的时候,proxy1被添加到XFF中,之后请求被发往proxy3;通过proxy3时,proxy2被添加到XFF中,之后请求的的去向不明,如果proxy3不是请求终点,请求会被继续转发。
鉴于伪造这一字段非常容易,应该谨慎使用X-Forwarded-For字段。正常情况下XFF中最后一个IP地址是最后一个代理服务器的IP地址, 这通常是一个比较可靠的信息来源。[1]
其次,还有一个是X-Forwarded-by字段,该字段是标识为负载均衡proxy的可信代理的IP地址;
例如上面的这个例子,X-Forwarded-For: client1, proxy1, proxy2, proxy3,可以配置当前的应用服务器的X-Forwarded-by字段可信IP为 proxy1, proxy2, proxy3;
这样通过X-Forwarded-For,X-Forwarded-by两个字段进行减法,直接就得到client1了;
还有一个是X-Forwarded-Proto,该字段记录最初从浏览器发出时候,是使用什么协议。因为有可能当一个请求最初和反向代理通信时,是使用https,但反向代理和服务器通信时改变成http协议,这个时候,X-Forwarded-Proto的值应该是https;
X-Forwarded-For和X-Forwarded-Proto的信息是很有价值的,在Tomcat中可以通过获取这两个字段的信息,拿到真实的客户端的请求IP和协议;
2.Remote IP Valve
Remote IP Valve就是利用X-Forwarded-For和X-Forwarded-Proto等字段,反转得到最原始的客户端的IP和请求信息的;
Attributes
The Remote IP Valve supports the following configuration attributes:
...