Nginx: nome do host do servidor correspondente na diretiva local

18

Eu tenho o nginx executando vários domínios sob uma diretiva de servidor único, como

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

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

Agora, preciso usar a diretiva de localização para corresponder a um subdomínio e aplicar a autenticação básica a ele. O equivalente a

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

Como eu faço isso?

Quintin Par
fonte

Respostas:

16

Você pode usar uma expressão regular para capturar o subdomínio e usá-lo posteriormente em seu local.

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

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

Como alternativa, pode ser preferível mover todas as configurações comuns para outro arquivo e criar blocos de servidor por subdomínio e incluir o arquivo externo.

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

    location / {
        ... 
    } 
}

(repita para outros servidores)

cyberx86
fonte
Estou faltando alguma coisa ou a linha de nome do servidor está ausente ?e <>? Eu acredito que deveria serserver_name ~^(?<sub>\.)?(?<domain>.+)$;
Mohammad AbuShady
Você provavelmente está correto - não consigo pensar em nenhuma razão para ser do jeito que estava no momento, então mudei para sua sugestão.
cyberx86
6

Uma opção é retornar um erro e enviá-lo para um local que lida com a autenticação 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
fonte
5

Você não precisa usar a diretiva de localização se usar o mapa. Esta é a solução mais simples e equivalente em que consigo pensar. Você pode nomear os arquivos htpasswd de acordo com o seu $ http_host, por exemplo 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
fonte
11
Funciona como um encanto.
conradkleinespel
@ Tom Siwik De qualquer forma, posso ajustar isso para impor restrições de IP com allow/ denyda mesma maneira também?
brinde
Se possível, você pode mapear várias variáveis. Veja: nginx.org/en/docs/varindex.html para obter uma lista de variáveis. Você provavelmente precisará em $remote_addrvez de $http_host. Não tenho certeza sobre os intervalos embora.
Tom Siwik 06/04
4

Se você possui vários (sub) domínios e eles não se comportam exatamente da mesma forma, você usa vários blcoks de servidor. Desculpe, mas essa é realmente a melhor maneira, mesmo que você tenha uma configuração maior.

Você pode invadir o gueto usando algo como if ($ http_host ~ foo), mas provavelmente irá se deparar com o comportamento imprevisível e estranho do if conforme documentado aqui: http://wiki.nginx.org/IfIsEvil

Não tente enganar o Nginx, basta usar as opções que ele oferece e você terá muito menos dores de cabeça.

Martin Fjordvald
fonte