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


18

我让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;
}

我该怎么做呢?

Answers:


16

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

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

    location / {
        root   /sites/$sub;
    }
}

或者,最好将所有通用配置移动到另一个文件,然后在每个子域中创建服务器块并包含外部文件。

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

    location / {
        ... 
    } 
}

(重复其他服务器)


我是否缺少某些内容,或者服务器名称行缺少?<>?我相信应该是server_name ~^(?<sub>\.)?(?<domain>.+)$;
Mohammad AbuShady 2013年

您可能是正确的-我想不出现在是这样的任何原因,因此我已将其更改为您的建议。
cyberx86

6

一种选择是返回错误并将该错误发送到处理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;
}

5

如果使用地图,则无需使用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;
}

1
奇迹般有效。
conradkleinespel '16

@Tom Siwik无论如何,我也可以通过同样的方法来调整它以使用allow/ 强制执行IP限制deny
敬酒

应该有可能,您可以映射许多变量。请参阅:nginx.org/en/docs/varindex.html以获取变量列表。您可能需要$remote_addr代替$http_host。虽然不确定范围。
Tom Siwik

4

如果您有多个(子)域,但它们的行为不完全相同,则可以使用多个服务器blcoks。抱歉,即使您的配置更大,这也是最好的方法。

您可以使用诸如if($ http_host〜foo)之类的东西来进行贫民窟破解,但是很可能与if的不可预测和怪异行为相抵触,如此处记录:http ://wiki.nginx.org/IfIsEvil

不要试图超越Nginx,只需使用它为您提供的选项,您的头痛就会大大减少。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.