我需要拒绝访问网站的所有,除了子网的数量,在那里的前端代理所在。同时,我需要设置真实的的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处理指令的方式的理解出了什么问题?
1条答案
按热度按时间t5fffqht1#
realip module在使用反向代理或负载平衡器后的Nginx时很方便,但它确实重新定义了
$remote_addr
,这会影响日志记录和allow
指令等。您可以使用
$realip_remote_addr
获取反向代理或负载平衡器的地址。您可以使用问题中的
geo
块来测试它,只需将该变量作为address参数包括在内即可。例如: