Nginx: Entspricht dem Hostnamen des Servers in der Location-Direktive

18

Ich habe Nginx mehrere Domänen unter einer einzigen Server-Direktive als ausgeführt

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

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

Jetzt muss ich die location-Direktive verwenden, um eine Unterdomäne zuzuordnen und grundlegende Authentifizierung darauf anzuwenden. Das Äquivalent von

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

Wie mache ich das?

Quintin Par
quelle

Antworten:

16

Sie können einen regulären Ausdruck verwenden, um die Unterdomäne zu erfassen und später an Ihrem Standort zu verwenden.

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

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

Alternativ ist es möglicherweise vorzuziehen, alle gängigen Konfigurationen in eine andere Datei zu verschieben und anschließend Serverblöcke pro Unterdomäne zu erstellen und die externe Datei einzuschließen.

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

    location / {
        ... 
    } 
}

(Wiederholung für andere Server)

cyberx86
quelle
Fehlt mir etwas oder fehlt in der Servernamenzeile ein ?und <>? Ich glaube, es sollte seinserver_name ~^(?<sub>\.)?(?<domain>.+)$;
Mohammad AbuShady
Sie haben mit ziemlicher Wahrscheinlichkeit recht - ich kann mir keinen Grund dafür vorstellen, dass es so war, wie es im Moment war, also habe ich es auf Ihren Vorschlag abgeändert.
cyberx86
6

Eine Möglichkeit besteht darin, einen Fehler zurückzugeben und diesen Fehler an einen Speicherort zu senden, der die HTTP-Authentifizierung verarbeitet:

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
quelle
5

Sie müssen die Location-Direktive nicht verwenden, wenn Sie eine Karte verwenden. Dies ist die einfachste Lösung und das Äquivalent, das ich mir vorstellen kann. Sie können die htpasswd-Dateien entsprechend Ihrem $ http_host benennen, z 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
quelle
1
Klappt wunderbar.
Conradkleinespel
@Tom Siwik Kann ich dies trotzdem anpassen, um IP-Beschränkungen mit allow/ denyauf die gleiche Weise durchzusetzen ?
Toast
Sollte es möglich sein, können Sie viele Variablen abbilden. Eine Liste der Variablen finden Sie unter: nginx.org/en/docs/varindex.html . Sie werden wahrscheinlich brauchen $remote_addrstatt $http_host. Ich bin mir jedoch nicht sicher über die Bereiche.
Tom Siwik
4

Wenn Sie mehrere (Sub-) Domains haben und diese sich nicht genau gleich verhalten , verwenden Sie mehrere Server-Blöcke. Tut mir leid, aber das ist im Ernst der beste Weg, obwohl Sie eine größere Konfiguration haben.

Sie können einen Ghetto-Hack durchführen, indem Sie so etwas wie if ($ http_host ~ foo) verwenden, aber dann werden Sie höchstwahrscheinlich das unvorhersehbare und seltsame Verhalten von if in Frage stellen, wie hier dokumentiert: http://wiki.nginx.org/IfIsEvil

Versuchen Sie nicht, Nginx auszutricksen, sondern nutzen Sie die Optionen, die es Ihnen bietet, und Sie werden viel weniger Kopfschmerzen haben.

Martin Fjordvald
quelle