nel*_*nic 6 postgresql erlang elixir azure phoenix-framework
当试图运行花好月圆(凤凰城),使用PostgreSQL数据库的Web应用程序托管的3 次党" 数据库,作为一种服务 "(Azure数据库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
Run Code Online (Sandbox Code Playgroud)
通过调查我们意识到错误是因为Azure PostgreSQL服务Enforce SSL Connection设置为Enabled(bydefault):

我们认为有"强制执行SSL"到Enabled是不错的安全,但我们不能把它与凤凰城的工作...
所以,我们暂时(暂时)禁用了 SSL:

但我们更喜欢这个问题的" 永久 "解决方案.
如果有人能澄清(或指向我们)如何通过SSL从Phoenix/Ecto连接到PostgreSQL,
我们将非常感激!:-)
应用程序(Phoenix)服务器是否需要配置SSL认证才能从App服务器连接到数据库服务器......?
例如:http://www.phoenixframework.org/docs/configuration-for-ssl?
微软有以下帮助指南: https://docs.microsoft.com/en-us/azure/postgresql/concepts-ssl-connection-security 这似乎表明,我们需要OpenSSL的应用服务器上......任何人都可以证实?
小智 4
我在将 Phoenix/Ecto/Postgrex 连接到 Azure Database for PostgreSQL 服务器时遇到了同样的问题。即使在我的 Repo 配置中进行设置后,即使在同一台计算机上ssl: true使用连接成功,我仍然无法使用 Postgrex 连接到数据库。psql "postgresql://...?sslmode=require" -U ...返回的错误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
...
Run Code Online (Sandbox Code Playgroud)
在深入研究源代码后,我发现失败的调用实际上是ssl.connect/3来自Erlang ssl 模块的调用:
# 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
Run Code Online (Sandbox Code Playgroud)
使用 Wireshark 进行一些窥探,我可以看到,当使用 成功连接时psql,我可以看到TLSV1.2协议为 的数据包,但是当 postgrex 连接 时,我在连接失败之前ssl: true看到协议为 的数据包。SSL
查看Ecto.Adapters.Postgres 选项文档,您会看到有一个ssl_opts配置选项最终被传递到其中:ssl.connect/3,您可以在其中设置versions覆盖用于连接的 TLS 版本。
我可以通过将以下内容添加到我的 Repo 配置来连接到数据库:
ssl_opts: [
versions: [:"tlsv1.2"]
]
Run Code Online (Sandbox Code Playgroud)
我的完整配置最终如下所示:
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"]
]
Run Code Online (Sandbox Code Playgroud)
我不太确定为什么需要明确设置 TLS 版本,也许在这方面具有更多专业知识的人可以对此有所了解。