前言
今天,群里大神再一次考了我:“最近你在看Nginx,那么我问你一个问题。。。”;另外一位大神,“这问题我觉得。。。XFF。。。”。当时,我只记住了关键字XFF ,确实不懂。于是,有了这篇文章。
XFF
- 照例,维基百科释义:
X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。
- 一般格式:
X-Forwarded-For: client1, proxy1, proxy2
为什么使用XFF
- 客户端通过反向代理服务器访问上游服务器的资源时,客户端IP,即源IP对上游服务器不是完全可见的,就会带来以下痛点:
不仅是业务、还是日志采集,通常需要源IP作为一个固定字段。
- 使用XFF请求头字段,能够解决这个痛点。
相关概念
remote_addr
:代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。
实战
测试环境
- 上一篇文章的
www.zacpark.com
反向代理。 - 服务
Controller
输出相关头部信息,笔者较懒,直接sout
了,不过可以凑合着用了。
System.out.println("x-forwarded-for: " + httpServletRequest.getHeader("x-forwarded-for"));
System.out.println("remote-addr: " + httpServletRequest.getRemoteAddr());
System.out.println("x-real-ip: " + httpServletRequest.getHeader("x-real-ip"));
- 使用
curl
命令,伪造HTTP请求头部信息,例如:
curl http://www.zacpark.com/index -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-Ip: 2.2.2.2'
Case1:不经过nginx代理
- 增加
:8080
就不会走nginx啦~
curl http://www.zacpark.com:8080/index -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-Ip: 2.2.2.2'
- 输出:
x-forwarded-for: 1.1.1.1
remote-addr: 127.0.0.1
x-real-ip: 2.2.2.2
Case2:经过nginx反向代理
- 直接上
www.zacpark.com
,没有端口~
curl http://www.zacpark.com/index -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-Ip: 2.2.2.2'
- 输出:
x-forwarded-for: 1.1.1.1
remote-addr: 127.0.0.1
x-real-ip: 2.2.2.2
Case3:通过nginx配置获取x-forwarded-for
- 我们在
nginx.conf
(具体格式参照上上篇博客)文件里的location
段添加一行配置。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 解析
proxy_add_x_forwarded_for
proxy_add_x_forwarded_for变量包含客户端请求头中的"X-Forwarded-For",与remote_addr用逗号分开。 如果没有"X-Forwarded-For" 请求头,则proxy_add_x_forwarded_for等于remote_addr。$remote_addr变量的值是客户端的IP。
- 输出
x-forwarded-for: 1.1.1.1, 127.0.0.1
remote-addr: 127.0.0.1
x-real-ip: 2.2.2.2
Case4:头部信息被伪造
由上述Case可见,x-real-ip
、x-forwarded-for
头部信息是可以伪造的,那么获取客户端IP就会有问题,那就完善下nginx配置!
- 再增加一行配置~
proxy_set_header X-Real-IP $remote_addr;
- 解析:
将$remote_addr赋值给
x-real-ip
头部。
- 输出
x-forwarded-for: 1.1.1.1, 127.0.0.1
remote-addr: 127.0.0.1
x-real-ip: 127.0.0.1
总结
本文通过实战对x-forwarded-for
进行了梳理,凌晨写的,总结就草草了事了,请原谅~。
参考文献
zh.wikipedia.org/wiki/X-Forw… www.loadbalancer.org/blog/nginx-… www.cnblogs.com/yum777/p/64…