From b2c6992d2b9b9cccb7209bde3ac59d20bd2aa2a6 Mon Sep 17 00:00:00 2001 From: Jamil Bou Kheir Date: Fri, 10 Sep 2021 00:28:01 +0000 Subject: [PATCH] Use postgres sequence for device address --- apps/fz_http/lib/fz_http/devices.ex | 6 ++++++ apps/fz_http/lib/fz_http/devices/device.ex | 9 +++------ .../live/device_live/index.html.heex | 2 ++ .../live/device_live/index_live.ex | 12 +++++++++--- .../live/device_live/show.html.heex | 4 ++-- .../20200228145810_create_devices.exs | 19 ++++++++++++++----- apps/fz_http/priv/repo/seeds.exs | 3 +-- apps/fz_http/test/support/fixtures.ex | 2 -- config/dev.exs | 1 - omnibus/cookbooks/firezone/recipes/network.rb | 2 +- 10 files changed, 38 insertions(+), 22 deletions(-) diff --git a/apps/fz_http/lib/fz_http/devices.ex b/apps/fz_http/lib/fz_http/devices.ex index 1d86ef423..ef6709a3f 100644 --- a/apps/fz_http/lib/fz_http/devices.ex +++ b/apps/fz_http/lib/fz_http/devices.ex @@ -7,6 +7,8 @@ defmodule FzHttp.Devices do alias FzCommon.NameGenerator alias FzHttp.{Devices.Device, Repo, Users.User} + @ipv4_prefix "10.3.2." + def list_devices do Repo.all(Device) end @@ -43,6 +45,10 @@ defmodule FzHttp.Devices do NameGenerator.generate() end + def ipv4_address(%Device{} = device) do + @ipv4_prefix <> Integer.to_string(device.address) + end + def to_peer_list do for device <- Repo.all(Device) do %{ diff --git a/apps/fz_http/lib/fz_http/devices/device.ex b/apps/fz_http/lib/fz_http/devices/device.ex index 052baf840..c9f4e854a 100644 --- a/apps/fz_http/lib/fz_http/devices/device.ex +++ b/apps/fz_http/lib/fz_http/devices/device.ex @@ -15,9 +15,7 @@ defmodule FzHttp.Devices.Device do field :private_key, FzHttp.Encrypted.Binary field :server_public_key, :string field :remote_ip, EctoNetwork.INET - field :octet_sequence, :integer, read_after_writes: true - field :interface_address4, EctoNetwork.INET - field :interface_address6, EctoNetwork.INET + field :address, :integer, read_after_writes: true field :last_seen_at, :utc_datetime_usec belongs_to :user, User @@ -30,9 +28,7 @@ defmodule FzHttp.Devices.Device do |> cast(attrs, [ :allowed_ips, :remote_ip, - :octet_sequence, - :interface_address4, - :interface_address6, + :address, :server_public_key, :private_key, :user_id, @@ -46,6 +42,7 @@ defmodule FzHttp.Devices.Device do :server_public_key, :private_key ]) + |> unique_constraint(:address) |> unique_constraint(:public_key) |> unique_constraint(:private_key) |> unique_constraint([:user_id, :name]) diff --git a/apps/fz_http/lib/fz_http_web/live/device_live/index.html.heex b/apps/fz_http/lib/fz_http_web/live/device_live/index.html.heex index 09d73acd7..8220c57b0 100644 --- a/apps/fz_http/lib/fz_http_web/live/device_live/index.html.heex +++ b/apps/fz_http/lib/fz_http_web/live/device_live/index.html.heex @@ -10,6 +10,7 @@ Name + WireGuard IP Public key Remote IP Last seen at @@ -21,6 +22,7 @@ <%= live_redirect(device.name, to: Routes.device_show_path(@socket, :show, device)) %> + <%= FzHttp.Devices.ipv4_address(device) %> <%= device.public_key %> <%= device.remote_ip || "Never connected" %> <%= device.last_seen_at %> diff --git a/apps/fz_http/lib/fz_http_web/live/device_live/index_live.ex b/apps/fz_http/lib/fz_http_web/live/device_live/index_live.ex index c43a5683b..19d2190d3 100644 --- a/apps/fz_http/lib/fz_http_web/live/device_live/index_live.ex +++ b/apps/fz_http/lib/fz_http_web/live/device_live/index_live.ex @@ -5,6 +5,7 @@ defmodule FzHttpWeb.DeviceLive.Index do use FzHttpWeb, :live_view alias FzHttp.Devices + alias FzHttpWeb.ErrorHelpers def mount(params, session, socket) do {:ok, @@ -36,7 +37,7 @@ defmodule FzHttpWeb.DeviceLive.Index do {:ok, device} -> @events_module.device_created( device.public_key, - "10.3.2.#{device.octet_sequence}" + Devices.ipv4_address(device) ) {:noreply, @@ -44,8 +45,13 @@ defmodule FzHttpWeb.DeviceLive.Index do |> put_flash(:info, "Device added successfully.") |> redirect(to: Routes.device_show_path(socket, :show, device))} - {:error, _changeset} -> - {:noreply, put_flash(socket, :error, "Error creating device.")} + {:error, changeset} -> + {:noreply, + put_flash( + socket, + :error, + "Error creating device: #{ErrorHelpers.aggregated_errors(changeset)}" + )} end end diff --git a/apps/fz_http/lib/fz_http_web/live/device_live/show.html.heex b/apps/fz_http/lib/fz_http_web/live/device_live/show.html.heex index c65ec422a..34f968360 100644 --- a/apps/fz_http/lib/fz_http_web/live/device_live/show.html.heex +++ b/apps/fz_http/lib/fz_http_web/live/device_live/show.html.heex @@ -33,7 +33,7 @@
Interface IP:
-
10.3.2.<%= @device.octet_sequence %>
+
<%= FzHttp.Devices.ipv4_address(@device) %>
Public key: @@ -81,7 +81,7 @@

 [Interface]
 PrivateKey = <%= @device.private_key %>
-Address = 10.3.2.<%= @device.octet_sequence %>
+Address = <%= FzHttp.Devices.ipv4_address(@device) %>
 DNS = 1.1.1.1, 1.0.0.1
 
 [Peer]
diff --git a/apps/fz_http/priv/repo/migrations/20200228145810_create_devices.exs b/apps/fz_http/priv/repo/migrations/20200228145810_create_devices.exs
index 7fcc84cd4..2d0ee7c7f 100644
--- a/apps/fz_http/priv/repo/migrations/20200228145810_create_devices.exs
+++ b/apps/fz_http/priv/repo/migrations/20200228145810_create_devices.exs
@@ -8,21 +8,30 @@ defmodule FzHttp.Repo.Migrations.CreateDevices do
       add :allowed_ips, :string
       add :private_key, :bytea, null: false
       add :server_public_key, :string, null: false
+      add :address, :integer, null: false
       add :remote_ip, :inet
-      # XXX: Rework this in app code
-      add :octet_sequence, :serial
-      add :interface_address4, :inet
-      add :interface_address6, :inet
       add :last_seen_at, :utc_datetime_usec
       add :user_id, references(:users, on_delete: :delete_all), null: false
 
       timestamps(type: :utc_datetime_usec)
     end
 
+    execute("CREATE SEQUENCE \
+      address_sequence \
+      AS SMALLINT \
+      MINVALUE 2 \
+      MAXVALUE 254 \
+      START 2 \
+      CYCLE \
+      OWNED BY devices.address \
+    ")
+
+    execute("ALTER TABLE devices ALTER COLUMN address SET DEFAULT NEXTVAL('address_sequence')")
+
     create index(:devices, [:user_id])
     create unique_index(:devices, [:public_key])
     create unique_index(:devices, [:private_key])
     create unique_index(:devices, [:user_id, :name])
-    create unique_index(:devices, [:octet_sequence])
+    create unique_index(:devices, [:address])
   end
 end
diff --git a/apps/fz_http/priv/repo/seeds.exs b/apps/fz_http/priv/repo/seeds.exs
index e188acc25..02a2401f3 100644
--- a/apps/fz_http/priv/repo/seeds.exs
+++ b/apps/fz_http/priv/repo/seeds.exs
@@ -26,8 +26,7 @@ alias FzHttp.{Devices, Rules, Users}
     public_key: "3Fo+SNnDJ6hi8qzPt3nWLwgjCVwvpjHL35qJeatKwEc=",
     server_public_key: "QFvMfHTjlJN9cfUiK1w4XmxOomH6KRTCMrVC6z3TWFM=",
     private_key: "2JSZtpSHM+69Hm7L3BSGIymbq0byw39iWLevKESd1EM=",
-    remote_ip: %Postgrex.INET{address: {127, 0, 0, 1}},
-    interface_address4: %Postgrex.INET{address: {10, 0, 0, 1}}
+    remote_ip: %Postgrex.INET{address: {127, 0, 0, 1}}
   })
 
 {:ok, _rule} =
diff --git a/apps/fz_http/test/support/fixtures.ex b/apps/fz_http/test/support/fixtures.ex
index bb72523d2..1c0205e8f 100644
--- a/apps/fz_http/test/support/fixtures.ex
+++ b/apps/fz_http/test/support/fixtures.ex
@@ -28,8 +28,6 @@ defmodule FzHttp.Fixtures do
 
     default_attrs = %{
       user_id: user_id,
-      interface_address4: "10.0.0.1",
-      interface_address6: "::1",
       public_key: "test-pubkey",
       name: "factory",
       private_key: "test-privkey",
diff --git a/config/dev.exs b/config/dev.exs
index f7e75096e..bc240c38a 100644
--- a/config/dev.exs
+++ b/config/dev.exs
@@ -32,7 +32,6 @@ config :fz_http, FzHttpWeb.Endpoint,
   ]
 
 config :fz_vpn,
-  wireguard_public_key: System.get_env("WIREGUARD_PUBLIC_KEY"),
   wg_path: "wg",
   cli: FzVpn.CLI.Live
 
diff --git a/omnibus/cookbooks/firezone/recipes/network.rb b/omnibus/cookbooks/firezone/recipes/network.rb
index dbadaeade..79e979514 100644
--- a/omnibus/cookbooks/firezone/recipes/network.rb
+++ b/omnibus/cookbooks/firezone/recipes/network.rb
@@ -42,7 +42,7 @@ end
 
 execute 'setup_wireguard_ip' do
   # XXX: Make this configurable
-  if_addr = '10.3.2.254/24'
+  if_addr = '10.3.2.1/24'
   command "ip address replace #{if_addr} dev #{wg_interface}"
 end