Nginx: nombre de host del servidor coincidente en la directiva de ubicación

18

Tengo nginx ejecutando múltiples dominios bajo una sola directiva de servidor como

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

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

Ahora, necesito usar la directiva de ubicación para que coincida con un subdominio y aplicarle la autenticación básica. El equivalente de

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

¿Cómo hago esto?

Quintin Par
fuente

Respuestas:

16

Puede usar una expresión regular para capturar el subdominio y luego usarlo más tarde en su ubicación.

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

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

Alternativamente, podría ser preferible mover todas las configuraciones comunes a otro archivo y luego crear bloques de servidor por subdominio e incluir el archivo externo.

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

    location / {
        ... 
    } 
}

(repetir para otros servidores)

cyberx86
fuente
¿Me estoy perdiendo algo o la línea del nombre del servidor falta ?y <>? Creo que debería serserver_name ~^(?<sub>\.)?(?<domain>.+)$;
Mohammad AbuShady
Probablemente tenga razón: no puedo pensar en ninguna razón para que sea así en este momento, así que lo he cambiado a su sugerencia.
cyberx86
6

Una opción es devolver un error y enviarlo a una ubicación que maneje la autenticación 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
fuente
5

No necesita usar la directiva de ubicación si usa el mapa. Esta es la solución más simple y equivalente que se me ocurre. Puede nombrar los archivos htpasswd de acuerdo con su $ http_host, por ejemplo 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
fuente
1
Funciona de maravilla.
conradkleinespel
@ Tom Siwik De todos modos, ¿puedo ajustar esto para hacer cumplir las restricciones de IP con allow/ denyde la misma manera también?
brindis
Debería ser posible, puede asignar muchas variables. Consulte: nginx.org/en/docs/varindex.html para obtener una lista de variables. Probablemente necesites en $remote_addrlugar de $http_host. Sin embargo, no estoy seguro de los rangos.
Tom Siwik
4

Si tiene múltiples (sub) dominios y no se comportan exactamente igual, entonces usa múltiples servidores blcoks. Lo sentimos, pero esa es realmente la mejor manera, a pesar de que tendrá una configuración más grande.

Puede hacer un hack de ghetto usando algo como if ($ http_host ~ foo) pero entonces probablemente se encontrará con el comportamiento impredecible y extraño de if como se documenta aquí: http://wiki.nginx.org/IfIsEvil

No intentes burlar a Nginx, solo usa las opciones que te da y tendrás muchos menos dolores de cabeza.

Martin Fjordvald
fuente