reescreva http para https com ngnix atrás do balanceador de carga


13

Estou usando um balanceador de carga da Rackspace que permite configurar minha chave / pem ssl dentro do painel de administração. Tudo funciona bem, eu posso usar os protocolos http e https. Mas se eu tentar redirecionar http para https usando:

server{
  listen *:80;
  server_name mydomain.com www.mydomain.com; 
  rewrite ^ https://mydomain.com$request_uri? permanent;

... Eu recebo um loop de redirecionamento. Sei que não estou ouvindo a porta 443, mas é porque o balanceador de carga tratou disso para mim. Eu também tentei envolver a reescrita if ($scheme ~* http){sem sucesso.

A outra parte da minha pergunta é que eu gostaria de remover o www do URL. Posso fazer isso com uma única reescrita? As reescritas acima não deveriam cuidar disso também?

Obrigado pela ajuda!


O balanceador de carga deve estar lhe enviando alguma indicação sobre se a conexão era HTTPS. Pergunte à Rackspace. (Ah, e você provavelmente não quer se livrar de www ...)
Michael Hampton

Interessante, vou analisar isso. Por que você acha que eu não devo me livrar do www?
jwerre

Respostas:


14

O sciurus está correto, pois os Cloud Load Balancers da Rackspace configuram o X-Forwarded-Proto como https quando o SSL é descarregado no balanceador de carga. Para evitar um loop de redirecionamento no nginx, você deve poder adicionar o seguinte à locationseção na configuração do vhost:

if ($http_x_forwarded_proto = "http") {
            rewrite  ^/(.*)$  https://mydomain.com/$1 permanent;
}

Isso deve evitar o loop infinito de redirecionamento ao redirecionar solicitações não https para https.


18

Ao usar nginx está embutido variáveis de servidor $request_urie $server_namevocê pode fazer isso sem o uso de expressões regulares em tudo. Adicione o seguinte ao locationbloco do seu servidor e pronto:

if ($http_x_forwarded_proto = "http") {
    return 301 https://$server_name$request_uri;
}

Isso pressupõe que seu balanceador de carga esteja enviando o $http_x_forwarded_protocabeçalho junto com a solicitação para suas instâncias de back-end. Outros cabeçalhos comuns incluem $http_x_forwarded_schemee também apenas $scheme.

Mais informações podem ser encontradas na documentação nginx Pitfalls and Common Mistakes : https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites


5
Definitivamente deve usar retorno sobre reescrita. Votado.
Designermonkey

1
Você pode usar em $hostvez de$server_name
Yossi

não funciona com server_name _; portanto, deve-se usar a variável $ host como sugerido pelo @Yossi.
Razvan Grigore

1

O balanceador de carga sempre fala com você por http. O que está acontecendo é

  1. O navegador solicita a porta 80 no balanceador de carga
  2. O balanceador de carga faz um pedido para a porta 80 em seu servidor da web
  3. Seu servidor da web envia um redirecionamento para o usuário
  4. O usuário faz um pedido para a porta 443 no balanceador de carga

As etapas 2 a 4 continuam repetindo até que o navegador detecte o loop de redirecionamento e desista.

EDIT: Para resolver isso, execute a reescrita somente quando o cabeçalho X-Forwarded-Proto estiver definido como http. Esse cabeçalho é como o balanceador de carga da Rackspace informa ao servidor da Web o protocolo pelo qual ele recebeu a solicitação.


Eu acho que isso explicaria por que $ SERVER_PROTOCOL sempre retorna HTTP
jwerre

Então você respondeu por que isso está acontecendo ... alguma sugestão sobre como corrigir?
jwerre
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.