谈谈一个重要的http协议头标:X-Forwarded-For
2015-06-29 18:50
267 查看
网络的基本知识不懂。
有次一个同事询问,为什么经过一个网页请求经过了Http代理服务器后,网站依然能够获知访问者的真实IP地址。不是经过代理了吗?两个原因无法获得真实IP:TCP连接是在代理和网站之间,而非用户与网站之间的;HTTP协议只是第七层协议,怎么会把IP层的访问者的源IP信息也发送了呢?
实际上我相信当年设计代理服务器的专家们也遇到了同样的问题,就是如何能把访问者的源IP(而不是代理服务器的IP)发送给网站服务器呢?当年squid的专家们设计了这样一种解决办法:在HTTP包头部分插入一个header名为X-Forwarded-For(简称XFF),值为客户端的真实IP地址。这样,尽管TCP连接是代理和网站之间建立的,但网站依然可以通过解析包头并读取X-Forwarded-For而获得用户的真实IP。
除了squid等缓存服务器以外,XFF被大量应用的另一个场景是负载均衡(LB)。当然,当LB用于发布web网站的时候,也可以称为HTTP反向代理。也就是LB负责将用户请求分发给后台服务器池(pool)。那么此时TCP连接也是介于LB和server的,中间没有外部用户什么事儿。很多情况下server上的应用程序要获得用户IP再做进一步处理,此时也需要在LB上启用XFF。
顺便提一下,这个XFF的名称是可以自定义的。比如可以定义为my-client-IP之类,然后记得在web程序那边设定好去取这个名为my-client-IP的头标即可。
上面讲的都是单层代理(负载均衡)的情况。那么当经过了多级代理的话,第二级代理会把前面一级代理的XFF值给覆盖吗?答案是不会。实际上可以用逗号保存多个IP地址,包括用户IP,第一级代理IP,第二级代理IP,直到第n-1级代理IP(如果有n级代理的话)。没有必要保存最后一级代理的IP到XFF中,因为这个IP地址就是在TCP包(确切说是IP包)里的源IP。
在LB上实现XFF的方法
1. 在f5的BigIP产品上,可以设置profile启用XFF。另外也可以用iRule实现:
2. 在netscaler上,这个属性一般是设置在service级别的。启用service的cip属性为ENABLED[xff-name-defined-by-yourself]。同时在netscaler的全局级别启用cip并赋值的话,会默认继承到该设备的所有service上。
全局级别: set ns config -cip ENABLED
[xff-name-defined-by-yourself]
有次一个同事询问,为什么经过一个网页请求经过了Http代理服务器后,网站依然能够获知访问者的真实IP地址。不是经过代理了吗?两个原因无法获得真实IP:TCP连接是在代理和网站之间,而非用户与网站之间的;HTTP协议只是第七层协议,怎么会把IP层的访问者的源IP信息也发送了呢?
实际上我相信当年设计代理服务器的专家们也遇到了同样的问题,就是如何能把访问者的源IP(而不是代理服务器的IP)发送给网站服务器呢?当年squid的专家们设计了这样一种解决办法:在HTTP包头部分插入一个header名为X-Forwarded-For(简称XFF),值为客户端的真实IP地址。这样,尽管TCP连接是代理和网站之间建立的,但网站依然可以通过解析包头并读取X-Forwarded-For而获得用户的真实IP。
除了squid等缓存服务器以外,XFF被大量应用的另一个场景是负载均衡(LB)。当然,当LB用于发布web网站的时候,也可以称为HTTP反向代理。也就是LB负责将用户请求分发给后台服务器池(pool)。那么此时TCP连接也是介于LB和server的,中间没有外部用户什么事儿。很多情况下server上的应用程序要获得用户IP再做进一步处理,此时也需要在LB上启用XFF。
顺便提一下,这个XFF的名称是可以自定义的。比如可以定义为my-client-IP之类,然后记得在web程序那边设定好去取这个名为my-client-IP的头标即可。
上面讲的都是单层代理(负载均衡)的情况。那么当经过了多级代理的话,第二级代理会把前面一级代理的XFF值给覆盖吗?答案是不会。实际上可以用逗号保存多个IP地址,包括用户IP,第一级代理IP,第二级代理IP,直到第n-1级代理IP(如果有n级代理的话)。没有必要保存最后一级代理的IP到XFF中,因为这个IP地址就是在TCP包(确切说是IP包)里的源IP。
在LB上实现XFF的方法
1. 在f5的BigIP产品上,可以设置profile启用XFF。另外也可以用iRule实现:
when HTTP_REQUEST { HTTP::header insert "X-Forwarded-For" [IP::client_addr] }
2. 在netscaler上,这个属性一般是设置在service级别的。启用service的cip属性为ENABLED[xff-name-defined-by-yourself]。同时在netscaler的全局级别启用cip并赋值的话,会默认继承到该设备的所有service上。
全局级别: set ns config -cip ENABLED
[xff-name-defined-by-yourself]
相关文章推荐
- 华硕X550C 安装Ubuntu 14.10 无线网络显示硬件被禁用的解决方法
- java 访问https忽略证书
- HTTP服务器nginx在android平台的使用(用于在线播放本地视频)
- Netty4 之 简单搭建HTTP服务
- OKHttp源码解析-ConnectionPool对Connection重用机制&Http/Https/SPDY协议选择
- [转载]tcp粘包分析
- HttpClient (HTTP 请求工具类)
- TCP/UDP常见端口参考
- Xcode7 使用NSURLSession发送HTTP请求报错
- https协议支持get/post方法
- 网络远程唤醒 WOL Magic Packet
- Python 下载网络mp4视频资源
- 一个简单的http请求
- iOS开发工具-网络封包分析工具Charles
- DBN深信度网络
- 虚拟机桥接网络设置(转)
- 基于IHttpAsyncHandler的实时大文件传送器
- 初识贝叶斯网络
- HttpWebRequest
- HttpClient get post