Phoenix in Production on EC2 不使用 AWS Load Balancer 在 HTTPS 中呈现
Phoenix in Production on EC2 not rendering in HTTPS with AWS Load Balancer
我已经按照这个 tutorial 在 EC2 上设置我的 phoenix 应用程序,后来我添加了 SSL 的负载均衡器。
我使用 ACM (Amazon Certificate Manager) 获取了 public 证书并应用到 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 流量重定向到 https。
如果您需要帮助在 ALB 上设置 SSL,我遵循了这个 guide
如果您的应用仍然没有出现在您的域下,请确保您有一个 A 记录,其中别名映射到您的负载均衡器的 DNS 名称
我建议将 docker 容器的侦听端口设置为 80 以外的端口,并且根本不要在 443 上侦听。
理由
我 认为 问题可能在于您的 http:
配置正在侦听端口 80。
启用 force_ssl:
后,您表示希望 http 连接转到端口 443,但是当某些内容到达 443 时(通过负载均衡器),您将其发送到您的(侦听)端口80... 将其重定向回 443?
修复
让 Phoenix 在任意端口(例如... 4010)上侦听 http 仅 连接。 (由于负载均衡器会终止您的 SSL,因此您与负载均衡器的所有通信都将通过 http。)这涉及更改您的 Docker 容器以将连接转发到该端口 - 您不想听您的容器中总共有 80 或 443 个。
您的 url:
配置将只查看 headers,根据需要将 http 请求重定向到 https。
顺便说一句,如果你设置了规则,亚马逊的ALB也可以为你做80 -> 443重定向;这使 Phoenix 甚至不必为端口 80 进行配置 url:
设置
我已经按照这个 tutorial 在 EC2 上设置我的 phoenix 应用程序,后来我添加了 SSL 的负载均衡器。
我使用 ACM (Amazon Certificate Manager) 获取了 public 证书并应用到 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 流量重定向到 https。
如果您需要帮助在 ALB 上设置 SSL,我遵循了这个 guide
如果您的应用仍然没有出现在您的域下,请确保您有一个 A 记录,其中别名映射到您的负载均衡器的 DNS 名称
我建议将 docker 容器的侦听端口设置为 80 以外的端口,并且根本不要在 443 上侦听。
理由
我 认为 问题可能在于您的 http:
配置正在侦听端口 80。
启用 force_ssl:
后,您表示希望 http 连接转到端口 443,但是当某些内容到达 443 时(通过负载均衡器),您将其发送到您的(侦听)端口80... 将其重定向回 443?
修复
让 Phoenix 在任意端口(例如... 4010)上侦听 http 仅 连接。 (由于负载均衡器会终止您的 SSL,因此您与负载均衡器的所有通信都将通过 http。)这涉及更改您的 Docker 容器以将连接转发到该端口 - 您不想听您的容器中总共有 80 或 443 个。
您的 url:
配置将只查看 headers,根据需要将 http 请求重定向到 https。
顺便说一句,如果你设置了规则,亚马逊的ALB也可以为你做80 -> 443重定向;这使 Phoenix 甚至不必为端口 80 进行配置 url:
设置