Nginx:在位置指令中匹配服务器主机名

Qui*_*Par 24 nginx

我有 nginx 在单个服务器指令下运行多个域

server {
        listen       80;
        server_name  www.domain.com;
        server_name  x.domain.com;
        server_name  y.domain.com;

----
----
----
}
Run Code Online (Sandbox Code Playgroud)

现在,我需要使用 location 指令来匹配子域并对其应用基本身份验证。相当于

location x.domain.com {
        auth_basic "Admin Login";
        auth_basic_user_file /etc/nginx/.htpasswd;
}
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?

cyb*_*x86 17

您可以使用正则表达式来捕获子域,然后稍后在您所在的位置使用它。

server {
    server_name   ~^(?<sub>\.)?(?<domain>.+)$;

    location / {
        root   /sites/$sub;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,最好将所有常见配置移动到其他文件,然后为每个子域创建服务器块并包含外部文件。

server {
        server_name  www.domain.com;
        include /etc/nginx/sites-enabled/default.inc;

    location / {
        ... 
    } 
}
Run Code Online (Sandbox Code Playgroud)

(其他服务器重复)


Tom*_*wik 8

如果使用 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 奇迹般有效。 (2认同)

小智 7

一种选择是返回错误并将该错误发送到处理 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;
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ald 5

如果您有多个(子)域并且它们的行为不完全相同,那么您可以使用多个服务器块。抱歉,但这确实是最好的方法,即使您将拥有更大的配置。

您可以使用 if ($http_host ~ foo) 之类的东西来进行 ghetto hack,但是您很可能会遇到 if 的不可预测和奇怪的行为,如下所示:http: //wiki.nginx.org/IfIsEvil

不要试图智胜 Nginx,只需使用它为您提供的选项,您的麻烦就会少得多。