PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come connettersi a PostgreSQL da Phoenix Web App tramite SSL?

Sfondo

Ho riscontrato lo stesso problema durante la connessione di Phoenix/Ecto/Postgrex al database di Azure per il server PostgreSQL. Anche dopo aver impostato ssl: true nella mia configurazione Repo, non ero ancora in grado di connettermi al database con Postgrex anche se mi connettevo usando psql "postgresql://...?sslmode=require" -U ... sulla stessa macchina riuscito. L'errore restituito con ssl: true era:

[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
    ...

Dopo aver esaminato il codice sorgente, ho scoperto che la chiamata non riuscita era in realtà ssl.connect/3 chiamata da il modulo 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

Facendo un po' di ficcanaso con Wireshark, sono stato in grado di vederlo quando mi sono connesso con successo con psql , ho potuto vedere i pacchetti con TLSV1.2 come protocollo, ma quando Postgrex si connetteva con ssl: true Stavo vedendo pacchetti con SSL come protocollo prima di non riuscire a connettersi.

Osservando i documenti sulle opzioni Ecto.Adapters.Postgres , vedrai che c'è un ssl_opts opzione di configurazione che finisce per essere passata a :ssl.connect/3 in cui puoi impostare versions per sovrascrivere le versioni TLS utilizzate per la connessione.

Soluzione

Sono stato in grado di connettermi al database aggiungendo quanto segue alla mia configurazione Repo:

ssl_opts: [
  versions: [:"tlsv1.2"]
]

La mia configurazione completa ha finito per assomigliare a questa:

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"]
  ]

Non sono molto sicuro del motivo per cui la versione TLS debba essere impostata in modo esplicito, forse qualcuno con più esperienza in questo settore può far luce su questo.