sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo conectarse a PostgreSQL desde Phoenix Web App a través de SSL?

Antecedentes

Estaba experimentando el mismo problema al conectar Phoenix/Ecto/Postgrex a Azure Database para el servidor PostgreSQL. Incluso después de configurar ssl: true en mi configuración de Repo, todavía no podía conectarme a la base de datos con Postgrex aunque me conectaba usando psql "postgresql://...?sslmode=require" -U ... en la misma máquina tuvo éxito. El error devuelto 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
    ...

Después de investigar el código fuente, descubrí que la llamada fallida era en realidad ssl.connect/3 llamada desde el módulo ssl de 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

Husmeando un poco con Wireshark, pude ver eso cuando me conecté con éxito con psql , pude ver paquetes con TLSV1.2 como protocolo, pero cuando postgrex se conectaba con ssl: true Estaba viendo paquetes con SSL como el protocolo antes de fallar en la conexión.

Mirando los Documentos de opciones de Ecto.Adapters.Postgres , verá que hay un ssl_opts opción de configuración que termina pasando a :ssl.connect/3 en el que puede establecer versions para anular la(s) versión(es) de TLS usadas para conectarse.

Solución

Pude conectarme a la base de datos agregando lo siguiente a mi configuración de Repo:

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

Mi configuración completa terminó luciendo así:

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

No estoy muy seguro de por qué la versión TLS debe configurarse explícitamente, tal vez alguien con más experiencia en esta área pueda arrojar algo de luz sobre esto.