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

27

В настоящее время у меня есть 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 OK для проверки работоспособности, в которой нуждается ELB »

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

Джордан Райтер
источник
Привет, пожалуйста, скажите мне, где вы положили этот код?
Юань Шаолинь Макулеле Лай
@ YuAnShaolinMaculelêLai Конечно. Это файлы конфигурации для nginx, поэтому я просто поместил код в файл в /etc/nginx/conf.d/. Я обычно называю файл domainname.conf, где «domainname» - это домен соответствующего веб-сайта. Вы можете назвать файл как хотите, если он заканчивается на .conf.
Джордан Рейтер
Большое спасибо. Я попытался создать новый файл, следующий за .conf. Но это не сработало для меня. Затем я поместил код в файл, сгенерированный из AWS, в /etc/nginx/conf.d/. Это работает сейчас.
Юань Шаолинь Макулеле Лай

Ответы:

9

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

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

ceejayoz
источник
На этой странице также говорится, что «если есть проблемы при использовании в контексте местоположения». Мне кажется , что вы можете делать то , что вы необходимость делать снаружи location {}, в server {}вместо этого. (Но, пожалуйста, дайте мне знать, если это не так!)
Экскалибур
15
  1. Настройте отображение AWB ELB ELB: 80 для экземпляра: 80 и ELB: 443 для экземпляра: 1443.
  2. Свяжите nginx для прослушивания через порт 80 и 1443.
  3. Переадресация запросов в порт 80 на порт 443.
  4. Проверка работоспособности должна быть HTTP: 1443. Он отклоняет HTTP: 80, потому что перенаправление 301.

настройка aws elb

Настройка NGINX

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

    server {
       listen         1443;
       server_name    www.example.org;
   } 
Ну Эверест
источник
как насчет настроек проверки работоспособности? не могли бы вы подробно остановиться на этом.
samkhan13
это не сработало с проверкой helth, установленной на http: 80, проверка работоспособности не удалась
samkhan13
2
Проверка здоровья должна быть HTTP:1443. Он отклоняет, HTTP:80потому что 301 перенаправления.
cbron
это в основном работало для меня, но строка перезаписи не работала с моим подстановочным доменом. Этот другой пост исправил эту часть: serverfault.com/questions/447258/…
Ron
9

Это решение использует условную логику, но, как предполагает принятый ответ, я также думаю, что это нормально. Ссылка: /programming/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;
  }
  ...
}
Джонни Мак
источник
1
должен быть более элегантный способ сделать это
Эдвард
0

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

Кенни Греулих
источник
к сожалению, это еще не поддерживается в Cloudformation
Арье Лейб Таурог