Перенаправление EC2 Elastic Load Balancer с HTTP на HTTPS

104

Я хочу перенаправить весь HTTP-запрос на https-запрос на ELB . У меня два экземпляра EC2. Я использую nginx для сервера. Я безуспешно пытался переписать файлы конфигурации nginx. Я хотел бы получить совет по этому поводу.

Амит Бадхека
источник
1
Похоже, что Интернет не может прийти к единому, полному и рабочему решению этой проблемы. Надеюсь, вы получите помощь в моем сообщении . Мне пришлось перепрыгнуть через обручи, чтобы наконец придумать это.
ADTC
1
Этот ответ имеет последнее решение, а не принятый
ансер

Ответы:

88

Балансировщики нагрузки приложений AWS теперь поддерживают перенаправление с HTTP на HTTPS.

Чтобы включить это в консоли, сделайте следующее:

  1. Перейдите в балансировщик нагрузки в EC2 и перейдите на вкладку «Слушатели».
  2. Выберите "Просмотр / редактирование правил" в HTTP-приемнике.
  3. Удалить все правила, кроме правила по умолчанию (внизу)
  4. Измените правило по умолчанию: выберите действие «Перенаправить на», оставьте все по умолчанию и введите «443» в качестве порта.

Собственное правило прослушивателя перенаправления

То же самое можно сделать с помощью интерфейса командной строки, как описано здесь .

Это также можно сделать в Cloudformation, где вам нужно настроить объект Listener следующим образом:

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

Если вы по-прежнему используете классические балансировщики нагрузки, используйте одну из конфигураций NGINX, описанных другими.

Улли
источник
1
Очень полезно знать, что теперь стало проще. Но это был бы лучший ответ с дополнительной информацией о том, что настроить, а не просто ссылкой.
Джон Рис
1
@JohnRees отредактировал ответ соответствующим образом, надеюсь, это поможет
Улли
Ницца. Я проголосовал за вас, чтобы довести вас до нуля. Ты заслуживаешь большего.
Джон Рис
2
@florian, похоже, вы используете Classic Load Balancer. Переключитесь на Application Load Balancer, чтобы получить эту возможность
Ulli
как назначить Application Load Balancer своему экземпляру? (поскольку instancesвкладки нет )
Флориан
107

ELB устанавливает X-Forwarded-Protoзаголовок, вы можете использовать его, чтобы определить, был ли исходный запрос на HTTP, и затем перенаправить на HTTPS.

Вы можете попробовать это в своей serverконфигурации:

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

Взгляните на документацию ELB .

Дмитрий Мухин
источник
3
Где сделать эту конфигурацию?
ericpeters0n
2
@ ericpeters0n фрагмент в ответе предназначен для nginxконфигурации, но принцип применим к любому веб-серверу.
Дмитрий Мухин
1
Если вы используете beanstalk с автономным пассажиром, перейдите по этой ссылке, чтобы узнать, как изменить конфигурацию nginx. qiita.com/tak_nishida/items/cf30a2d373744943b943
Yeonho
3
Убедитесь, что на балансировщике нагрузки есть прослушиватели HTTP и HTTPS.
Гэвин Палмер
1
@ Рональд, под сервером conf в ответе я подразумеваю сервер nginx на экземплярах ec2, которые работают за ELB.
Дмитрий Мухин
34

У меня была такая же проблема, в моей ситуации HTTPS полностью обрабатывался ELB, и я не знал свой исходный домен заранее, поэтому я сделал что-то вроде:

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

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

И затем, конечно, указываем ELB https на порт 80 экземпляра, а затем маршрут http на порт 81 экземпляра.

ТайлерФаулер
источник
3
Это гениально.
Энди Хайден
2
@CodyBugstein, это конфиг nginx, если он у вас есть
timurso
@timurso, если есть что?
CodyBugstein
@CodyBugstein, если у вас есть nginx перед вашим приложением (у меня, например, нет - он направляется напрямую в контейнер, в котором запущен ExpressJS)
timurso
Куда подевался бы nginx? Внутри ELB? Внутри EC2? Это где-то настроено в Elastic Beanstalk?
CodyBugstein
16

Amazon Elastic Load Balancer (ELB) поддерживает заголовок HTTP под названием X-FORWARDED-PROTO. Все запросы HTTPS, проходящие через ELB, будут иметь значение X-FORWARDED-PROTO, равное «HTTPS». Для HTTP-запросов вы можете принудительно использовать HTTPS, добавив следующее простое правило перезаписи. У меня работает нормально!

Apache

Вы можете добавить в файл .htaccess следующие строки:

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

Или, если вы используете vhost.conf для управления несколькими доменами на одном и том же веб-сервере EC2, вы можете добавить следующее в vhost.conf (добавить его в домен, для которого вы хотите использовать https):

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

IIS

Установите модуль IIS Url-Rewrite, используя графический интерфейс конфигурации, добавьте следующие параметры:

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

Подробнее здесь

Иман Седиги
источник
У нас возникла проблема с перенаправлением нашего экземпляра обычного HTTP-трафика, потому что заголовок даже не присутствовал. Я RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
решаю это, поставив
Это вызывает бесконечные перенаправления. Я использую IIS с сервером Windows.
Это ловушка
@ Itatrap: для IIS, если это не сработало, попробуйте сценарий по этому URL-адресу: stephen.genoprime.com/2012/01/01/aws-elb-ssl-with-iis.html
Иман Седиги,
5

Приведенные выше решения htaccess привели к сбою проверки работоспособности ELB. У меня были проблемы с поиском решения, пока я не обнаружил в Интернете статью, в которой у кого-то были те же проблемы, что и у меня. Его решение заключалось в том, чтобы вместо этого добавить это в начало файла htaccess:

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

Чтобы разрешить этот и другие локальные запросы через HTTP при перенаправлении внешних запросов через ELB на HTTPS, настройте условие перезаписи так, чтобы оно соответствовало http, а не отрицательное совпадение на https.

Источник: перенаправление HTTP на HTTPS с помощью AWS и ELB

омики
источник
«настроить условие перезаписи так, чтобы оно соответствовало http, а не отрицательное совпадение на https», это часть, которую я пытался исправить. Спасибо!
Merricat
3

У меня была странная проблема с конфигурацией nginx и ELB. Моя установка включала 3 разных сервиса внутри одного nginx за ELB. И у меня была проблема со смешанным содержимым: когда ваш запрос к ELB - https, но только внутри ELB http, а сервер создает относительный путь к статическому с помощью http, поэтому браузер не работает с проблемой «смешанного содержимого». И я должен создать решение для работы http / https без каких-либо перенаправлений.

Конфигурация находится в nginx/conf.d/папке:

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

Это означает, что мы будем знать, что такое настоящий клиентский протокол. Как видите, он у нас будет в $switchvar. И в этот момент вы используете это везде, где вам это нужно:

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

С настройкой HTTPS приложение php автоматически определит правильный протокол и тщательно построит относительный путь для предотвращения проблем со смешанным содержимым.

С уважением.

Олег Николаиченко
источник
3

На основе ответа @Ulli.Если вы хотите настроить его с помощью Terraform , вот пример>

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

Источник

Матье Лескодрон
источник
-2

Создайте файл .ebextensions/00_forward_http_to_https.configсо следующим содержанием:

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"

Обязательно заранее установите переменную среды APP_URL в консоли управления AWS.

Андрес
источник
Как я могу это сделать при балансировке TCP-соединений с ELB?
бум
1
Я не понимаю, где ваш ответ соответствует вопросу ... вы говорите об эластичном стебле bean-компонента, и вопрос касается nginx внутри EC2.
jvarandas