Nginx: Dopasowana nazwa hosta serwera w dyrektywie lokalizacji

18

Mam Nginx z wieloma domenami w ramach dyrektywy o jednym serwerze jako

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

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

Teraz muszę użyć dyrektywy lokalizacji, aby dopasować subdomenę i zastosować do niej podstawowe uwierzytelnianie. Odpowiednik

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

Jak mam to zrobic?

Quintin Par
źródło

Odpowiedzi:

16

Możesz użyć wyrażenia regularnego, aby przechwycić poddomenę, a następnie użyć jej później w swojej lokalizacji.

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

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

Alternatywnie może być wskazane przeniesienie wszystkich typowych konfiguracji do innego pliku, a następnie utworzenie bloków serwera dla subdomeny i dołączenie pliku zewnętrznego.

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

    location / {
        ... 
    } 
}

(powtórz dla innych serwerów)

cyberx86
źródło
Czy coś brakuje lub czy w linii nazwy serwera brakuje a ?i <>? Uważam, że tak powinno byćserver_name ~^(?<sub>\.)?(?<domain>.+)$;
Mohammad AbuShady
Prawdopodobnie masz rację - nie mogę wymyślić żadnego powodu, aby był taki, jaki był w tej chwili, więc zmieniłem to na twoją sugestię.
cyberx86 30.09.13
6

Jedną z opcji jest zwrócenie błędu i wysłanie go do lokalizacji obsługującej uwierzytelnianie 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
źródło
5

Jeśli korzystasz z mapy, nie musisz używać dyrektywy lokalizacyjnej. To najprostsze rozwiązanie i ekwiwalent, jaki mogę wymyślić. Możesz nazwać pliki htpasswd zgodnie ze swoim $ http_host np 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;
}
Tom Siwik
źródło
1
Działa jak marzenie.
conradkleinespel 14.04.16
@Tom Siwik W każdym razie czy mogę to zmienić, aby egzekwować ograniczenia własności intelektualnej za pomocą allow/ denyw ten sam sposób?
tosty
Powinno być możliwe, możesz zmapować wiele zmiennych. Zobacz: nginx.org/en/docs/varindex.html, aby uzyskać listę zmiennych. Prawdopodobnie będziesz potrzebować $remote_addrzamiast $http_host. Nie jestem jednak pewien co do zakresów.
Tom Siwik
4

Jeśli masz wiele (pod) domen i nie zachowują się one dokładnie tak samo, korzystasz z wielu serwerów blcoks. Przepraszamy, ale to naprawdę najlepszy sposób, nawet jeśli będziesz mieć większą konfigurację.

Możesz zrobić włamanie do getta, używając czegoś takiego jak if ($ http_host ~ foo), ale najprawdopodobniej uciekniesz przed nieprzewidywalnym i dziwnym zachowaniem if, jak udokumentowano tutaj: http://wiki.nginx.org/IfIsEvil

Nie próbuj przechytrzyć Nginx, po prostu skorzystaj z opcji, które ci daje, a będziesz mieć o wiele mniej problemów.

Martin Fjordvald
źródło