Pozadí
Měl jsem stejný problém s připojením Phoenix/Ecto/Postgrex k serveru Azure Database for PostgreSQL. I po nastavení ssl: true
v mé konfiguraci Repo jsem se stále nemohl připojit k databázi pomocí Postgrex, i když se připojoval pomocí psql "postgresql://...?sslmode=require" -U ...
na stejném stroji uspěl. Chyba se vrátila s ssl: true
bylo:
[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
...
Po prostudování zdrojového kódu jsem zjistil, že neúspěšné volání bylo ve skutečnosti ssl.connect/3
volání z modulu 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
Když jsem provedl nějaké slídění s Wiresharkem, viděl jsem to při úspěšném připojení pomocí psql
, viděl jsem pakety s TLSV1.2
jako protokol, ale když se postgrex připojoval pomocí ssl: true
Viděl jsem pakety s SSL
jako protokol před selháním připojení.
Podívejte se na dokumenty k možnostem Ecto.Adapters.Postgres
, uvidíte ssl_opts
konfigurační možnost, která skončí předáním :ssl.connect/3
ve kterém můžete nastavit versions
k přepsání verzí TLS použitých k připojení.
Řešení
Podařilo se mi připojit k databázi přidáním následujícího do konfigurace Repo:
ssl_opts: [
versions: [:"tlsv1.2"]
]
Moje úplná konfigurace nakonec vypadala takto:
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"]
]
Opravdu si nejsem jistý, proč je třeba verzi TLS nastavit explicitně, možná by to mohl objasnit někdo, kdo má v této oblasti více zkušeností.