Назад | Перейти на главную страницу

Перенаправляйте все HTTP-запросы за Amazon ELB на https без использования if

В настоящее время у меня есть ELB, обслуживающий как http://www.example.org и https://www.example.org.

Я хотел бы настроить его так, чтобы любой запрос, указывающий на http://www.example.org перенаправлен на https://www.example.org.

ELB отправляет https-запросы как http-запросы, используя:

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

не будет работать, потому что запросы на https://www.example.org все равно будет перенесен на порт 80 на nginx.

Я знаю, что его можно переписать как

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

Но все, что я читал, говорит, что if следует избегать любой ценой в конфигурации nginx, и это будет для каждого отдельного запроса. Кроме того, это означает, что мне нужно настроить специальную отдельную конфигурацию для проверки работоспособности (как описано здесь: «… Когда вы находитесь за ELB, где ELB действует как конечная точка HTTPS и отправляет только HTTP-трафик на ваш сервер, вы нарушаете возможность ответа ответом HTTP 200 OK для проверки работоспособности, необходимой ELB») .

Я подумываю о том, чтобы ввести логин в код веб-приложения, а не в конфигурацию nginx (и для целей этого вопроса предположим, что это приложение на основе Django), но я не уверен, будет ли это больше накладных расходов, чем в if в комплектации.

  1. Настройте в AWS ELB сопоставление ELB: 80 с экземпляром: 80 и ELB: 443 с экземпляром: 1443.
  2. Привяжите nginx для прослушивания портов 80 и 1443.
  3. Перенаправляйте запросы, поступающие на порт 80, на порт 443.
  4. Проверка работоспособности должна быть HTTP: 1443. Он отклоняет HTTP: 80 из-за перенаправления 301.

Настройка NGINX

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

    server {
       listen         1443;
       server_name    www.example.org;
   } 

В этом решении используется условная логика, но, как следует из принятого ответа, я также думаю, что это нормально. Ссылка: https://stackoverflow.com/questions/4833238/nginx-conf-redirect-multiple-conditions

Кроме того, это не требует открытия дополнительных портов в настройках безопасности aws для образа. Вы можете завершить SSL в AWS LB и направить https-трафик на http-порт 80 вашего экземпляра.

В этом примере проверка работоспособности LB попадает / работоспособность на порт 80, который направляется на сервер приложений, поэтому проверка работоспособности подтверждает, что и nginx, и ваше приложение дышат.

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;
  }
  ...
}

Если он так работает правильно, не бойтесь этого. http://wiki.nginx.org/IfIsEvil

Важно отметить, что поведение if не противоречит, учитывая два идентичных запроса, он не будет случайным образом терпеть неудачу на одном и работать на другом, при надлежащем тестировании и понимании того, можно ли использовать. Тем не менее, совет использовать другие директивы, где они есть, по-прежнему очень актуальны.

Теперь вы можете создать новый прослушиватель в настройках AWS Load Balancer, который перенаправляет HTTP-порт 80 на HTTPS-порт 443. Таким образом, вам больше не нужно прикасаться к конфигурации nginx / apache.