gpt4 book ai didi

postgresql - 如何通过 SSL 从 Phoenix Web App 连接到 PostgreSQL?

转载 作者:行者123 更新时间:2023-11-29 11:25:32 26 4
gpt4 key购买 nike

尝试使用 PostgreSQL 数据库托管的第三方“数据库即服务”运行 Elixir (Phoenix) Web 应用程序 ( Azure Database for PostgreSQL )。

我们尝试使用 mix phoenix.server 启动应用程序我们看到以下错误:

[info] Running Pxblog.Endpoint with Cowboy using http://localhost:4000
[error] GenServer #PID<0.247.0> terminating
** (FunctionClauseError) no function clause matching in Postgrex.Messages.decode_fields/1
(postgrex) lib/postgrex/messages.ex:339: Postgrex.Messages.decode_fields("")
(postgrex) lib/postgrex/messages.ex:344: Postgrex.Messages.decode_fields/1
(postgrex) lib/postgrex/messages.ex:344: Postgrex.Messages.decode_fields/1
(postgrex) lib/postgrex/messages.ex:131: Postgrex.Messages.parse/3
(postgrex) lib/postgrex/protocol.ex:1842: Postgrex.Protocol.msg_decode/1
(postgrex) lib/postgrex/protocol.ex:1816: Postgrex.Protocol.msg_recv/3
(postgrex) lib/postgrex/protocol.ex:560: Postgrex.Protocol.auth_recv/3
(postgrex) lib/postgrex/protocol.ex:475: Postgrex.Protocol.handshake/2
(db_connection) lib/db_connection/connection.ex:134: DBConnection.Connection.connect/2
(connection) lib/connection.ex:622: Connection.enter_connect/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: nil
State: Postgrex.Protocol

见解:在 Azure DB 上启用了“强制 SSL”...

通过调查,我们意识到该错误的原因是 Azure PostgreSQL 服务有 Enforce SSL Connection设置为Enabled (作者:default):

azure-psql-ssl-enabled

我们认为“强制执行 SSL”为 Enabled对于安全来说有好处,但我们无法让它与 Phoenix 一起工作...

(临时)解决方案:禁用“强制 SSL”

因此,我们暂时(暂时)禁用了 SSL: azure-psql-ssl-disable

但我们更希望对此问题有一个“永久”解决方案。

首选解决方案:连接到 PostgreSQL 时使用 SSL

如果有人可以澄清(或向我们指出)如何通过 SSL 从 Phoenix/Ecto 连接到 PostgreSQL
我们将非常感激! :-)

应用程序(Phoenix)服务器是否需要配置 SSL 证书才能从应用程序服务器连接到数据库服务器...?
例如:http://www.phoenixframework.org/docs/configuration-for-ssl

Microsoft 有以下帮助指南: https://learn.microsoft.com/en-us/azure/postgresql/concepts-ssl-connection-security似乎表明我们需要在应用服务器上使用 OpenSSL ...任何人都可以确认吗?

最佳答案

背景

我在将 Phoenix/Ecto/Postgrex 连接到 Azure Database for PostgreSQL 服务器时遇到了同样的问题。即使设置后ssl: true在我的 Repo 配置中,即使使用 psql "postgresql://...?sslmode=require" -U ... 连接,我仍然无法使用 Postgrex 连接到数据库。在同一台机器上成功了。返回错误 ssl: true是:

[error] Postgrex.Protocol (#PID<0.1853.0>) failed to connect: **(DBConnection.ConnectionError) ssl connect: closed

** (DBConnection.ConnectionError) connection not available because of disconnection
(db_connection) lib/db_connection.ex:926: DBConnection.checkout/2
...

深入研究源代码后,我发现失败的调用实际上是 ssl.connect/3调用 the Erlang ssl module :

# deps/postgrex/lib/postgrex/protocol.ex:535

defp ssl_connect(%{sock: {:gen_tcp, sock}, timeout: timeout} = s, status) do
case :ssl.connect(sock, status.opts[:ssl_opts] || [], timeout) do
{:ok, ssl_sock} ->
startup(%{s | sock: {:ssl, ssl_sock}}, status)
{:error, reason} ->
disconnect(s, :ssl, "connect", reason)
end
end

使用 Wireshark 进行一些窥探,当使用 psql 成功连接时,我能够看到这一点,我可以看到带有 TLSV1.2 的数据包作为协议(protocol),但是当 postgrex 使用 ssl: true 连接时我看到数据包带有 SSL作为连接失败之前的协议(protocol)。

查看Ecto.Adapters.Postgres options docs ,你会看到有一个 ssl_opts配置选项最终被传递到 :ssl.connect/3您可以在其中设置 versions覆盖用于连接的 TLS 版本。

解决方案

通过将以下内容添加到我的 Repo 配置中,我能够连接到数据库:

ssl_opts: [
versions: [:"tlsv1.2"]
]

我的完整配置最终如下所示:

config :myapp, Myapp.Repo,
adapter: Ecto.Adapters.Postgres,
username: "myapp@dev-db",
password: "...",
database: "myapp_dev",
port: 5432,
hostname: "dev-db.postgres.database.azure.com",
pool_size: 10,
ssl: true,
ssl_opts: [
versions: [:"tlsv1.2"]
]

我不太确定为什么需要显式设置 TLS 版本,也许在这方面具有更多专业知识的人可以对此有所了解。

关于postgresql - 如何通过 SSL 从 Phoenix Web App 连接到 PostgreSQL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44000579/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com