Przekierowywanie EC2 Elastic Load Balancer z HTTP do HTTPS


104

Chcę przekierować wszystkie żądania HTTP do żądania https w ELB . Mam dwie instancje EC2. Używam nginx na serwerze. Próbowałem przepisać pliki conf Nginx bez żadnego sukcesu. Bardzo chciałbym uzyskać porady na ten temat.


1
Wygląda na to, że Internet nie może uzgodnić jednego, kompletnego i działającego rozwiązania tego problemu. Mam nadzieję, że w moim poście znajdziesz pomoc . Musiałem w końcu przeskoczyć przez obręcze, aby to wymyślić.
— ADTC,

1
Ten ans ma najnowsze rozwiązanie, a nie zaakceptowaną odpowiedź
— AsifM

Odpowiedzi:


87

Moduły równoważenia obciążenia aplikacji AWS obsługują teraz natywne przekierowanie HTTP na HTTPS.

Aby włączyć to w konsoli, wykonaj następujące czynności:

  1. Przejdź do Load Balancera w EC2 i wybierz zakładkę „Listeners”
  2. W odbiorniku HTTP wybierz opcję „Wyświetl / edytuj reguły”
  3. Usuń wszystkie reguły oprócz domyślnej (na dole)
  4. Edytuj regułę domyślną: wybierz „Przekieruj do” jako akcję, pozostaw wszystko jako domyślne i wpisz „443” jako port.

Reguła nasłuchiwania natywnych przekierowań

To samo można osiągnąć za pomocą interfejsu wiersza polecenia, jak opisano tutaj .

Można to również zrobić w Cloudformation, gdzie musisz skonfigurować obiekt Listener w następujący sposób:

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

Jeśli nadal używasz klasycznych modułów równoważenia obciążenia, skorzystaj z jednej z konfiguracji NGINX opisanych przez innych.


1
Bardzo przydatne jest wiedzieć, że teraz jest łatwiej. Ale to byłaby lepsza odpowiedź, zawierająca więcej informacji o tym, co należy skonfigurować, zamiast zwykłego łącza.
— John Rees,

1
@JohnRees odpowiednio zredagował odpowiedź, mam nadzieję, że to pomoże
— Ulli

Miły. Głosowałem za tobą, żeby doprowadzić cię do zera. Zasługujesz na więcej.
— John Rees,

2
@florian wydaje się, że używasz klasycznego modułu równoważenia obciążenia. Przełącz się na moduł równoważenia obciążenia aplikacji, aby uzyskać tę opcję
— Ulli

jak przypisać moduł równoważenia obciążenia aplikacji do mojego wystąpienia? (ponieważ nie ma instanceskarty)
— Florian

107

ELB ustawia X-Forwarded-Protonagłówek, możesz go użyć do wykrycia, czy pierwotne żądanie dotyczyło HTTP i przekierowania do HTTPS.

Możesz spróbować tego w swoim serverconf:

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

Spójrz na dokumentację ELB .


3
Gdzie można zrobić tę konfigurację?
— ericpeters0n

2
@ ericpeters0n fragment odpowiedzi dotyczy nginxkonfiguracji, ale zasada ma zastosowanie do każdego serwera WWW.
— Dmitry Mukhin

1
jeśli używasz łodygi fasoli z samodzielnym pasażerem, skorzystaj z tego linku, aby dowiedzieć się, jak zmienić konfigurację nginx. qiita.com/tak_nishida/items/cf30a2d373744943b943
— Yeonho

3
Upewnij się, że masz odbiorniki HTTP i HTTPS w swoim module równoważenia obciążenia.
— Gavin Palmer

1
@Ronald, przez server conf w odpowiedzi mam na myśli serwer nginx na instancjach ec2, które działają za ELB.
— Dmitry Mukhin

34

Miałem ten sam problem, w mojej sytuacji HTTPS był obsługiwany w całości przez ELB i nie znałem domeny źródłowej z wyprzedzeniem, więc skończyło się na zrobieniu czegoś takiego:

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

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

Następnie oczywiście wskazując ELB „https” na port instancji 80, a następnie trasę „http” do portu instancji 81.


3
To jest genialne.
— Andy Hayden

2
@CodyBugstein, to jest konfiguracja nginx, jeśli ją masz
— timurso

@timurso, jeśli masz, co?
— CodyBugstein

@CodyBugstein, jeśli przed aplikacją masz nginx (ja, na przykład, nie - jest kierowany bezpośrednio do kontenera z uruchomionym ExpressJS)
— timurso

Gdzie poszedłby nginx? Wewnątrz ELB? Wewnątrz EC2? Czy jest to gdzieś skonfigurowane w Elastic Beanstalk?
— CodyBugstein

16

Amazon Elastic Load Balancer (ELB) obsługuje nagłówek HTTP o nazwie X-FORWARDED-PROTO. Wszystkie żądania HTTPS przechodzące przez ELB będą miały wartość X-FORWARDED-PROTO równą „HTTPS”. W przypadku żądań HTTP możesz wymusić HTTPS, dodając następującą prostą regułę przepisywania. U mnie działa dobrze!

Apache

W pliku .htaccess możesz dodać następujące wiersze:

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

Lub jeśli używasz vhost.conf do zarządzania wieloma domenami na tym samym serwerze internetowym EC2, możesz dodać następujący plik do vhost.conf (dodać go do domeny, w której chcesz używać https):

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

IIS

Zainstaluj moduł IIS Url-Rewrite, używając konfiguracyjnego GUI, dodaj następujące ustawienia:

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

Przeczytaj więcej tutaj


Mieliśmy problem z przekierowywaniem przez naszą instancję normalnego ruchu http, ponieważ nagłówek nie był nawet obecny. Rozwiązuję to, RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
— stawiając

Powoduje to nieskończone przekierowania. Używam usług IIS z serwerem Windows.
— To pułapka

@ It'satrap: W przypadku usług IIS, jeśli to nie zadziałało, wypróbuj skrypt z tego adresu URL: stephen.genoprime.com/2012/01/01/aws-elb-ssl-with-iis.html
— Iman Sedighi

5

Powyższe rozwiązania htaccess spowodowały niepowodzenie kontroli stanu ELB. Miałem problemy ze znalezieniem rozwiązania, dopóki nie znalazłem w Internecie artykułu, w którym ktoś miał te same problemy, co ja. Jego rozwiązaniem było dodanie tego na początku pliku htaccess zamiast tego:

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

Aby zezwolić na to i inne żądania lokalne za pośrednictwem protokołu HTTP podczas przekierowywania żądań zewnętrznych przez ELB do HTTPS, dostosuj warunek przepisywania tak, aby był zgodny z protokołem http zamiast wykluczającego dopasowania na https.

Źródło: przekierowanie HTTP do HTTPS z AWS i ELB


„dostosuj warunek przepisywania, aby pasował do http zamiast do dopasowania negatywnego do https”, to część, którą próbowałem naprawić. Dziękuję Ci!
— Merricat


3

Miałem dziwny problem z konfiguracją nginx i ELB. Moja konfiguracja obejmowała 3 różne usługi w jednym nginx za ELB. I miałem problem z mieszaną zawartością: kiedy twoje żądanie do ELB to https, ale wewnątrz ELB tylko http, a serwer tworzy ścieżkę względną do statycznej za pomocą http, więc przeglądarka nie działa z problemem `` mieszanej zawartości ''. I muszę stworzyć rozwiązanie dla obu protokołów http / https bez żadnych przekierowań.

Oto konfiguracja znajdująca się w nginx/conf.d/folderze:

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

Oznacza to, że będziemy mieć wiedzę, jaki jest prawdziwy protokół klienta. Jak widać, będziemy go mieli w $switchvar. W tej chwili używasz tego we wszystkich miejscach, w których tego potrzebujesz:

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

Dzięki ustawieniu HTTPS aplikacja php automatycznie wykryje właściwy protokół i starannie zbuduje ścieżkę względną, aby zapobiec problemom z mieszaną zawartością.

Z poważaniem.


3

Na podstawie odpowiedzi @ Ulli Jeśli chcesz skonfigurować go za pomocą Terraform , oto przykład>

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"
    }
  }
}

Źródło


-2

Utwórz plik .ebextensions/00_forward_http_to_https.configz następującą zawartością:

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"

Upewnij się, że wcześniej ustawiłeś zmienną środowiskową APP_URL z konsoli zarządzania AWS.


Jak mogę to zrobić, równoważąc połączenia TCP z ELB?
— boom

1
Nie widzę, gdzie twoja odpowiedź pasuje do pytania ... mówisz o łodydze fasoli elastycznej, a pytanie dotyczy nginx wewnątrz EC2.
— jvarandas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.