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?

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)


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

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

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.