Baggrund
Jeg oplevede det samme problem med at forbinde Phoenix/Ecto/Postgrex til Azure Database til PostgreSQL-server. Selv efter indstilling af ssl: true
i min Repo-konfiguration var jeg stadig ikke i stand til at oprette forbindelse til databasen med Postgrex, selvom jeg oprettede forbindelse ved hjælp af psql "postgresql://...?sslmode=require" -U ...
på samme maskine lykkedes. Fejlen returnerede 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 at have gravet igennem kildekoden opdagede jeg, at det mislykkede opkald faktisk var ssl.connect/3
opkald fra Erlang ssl-modulet
:
# 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
Da jeg snokede med Wireshark, kunne jeg se det, når jeg oprettede forbindelse med psql
, kunne jeg se pakker med TLSV1.2
som protokollen, men da postgrex oprettede forbindelse med ssl: true
Jeg så pakker med SSL
som protokollen, før der ikke blev oprettet forbindelse.
Ser på dokumenterne for Ecto.Adapters.Postgres-indstillinger
, vil du se, at der er en ssl_opts
konfigurationsmulighed, som ender med at blive sendt til :ssl.connect/3
hvor du kan indstille versions
for at tilsidesætte den eller de TLS-versioner, der bruges til at oprette forbindelse.
Løsning
Jeg var i stand til at oprette forbindelse til databasen ved at tilføje følgende til min Repo-konfiguration:
ssl_opts: [
versions: [:"tlsv1.2"]
]
Min fulde konfiguration endte med at se sådan her ud:
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"]
]
Jeg er ikke helt sikker på, hvorfor TLS-versionen skal indstilles eksplicit, måske kan nogen med mere ekspertise på dette område kaste lys over dette.