Use postgres sequence for device address

This commit is contained in:
Jamil Bou Kheir
2021-09-10 00:28:01 +00:00
parent 642fae900d
commit b2c6992d2b
10 changed files with 38 additions and 22 deletions

View File

@@ -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
%{

View File

@@ -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])

View File

@@ -10,6 +10,7 @@
<thead>
<tr>
<th>Name</th>
<th>WireGuard IP</th>
<th>Public key</th>
<th>Remote IP</th>
<th>Last seen at</th>
@@ -21,6 +22,7 @@
<td>
<%= live_redirect(device.name, to: Routes.device_show_path(@socket, :show, device)) %>
</td>
<td class="code"><%= FzHttp.Devices.ipv4_address(device) %></td>
<td class="code"><%= device.public_key %></td>
<td class="code"><%= device.remote_ip || "Never connected" %></td>
<td><%= device.last_seen_at %></td>

View File

@@ -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

View File

@@ -33,7 +33,7 @@
<dt>
<strong>Interface IP:</strong>
</dt>
<dd>10.3.2.<%= @device.octet_sequence %></dd>
<dd><%= FzHttp.Devices.ipv4_address(@device) %></dd>
<dt>
<strong>Public key:</strong>
@@ -81,7 +81,7 @@
<pre><code id="wg-conf">
[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]

View File

@@ -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

View File

@@ -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} =

View File

@@ -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",

View File

@@ -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

View File

@@ -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