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

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

Quintin Par
источник

Ответы:

16

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

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

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

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

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

    location / {
        ... 
    } 
}

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

cyberx86
источник
Я что-то пропустил или в строке имени сервера отсутствует a ?и <>? Я считаю, что это должно бытьserver_name ~^(?<sub>\.)?(?<domain>.+)$;
Мухаммед Абу Шади
Вы, скорее всего, правы - я не могу думать о какой-либо причине, как это было в данный момент, поэтому я изменил это на ваше предложение.
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;
}
slaptijack
источник
5

Вам не нужно использовать директиву местоположения, если вы используете карту. Это самое простое решение и эквивалент, который я могу придумать. Вы можете назвать файлы 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;
}
Том Сивик
источник
1
Работает как шарм.
conradkleinespel
@ Tom Siwik В любом случае, я могу настроить это так же, чтобы принудительно устанавливать ограничения IP с allow/ deny?
Тост
Должно быть возможно, вы можете отобразить много переменных. Смотрите: nginx.org/en/docs/varindex.html для списка переменных. Вам, вероятно, нужно $remote_addrвместо $http_host. Не уверен насчет диапазонов, хотя.
Том Сивик
4

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

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

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

Мартин Фьордвальд
источник