Назад | Перейти на главную страницу

Nginx: соответствие имени хоста сервера в директиве местоположения

У меня nginx работает с несколькими доменами под одной директивой сервера как

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

----
----
----
}

Теперь мне нужно использовать директиву местоположения, чтобы сопоставить поддомен и применить к нему базовую аутентификацию. Эквивалент

location x.domain.com {
        auth_basic "Admin Login";
        auth_basic_user_file /etc/nginx/.htpasswd;
}

Как мне это сделать?

Вы можете использовать регулярное выражение для захвата субдомена, а затем использовать его позже в вашем регионе.

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

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

В качестве альтернативы, может быть предпочтительнее переместить все общие конфигурации в другой файл, а затем создать серверные блоки для каждого поддомена и включить внешний файл.

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

    location / {
        ... 
    } 
}

(повторить для других серверов)

Вам не нужно использовать директиву location, если вы используете карту. Это самое простое и эквивалентное решение, которое я могу придумать. Вы можете назвать файлы htpasswd в соответствии с вашим $ http_host, например. 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;
}

Один из вариантов - вернуть ошибку и отправить ее в место, которое обрабатывает 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;
}

Если у вас несколько (под) доменов, и они не работают именно похоже, тогда вы используете несколько серверных блоков. Извините, но это действительно лучший способ, даже если у вас будет более крупная конфигурация.

Вы можете взломать гетто, используя что-то вроде if ($ http_host ~ foo), но тогда вы, скорее всего, столкнетесь с непредсказуемым и странным поведением if, как описано здесь: http://wiki.nginx.org/IfIsEvil

Не пытайтесь перехитрить Nginx, просто используйте те возможности, которые он дает, и у вас будет гораздо меньше головной боли.