Nginx: correspondance du nom d'hôte du serveur dans la directive d'emplacement

18

J'ai nginx exécutant plusieurs domaines sous une seule directive serveur comme

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

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

Maintenant, je dois utiliser la directive location pour faire correspondre un sous-domaine et lui appliquer l'authentification de base. L'équivalent de

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

Comment puis-je faire cela?

Quintin Par
la source

Réponses:

16

Vous pouvez utiliser une expression régulière pour capturer le sous-domaine, puis l'utiliser plus tard dans votre emplacement.

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

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

Alternativement, il peut être préférable de déplacer toutes les configurations courantes vers un autre fichier, puis de créer des blocs serveur par sous-domaine et d'inclure le fichier externe.

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

    location / {
        ... 
    } 
}

(répéter pour les autres serveurs)

cyberx86
la source
Suis-je en train de manquer quelque chose ou la ligne de nom du serveur manque-t-elle un ?et <>? Je crois que ça devrait êtreserver_name ~^(?<sub>\.)?(?<domain>.+)$;
Mohammad AbuShady
Vous avez très probablement raison - je ne vois aucune raison pour que ce soit comme cela en ce moment, alors je l'ai changé en votre suggestion.
cyberx86
6

Une option consiste à renvoyer une erreur et à l'envoyer à un emplacement qui gère l'authentification 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
la source
5

Vous n'avez pas besoin d'utiliser la directive location si vous utilisez la carte. C'est la solution la plus simple et équivalente à laquelle je puisse penser. Vous pouvez nommer les fichiers htpasswd en fonction de votre $ http_host par exemple 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
la source
1
Fonctionne comme un charme.
conradkleinespel
@ Tom Siwik Quoi qu'il en soit, je peux régler cela pour appliquer les restrictions IP avec allow/ denyde la même manière?
toast le
Cela devrait être possible, vous pouvez mapper de nombreuses variables. Voir: nginx.org/en/docs/varindex.html pour une liste de variables. Vous en aurez probablement besoin à la $remote_addrplace de $http_host. Je ne suis pas sûr des plages cependant.
Tom Siwik
4

Si vous avez plusieurs (sous) domaines et qu'ils ne se comportent pas exactement de la même manière , vous utilisez plusieurs blcoks de serveur. Désolé mais c'est vraiment la meilleure façon, même si vous aurez une configuration plus grande.

Vous pouvez faire un piratage du ghetto en utilisant quelque chose comme if ($ http_host ~ foo), mais vous vous exposerez très probablement au comportement imprévisible et étrange de if comme indiqué ici: http://wiki.nginx.org/IfIsEvil

N'essayez pas de déjouer Nginx, utilisez simplement les options qu'il vous offre et vous aurez beaucoup moins de maux de tête.

Martin Fjordvald
la source