Nginx与XFF:X-Forwarded-For

6,848 阅读2分钟

前言

今天,群里大神再一次考了我:“最近你在看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

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-ipx-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…