Bối cảnh
Tôi đã gặp sự cố tương tự khi kết nối Phoenix / Ecto / Postgrex với Cơ sở dữ liệu Azure cho máy chủ PostgreSQL. Ngay cả sau khi đặt ssl: true
trong cấu hình Repo của mình, tôi vẫn không thể kết nối với cơ sở dữ liệu bằng Postgrex mặc dù kết nối bằng psql "postgresql://...?sslmode=require" -U ...
trên cùng một máy đã thành công. Lỗi trả về với ssl: true
là:
[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
...
Sau khi tìm hiểu mã nguồn, tôi phát hiện ra rằng cuộc gọi không thành công thực sự là ssl.connect/3
gọi từ mô-đun ssl 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
Thực hiện một số dò tìm với Wireshark, tôi có thể thấy điều đó khi kết nối thành công với psql
, Tôi có thể thấy các gói có TLSV1.2
là giao thức, nhưng khi postgrex đang kết nối với ssl: true
Tôi thấy các gói có SSL
làm giao thức trước khi không kết nối được.
Xem xét tài liệu về Ecto.Adapters.Postgres
, bạn sẽ thấy có một ssl_opts
tùy chọn cấu hình cuối cùng được chuyển đến :ssl.connect/3
trong đó bạn có thể đặt versions
để ghi đè (các) phiên bản TLS được sử dụng để kết nối.
Giải pháp
Tôi đã có thể kết nối với cơ sở dữ liệu bằng cách thêm phần sau vào cấu hình Repo của mình:
ssl_opts: [
versions: [:"tlsv1.2"]
]
Cấu hình đầy đủ của tôi trông như thế này:
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"]
]
Tôi thực sự không chắc tại sao phiên bản TLS cần được đặt rõ ràng, có lẽ ai đó có chuyên môn hơn trong lĩnh vực này có thể làm sáng tỏ điều này.