zoukankan      html  css  js  c++  java
  • Nginx 与 X-Forwarded-For


    HTTP扩展头部 X-Forwarded-For,以及在nginx中使用http_x_forwarded_for变量来完成一些"特殊"功能,例如网站后台面向内部工作人员,希望只允许办公室网络IP访问。

     X-Forwarded-For,它用来记录代理服务器的地址,每经过一个代理该字段会追加上一个记录。例如:6.6.6.6, 8.8.8.8。


    拿出生产环境的一个例子,客户端浏览网站发出一个请求,请求先经过阿里云SLB负载均衡器,然后进入Rancher内部的LB负载均衡器,经过两次负载均衡器转发后请求到达nginx服务器。


    X-Forwarded-For HTTP扩展头部

    日志中的记录表示 client: 101.251.xxx.192 、proxy1: 100.97.xxx.187,不是说 X-Forwarded-For用来记录代理服务器的地址,每经过一个代理该字段会追加上一个记录,为什么client IP 会出现在这个字段中呢?

    带着疑惑这里有必要专门讲一讲 X-Forwarded-For HTTP头部。X-Forwarded-For 是一个 HTTP扩展头部,HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 Squid缓存代理软件引入,用来表示 HTTP请求端真实IP。最终成为事实上的标准被写入 RFC 7239(Forwarded HTTP Extension)标准之中。

    X-Forwarded-For 标准格式

    X-Forwarded-For: client, proxy1, proxy2
     

    从标准格式可以看出,X-Forwarded-For头部信息可以有多个,中间使用逗号分隔,第一项为真实的客户端IP剩下的就是经过的代理或负载均衡的IP地址,经过几个就会出现几个。

    回到上面的示例,HTTP请求到达nginx服务器之前,经过了两个代理Proxy1、Proxy2,IP 分别为IP1、IP2,用户真实IP为 IP0,那么按照 XFF标准格式,nginx服务器最终的XFF变量如下:

    X-Forwarded-For: IP0, IP1

    Proxy2是直连服务器的,它会给 XFF追加IP1,表示它是在帮 Proxy1转发请求,IP2是在服务端通过 Remote Address 获得。Remote Address 也无法伪造,因为建立TCP连接需要三次握手,如果伪造了源IP,无法建立TCP连接,更不会有后面的 HTTP请求。


    nginx 中的 http_x_forwarded_for 变量用来表示 X-Forwarded-For ,下面用一个例子说明 nginx 如何使用 http_x_forwarded_for,例如借用这个变量限制网站后台访问。

    1. 环境

    browser -> haproxy -> nginx

    目标判断 haproxy负载均衡传递的 http_x_forwarded_for变量,确定是否为办公室IP?是否允许访问网站后台?

    2. 方法

    a. 修改 nginx 虚拟主机配置文件,添加以下语句。

    cat default.conf
    
    server  
    {    
      #... 其它配置项省略
    
        location ^~ /admin/ {
    
          if ($http_x_forwarded_for !~ 'your_office_ip') {
             return 403;
          }
          
          #... 其它配置项省略    
        }
    
    }

    b. 重新加载

    nginx -t && nginx -s reload

    c. 伪造XFF

    需要特别说明的是XFF是可以伪造的,例如使用curl 发送一个带有"X-Forwarded-For:8.8.8.8"的头部信息。

    curl -IL -H "X-Forwarded-For:8.8.8.8" https://www.test.com/static/09.png

    假设你采用XFF对比IP方式来限制网站后台访问,如果对方知道你的网站在用这个策略限制后台访问,并且通过一些方法知道了你办公室的IP地址,那么这个策略也就失效了。如果你的网站"前后台"可以分离,那么可以为分离后的后台服务器添加防火墙规则,通过网络层限制来源IP地址达到同样目的。

  • 相关阅读:
    Linux环境下安装jdk1.8(CentOS7)
    MySQL创建外键报错ERROR 3780 (HY000): Referencing column ‘user_id’ and referenced column ‘id’ in foreign key constraint ‘fk_user_id’ are incompatible.
    scrapy框架的使用
    开源《热血传奇》服务端引擎(C#编写),可以顺利进行游戏(更新编译和部署教程)
    记录一下今天刚开通的博客
    Sql Server 2005中还原整个数据库重命名问题
    第一次学开车
    转载:c#与ASP.NET中DateTime.Now函数详解
    winform进度条收藏
    今天新注册的,庆祝一下
  • 原文地址:https://www.cnblogs.com/augusite/p/15502590.html
Copyright © 2011-2022 走看看