目前有一个地点被封锁/
location / {
root /var/www/docs;
proxy_pass http://backend;
proxy_buffering on;
proxy_buffer_size 64k;
proxy_buffers 256 64k;
}
需要通过IP进行过滤。
理想情况下,为了减少相同指令的重复次数location
,我想在location
块内执行测试
location / {
if ($uri ~ '^/(abc|def|ghi)') {
allow 10.0.0.0/8;
allow 1.2.3.4;
deny all;
}
root /var/www/docs;
proxy_pass http://backend;
proxy_buffering on;
proxy_buffer_size 64k;
proxy_buffers 256 64k;
}
allow
不幸的是, /指令似乎deny
不能在块内使用if
。
/etc/nginx/sites-enabled/mysite:20 中不允许使用“allow”指令
是否有一种优雅的方式来执行测试而无需重复location
块?
(喜欢
location ~ /(abc|def|ghi) {
allow 10.0.0.0/8;
allow 1.2.3.4;
deny all;
... 5 other lines root,proxy...
}
location / {
... 5 other lines root,proxy...
}
)
答案1
就像 coredump 所说的那样,不,使用多个位置。
但可以使location
块的内容不那么重复。这里的关键是location
包含root
和proxy_...
指令的命名块。
例如:
location / {
try_files $uri @proxy;
}
location ~ /(abc|def|ghi) {
allow 10.0.0.0/8;
allow 1.2.3.4;
deny all;
try_files $uri @proxy;
}
location @proxy {
root /var/www/docs;
proxy_pass http://backend;
proxy_buffering on;
proxy_buffer_size 64k;
proxy_buffers 256 64k;
}
可能更好的方法是将root
指令放在所有location
块之外。
答案2
首先,你必须定义一个变量来保存你的 IP 过滤器。这将进入httpnginx 配置部分:
map $remote_addr (or $http_x_forwarded_for if behind a proxy) $allowed {
default deny;
~\s*111.222.333.444$ allow;
~\s*333.444.555.*$ allow;
}
然后在服务器部分中,你编写了 if 构造并根据变量的内容过滤访问位置$允许:
location / {
if ( $allowed = "deny" ) { return 403; }
#...
}
答案3
通常在这种情况下可以帮助“嵌套位置”......
location / {
root /var/www/docs;
allow all;
location /admin {
deny 1.2.3.4;
}
}
... 但并非所有指令都会在嵌套位置中继承。遗憾的是,但确实如此proxy_pass
,以及类似的指令不会被继承... 因此,之前提出的解决方案(使用 @namedlocation)在这种情况下是正确的。当然,fastcgi_pass
您也可以使用“proxy_pass block”指令。include