Nginx -是否可以仅结合set_真实的_ip_from允许从某些子网访问?

iecba09b  于 2023-02-07  发布在  Nginx
关注(0)|答案(1)|浏览(162)

我需要拒绝访问网站的所有,除了子网的数量,在那里的前端代理所在。同时,我需要设置真实的的IP为进一步处理。该图看起来像这样:

Some infrastructure proxying traffic to nginx
 ________         ______________________________________________             _________________
|        |       |                                              |           |                 |
| Client |------>|public-allowed ingress IP          egress IP's|<--------->| Nginx           |
|________|       |______________________________________________|           |_________________|
                                                                             Allowed access
                                                                             for «egress IP's»
                                                                             only.

首先,我尝试了下一个配置(所有IP仅供参考):

server {
       server_name someserver.tld;

       # Subnets where frontend proxies are located
       allow   1.2.3.0/24;
       allow   4.5.6.0/24;
       allow   7.8.9.0/24;
       
       # Deny access bypassing proxies
       deny    all;

       set_real_ip_from 1.2.3.0/24;
       set_real_ip_from 4.5.6.0/24;
       set_real_ip_from 7.8.9.0/24;
       real_ip_header X-Forwarded-For;
       real_ip_recursive on;

        … skipped …
}

不出所料,这是行不通的:nginx设置客户端的真实的IP,然后检查条件并拒绝每个人访问站点。所以我尝试下一步:

# This block is outside of «server» section, so I expect it will be processed first
geo $someserver_allow {
        default     0;
        1.2.3.0/24  1;
        4.5.6.0/24  1;
        7.8.9.0/24  1;
}

server {
       server_name someserver.tld;

       # Deny access bypassing proxies
       if ($someserver_allow != 1) {
               return 403 "Bypassing the frontend is not allowed.";
       }

       set_real_ip_from 1.2.3.0/24;
       set_real_ip_from 4.5.6.0/24;
       set_real_ip_from 7.8.9.0/24;
       real_ip_header X-Forwarded-For;
       real_ip_recursive on;

        … skipped …
}

我以为nginx会处理geo指令,设置$someserverallow忽略server部分中的real_ip_header,但似乎我错了。为了确定我注解掉了整个if子句,并在geo部分之后添加了下面几行:

map $someserver_allow $downstream {
        default $remote_addr;
}

并且还在服务器部分中添加了以下内容:

add_header X-Downstream-IP "$downstream"

用我的浏览器请求前端服务器,我在X-Downstream-IP标头中得到了我自己的IP地址,而不是代理服务器的IP。
那么,我的配置出了什么问题,或者,也许,我对nginx处理指令的方式的理解出了什么问题?

t5fffqht

t5fffqht1#

realip module在使用反向代理或负载平衡器后的Nginx时很方便,但它确实重新定义了$remote_addr,这会影响日志记录和allow指令等。
您可以使用$realip_remote_addr获取反向代理或负载平衡器的地址。
您可以使用问题中的geo块来测试它,只需将该变量作为address参数包括在内即可。
例如:

geo $realip_remote_addr $someserver_allow {
    default     0;
    1.2.3.0/24  1;
    4.5.6.0/24  1;
    7.8.9.0/24  1;
}

相关问题