O proxy_pass dinâmico de Nginx não resolve corretamente

5

Estou tendo problemas para configurar o nginx, procurei soluções na web e tenho alguns bits, mas ainda não consigo criar a configuração correta.

Eu registrei um domínio, digamos - www.example.com. Eu configurei tudo no site dos registradores, pingando www.example.com e www. *. Example.com foi bem-sucedido.

Eu tenho o Apache Tomcat em execução na minha máquina ouvindo na porta 8080. Desejo configurar o proxy_pass dinâmico. Portanto, se eu tiver o aplicativo MyApp sendo executado no tomcat e acessível por meio do localhost: 8080 / MyApp, eu quero ser capaz de alcançá-lo com www.MyApp.example.com, então, basicamente, o subdomínio seria o nome do aplicativo no tomcat. / p>

Aqui está minha configuração do nginx:

server {
  server_name ~^(www\.)?(?<sub_domain>.+)\.example\.com$;
  listen 80;

  location / {
     proxy_pass http://localhost:8080/$sub_domain/;
  }
}

Quando vou para www.myapp.example.com, estou sendo redirecionado para http://localhost:8080/myapp - quero dizer que literalmente acabo com http://localhost:8080/myapp no meu navegador.

Se, no entanto, eu alterar a regex na configuração nginx para:

server {
      server_name www.myapp.example.com myapp.example.com
      listen 80;

      location / {
         proxy_pass http://localhost:8080/myapp/;
      }
    }

Então tudo funciona como um encanto. Eu sei que tem que fazer alguma coisa com o resolvedor, eu já tentei colocar resolvedor no nginx mas ele não muda nada.

O que estou perdendo aqui?

// edit:

Aqui está minha configuração. Ainda estou sendo redirecionado para www.myapp.example.com/myapp/login em vez de www.myapp.example.com/login. Eu mudei o regex, ainda é o mesmo.

  http {

    upstream backend {

             server 127.0.0.1:8080;

    }

    server {                                                         
          server_name ~^(www\.)?(?<sub_domain>.+)\.example\.com$;
          listen 80;                                                        


           location / {
               proxy_set_header "Host" $host;
               proxy_pass http://backend/prefix-$sub_domain/;

               proxy_redirect http://$host/prefix-$sub_domain/ http://$host;

           }

    }

curl:

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /prefix-myapp/ HTTP/1.1
> User-Agent: curl/7.35.0
> Accept: */*
> Host: www.myapp.example.com
>
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=E609EB96D8F27FD6F4E7F9ED9ACA5245; Path=/prefix-myapp/; HttpOnly
< Location: http://www.myapp.example.com/prefix-myapp/login;jsessionid=E609EB96D8F27FD6F4E7F9ED9ACA5245
< Content-Length: 0
< Date: Tue, 21 Oct 2014 16:48:05 GMT
<
* Connection #0 to host 127.0.0.1 left intact

Editar: //

Muito obrigado Xavier! Adicionando as seguintes duas linhas ajudou:

proxy_pass http://backend/prefix-$domain$request_uri;
proxy_redirect http://$host/prefix-$domain http://$host;

2 Mais perguntas:

  1. Essa configuração tem grande impacto no desempenho?
  2. Posso filtrar algo do $ request_uri (por exemplo, JSESSIONID = 1233 ....)?

Mais uma vez, muito obrigado! Demorei uma semana para descobrir isso!

    
por Stugal 21.10.2014 / 10:03

1 resposta

7

Quando você estiver usando variáveis em uma diretiva proxy_pass , o nginx usará a resolução em tempo de execução, exceto se:

  • o servidor de destino é declarado como um endereço IP
  • o nome do servidor de destino faz parte de um grupo de servidores upstream
  • o nome do servidor de destino já foi resolvido (por exemplo, ele corresponde a um nome de servidor em outro bloco de servidor)

Aqui, um resolvedor de tempo de execução não ajudará como o host local pode não ser resolvido por um DNS. Também é um desperdício ter resolução em tempo de execução, pois você pode evitá-lo aqui.

Então, duas soluções simples:

  • use 127.0.0.1
  • declare um bloco upstream se você tiver nomes de servidores ou um pool de servidores de destino

Agora, você precisa que o redirecionamento do servidor proxy esteja correto. Então, ou:

  • seu alvo de proxy manipula o cabeçalho do host e você o passa com:

    proxy_set_header "Host" $host;

  • seu alvo proxy não pode manipular o cabeçalho do host para redirecionamentos e você precisa reescrevê-los com nginx usando:

    proxy_redirect http://$proxy_host/$sub_domain http://$host;

No entanto, se não suportar o cabeçalho do Host, os links serão quebrados.

    
por 21.10.2014 / 14:01