PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment se connecter à PostgreSQL depuis Phoenix Web App via SSL ?

Contexte

Je rencontrais le même problème en connectant Phoenix/Ecto/Postgrex au serveur Azure Database pour PostgreSQL. Même après avoir défini ssl: true dans ma configuration Repo, je n'étais toujours pas en mesure de me connecter à la base de données avec Postgrex même si je me connectais en utilisant psql "postgresql://...?sslmode=require" -U ... sur la même machine a réussi. L'erreur renvoyée avec ssl: true était :

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

Après avoir fouillé dans le code source, j'ai découvert que l'appel défaillant était en fait le ssl.connect/3 appel depuis le module ssl d'Erlang :

# 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

En fouinant avec Wireshark, j'ai pu voir cela lors de la connexion avec psql , je pouvais voir des paquets avec TLSV1.2 comme protocole, mais lorsque postgrex se connectait avec ssl: true Je voyais des paquets avec SSL comme protocole avant d'échouer à se connecter.

En regardant la docs sur les options Ecto.Adapters.Postgres , vous verrez qu'il y a un ssl_opts option de configuration qui finit par être transmise à :ssl.connect/3 dans lequel vous pouvez définir des versions pour remplacer la ou les versions TLS utilisées pour se connecter.

Solution

J'ai pu me connecter à la base de données en ajoutant ce qui suit à ma configuration Repo :

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

Ma configuration complète a fini par ressembler à ceci :

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

Je ne sais pas vraiment pourquoi la version TLS doit être définie explicitement, peut-être que quelqu'un avec plus d'expertise dans ce domaine peut nous éclairer à ce sujet.