patches/realtime-v2.134.10-hakopod-tls.patch
Rama main · réplica de lectura del repositorio original.
--- 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