PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como se conectar ao PostgreSQL do Phoenix Web App via SSL?

Plano de fundo


Eu estava enfrentando o mesmo problema ao conectar o Phoenix/Ecto/Postgrex ao banco de dados do Azure para servidor PostgreSQL. Mesmo depois de definir ssl: true na minha configuração do Repo, ainda não consegui me conectar ao banco de dados com o Postgrex mesmo conectando usando psql "postgresql://...?sslmode=require" -U ... na mesma máquina conseguiu. O erro retornado com ssl: true foi:
[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
    ...

Depois de pesquisar o código-fonte, descobri que a chamada com falha era na verdade o ssl.connect/3 chamada do módulo 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

Fazendo algumas espionagens com o Wireshark, pude ver isso ao conectar com sucesso com psql , pude ver pacotes com TLSV1.2 como o protocolo, mas quando o postgrex estava se conectando com ssl: true Eu estava vendo pacotes com SSL como o protocolo antes de falhar na conexão.

Examinando os documentos de opções Ecto.Adapters.Postgres , você verá que há um ssl_opts opção de configuração que acaba sendo passada para :ssl.connect/3 no qual você pode definir versions para substituir a(s) versão(ões) de TLS usada(s) para se conectar.

Solução


Consegui me conectar ao banco de dados adicionando o seguinte à minha configuração do Repo:
ssl_opts: [
  versions: [:"tlsv1.2"]
]

Minha configuração completa ficou assim:
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"]
  ]

Não tenho certeza de por que a versão TLS precisa ser definida explicitamente, talvez alguém com mais experiência nessa área possa esclarecer isso.