背景
Phoenix / Ecto/PostgrexをPostgreSQLサーバー用のAzureデータベースに接続するときに同じ問題が発生していました。 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
であることがわかりました。 Erlangsslモジュール
からの呼び出し :
# 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
のパケットを見ることができました プロトコルとして、ただしpostgrexがssl: true
に接続していたとき SSL
のパケットが表示されていました 接続に失敗する前のプロトコルとして。
Ecto.Adapters.Postgresオプションのドキュメント
を見る 、ssl_opts
があることがわかります 最終的に:ssl.connect/3
に渡される構成オプション versions
を設定できます 接続に使用されるTLSバージョンを上書きします。
ソリューション
リポジトリ構成に以下を追加することで、データベースに接続できました。
ssl_opts: [
versions: [:"tlsv1.2"]
]
私の完全な構成は次のようになりました:
config :myapp, Myapp.Repo,
adapter: Ecto.Adapters.Postgres,
username: "[email protected]",
password: "...",
database: "myapp_dev",
port: 5432,
hostname: "dev-db.postgres.database.azure.com",
pool_size: 10,
ssl: true,
ssl_opts: [
versions: [:"tlsv1.2"]
]
TLSバージョンを明示的に設定する必要がある理由はよくわかりません。おそらく、この分野の専門知識を持っている人がこれに光を当てることができます。