Nginx 获取/传递真实IP、追踪请求包转发链 及 防范源IP伪造
(转载)
获取/传递真实IP
环境模拟:
客户端-->Nginx1/CDN/DDOS高防-->Nginx2-->后端Server
request Header 部分请求头字段:
- X-Real-IP 用来保存客户端真实IP,默认为空
- X-Forwarded-For 用来保存请求包的转发地址链,默认为空
对应变量:
$remote_addr
此变量保存的是http请求的发起方IP,也就是上一跳的IP$http_x_real_ip
此变量默认为空,用来保存真实客户端IP给后端,对应header中的
修改方法:
proxy_set_header 此方法可以用来修改Header,目的为了传递修改后的信息给下一跳
参考配置:Ngx1
proxy_set_header X-Real-IP $remote_addr; #将上一跳的IP保存至 X-Real-IP 并可以向后传递
注意:
一旦ngx1修改了header中的 X-Real-IP,
ngx2和server就可以直接使用 $http_x_real_ip
来获取到真实IP,不需要额外加配置
追踪请求包转发链
变量介绍:
-
$http_x_forwarded_for
此变量保存的是请求的转发IP链,对应header中的 X-Forwarded-For
X-Forwarded-For数组,包含多个IP,用逗号+空格分隔,最前端(client1)是客户端源IP,中间每一层代理将连接它的客户端IP追加在X-Forwarded-For末尾。X-Forwarded-For: clientIP, proxyIP1, proxyIP2, ...
-
$proxy_add_x_forwarded_for
此变量保存的是:将本级代理的IP,追加到X-Forwarded-For列表之后的值。
参考配置:Ngx1/Ngx2
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
如需打印到nginx日志,在log_format
直接使用 $http_x_forwarded_for
即可。
防范 源IP伪造
攻击方式:
正常客户端发起的request,不应该带有 X-Forwarded-For 请求头,
但是攻击者会在header里伪造一个IP:X-Forwarded-For: fakeIP
用curl命令修改header模拟IP伪造:
curl -I -H "X-FORWARDED-FOR:1.2.3.4" http://nginx1/
服务端第一层代理服务收到请求,发现已经有X-Forwarded-For,误把这个请求的来源当成一个代理,于是追加了“代理IP”(其实是客户端的真实IP),经过几层代理后,最终Server获取到的Header是:
X-Forwarded-For: fakeIP, client, nginx1, nginx2
解决方案:
在最外层代理ngx1上,不采信客户端的 X-Forwarded-For,直接用$remote_addr
覆盖,不用$proxy_add_x_forwarded_for
追加。
参考配置:Ngx1
proxy_set_header X-Forwarded-For $remote_addr;
中间几层的代理Nginx参考配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;