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!

jwerre
fonte
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.

slade
fonte
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

Luke Peterson
fonte
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.

sciurus
fonte
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