Redirecione todas as solicitações http atrás do Amazon ELB para https sem usar se

27

Atualmente, tenho um ELB atendendo a http://www.example.org e https://www.example.org .

Gostaria de configurá-lo para que qualquer solicitação apontando para http://www.example.org seja redirecionada para https://www.example.org .

O ELB envia as solicitações https como solicitações http, usando:

server {
      listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
}

não funcionará porque as solicitações feitas para https://www.example.org ainda serão feitas para a porta 80 no nginx.

Eu sei que é possível reescrevê-lo como

server {
      listen         80;
      server_name    www.example.org;
      if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$1 permanent;
      }
}

Mas tudo o que li disse que ifdeveria ser evitado a todo custo na configuração do nginx, e isso seria para cada solicitação. Além disso, significa que tenho que definir uma configuração separada especial para a verificação de integridade ( conforme descrito aqui : "... quando você está atrás de um ELB, em que o ELB está agindo como ponto de extremidade HTTPS e enviando apenas tráfego HTTP para o servidor, você interrompa a capacidade de responder com uma resposta HTTP 200 OK para a verificação de integridade de que o ELB precisa ").

Estou pensando em colocar o login no código do aplicativo da Web em vez da configuração do nginx (e, para os fins desta pergunta, vamos supor que seja um aplicativo baseado no Django), mas não tenho certeza se isso seria mais caro do que a if configuração.

Jordan Reiter
fonte
Oi, você pode me dizer onde você coloca esses códigos?
YuAn Shaolin Maculelê Lai
@ YuAnShaolinMaculelêLai Claro. Estes são arquivos de configuração para o nginx, então eu apenas coloquei o código em um arquivo em /etc/nginx/conf.d/. Normalmente, nomeio o arquivo domainname.conf em que "domainname" é o domínio do site em questão. Você pode nomear o arquivo como quiser, desde que termine com .conf.
Jordan Reiter
Muito obrigado. Eu tentei criar um novo arquivo seguindo por .conf. Mas não funcionou para mim. Em seguida, coloquei o código no arquivo gerado pela AWS em /etc/nginx/conf.d/. Funciona agora.
YuAn Shaolin Maculelê Lai

Respostas:

9

Se estiver funcionando corretamente, não se assuste. http://wiki.nginx.org/IfIsEvil

É importante observar que o comportamento de if não é inconsistente, dado dois pedidos idênticos, ele não falhará aleatoriamente em um e funcionará no outro, com testes e entendimento adequados de ifs . Os conselhos para usar outras diretivas, quando disponíveis, ainda se aplicam muito.

ceejayoz
fonte
Esta página também diz que "se tiver problemas quando usado no contexto do local". Parece-me que você pode fazer o que precisa fazer fora location {}, dentro server {}. (Mas por favor deixe-me saber se isso é incorreto!)
Excalibur
15
  1. Configure o mapeamento do AWS ELB ELB: 80 para a instância: 80 e ELB: 443 para a instância: 1443.
  2. Ligue o nginx para ouvir nas portas 80 e 1443.
  3. Encaminhar solicitações chegando na porta 80 à porta 443.
  4. A verificação de integridade deve ser HTTP: 1443. Ele rejeita o HTTP: 80 porque o redirecionamento 301.

instalação do aws elb

Configuração do NGINX

    server {
       listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
    }

    server {
       listen         1443;
       server_name    www.example.org;
   } 
nu everest
fonte
e as configurações de verificação de saúde? você poderia, por favor, elaborar isso também.
precisa saber é o seguinte
isso não funcionou com a verificação de segurança definida como http: 80, a verificação de integridade falha.
precisa saber é o seguinte
2
Exame de saúde deve ser HTTP:1443. Rejeita o HTTP:80porque o redirecionamento 301.
Cbron 19/06
isso funcionou principalmente para mim, mas a linha de reescrita não funcionou com meu domínio curinga. Esta outra postagem corrigiu essa parte: serverfault.com/questions/447258/…
Ron
9

Essa solução usa lógica condicional, mas como a resposta aceita sugere, também acho que isso está ok. Ref: https://stackoverflow.com/questions/4833238/nginx-conf-redirect-multiple-conditions

Além disso, isso não requer a abertura de portas adicionais nas configurações de segurança do aws para a imagem. Você pode encerrar o SSL no AWS LB e rotear o tráfego https para a porta http 80 na sua instância.

Neste exemplo, a verificação de integridade do LB atinge / integridade na porta 80, que é direcionada para o servidor de aplicativos, portanto, a verificação de integridade valida o nginx e seu aplicativo está respirando.

server {
  listen 80 default deferred;

  set $redirect_to_https 0;
  if ($http_x_forwarded_proto != 'https') {
    set $redirect_to_https 1;
  }
  if ($request_uri = '/health') {
    set $redirect_to_https 0;
  }
  if ($redirect_to_https = 1) {
    rewrite ^ https://www.example.com$request_uri? permanent;
  }
  ...
}
Jonny Mac
fonte
11
deve haver uma maneira mais elegante de fazer isso
Edward
0

Agora você pode criar um novo ouvinte nas configurações do AWS Load Balancer que redireciona a porta HTTP 80 para a porta HTTPS 443. Portanto, você não precisa mais tocar na configuração do nginx / apache.

Kenny Greulich
fonte
infelizmente, ele ainda não é suportado no Cloudformation
Aryeh Leib Taurog