关于nginx - $remote_addr的解释
nginx的自带变量 $remote_addr 代表客户端的IP
remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的.
当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理(比如clb),那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。
但是实际场景中,我们即使有代理,也需要将$remote_addr设置为真实的用户IP, 以下利用with-http_realip_module模块实现
安装(nginx或者openresty编译需要加--with-http_realip_module)
1 | ./configure ...... --with-http_realip_module |
添加如下配置
1 | # 从哪个header头检索出要的IP地址 |
- 字段说明
set_real_ip_from为定义信任ip,如果发送方的ip不在信任中,则不处理,$remote_addr就还会是发送发的地址。如果ip在信任中,则会根据下一个参数real_ip_header的设定,将指定的header头字段的数据作为$remote_addr。
如果real_ip_header中定义的header头字段,只传来了一个IP,比如默认的X-Real-Ip,则会直接将这个ip作为$remote_addr。这时候,如果像阿里云SLB,CDN,或者别的nginx等这类代理传来的,其真实IP可以是通过别的header字段传来的,那么跟去实际情况,定义此字段,这里我用的常见的X-Forwarded-For字段
这里需要说明一下X-Forwarded-For这个header信息,用于记录此请求所进过的ip,假设本nginx为第3层代理,那么获取到的X-Forwarded-For就会记录3个ip,分别顺序为:
1 用户IP 第一层代理IP 第二层代理IP
默认情况下x-forwarded-for是个串
假设用户的ip为: 120.22.11.11
在real_ip_recursive on的情况下
- 假如
61.22.22.22, 121.207.33.33, 192.168.50.121都出现在set_real_ip_from中,仅仅120.22.11.11没出现,那么他就被认为是用户的ip地址,并且赋值到remote_addr变量 - 总结: 从右边往左一直取到第一个不信任的IP作为$remote_addr,示例这里是全部信任,那么最左边的IP则会被作为$remote_addr。
- 假如
在real_ip_recursive off或者不设置的情况下
假如
192.168.50.121出现在set_real_ip_from中,排除掉,接下来的ip地址便认为是用户的ip地址总结: 从右往左,取第一个出现在信任中的IP的左边一位的IP作为$remote_addr,示例这里是全信任,所以就会取到第一层代理IP
