Ctrl K
ComunidadGuías…

patches/realtime-v2.134.10-hakopod-tls.patch

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
--- a/config/runtime.exs
+++ b/config/runtime.exs
@@ -155,9 +155,14 @@
 
 ssl_opts =
   cond do
-    db_ssl and is_binary(db_ssl_ca_cert) -> [cacertfile: db_ssl_ca_cert]
-    db_ssl -> [verify: :verify_none]
-    true -> false
+    db_ssl and is_binary(db_ssl_ca_cert) ->
+      Realtime.DatabaseTLS.options(db_host, db_ssl_ca_cert)
+
+    db_ssl ->
+      raise "DB_SSL_CA_CERT is required when DB_SSL is enabled"
+
+    true ->
+      false
   end
 
 metrics_pusher_extra_labels =
--- a/lib/realtime/database.ex
+++ b/lib/realtime/database.ex
@@ -71,8 +71,13 @@
       |> Map.new()
       |> then(&Map.merge(settings, &1))
 
-    with {:ok, addrtype} <- detect_ip_version(settings["db_host"]) do
-      ssl = if default_ssl_param(settings), do: [verify: :verify_none], else: false
+    with true <- default_ssl_param(settings),
+         {:ok, addrtype} <- detect_ip_version(settings["db_host"]) do
+      ssl =
+        Realtime.DatabaseTLS.options(
+          settings["db_host"],
+          System.fetch_env!("DB_SSL_CA_CERT")
+        )
 
       {:ok,
        %__MODULE__{
@@ -88,6 +93,9 @@
          socket_options: [addrtype],
          ssl: ssl
        }}
+    else
+      false -> {:error, :tls_required}
+      error -> error
     end
   end
 
--- a/lib/realtime/database_tls.ex
+++ b/lib/realtime/database_tls.ex
@@ -0,0 +1,18 @@
+defmodule Realtime.DatabaseTLS do
+  @moduledoc false
+
+  @tls_versions [:"tlsv1.2", :"tlsv1.3"]
+
+  @spec options(String.t(), String.t()) :: keyword()
+  def options(server_name, ca_path) when is_binary(server_name) and is_binary(ca_path) do
+    [
+      verify: :verify_peer,
+      versions: @tls_versions,
+      cacertfile: ca_path,
+      server_name_indication: to_charlist(server_name),
+      customize_hostname_check: [
+        match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
+      ]
+    ]
+  end
+end
--- a/priv/repo/seeds.exs
+++ b/priv/repo/seeds.exs
@@ -37,7 +37,7 @@
             "region" => "us-east-1",
             "poll_interval_ms" => 100,
             "poll_max_record_bytes" => 1_048_576,
-            "ssl_enforced" => false
+            "ssl_enforced" => true
           }
         }
       ]
--- a/test/realtime/database_test.exs
+++ b/test/realtime/database_test.exs
@@ -383,16 +383,27 @@
     test "handles SSL properties", %{tenant: tenant} do
       application_name = "realtime_connect"
       backoff = :stop
+      previous_ca = System.get_env("DB_SSL_CA_CERT")
+      System.put_env("DB_SSL_CA_CERT", "/etc/hakopod-database-ca/ca.crt")
+
+      on_exit(fn ->
+        if previous_ca,
+          do: System.put_env("DB_SSL_CA_CERT", previous_ca),
+          else: System.delete_env("DB_SSL_CA_CERT")
+      end)
 
       settings = Realtime.PostgresCdc.filter_settings("postgres_cdc_rls", tenant.extensions)
       settings = Map.put(settings, "ssl_enforced", true)
       {:ok, settings} = Database.from_settings(settings, application_name, backoff)
-      assert settings.ssl == [verify: :verify_none]
+      assert settings.ssl[:verify] == :verify_peer
+      assert settings.ssl[:versions] == [:"tlsv1.2", :"tlsv1.3"]
+      assert settings.ssl[:cacertfile] == "/etc/hakopod-database-ca/ca.crt"
+      assert settings.ssl[:server_name_indication] == ~c"127.0.0.1"
+      assert is_function(settings.ssl[:customize_hostname_check][:match_fun], 2)
 
       settings = Realtime.PostgresCdc.filter_settings("postgres_cdc_rls", tenant.extensions)
       settings = Map.put(settings, "ssl_enforced", false)
-      {:ok, settings} = Database.from_settings(settings, application_name, backoff)
-      refute settings.ssl
+      assert {:error, :tls_required} = Database.from_settings(settings, application_name, backoff)
     end
   end
 
--- a/test/realtime/database_tls_test.exs
+++ b/test/realtime/database_tls_test.exs
@@ -0,0 +1,15 @@
+defmodule Realtime.DatabaseTLSTest do
+  use ExUnit.Case, async: true
+
+  alias Realtime.DatabaseTLS
+
+  test "requires peer and hostname verification with the supplied CA" do
+    options = DatabaseTLS.options("db", "/etc/hakopod-database-ca/ca.crt")
+
+    assert options[:verify] == :verify_peer
+    assert options[:versions] == [:"tlsv1.2", :"tlsv1.3"]
+    assert options[:cacertfile] == "/etc/hakopod-database-ca/ca.crt"
+    assert options[:server_name_indication] == ~c"db"
+    assert is_function(options[:customize_hostname_check][:match_fun], 2)
+  end
+end