我需要重定向到一个 URL,除非用户来自我们的内部 IP 地址或者他们正在访问特定路径。
我试过这个:
location ~* /foobar {
break;
}
location ~* / {
if ($remote_addr != 111.222.333.444) {
rewrite ^ https://external.tld/
}
}
但这似乎不起作用。该特定配置在访问https://mydomain.tld/foobar和“欢迎使用 nginx!”时会导致 404 。从我们的 IP 地址访问它时的页面。但是,在我们的 IP 地址之外访问https://mydomain.tld/foobar确实会正确重定向到https://external.tld/
由于您不想(或不允许)显示您的完整服务器块,我会做一些猜测。您的配置最有可能发生了什么?您创建了两个额外的位置块,用于处理任何传入请求。检查
location
指令文档。唯一可以超越来自正则表达式匹配位置的请求的两种位置类型是精确位置 (location = /uri { ... }
) 和不检查正则表达式前缀位置 (location ^~ /prefix { ... }
)。否则,将选择第一个正则表达式匹配位置。每个服务器块都有它的根目录,即使它没有使用
root
指令明确指定。使用前缀(编译时指定,可以通过nginx -V
命令检查)和/html
后缀来选择。假设您的 nginx 前缀是/usr/share/nginx
. 然后,您的默认根目录将位于该目录中,除非使用该指令/usr/share/nginx/html
明确指定。root /some/path
服务请求时的默认 nginx 行为可以描述为
try_files $uri $uri/ =404
.假设我们有一个
https://mydomain.tld/foobar
请求。为了提供它,您的第一个location ~* /foobar { break; }
将被选为第一个匹配的正则表达式位置。第一个指令break
意味着ngx_http_rewrite_module
将停止处理当前的指令集。break
但是这个位置块内没有这些指令(除了那个)!是的,这意味着这个break
指令在这里没有用。接下来,nginx 会检查是否存在一个/usr/share/nginx/html/foobar
文件,/usr/share/nginx/html/foobar/
目录中的一个索引文件(默认为index.html
),两次检查都失败后,返回一个HTTP 404 Not Found
错误。现在假设我们有一个
https://mydomain.tld/
请求。您的第一个位置块不会匹配它,因此location ~* / { ... }
选择第二个来处理此请求(此位置块将匹配任何可能的有效请求)。如果 IP 地址检查未通过,则重定向将取而代之。但如果它通过了,nginx 会以与上述相同的方式处理您的请求,从目录中返回您的默认欢迎index.html
文件。/usr/share/nginx/html/
看起来您不了解如何
ngx_http_rewrite_module
处理来自 的指令。再次阅读文档的第一部分:您可以将支票放在服务器块级别:
上述
break
指令将按预期工作,ngx_http_rewrite_module
服务器级别的指令将停止执行。这意味着该模块中的任何其他指令(如set
、if
、return
等rewrite
)(如果有)应放在上述块之前。这不适用于ngx_http_rewrite_module
放置在位置级别的指令。还有一个可能的警告。如果您的
https://mydomain.tld/foobar
页面使用任何资产(脚本、样式、图像等),也应该允许访问这些资产。例如,您可以更改条件以允许任何以/foobar
前缀 using开头的内容if ($uri ~* ^/foobar) { break; }
。如果无法使用单个正则表达式检查它们的地址,则可以使用多个if (...) { break; }
块。