nginx网关中使用realip模块

最近在项目中,遇到了关于nginx中配置白名单的问题。当中踩了一点坑,进行一个小结。

需求的背景是:让某个url只允许某些网段可访问

首先,前端请求在系统中的转发过程是:到集群代理服务器、然后再到云网关(如xlb)、接着到nginx网关、最后到前端的项目服务。

查阅相关资料,查找nginx相关知识。在对应的配置文件中,找到某个url(如: aaa)的配置, 然后进行配置。

location ~ /(aaa|bbb ) {        real_ip_header    X-Forwarded-For;        real_ip_recursive on;        allow xx.xxx.xx.xxx;        allow xxx.xxx.xx.xxx;        allow 192.168.0.0/16;        allow 10.0.0.0/8;        allow 172.xx.0.0/12;         deny all;}

这里,location的匹配规则:

= 表示精准匹配

~表示区分大小写的正则匹配         以aaa, bbb结尾

~*表示不区分大小写的正则匹配    以aaa, bbb结尾

^~表示以某字符开头,只匹配路径 如请求为/static/20%/aa可以被规则 ^~ /static//aa匹配到  以xxx开头

/ 任何请求都会匹配

       通过测试发现,使用外网访问url,仍然可访问。在容器中进行验证可到的结果反而是已生效。通过容器中的日志查询,发现了外网访问先到xlb, 接着再到nginx网关。到达xlb时访问的ip已不是外网ip,真实IP没有被识别。会被ip命中从而可以访问。

      通过了解相关知识,需要增加配置set_real_ip_from, 于是更改后的配置变为

location ~ /(aaa|bbb ) {set_real_ip_fromxx1.xx.xx.0 //代理服务器IP或者网段1et_real_ip_fromxx2.xx.xx.xx//代理服务器IP或者网段2et_real_ip_fromxx3.xx.xx.xx //代理服务器IP或者网段3        real_ip_header    X-Forwarded-For;real_ip_recursive on;        allow xx.xxx.xx.xxx;    //允许访问的IP或网段        allow xxx.xxx.xx.xxx;        allow 192.168.0.0/16;        allow 10.0.0.0/8;allow 172.xx.0.0/12;         deny all;}

其中,set_rel_ip_from: 表示来自代理服务器的IP,不是用户的真实IP

real_ip_header: 表示从header中的哪个属性检索出所要的IP

real_ip_recursive: on  表示递归排除IP地址,IP串从右往左排除set_real_ip_from 中出现的IP。如果IP串有个IP并不在其中,那么这个IP就是用户IP.  

例如:真实服务器获取的IP串如下

xx4.xx.xx.xx xx3.xx.xx.xxxx2.xx.xx.xx xx1.xx.xx.0

   当real_ip_recursive: on, xx3.xx.xx.xx xx2.xx.xx.xx xx1.xx.xx.0 都在set_rel_ip_from列表中,递归到xx4.xx.xx.xx时,会认为这个IP是用户IP。意思是将IP串中最后一个不是set_real_ip_from中的IP命中;

     当real_ip_recursive: off 时,会将最后一个IP作为用户IP,即xx3.xx.xx.xx,实质上这是代理服务器3的IP.

      在这次配置上线中,除了需要nginx realip的相关知识储备外,还需要了解从浏览器输入url 到请求到达服务器经历的过程。当然,如果是购买了云厂商的服务(如华为云、AWS等),可进行负载均衡配置,不需在网关层进行处理,具体需要结合项目的结构。

想更详尽的了解nginx realip的知识,可以参考#set_real_ip_from