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.

Amit Badheka
źródło
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.

Ulli
źródło
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 .

Dmitry Mukhin
źródło
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.

TylerFowler
źródło
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

Iman Sedighi
źródło
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

omikes
źródło
„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.

Oleg Mykolaichenko
źródło
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

Mathieu Lescaudron
ź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.

Andres
źródło
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