diff --git a/apps/fz_http/lib/fz_http/devices.ex b/apps/fz_http/lib/fz_http/devices.ex index fae570914..e7c82ae7d 100644 --- a/apps/fz_http/lib/fz_http/devices.ex +++ b/apps/fz_http/lib/fz_http/devices.ex @@ -103,8 +103,21 @@ defmodule FzHttp.Devices do end end + def persistent_keepalives(device) do + if device.use_default_persistent_keepalives do + Settings.default_device_persistent_keepalives() + else + device.persistent_keepalives + end + end + def defaults(changeset) do - ~w(use_default_allowed_ips use_default_dns_servers use_default_endpoint)a + ~w( + use_default_allowed_ips + use_default_dns_servers + use_default_endpoint + use_default_persistent_keepalives + )a |> Enum.map(fn field -> {field, Device.field(changeset, field)} end) |> Map.new() end @@ -122,6 +135,7 @@ defmodule FzHttp.Devices do PublicKey = #{device.server_public_key} AllowedIPs = #{allowed_ips(device)} Endpoint = #{endpoint(device)}:#{wireguard_port} + #{persistent_keepalives_config(device)} """ end @@ -136,6 +150,17 @@ defmodule FzHttp.Devices do update_device(device, config_token_attrs) end + defp persistent_keepalives_config(device) do + pk = persistent_keepalives(device) + pk && "PersistentKeepalives = #{pk}" + + if is_nil(pk) do + "" + else + "PersistentKeepalives = #{pk}" + end + end + defp dns_servers_config(device) when is_struct(device) do dns_servers = dns_servers(device) diff --git a/apps/fz_http/lib/fz_http/devices/device.ex b/apps/fz_http/lib/fz_http/devices/device.ex index 1ea9ca7f7..158a0561f 100644 --- a/apps/fz_http/lib/fz_http/devices/device.ex +++ b/apps/fz_http/lib/fz_http/devices/device.ex @@ -23,7 +23,9 @@ defmodule FzHttp.Devices.Device do field :use_default_allowed_ips, :boolean, read_after_writes: true, default: true field :use_default_dns_servers, :boolean, read_after_writes: true, default: true field :use_default_endpoint, :boolean, read_after_writes: true, default: true + field :use_default_persistent_keepalives, :boolean, read_after_writes: true, default: true field :endpoint, :string + field :persistent_keepalives, :integer field :allowed_ips, :string field :dns_servers, :string field :private_key, FzHttp.Encrypted.Binary @@ -62,9 +64,11 @@ defmodule FzHttp.Devices.Device do :use_default_allowed_ips, :use_default_dns_servers, :use_default_endpoint, + :use_default_persistent_keepalives, :allowed_ips, :dns_servers, :endpoint, + :persistent_keepalives, :remote_ip, :address, :server_public_key, @@ -86,12 +90,21 @@ defmodule FzHttp.Devices.Device do :server_public_key, :private_key ]) - |> validate_required_unless_default([:allowed_ips, :dns_servers, :endpoint]) - |> validate_omitted_if_default([:allowed_ips, :dns_servers, :endpoint]) + |> validate_required_unless_default([ + :allowed_ips, + :dns_servers, + :endpoint, + :persistent_keepalives + ]) + |> validate_omitted_if_default([:allowed_ips, :dns_servers, :endpoint, :persistent_keepalives]) |> validate_list_of_ips_or_cidrs(:allowed_ips) |> validate_list_of_ips(:dns_servers) |> validate_no_duplicates(:dns_servers) |> validate_ip(:endpoint) + |> validate_number(:persistent_keepalives, + greater_than_or_equal_to: 0, + less_than_or_equal_to: 120 + ) |> unique_constraint(:address) |> validate_number(:address, greater_than_or_equal_to: 2, less_than_or_equal_to: 254) |> unique_constraint(:public_key) diff --git a/apps/fz_http/lib/fz_http/macros.ex b/apps/fz_http/lib/fz_http/macros.ex index 1e7048e4b..91c90da3a 100644 --- a/apps/fz_http/lib/fz_http/macros.ex +++ b/apps/fz_http/lib/fz_http/macros.ex @@ -3,6 +3,9 @@ defmodule FzHttp.Macros do Metaprogramming macros """ + @doc """ + Defines getters for all Setting keys as functions on the Settings module. + """ defmacro def_settings(keys) do quote bind_quoted: [keys: keys] do Enum.each(keys, fn key -> diff --git a/apps/fz_http/lib/fz_http/settings.ex b/apps/fz_http/lib/fz_http/settings.ex index f754f2177..8c22f35df 100644 --- a/apps/fz_http/lib/fz_http/settings.ex +++ b/apps/fz_http/lib/fz_http/settings.ex @@ -13,6 +13,7 @@ defmodule FzHttp.Settings do default.device.allowed_ips default.device.dns_servers default.device.endpoint + default.device.persistent_keepalives )) @doc """ diff --git a/apps/fz_http/lib/fz_http/settings/setting.ex b/apps/fz_http/lib/fz_http/settings/setting.ex index ae393d8fc..d8f4db7f3 100644 --- a/apps/fz_http/lib/fz_http/settings/setting.ex +++ b/apps/fz_http/lib/fz_http/settings/setting.ex @@ -15,6 +15,7 @@ defmodule FzHttp.Settings.Setting do import FzHttp.SharedValidators, only: [ + validate_ip: 2, validate_list_of_ips: 2, validate_list_of_ips_or_cidrs: 2, validate_no_duplicates: 2 @@ -57,8 +58,12 @@ defmodule FzHttp.Settings.Setting do defp validate_kv_pair(changeset, "default.device.endpoint") do changeset - |> validate_list_of_ips_or_cidrs(:value) - |> validate_no_duplicates(:value) + |> validate_ip(:value) + end + + defp validate_kv_pair(changeset, "default.device.persistent_keepalives") do + changeset + |> validate_number(:value, greater_than_or_equal_to: 0, less_than_or_equal_to: 120) end defp validate_kv_pair(changeset, unknown_key) do diff --git a/apps/fz_http/lib/fz_http_web/live/device_live/form_component.ex b/apps/fz_http/lib/fz_http_web/live/device_live/form_component.ex index fa5163087..598c6a307 100644 --- a/apps/fz_http/lib/fz_http_web/live/device_live/form_component.ex +++ b/apps/fz_http/lib/fz_http_web/live/device_live/form_component.ex @@ -18,6 +18,10 @@ defmodule FzHttpWeb.DeviceLive.FormComponent do |> assign(:default_device_allowed_ips, Settings.default_device_allowed_ips()) |> assign(:default_device_dns_servers, Settings.default_device_dns_servers()) |> assign(:default_device_endpoint, default_device_endpoint) + |> assign( + :default_device_persistent_keepalives, + Settings.default_device_persistent_keepalives() + ) |> assign(:changeset, changeset)} end diff --git a/apps/fz_http/lib/fz_http_web/live/device_live/form_component.html.heex b/apps/fz_http/lib/fz_http_web/live/device_live/form_component.html.heex index 3c4477a0e..de81b699a 100644 --- a/apps/fz_http/lib/fz_http_web/live/device_live/form_component.html.heex +++ b/apps/fz_http/lib/fz_http_web/live/device_live/form_component.html.heex @@ -92,6 +92,39 @@
++ Default: <%= @default_device_persistent_keepalives %> +
++ Interval for WireGuard + + persistent keepalives. A value of 0 disables this. Leave this disabled + unless you're experiencing NAT or firewall traversal problems. +
++ <%= error_tag f, :persistent_keepalives %> +
+