50 | postread阶段:获取真实客户端地址的realip模块
获取真实用户IP地址
realip模块可以帮助我们发现真实的用户ip地址。这为我们后续的模块实现,例如限速、限流等等功能提供了可能性。
image.png
TCP有个四元组,根据一条连接的src ip就能够判断出,用户的IP地址了。但是实际上因为中间有反向代理,反向代理会导致上游的机器建立的新的TCP连接,所以上游的服务器想通过TCP连接中的src ip是无法拿到用户的真实ip地址。上图右半部分是举的例子。
怎么才能拿到真实的用户IP呢?使用X-Forwarded-For、X-Real-IP。两者区别,Real-IP只能传一个IP,Forward-For是一直往上加的。为什么累加呢?看右边的例子。CDN往后发的时候要让后面的上游服务知道CDN的地址,所以就累加了 一个1.1.1.1
。
拿到真实用户IP后如何使用呢?
image.png
根据我们在real_ip中配置的指令,real ip模块会把从X-Forwarded-For或者X-Real-IP 这个头部里的值,覆盖到binary_remote_addr、remote_addr变量。这样之后的限速才会有意义。所以就能理解limit_conn模块,它的顺序一定要在preaccess阶段,不能在postread阶段。
如何启动realip模块
image.png
因为它改变了原来的remode_addr跟remode_port,它带来了两个变量 realip_remote_addr、realip_remote_port来维护原先的变量。
提供的三个 指令
image.png
set_real_ip_from:对于什么样的tcp连接的source ip,才做替换remote_add替换这件事。
real_ip_header:到底是从x-real-ip取还是x-forward-for、proxy_protocol中取。如果是x-forward-for,它有多个ip地址,那么取最后的那个。
real_ip_recursive:环回地址。默认是关闭的。打开的时候,会把x-forward-for里面最后的那个地址,如果是和客户端地址相同的话,会把它pass掉,去取上一个地址。
实践
image.png
把本机设置为可信地址set_real_ip_from 116.62.160.193
(本机ip)。
image.png
接着把real_ip_recursive 设置为on。
image.png
为什么会有这个结果呢?因为客户端的地址是116.62.160.193
。触发了一个环回地址的配置,然后pass掉了,然后使用它之前的一个地址。
处于postread 阶段,可以拿到未经任何加工的x-real-ip或x-forward-for里面的用户地址。因为后续有很多模块可能会修改x-forward-for等等头部的值。
留言问题
1.Nginx有办法获取IP的请求端口吗?就是发起HTTP请求连接的客服端端口。
作者回复
如果nginx与客户端之间没有其他反向代理,可以用remote_port获取到。如果存在其他反向代理,就无法用通用的办法获取到了。
2.三个问题
1、例如 proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for的值赋值给前面的变量 X-Forwarded-For 吗? 那变量X-Forwarded-For名称是否可以随意进行定义?该变量的用处是什么,因为nginx的日志定义log_format中并未使用到X-Forwarded-For这个变量
*2、如果是多层nginx代理,nginx01+nginx02 nginx02如何获取到客户端的真实ip地址3、proxy_set_header中的定义,在log_format中并未应用到,各变量的作用在此次视频中也未讲解到
作者回复
1、proxy_set_header是设置发向上游服务的请求头部的指令,第4部分课程会详细介绍。
X-Forwarded-For是RFC7239定义的头部,所有各大web服务都支持,你改了后就只能自己处理,不能依赖nginx之类的服务自动处理了。这一节课介绍的realip模块,也必须通过这个名称来修改remote_addr变量。2、通过X-forwarded-for或者x-realip头部。
3、proxy反向代理在第4部分介绍。咱们课程后面内容还很多
作者:言十年
链接:https://www.jianshu.com/p/52fd2115440d
共同学习,写下你的评论
评论加载中...
作者其他优质文章