我有 nginx 在单个服务器指令下运行多个域,如下所示
server {
listen 80;
server_name www.domain.com;
server_name x.domain.com;
server_name y.domain.com;
----
----
----
}
现在,我需要使用 location 指令来匹配子域并对其应用基本身份验证。相当于
location x.domain.com {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/.htpasswd;
}
我该怎么做呢?
答案1
您可以使用正则表达式来捕获子域,然后稍后在您的位置使用它。
server {
server_name ~^(?<sub>\.)?(?<domain>.+)$;
location / {
root /sites/$sub;
}
}
或者,最好将所有常见配置移动到其他文件,然后为每个子域创建服务器块并包含外部文件。
server {
server_name www.domain.com;
include /etc/nginx/sites-enabled/default.inc;
location / {
...
}
}
(对其他服务器重复此操作)
答案2
如果使用 map,则无需使用 location 指令。这是我能想到的最简单的解决方案和等效方案。您可以根据 $http_host 命名 htpasswd 文件,例如x.domain.com.htpasswd
。
map $http_host $auth_type {
default "off"; #This will turn off auth-basic
x.domain.com "Restricted"; #This or any other string will turn it back on
}
server {
auth_basic $auth_type;
auth_basic_user_file /etc/nginx/conf.d/$http_host.htpasswd;
}
答案3
一种选择是返回错误并将该错误发送到处理 HTTP 身份验证的位置:
if ($host = x.domain.com) {
return 550;
}
error_page 550 = @xauth;
location @xauth {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/.htpasswd;
}
答案4
如果你有多个(子)域名,但它们的行为不正常确切地相同,则使用多个服务器块。抱歉,但这确实是最好的方法,即使您的配置较大。
您可以使用类似 if ($http_host ~ foo) 的方法进行贫民窟黑客攻击,但随后您很可能会遇到 if 的不可预测和奇怪的行为,如下所述:http://wiki.nginx.org/IfIsEvil
不要试图超越 Nginx,只需使用它提供的选项,你就会少受很多麻烦。