Bakgrund
Jag upplevde samma problem med att ansluta Phoenix/Ecto/Postgrex till Azure Database for PostgreSQL-server. Även efter inställning av ssl: true
i min Repo-konfiguration kunde jag fortfarande inte ansluta till databasen med Postgrex även om jag ansluter med psql "postgresql://...?sslmode=require" -U ...
på samma maskin lyckades. Felet returnerade med ssl: true
var:
[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
...
Efter att ha grävt igenom källkoden upptäckte jag att det misslyckade samtalet faktiskt var ssl.connect/3
samtal från Erlang ssl-modulen
:
# 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
När jag snokade med Wireshark kunde jag se det när jag ansluter framgångsrikt med psql
, kunde jag se paket med TLSV1.2
som protokollet, men när postgrex ansluter till ssl: true
Jag såg paket med SSL
som protokollet innan det inte gick att ansluta.
Tittar på dokumentationen för Ecto.Adapters.Postgres-alternativ
, kommer du att se att det finns en ssl_opts
konfigurationsalternativ som till slut skickas till :ssl.connect/3
där du kan ställa in versions
för att åsidosätta den eller de TLS-versioner som används för att ansluta.
Lösning
Jag kunde ansluta till databasen genom att lägga till följande till min Repo-konfiguration:
ssl_opts: [
versions: [:"tlsv1.2"]
]
Min fullständiga konfiguration såg ut så här:
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"]
]
Jag är inte riktigt säker på varför TLS-versionen behöver ställas in explicit, kanske någon med mer expertis inom detta område kan kasta lite ljus över detta.