Phoenix в производстве на EC2 не рендерится в HTTPS с AWS Load Balancer - PullRequest
0 голосов
/ 30 января 2020

Я следовал этому учебнику , чтобы настроить приложение Phoenix на EC2, и позже я добавил балансировщик нагрузки для SSL.

Я использовал ACM (Amazon Certificate Manager), чтобы получить сертификат publi c и применяется к Amazon Load Balancer (ALB).

Я все еще не совсем уверен в отображении портов, поэтому я предполагаю, что это может быть причиной.

# config/prod.exs

host = System.get_env("HOST") || "example.com"

config :app_web, AppWeb.Endpoint,
  force_ssl: [rewrite_on: [:x_forwarded_proto]],
  load_from_system_env: true,
  http: [port: 80],
  url: [host: host, port: 80],
  url: [host: host, port: 443, scheme: "https"],
  server: true,
  secret_key_base: System.get_env("SECRET_KEY_BASE")
# docker-compose.yml
version: '2'
services:
  kroo:
    image: [image url]
    environment:
      - HOST=0.0.0.0
    ports:
      - '443:443'
      - '80:80'
$ docker ps
PORTS
0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
$ docker logs 
01:56:30.177 [info] Running AppWeb.Endpoint with cowboy 2.7.0 at 0.0.0.0:80 (http)
01:56:30.177 [info] Access AppWeb.Endpoint at https://example.com
Running Release tasks
[]
01:56:31.316 [info] Already up
01:56:33.085 [info] Plug.SSL is redirecting GET / to https://example.com with status 301

Когда я не включаю force_ssl: [rewrite_on: [:x_forwarded_proto]], я могу нормально отображать страницу в http, но когда я включаю force_ssl, он перенаправляет https, который работает нормально , но я не могу соединиться с ошибкой.

Моя путаница заключается в том, что, поскольку балансировщик нагрузки заботится о SSL, у меня нет ключа и сертификата для SSL, поэтому у меня нет опции https: [] в prod.exs.

Не мог бы кто-нибудь указать, что я здесь не так делаю?

Спасибо

ОБНОВЛЕНИЕ : я наконец-то все заработал, ниже мои рабочие конфиги на случай, если кто-нибудь посчитает это полезным.

# config/prod.exs

# https config is not needed since ALB is handling the SSL
# Phoenix app serving in http is fine
config :app_web, AppWeb.Endpoint,
  load_from_system_env: true,
  http: [port: 8080],
  url: [host: "example.com"],
  server: true,
  secret_key_base: System.get_env("SECRET_KEY_BASE")
# docker-compose.yml
# map phoenix port 8080 to docker 8080
  ports:
    - '8080:8080'

Поскольку я не предоставляю SSL-сертификаты, но я все еще хочу принудительно использовать ssl, как предложил @jamesvl в ответе, используйте балансировщик нагрузки для перенаправления http traffi c для https.

Если вам нужна помощь в настройке SSL на ALB, я следовал этому руководству

Если каким-то образом ваше приложение все еще не отображается в вашем домене, убедитесь, что у вас есть A Запись с сопоставлением псевдонима DNS-имени вашего балансировщика нагрузки

1 Ответ

1 голос
/ 30 января 2020

Я бы предложил установить для порта прослушивания вашего docker контейнера значение, отличное от 80, и вообще не слушать 443.

Обоснование

I думаю проблема может быть в ie в том факте, что ваша http: конфигурация прослушивает порт 80.

При включенном force_ssl: вы указываете, что хотите http подключается к go к порту 443, но когда что-то приходит на 443 (через балансировщик нагрузки), вы отправляете это на свой (слушающий) порт 80 ... который перенаправляет его обратно на 443?

Fix

Пусть Phoenix прослушивает произвольный порт (скажем ... 4010) для http только соединений. (Поскольку балансировщик нагрузки выполняет SSL-завершение, все ваше общение с балансировщиком нагрузки будет происходить через http.) Это включает в себя изменение контейнера Docker для перенаправления соединений на этот порт - вы не хотите прослушивать 80 или Всего 443 в вашем контейнере.

Ваша конфигурация url: будет тогда рассматривать только заголовки, перенаправляя http-запросы на https по мере необходимости.

Кстати, ALB от Amazon также может делать 80 -> 443 перенаправление для вас, если вы устанавливаете правила; это избавляет Phoenix от необходимости иметь настройки url: для порта 80 вообще

...