s

https://en.wikipedia.org/wiki/X-Forwarded-For

http://www.cnblogs.com/yihang/archive/2010/12/19/1910365.html

问题表象1:

拦截量从5点开始增多,从日志看是因为请求中x_forwarded_for字段为空,导致WAF获取不到用户的IP,WAF会将所有未获取到IP的请求当成同一个人发起,超过频率限制被拦截

分析问题1:

web访问软防火墙安全规则1:如果一个用户连续两次请求之前时间间隔不大于1秒,算1次;

web访问软防火墙安全规则2:B2C分区设置的每分钟一个用户此种情况拦截阈值为4200,除以集群系数,每台防火墙服务器上每分钟一个用户此种情况超过70次就会拦截。

解决问题1:

数据链路:用户 -- > CDN -- > F5 VIP(无配置x_forwarded_for导致) --> WAF(误认为同一IP,触发封禁规则) -->  B2C 主站。

解决方法1

数据链路:用户 -- > CDN -- > F5 VIP(无配置x_forwarded_for导致) --> WAF(同一F5 VIP设置白名单,临时解禁规则) -->  B2C 主站。

解决方法2

数据链路:用户 -- > CDN -- > F5 VIP(配置x_forwarded_for) --> WAF(不再认为同一VIP F5设备,终极解决) -->  B2C 主站。

先来看一下X-Forwarded-For的定义:
X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中可以找到该项的详细介绍。
标准格式如下:
X-Forwarded-For: client1, proxy1, proxy2
从标准格式可以看出,X-Forwarded-For头信息可以有多个,中间用逗号分隔,第一项为真实的客户端ip,剩下的就是曾经经过的代理或负载均衡的ip地址,经过几个就会出现几个。
按照上图的Web架构图,可以很容易的看出,当用户请求经过CDN后到达Nginx负载均衡服务器时,其X-Forwarded-For头信息应该为 客户端IP,CDN的IP 但实际情况并非如此,一般情况下CDN服务商为了自身安全考虑会将这个信息做些改动,只保留客户端IP。我们可以通过程序获得X-Forwarded-For信息或者通过Nginx的add header方法来设置返回头来查看。
下面来分析请求头到达Nginx负载均衡服务器的情况;在默认情况下,Nginx并不会对X-Forwarded-For头做任何的处理,除非用户使用proxy_set_header 参数设置:
proxy_set_header 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
当Nginx设置X-Forwarded-For等于$proxy_add_x_forwarded_for后会有两种情况发生
1、如果从CDN过来的请求没有设置X-Forwarded-For头(通常这种事情不会发生),而到了我们这里Nginx设置将其设置为$proxy_add_x_forwarded_for的话,X-Forwarded-For的信息应该为CDN的IP,因为相对于Nginx负载均衡来说客户端即为CDN,这样的话,后端的web程序时死活也获得不了真实用户的IP的。
2、CDN设置了X-Forwarded-For,我们这里又设置了一次,且值为$proxy_add_x_forwarded_for的话,那么X-Forwarded-For的内容变成 ”客户端IP,Nginx负载均衡服务器IP“如果是这种情况的话,那后端的程序通过X-Forwarded-For获得客户端IP,则取逗号分隔的第一项即可。
如上两点所说,如果我们知道了CDN设置了X-Forwarded-For信息,且只有客户端真实的IP的话,那么我们的Nginx负载均衡服务器可以不必理会该头,让它默认即可。
其实Nginx中还有一个$http_x_forwarded_for变量,这个变量中保存的内容就是请求中的X-Forwarded-For信息。如果后端获得X-Forwarded-For信息的程序兼容性不好的话(没有考虑到X-Forwarded-For含有多个IP的情况),最好就不要将X-Forwarded-For设置为 $proxy_add_x_forwarded_for。应该设置为$http_x_forwarded_for或者干脆不设置!

end

NGINX X-Forwarded-For / XFF / xforword的更多相关文章

  1. 关于httpservletrequest的获取真实的ip

    via 值为: 下面是一些DemoWTP/1.1 GDSZ-PS-GW010-WAP05.gd.chinamobile.com (Nokia WAP Gateway 4.0 CD3/ECD13_C/N ...

  2. Struts如何获取客户端ip地址

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...

  3. X-FORWARDED-FOR

    外界流传的JAVA/PHP服务器端获取客户端IP都是这么取的: 伪代码: 1)ip = request.getHeader("X-FORWARDED-FOR")     可伪造,参 ...

  4. PHP-客户端的IP地址伪造、CDN、反向代理、获取的那些事儿

    外界流传的JAVA/PHP服务器端获取客户端IP都是这么取的: 伪代码: 1)ip = request.getHeader("X-FORWARDED-FOR")     可伪造,参 ...

  5. 经过Nginx代理后如何区分HTTP请求头中的X-Forwarded-For和X-Real-IP,以及Java示例

    在开发工作中,我们常常需要获取客户端的IP.一般获取客户端的IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实 ...

  6. nginx+tomcat集群配置(3)---获取真实客户端IP

    前言: 在初步构建的nginx+tomcat服务集群时, 发现webserver获取到的客户端ip都是同一个, 皆为作为反向代理服务的nginx所在的机器IP. 这不太符合我们的基本需求, 为将来的数 ...

  7. Nginx 获取真实 IP 方案

    问题根源: 基于七层的负载均衡系统,获取IP的原理都是通过XRI和XFF进行处理,从中选出“正常情况下”的源头IP,然而这两个Header都是普通的HTTP头,任何代理程序都可以轻易修改伪造它们,使得 ...

  8. nginx做反向代理负载均衡 Java怎么获取后端服务器获取用户IP

    nginx做反向负载均衡,后端服务器获取真实客户端ip   首先,在前端nginx上需要做如下配置: location / proxy_set_hearder host                 ...

  9. CentOS6.5+nginx+tomcat负载均衡集群

    思路: 1.安装jdk 2.安装tomcat 3.安装nginx依赖库 4.安装nginx 5.nginx+2个tomcat集群 一:网络拓扑

随机推荐

  1. ie11的版本判断

    我的电脑昨天更新的时候把ie11给更新出来了,然后发现我的skylineweb项目提示我的浏览器不是ie,这样显然是浏览器检测出现了问题.查找后找到了下面的解决方法.大家的电脑如果也更新成了ie11的 ...

  2. 不可解问题之停机问题(Undecidable Problem Halting Problem)

    计算机技术已运用到人类生活的方方面面,帮助人类解决各种问题.可你是否有想过,计算机是否能为人类解决所有问题呢? 假如你是一个程序猿,你已编写过很多程序.有些程序一下子就能出结果,有些程序则好久都没有显 ...

  3. window文件过长无法删除的处理方式

    解决方案: 如:aaa是要删除的文件夹,进入到要删除的文件夹下,新建一个test  1.以管理员身份打开CMD:  2 新建test空白目录:  3 执行命令,删除aaa文件夹:robocopy te ...

  4. 【比赛】NOIP2018 旅行

    发现 \(m\) 只有两种取值,于是可做了 树的直接贪心 图的枚举环上的边去掉,然后做树的贪心,搜的时候剪一下枝吧 写得有点乱 #include<bits/stdc++.h> #defin ...

  5. Hdoj 1087.Super Jumping! Jumping! Jumping!

    Problem Description Nowadays, a kind of chess game called "Super Jumping! Jumping! Jumping!&quo ...

  6. python 获取当前文件夹下所有文件名

    os 模块下有两个函数: os.walk() os.listdir() 1 # -*- coding: utf-8 -*- 2 3 import os 4 5 def file_name(file_d ...

  7. ComM(通信管理)和CanNm(network)

    1      网络管理组成部分 网络管理部分由通信管理器(简称ComM),通用网络管理器接口(简称NmIf),总线相关的网络管理器(简称NM,包括CanNM,LinNM,FrNM),总线相关的状态管理 ...

  8. Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS

    题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...

  9. Linux命令模拟Http的get或post请求

    Http请求指的是客户端向服务器的请求消息,Http请求主要分为get或post两种,在Linux系统下可以用curl和wget命令来模拟Http的请求. get请求: 1.使用curl命令: cur ...

  10. 用popart构建常染色体单倍型网络(Autosomal haplotypes network construction with popart)

    1)将vcf转化为plink格式,假定输入的vcf文件名为:17893893-17898893.vcf,也可以参考链接:将vcf文件转化为plink格式并且保持phasing状态 /vcftools ...