PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm cách nào để kết nối với PostgreSQL từ Phoenix Web App qua SSL?

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres:lệnh chân không không làm sạch các bộ giá trị đã chết

  2. cách mở kết nối PostgreSQL khỏi IBM WSJdbc41Connection

  3. Làm thế nào để cung cấp một ứng dụng khách API với 1.000.000 kết quả cơ sở dữ liệu?

  4. Giám sát PostgreSQL trong môi trường kết hợp

  5. Làm cách nào để ngắt một truy vấn RPostgresql trong R