nginx(三十九) ngx_http_realip_module模块学习

news/2024/4/26 7:36:28/文章来源:https://blog.csdn.net/wzj_110/article/details/127115450

一   指令学习

①   set_real_ip_from

解读:表示这些是来自'代理服务器的ip [受信的]',不是用户的'真实ip'大白话理解: 如果发现与nginx建连的是这些'受信ip',则可以通过特殊方式获取'client_ip';否则则'不处理'

细节点: 把set_real_ip_from xxx '放在server{}下','不要'放在location{}中原因: realip工作在'find_config阶段之前'

++++++++++  关于设置为'CIDR'场景的理解  ++++++++++场景1:real_client --> '中间层' -> 'SNAT源地址转换' --> 替换为'CIDR地址池'中的'某个ip' --> 导致ip一直'发生变化',所以要'使用网段'场景2:'CDN的ip'比较多,可以用'子网掩码',把一段ip设为'可信地址'的

CDN 获取客户端的真实ip 

②    real_ip_header

+++++++++++++"指令解读"+++++++++++++1)  则是告诉'nginx' 从'哪里[重点]'获取真正的'client_ip'和'client_port'2) 找到之后,然后替换'$remote_addr'和'$remote_port'

方式1: '自定义field'、'X-Real-IP'、'X-Forwarded-For' 请求头 -->'七层'

PROXY protocol

方式2:  proxy_protocol -->'四层'++++++++ "前置条件"  ++++++++ 目的: 通过在 'listen 指令'中设置 proxy_protocol 参数来'启用 PROXY 协议'listen  443  ssl  proxy_protocol;listen  8443   proxy_protocol;细节点: 在一个'server'块中,可以同时设置'多个'listen

listen指令 

③    real_ip_recursive

对于这个指令的讨论

real_ip_recursive 是否'递归地排除'直至得到'用户ip'1)off :会将 real_ip_header 指定的HTTP头中的'最后一个ip'作为真实ip2)on  :会将 real_ip_header 指定的HTTP头中的'最后一个不是信任服务器的ip'当成真实ip

1)首先,real_ip_header 指定一个'http首部'名称,默认是X-Real-Ip2) 假设用'默认值'的话,nginx在'接收'到报文后,会查看http首部X-Real-Ip[1]、X-Real-Ip是'1个值'如果有1个ip,它会去核对,'发送方的ip'是否在set_real_ip_from'指定的信任ip列表'中;如果是'被信任'的,它会去认为这个X-Real-Ip中的ip值是'前代理'告诉自己的-->用户的真实ip值于是,它会将该值'赋值'给自身的$remote_addr变量;如果'不被信任',那么将'不作处理',那么$remote_addr还是'发送方'的ip地址;[2] 如果X-Real-Ip有'多个'ip值比如'代理'是这么设置的:proxy_set_header X-Real-Ip $proxy_add_x_forwarded_for;得到的是'一串IP',那么此时real_ip_recursive 的值就'至关重要'了;nginx将会从ip列表的'右到左',去比较set_real_ip_from 的'信任列表中的ip';1、如果real_ip_recursive为'off',那么当'最右边'一个ip,发现是信任ip,即认为下一个IP(右边第二个)就是用户的真正IP;2、如果real_ip_recursive为'on',那么将从'右到左'依次比较,直到找到一个'不是信任ip'为止,然后同样把IP值复制给$remote_addr。

案例讲解

④  变量

三    知识铺垫

(1)相关内置变量

①    $remote_addr

强调: 这里的'客户端'指的是'直接请求nginx'的客户端,非'origin_client_ip'补充: $remote_addr是获取的是'直接tcp连接'的客户端IP,这个是'无法伪造'的通俗: 与nginx建立tcp连接的'对端ip'地址

②    $proxy_add_x_forwarded_for

+++++++++  "解读"  +++++++++1) 如果请求到'nginx',没有携带'X-Forwarder-For'请求头,则$proxy_add_x_forwarded_for'记录'的是'$remote_addr'2) 如果请求到'nginx',并且'携带X-Forwarder-For'请求头,则$proxy_add_x_forwarded_for除了记录"X-Forwarder-For"头的值,还会将'$remote_addr'追加末尾,以"逗号分割"X-Forwarded-For: client1, proxy1, proxy2+++++++++  "常用"  +++++++++proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

伪造XFF

1)client '自定义' X-Forwarded-For: 'false_client1', 'proxy1'2)server 设置 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;3)导致upstream_server'上游服务器'获取的是X-Forwarded-For的第一个ip,也即'false_client'

③    $proxy_protocol_addr  $proxy_protocol_port

说明: 通过'proxy protocal'中解析出来'client_real_ip'和'client_real_port'备注: 这两个变量是'core'提供的

(2)前置条件

①   nginx编译realip模块

七层: 默认"源码编译"情况下是'该参数不被'编译,应使用 --with-http_realip_module 配置参数'启用'它

+++++++++++  "未编译这个参数使用该模块的指令会报错"  +++++++++++
​[emerg] unknown directive "set_real_ip_from" in /etc/nginx/nginx.conf:行号

②   nginx 对 proxy protocol协议支持

代理协议:分为v1和'v2'两个版本,v1是人类易读的,'v2是二进制'格式的应用场景:一般上层作为'tcp'代理,'代理层(send方)'需要支持'Proxy protocol',才能在'TCP报文中添加特殊信息',同时'nginx也需要支持'Proxy protocol,才能'解析'

重点: 了解'云厂商'如何实现的

阿里云 通过Proxy Protocol获取客户端真实IP(四层监听)

haproxy作者 关于PROXY protocol协议解读

AWS 关于 PROXY protocol解读

nginx 关于 proxy protocol的使用

Proxy Protocol support software

华为云 VPCEP 关于 Proxy Protocol

华为云 WAF 获取客户端真实ip 

(3)   PROXY protocol

①    引入

②    拓扑理解

③    协议格式

④    抓包分析

⑤    思考

+++++++  七层'为什么'使用Proxy protocol  +++++++1)客户端没有'XFF、X-Real-Ip'头,你不能要求'client'做改变2)XFF头等可能被'伪造',不具备'可考'性四层使用'Proxy protocol'原因: 不具备解析'HTTP'七层的能力

四    案例讲解

(1)案例一

+++++++++  "X-Forwarded-For应用"  +++++++++1)一般'CDN'厂商是通过这种方式获取2)这里讲解的是'nginx'获取客户端的'real_ip'方法; 'web应用(tomcat、django)'也可以处理

①    请求链路

client('172.25.2.157') -> proxy1('172.25.2.157') -> server('172.25.2.100')

②    默认

  

③    对比实验1

细节点: 观察'$remote_addr'

④    对比实验2

理解: 开启回溯之后,nginx认为'可信的地址'都是'proxy',所以继续'往前'追溯,直到找到一个不是'可信'的地址,认为是'real_ip'

(2)案例二

①    应用场景

 ②    配置

需求: 配置Proxy Protocol获取'源地址'功能,本次实验利用'http'而非'stream'模块

③   客户端测试

④     扩展

四层(haproxy) + 七层(nginx) + PROXY protocol获取客户端的真实ip

haproxy的Proxy Protocol代理协议

注意点:'PROXY protocol'是端口级别;作用所有相同端口,可能'导致报错'

参考地址

(3)关于兼容性日志的思考

说明: 很多时候,访问线路不一样,导致获取'client_real_ip'的方式不一样,导致'日志'记录方式不一样

①    端口

+++++++++  "多条线路通过端口区分"  +++++++++server {listen  443  http2;  # 兼容http1.1listen 6443  ssl proxy_protocol;...}+++++++++  "补充其它细节"  +++++++++server  {listen 443 ssl http2;
}特点: 上述配置只支持'http2'协议,不兼容http1现象: curl发送请求时,'直接返回的是http/2',而'不是'http/1.1原因: 虽然服务端配置了'只使用http2',但万一'客户端未支持'http2协议,直接返回http2客户端会'解析不了'

②    日志格式

关于map的知识铺垫

++++++++++++  "假定有两条解析线路"  ++++++++++++1)线路1 -->通过'waf(web应用防火墙-->也是一层代理)'到nginx备注:不同的'云厂商'waf透传源ip的方式'(管理面和租户面还不太一样)'不一样,一般有'自定义http变量[本次讲解]'、'XFF'头方式传递2)线路2 -->通过'haproxy、vpcep [支持PROXY protocol]'到nginxmap $proxy_protocol_addr $client_real_ip {""  $middle_real_ip;default $proxy_protocol_addr;
}map $http_waf_real_ip $middle_real_ip {""  $remote_addr;default $http_waf_real_ip;
}日志格式的'重点': X-Real-IP=[$client_real_ip]+++++++++  '分割线'  +++++++++ 如何'递归'解析: 使用$client_real_ip --> '使用'的时候 --> $middle_real_ip1)map指令对应的'结果变量'只有在'之后的配置文件'中'使用'到了该结果变量的时候2)才会'使用前面'定义的map模块('有该变量的')来进行映射

四    遗留

client --> waf('规则清洗')    --> lvs(dr) --> nginx 获取客户端的真实ip -->什么变量透传的client --> lvs(fullnat)     -->  nginx toa获取客户端的真实ip​
我的'上层4层代理服务器'如果要获取这个连接的'真实'地址,也需要在收到'tcp报文时解析proxy_protocol 协议'client --> lvs(fullnat) --> nginx 不装toa模块,获取的是什么限速、限流、做统计
​
投票系统,防止刷票,需要限制一个IP只能投票一次 -->客户端真实ip的应用场景++++++  400报错场景  ++++++
​
1)Bad Request(Invalid Hostname) HTTP Error 400$proxy_host  --> 默认 proxy_set_header  --> invalid host -->后端服务报错'400'根因:长连接导致,全局的'proxy_set_header'被覆盖2)双向认证,客户端证书过期3)请求头太大request header过大所引起,request过大,通常是由于cookie中写入了较大的值所引起https://www.cnblogs.com/duanweishi/p/9286461.html400是一种是HTTP状态码,400 Bad Request。是在打开网页时浏览器返回到客户端的一种状态码。显示在客户端的也就是400页面。
400页面是当用户在打开网页时,返回给用户界面带有400提示符的页面。其含义是你访问的页面域名不存在或者请求错误。
主要有两种形式:
1、bad request意思是“错误的请求";
2、invalid hostname意思是"不存在的域名”思考: nginx的'排查'思路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_17219.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM -- 垃圾回收器7种(四)

阅读前可参考 https://blog.csdn.net/MinggeQingchun/article/details/126947384 https://blog.csdn.net/MinggeQingchun/article/details/127066302 https://blog.csdn.net/MinggeQingchun/article/details/127089533 JVM官方调优指南 https://docs.oracle.com/javase/8/d…

JVET提案学习:块重要性映射Block importance mapping

JVET-Y0077:AHG10: Block importance mapping 是爱立信提出的视频前处理操作,已经被集成到了VTM和HM中。 Block importance mapping需要与MCTF结合,利用MCTF中计算出的参数得到每个ctu的重要性,根据块重要性去调整每个ctu的QP。…

安装selenium

一、安装python 二、安装pycharm 三、安装selenium 安装pip install selenium 卸载pip uninstall selenium 查看pip show selenium 打开pycharm,在终端输入pip install selenium 四、安装浏览器驱动 火狐浏览器 Firefox 48 以上版本 selenium 3.x Firefox驱动(g…

用友U8.0 V10虚拟机安装教VBox + Vmware

用友ERP这个软件是我计算机生涯中最痛苦的软件了,它比C和Pytho难学很多,课上4个小时也不一定能把实验做完,所以要求课后进行一些学习和巩固。 然而,这个软件比较优秀,在新版本的计算机中安装,可能和自己电脑…

PTA 22-23-1学期《数据结构》拓展练习题集

文章目录6-1 单链表逆转6-2 逆序数据建立链表6-3 删除单链表偶数节点6-4 两个有序链表序列的合并6-5 带头结点的单链表就地逆置6-6 单链表插入排序6-7 双端队列6-8 有序数组的插入6-9 线性表元素的区间删除6-10 在一个数组中实现两个堆栈6-11 使用函数实现字符串部分复制6-12 判…

【scratch高阶案例教学】scratch斐波那契数列 scratch创意编程 少儿编程 小朋友们也可以完成如此神奇的数列

目录 scratch斐波那契数列 一、案例简介 二、案例演示 三、案例分析 1、角色分析

springmvc实现增删改查(mysql数据库)

目录 要求: 创建工程: 大致思路: 配置spring配置文件: 配置webapp下WEB-INF下的web.xml文件: 现在开始正式的写代码: dao层: service层: controller层: 整个项目源…

java web开发(编写第一个servlet程序)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 之前从来没有编写过servlet程序,更没有用tomcat部署过java web程序。所以,趁着IDEA安装好、maven配置好,开始用…

FastDFS模拟场景

新增tracker服务 模拟场景:当多个tracker同时宕机无法恢复时临时添加新的tracker是否可行 实现方案 将之前已有的tracker server的配置文件scp一份到新的机器上,并在新机器上创建store_path对应的目录依次关闭storage server服务在每个storage server中的…

作为一名前端,该如何理解Nginx?

作为一名小前端,只需要好好写代码,至于部署相关的操作,我们通常接触不到,正所谓专业的人干专业的事,我们在工作中并不需要去配置,但这并不代表不需要了解,相信大家都多多少少听过nginx&#xff…

窗口函数OVER(PARTITION BY)详细用法——语法+函数+开窗范围ROWS和RANGE

目录 一、函数写法 二、开窗的窗口范围ROWS与RANGE 1.范围限定用法 2.ROWS和RANGE的区别 (1) ROWS按行数限定 (2) RANGE按数据范围限定 order by 数字 例1 汇总数据范围为:[当前行值,当前行值3] 例2 汇总数据范围为:[当前行值-3,当前行值] o…

较多业步骤场景通用框架

我们工作的大部分时间都在写业务代码,如何写好业务代码必然是我们追求的一大目标,在编程方面,简单、易懂、可扩展性是衡量代码质量的通用标准,所以在工作中,我们能用java将产品经理的想法表达出来还不够,我…

OSCP-Vulnhub靶机记录-LordoftheRoot-walkthrough

靶机地址 https://www.vulnhub.com/entry/lord-of-the-root-101,129/ 交流学习联系:webMsec 靶机安装 主机发现 靶机ip 192.168.160.131 使用nmap扫描后发现只开放了22 ssh 尝试连接ssh 这里需要端口碰撞 再次nmap扫描 1337端口开放apache Dirsearch扫一下 404…

IS-IS 路由选择协议入门

为了理解中间系统一中间系统(IntermediateSystem-to-Intermediate System, IS-IS) 路由选择协议的本质和内在的工作原理,把它放在整个网际协议和相关技术的框架中学习是十分重要的。本章深入IS-IS协议的本质,并且探讨了国际标准化组织(Intemational Orga…

Understanding the Users and Videos by Mining a Novel Danmu Dataset

题目:Understanding the Users and Videos by Mining a Novel Danmu Dataset 作者:Guangyi Lv, Kun Zhang, Le Wu, Enhong Chen, Tong Xu, Qi Liu, and Weidong He 发表:IEEE TRANSACTIONS ON BIG DATA, 2022 切入点:弹幕交流…

C++实现二分法求零点

​目录前言 题目: 一、零点是什么? 二、二分法求零点 1.二分法 2.完整代码 总结 前言 首先,我们要清楚我们是干嘛的;其次,知道原理;最后,才能明白自己要怎么办。明确:用二分法求函数。 题目: 二分法求函数的零点: 有函数: f(x) = x5 - 15 * x4+ 85 * x3- 225 * x2…

十一、动态规划题目相关

学习来源: 代码随香炉:https://www.programmercarl.com/ labuladong算法:https://labuladong.github.io/algo/ 动态规划 动态规划五部曲 确定dp数组(dp table)以及下标的含义 确定递推公式 dp数组如何初始化 确定遍历…

炫酷的花式滑块滑动无缝切换特效

💂 个人网站:【 海拥】【小霸王游戏机】【大转盘】🤟 风趣幽默的前端学习课程:👉28个案例趣学前端💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习群】【学习文档】💬 免费且实用的计…

【ML05】Feature Scaling 特征缩放

Feature ScalingFeature Scaling 特征缩放的目的是什么Feature Scaling Method #3Dividing by maximumMean NormalizationZ-Score normalizationFeature Scaling 特征缩放的目的是什么 考虑前两个组图: 组图1:同一辆大货车拉货,同一个函数在…

Flink学习笔记(2)——Flink快速上手

目录 一、Flink快速上手 1.1、环境准备 1.2 创建项目 1.3 编写代码 1.3.1 批处理 1.3.2 流处理 1.4 本章总结 一、Flink快速上手 对 Flink 有了基本的了解后,接下来就要理论联系实际,真正上手写代码了。Flink 底层是 以 Java 编写的,…