如何在负载均衡器上将流量从 Http 重定向到 Phoenix Elixir 中的 Https for SSL?
how to redirect traffic from Http to Https in Phoenix Elixir for SSL on Load Balancer?
我需要将流量从 Http 转发到 Https,SSL 在负载均衡器上,所以我需要做的就是使用 plug_ssl
转发 header 所以在我的 prod.exs
我补充说:
config :web, Web.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto]]
在我的 prod.exs
中并删除 config :web, Web.Endpoint
中的所有其他内容
没用。
我做错了什么?
我需要将 force_ssl
放入我的 router
中吗?
提前致谢。
您可能只需要为不用于运行状况检查或与之相关的端点启用 force_ssl
插件。
我在 GKE 上的 k8s Ingress 遇到了类似的问题,解决方案是将 force_ssl
on router 仅用于我的应用程序路由,并让 /healthz
(配置为我的健康检查路由)使用 HTTP。
config/prod.exs
的例子:
# Tells if we need to enforce SSL for our endpoints.
# Only production/staging should enforce
config :my_app, force_ssl: true
config :my_app, MyAppWeb.Endpoint,
load_from_system_env: true,
url: [host: "${APP_HOST}", port: 80],
server: true,
http: [port: "${PORT}"],
url: [scheme: "https", host: "${APP_HOST}", port: 443],
secret_key_base: "${SECRET_KEY_BASE}"
这里是 lib/my_app_web/router.ex
的例子:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
# This route will NOT enforce SSL
get("/healthz", MyAppWeb.HealthCheckController, :show)
pipeline :api do
plug(:accepts, ["json"])
if Application.get_env(:my_app, :force_ssl) do
plug(Plug.SSL, rewrite_on: [:x_forwarded_proto], host: nil)
end
end
scope "/", MyAppWeb do
pipe_through(:api)
# My routes will go here, and will be enforced if the
# application flag `force_ssl` is enabled.
end
end
调试起来有点棘手。如果您正在使用 kubernetes
,请尝试使用 kubectl describe ingress YOUR-INGRESS-HERE
,并在进行测试时始终检查 headers 以了解您的请求和响应。
通常 healthchecker 会直接使用本地网络调用您的服务器,而不是您的应用所在的域。这样您就可以将您的本地地址放入 exclude
选项。
这是我所做的:
config :my_app, MyApp.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto], exclude: ["localhost", "${IP_ADDRESS}"]],
我使用 distillery
从环境变量中获取的
位置(这取决于您的部署类型以及获取方式)。然而,当你不使用 distillery
时,你可以通过这种方式获取环境变量:
config :my_app, MyApp.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto], exclude: ["localhost", System.get_env("IP_ADDRESS")]],
我需要将流量从 Http 转发到 Https,SSL 在负载均衡器上,所以我需要做的就是使用 plug_ssl
转发 header 所以在我的 prod.exs
我补充说:
config :web, Web.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto]]
在我的 prod.exs
中并删除 config :web, Web.Endpoint
没用。
我做错了什么?
我需要将 force_ssl
放入我的 router
中吗?
提前致谢。
您可能只需要为不用于运行状况检查或与之相关的端点启用 force_ssl
插件。
我在 GKE 上的 k8s Ingress 遇到了类似的问题,解决方案是将 force_ssl
on router 仅用于我的应用程序路由,并让 /healthz
(配置为我的健康检查路由)使用 HTTP。
config/prod.exs
的例子:
# Tells if we need to enforce SSL for our endpoints.
# Only production/staging should enforce
config :my_app, force_ssl: true
config :my_app, MyAppWeb.Endpoint,
load_from_system_env: true,
url: [host: "${APP_HOST}", port: 80],
server: true,
http: [port: "${PORT}"],
url: [scheme: "https", host: "${APP_HOST}", port: 443],
secret_key_base: "${SECRET_KEY_BASE}"
这里是 lib/my_app_web/router.ex
的例子:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
# This route will NOT enforce SSL
get("/healthz", MyAppWeb.HealthCheckController, :show)
pipeline :api do
plug(:accepts, ["json"])
if Application.get_env(:my_app, :force_ssl) do
plug(Plug.SSL, rewrite_on: [:x_forwarded_proto], host: nil)
end
end
scope "/", MyAppWeb do
pipe_through(:api)
# My routes will go here, and will be enforced if the
# application flag `force_ssl` is enabled.
end
end
调试起来有点棘手。如果您正在使用 kubernetes
,请尝试使用 kubectl describe ingress YOUR-INGRESS-HERE
,并在进行测试时始终检查 headers 以了解您的请求和响应。
通常 healthchecker 会直接使用本地网络调用您的服务器,而不是您的应用所在的域。这样您就可以将您的本地地址放入 exclude
选项。
这是我所做的:
config :my_app, MyApp.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto], exclude: ["localhost", "${IP_ADDRESS}"]],
我使用 distillery
从环境变量中获取的
位置(这取决于您的部署类型以及获取方式)。然而,当你不使用 distillery
时,你可以通过这种方式获取环境变量:
config :my_app, MyApp.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto], exclude: ["localhost", System.get_env("IP_ADDRESS")]],