Redirecionando EC2 Elastic Load Balancer de HTTP para HTTPS

104

Quero redirecionar todas as solicitações HTTP para solicitações https no ELB . Eu tenho duas instâncias EC2. Estou usando o nginx para o servidor. Eu tentei reescrever os arquivos conf do nginx sem sucesso. Eu adoraria alguns conselhos sobre isso.

Amit Badheka
fonte
1
Parece que a Internet não consegue chegar a um acordo sobre uma solução única, completa e funcional para este problema. Espero que você possa obter alguma ajuda aqui no meu post . Eu tive que saltar obstáculos para chegar a isso, finalmente.
ADTC
1
Este ans tem a solução mais recente, não o anser aceito
AsifM de

Respostas:

87

Os balanceadores de carga de aplicativos AWS agora oferecem suporte a redirecionamento de HTTP para HTTPS nativo.

Para habilitar isso no console, faça o seguinte:

  1. Vá para o seu balanceador de carga no EC2 e aba "Ouvintes"
  2. Selecione "Visualizar / editar regras" em seu ouvinte HTTP
  3. Exclua todas as regras, exceto a padrão (inferior)
  4. Editar regra padrão: escolha "Redirecionar para" como uma ação, deixe tudo como padrão e insira "443" como uma porta.

Regra de escuta de redirecionamento nativo

O mesmo pode ser alcançado usando o CLI conforme descrito aqui .

Também é possível fazer isso no Cloudformation, onde você precisa configurar um objeto Listener como este:

  HttpListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: HTTP
      DefaultActions:
      - Type: redirect 
        RedirectConfig:
          Protocol: HTTPS
          StatusCode: HTTP_301
          Port: 443

Se você ainda usa balanceadores de carga clássicos, vá com uma das configurações NGINX descritas pelos outros.

Ulli
fonte
1
Muito útil saber que é mais fácil agora. Mas essa seria uma resposta melhor com mais informações sobre o que configurar em vez de apenas um link.
John Rees
1
@JohnRees editou a resposta de acordo, espero que ajude
Ulli
Agradável. Eu votei a favor de você para chegar a zero. Você merece mais.
John Rees
2
@florian, você parece estar usando um balanceador de carga clássico. Mude para o balanceador de carga de aplicativo para obter essa opção
Ulli
como atribuo o Balanceador de Carga do Aplicativo à minha instância? (como não há instancesguia)
Florian
107

O ELB define o X-Forwarded-Protocabeçalho, você pode usá-lo para detectar se a solicitação original foi para HTTP e redirecionar para HTTPS.

Você pode tentar isso em seu serverconf:

if ($http_x_forwarded_proto = 'http') {
    return 301 https://yourdomain.com$request_uri;
}

Dê uma olhada na documentação do ELB .

Dmitry Mukhin
fonte
3
Onde se faz essa configuração?
ericpeters0n
2
@ ericpeters0n o snippet na resposta é para nginxconfiguração, mas o princípio é aplicável a qualquer servidor web.
Dmitry Mukhin
1
se você estiver usando beanstalk com passageiro independente, siga este link para instruções sobre como alterar a configuração do nginx. qiita.com/tak_nishida/items/cf30a2d373744943b943
Yeonho
3
Certifique-se de ter ouvintes HTTP e HTTPS em seu balanceador de carga.
Gavin Palmer
1
@Ronald, por conf do servidor na resposta, quero dizer servidor nginx em instâncias ec2 que estão sendo executadas por trás de ELB.
Dmitry Mukhin
34

Eu tive o mesmo problema, na minha situação o HTTPS era totalmente gerenciado pelo ELB e eu não sabia meu domínio de origem com antecedência, então acabei fazendo algo como:

server {
  listen 81;
  return 301 https://$host$request_uri;
}

server {
  listen 80;
  # regular server rules ...
}

E então, é claro, apontando o ELB 'https' para a porta 80 da instância e a rota 'http' para a porta 81 da instância.

TylerFowler
fonte
3
Isso é gênio.
Andy Hayden de
2
@CodyBugstein esta é a configuração do nginx, se você tiver uma
timurso
@timurso se você tem um o quê?
CodyBugstein de
@CodyBugstein se você tiver o nginx na frente de seu aplicativo (eu, por exemplo, não - ele é roteado diretamente para um contêiner executando ExpressJS)
timurso
Para onde iria o nginx? Dentro do ELB? Dentro do EC2? Isso está configurado no Elastic Beanstalk em algum lugar?
CodyBugstein de
16

O Amazon Elastic Load Balancer (ELB) oferece suporte a um cabeçalho HTTP chamado X-FORWARDED-PROTO. Todas as solicitações HTTPS que passam pelo ELB terão o valor de X-FORWARDED-PROTO igual a “HTTPS”. Para as solicitações HTTP, você pode forçar o HTTPS adicionando a seguinte regra de reescrita simples. Para mim, funciona bem!

Apache

Você pode adicionar as seguintes linhas em seu arquivo .htaccess:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}

Ou se você usar vhost.conf para gerenciar vários domínios no mesmo servidor da web EC2, você pode adicionar o seguinte ao vhost.conf (adicione-o ao domínio que deseja usar https para ele):

<VirtualHost *:80>
...
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
...
</VirtualHost>

IIS

Instale o módulo IIS Url-Rewrite, usando a GUI de configuração, adicione estas configurações:

<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPS rewrite behind ELB rule" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" ignoreCase="false" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{SERVER_NAME}{URL}" />
</rule>
</rules>
</rewrite>

Leia mais aqui

Iman Sedighi
fonte
Tivemos o problema de fazer nossa instância redirecionar o tráfego http normal porque o cabeçalho nem mesmo estava presente. Eu resolvo fazendo a condição:RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
natronite
Isso está causando redirecionamentos infinitos. Estou usando o IIS com o servidor Windows.
É uma armadilha
@ It'satrap: Para IIS, se não funcionou, tente o script neste URL: stephen.genoprime.com/2012/01/01/aws-elb-ssl-with-iis.html
Iman Sedighi
5

As soluções htaccess acima causaram falha na verificação de integridade do ELB. Tive alguns problemas para encontrar a solução até que descobri um artigo online em que alguém tinha os mesmos problemas que eu. Sua solução foi adicionar isso ao início do arquivo htaccess:

RewriteEngine on 
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Para permitir esta e outras solicitações locais por HTTP enquanto redireciona solicitações externas por meio do ELB para HTTPS, ajuste a condição de reescrita para corresponder a http em vez de uma correspondência negativa a https.

Fonte: Redirecionando HTTP para HTTPS com AWS e ELB

omikes
fonte
"ajustar a condição de reescrita para corresponder ao http em vez de uma correspondência negativa ao https", essa é a parte que eu estava tentando corrigir. Obrigado!
Merricat
4

Pode não ser a solução que você está procurando, mas outra opção pode ser usar o AWS CloudFront além do ELB. O CloudFront oferece a opção de redirecionar todo o tráfego HTTP de entrada para HTTPS.

MojoJojo
fonte
3

Tive um problema estranho com a configuração do nginx e do ELB. Minha configuração incluiu 3 serviços diferentes dentro de um nginx atrás do ELB. E eu tive problema de conteúdo misto: quando sua solicitação para ELB é https, mas dentro de ELB http apenas, e o servidor cria um caminho relativo para estático usando http, então o navegador falha com o problema de 'conteúdo misto'. E devo criar solução tanto para http / https funcionar sem nenhum redirecionamento.

Aqui está a configuração localizada na nginx/conf.d/pasta:

# Required for http/https switching
map $http_x_forwarded_port $switch {
  default   off;
  "80"    off;
  "443"   on;
}

Isso significa que teremos conhecimento do que é o protocolo do cliente real. Como você pode ver, o teremos na $switchvar. E, neste momento, você usa isso em todos os locais onde precisar:

location ~ /softwareapi/index.php {
  fastcgi_param HTTPS $switch;
  .. other settings here ..
}

Com a configuração de HTTPS, o aplicativo php detecta automaticamente o protocolo correto e constrói cuidadosamente o caminho relativo para evitar problemas de conteúdo misto.

Cumprimentos.

Oleg Mykolaichenko
fonte
3

Baseado na resposta de @Ulli. Se você deseja configurá-lo usando o Terraform , aqui está um exemplo>

resource "aws_alb_listener" "web" {
  load_balancer_arn = "${aws_alb.web.arn}"

  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

Fonte

Mathieu Lescaudron
fonte
-2

Crie um arquivo .ebextensions/00_forward_http_to_https.configcom o seguinte conteúdo:

files: 
  /tmp/deployment/http_redirect.sh:
    mode: "000755"
    content: |
      APP_URL=`/opt/elasticbeanstalk/bin/get-config environment --output yaml | grep -oP 'APP_URL: \K([^\s)\"](?!ttp:))+'`
      sed -ie 's@$proxy_add_x_forwarded_for;@$proxy_add_x_forwarded_for;\n        if ($http_x_forwarded_proto = 'http') { return 301 https://'"$APP_URL"'$request_uri; }@' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

container_commands:
  http_redirect:
    command: "/tmp/deployment/http_redirect.sh"

Certifique-se de definir a variável de ambiente APP_URL no console de gerenciamento AWS com antecedência.

Andres
fonte
Como posso fazer isso ao balancear conexões TCP com ELB?
boom
1
Não vejo onde sua resposta se encaixa na pergunta ... você está falando sobre talo de feijão elástico e a pergunta é sobre nginx dentro de um EC2.
jvarandas de