X-Forwarded-For缺陷与陷阱

一、定义

X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中可以找到该项的详细介绍。

二、起源

X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。 Squid 缓存代理服务器的开发人员最早引入了这一HTTP头字段,并由IETF在Forwarded-For HTTP头字段标准化草案中正式提出。

三、格式

这一HTTP头一般格式如下:
X-Forwarded-For: client1, proxy1, proxy2, proxy3

其中的值通过一个 逗号+空格 把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。 在上面这个例子中,这个请求成功通过了3台代理服务器:proxy1, proxy2 及 proxy3。请求由client1发出,到达了proxy3(proxy3可能是请求的终点)。请求刚从client1中发出时,XFF是空的,请求被发往proxy1;通过proxy1的时候,client1被添加到XFF中,之后请求被发往proxy2;通过proxy2的时候,proxy1被添加到XFF中,之后请求被发往proxy3;通过proxy3时,proxy2被添加到XFF中,之后请求的的去向不明,如果proxy3不是请求终点,请求会被继续转发。

四、来源IP可信吗?

因为伪造这一字段非常容易,所以应该谨慎使用X-Forwarded-For字段。正常情况下XFF中最后一个IP地址是最后一个代理服务器的IP地址, 这通常是一个比较可靠的信息来源。下面会详细说明,在什么情况下,这个信息并不准确。

1. 客户端设置代理

如果客户端使用了http代理(一般大公司内部上网都需要使用代理),同时,这个代理并没有正确设置(也可能是故意不设置)XFF,那么,XFF中client1的位置就会被http代理的ip取代,那么我们就无法正确获取客户端的真实IP。

2. 网络NAT设备

为了减缓可用的IP地址空间的枯竭, 大多数ISP网络或者公司网络中都会使用NAT设备,这样,一个公司或者一个小区的用户就可以共享使用一个IP来实现上网需求。NAT设备工作在IP层和TCP层,所以XFF不管怎么设置也无法解决这个问题。
这种情况下,我们也无法拿到客户的真实IP。

查看真实IP

Windows:

无线局域网适配器 无线网络连接:

   连接特定的 DNS 后缀 . . . . . . . : lan
   描述. . . . . . . . . . . . . . . : Intel(R) Centrino(R) Wireless-N 1000
   物理地址. . . . . . . . . . . . . : 00-1E-64-91-DF-00
   DHCP 已启用 . . . . . . . . . . . : 是
   自动配置已启用. . . . . . . . . . : 是
   本地链接 IPv6 地址. . . . . . . . : fe80::7d79:4d1d:58e6:32cc%12(首选)
   IPv4 地址 . . . . . . . . . . . . : 192.168.1.186(首选)
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   获得租约的时间  . . . . . . . . . : 2016年9月9日 20:45:08
   租约过期的时间  . . . . . . . . . : 2016年9月12日 0:01:30
   默认网关. . . . . . . . . . . . . : 192.168.1.1
   DHCP 服务器 . . . . . . . . . . . : 192.168.1.1
   DHCPv6 IAID . . . . . . . . . . . : 201334372
   DHCPv6 客户端 DUID  . . . . . . . : 00-01-00-01-1D-69-C7-A1-00-27-13-65-48-AE

   DNS 服务器  . . . . . . . . . . . : 8.8.8.8
   TCPIP 上的 NetBIOS  . . . . . . . : 已启用

以太网适配器 本地连接:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . :
   描述. . . . . . . . . . . . . . . : Intel(R) 82567LF Gigabit Network Connecti
on
   物理地址. . . . . . . . . . . . . : 00-27-13-65-48-AE
   DHCP 已启用 . . . . . . . . . . . : 是
   自动配置已启用. . . . . . . . . . : 是

Linux

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno16777728: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:42:15:de brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.248/24 brd 192.168.1.255 scope global dynamic eno16777728
       valid_lft 38029sec preferred_lft 38029sec
    inet6 fe80::20c:29ff:fe42:15de/64 scope link 
       valid_lft forever preferred_lft forever

查看自己的公网IP

访问以下两个网址,返回的网页会告诉你,你的公网IP是多少

可以用curl访问网址,举个例子

[root@localhost ~]# curl http://www.ip.cn
当前 IP:223.72.90.206 来自:北京市 移动

结果,我的真实ip是192.168.1.186(私有IP),但是在XFF中会显示我的IP为223.72.90.206。

3. 后端服务购买安全服务

有的公司使用加速乐, 我们可以认为使用这种服务后,相当于增加了一层http代理。

DNS是否被“主动劫持”

我们可以查看一下域名是否使用了加速乐(查看其他的安全服务也是类似的方法)

[root@localhost ~]# dig www.XXXXXX.com

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.3 <<>> www.51kahui.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31138
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.51kahui.com.       IN  A

;; ANSWER SECTION:
www.XXXXXX.com. 600 IN  CNAME   a29dXXXXXXa8f83b.cdn.jiashule.com.
a29dXXXXXXa8f83b.cdn.jiashule.com. 4 IN A   111.13.147.215
a29dXXXXXXa8f83b.cdn.jiashule.com. 4 IN A   111.13.147.195

结果,XFF中有一层proxy就是加速乐的IP,由于加速乐有很多节点,所以这个IP地址新并不是固定的。内部消息显示加速乐节点的IP要达到上万个,尽管我太想相信。但是这至少说明一点,就是XFF中proxy的IP地址是多变的。

是否被动注入安全服务

最近测试发现,使用电信4G网络的时候,XFF会莫名其妙的加入多个proxy代理,但是这个IP地址实在是无法查证,我们姑且认为他们也是一种安全服务吧

4. 攻击者

攻击者可以很容易伪造XFF,在发出请求时在XFF值中插入多个IP地址,以混淆服务端获取到客户端的真实IP。

结论,从XFF中的获取到的客户端IP地址并不可信,在使用各种ACL策略的时候,需要读者权衡利弊来满足业务需求。

五、Nginx中获取客户端IP的正确姿势

nginx目前在各个互联网公司中的标配, 其中ngx_http_realip_module模块就提供从XFF中实现获取用户的真实IP的功能。

配置方式

set_real_ip_from 10.0.0.0/8;
set_real_ip_from 100.64.0.0/10;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

但是,上面的配置有一些问题,你发现什么问题了吗?

问题所在

首先,我们解释一下上面最后一条配置语句的含义

proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

实际上的含义是

proxy_set_header  X-Forwarded-For '$X-Forwarded-For, $remote_addr';

我们可以看到,proxy_add_x_forwarded_for等于X-Forwarded-For加上$remote_addr。但是有一个问题,realip模块要比proxy模块运行的早,在realip模块中会把remote_addr重置为客户端IP,这样会导致 X-Forwarded-For设置错误。

我们拿proxy3为例,正常情况下,XFF传到proxy4服务时,XFF的值是

client1, proxy1,proxy2

如果按照上面的配置的话,XFF值会是

client1, proxy1,client1

如果内部有两级Nginx的话,XFF值会是

client1, proxy1,client1,cleint1

总之,只要是XFF出现的重复的IP地址,就有理由怀疑是Nginx配置引起的。

下面是才是realip的正确配置

set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.1.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

proxy_set_header X-Forwarded-For '$http_x_forwarded_for, $realip_remote_addr';

realip_remote_addr是remote_addr的副本信息,当realip模块修改了remote_addr的值时,realip_remote_addr用于保留$remote_addr的原始值。

六、从XFF中可以得到哪些确定的信息

假设有这样一个XFF

X-Forwarded-For: client1, proxy1, proxy2, proxy3

其中,如果proxy2,proxy3是我们已知(可信)代理的话,我们可以确定proxy1的IP地址是可信的。

七、参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,511评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,495评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,595评论 0 225
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,558评论 0 190
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,715评论 3 270
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,672评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,112评论 2 291
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,837评论 0 181
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,417评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,928评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,316评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,773评论 2 234
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,253评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,827评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,440评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,523评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,583评论 2 249

推荐阅读更多精彩内容