diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 025c3f43c..1a0558ec7 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -63,20 +63,6 @@ jobs: with: run: ${{ steps.apply-run.outputs.run_id }} comment: "Apply Run from GitHub Actions CI ${{ github.sha }}" - - name: Report Status - if: failure() - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} - SLACK_USERNAME: "GitHub Actions" - SLACK_COLOR: "#ff0000" - MSG_MINIMAL: "ref,actions url" - SLACK_TITLE: "Deployment Failed" - SLACK_MESSAGE: - "Automatic deployment to ${{ env.TF_WORKSPACE }} failed" - with: - status: ${{ job.status }} - notify_when: "failure" update-release-draft: needs: deploy-staging diff --git a/.tool-versions b/.tool-versions index 8967f5ac1..4ecfd2773 100644 --- a/.tool-versions +++ b/.tool-versions @@ -3,7 +3,7 @@ nodejs 18.16.0 elixir 1.15.7-otp-26 erlang 26.1.2 -terraform 1.6.5 +terraform 1.6.6 # Used for static analysis python 3.9.13 diff --git a/elixir/apps/domain/lib/domain/auth.ex b/elixir/apps/domain/lib/domain/auth.ex index c2e8678b4..5227419fa 100644 --- a/elixir/apps/domain/lib/domain/auth.ex +++ b/elixir/apps/domain/lib/domain/auth.ex @@ -7,7 +7,8 @@ defmodule Domain.Auth do @default_session_duration_hours %{ account_admin_user: 24 * 7 - 1, - account_user: 24 * 7 + account_user: 24 * 7, + service_account: 20 * 365 * 24 * 7 } @max_session_duration_hours @default_session_duration_hours diff --git a/elixir/apps/domain/priv/repo/migrations/20231212194048_change_account_slugs_to_citext.exs b/elixir/apps/domain/priv/repo/migrations/20231212194048_change_account_slugs_to_citext.exs new file mode 100644 index 000000000..422c5dcd5 --- /dev/null +++ b/elixir/apps/domain/priv/repo/migrations/20231212194048_change_account_slugs_to_citext.exs @@ -0,0 +1,11 @@ +defmodule Domain.Repo.Migrations.ChangeAccountSlugsToCitext do + use Ecto.Migration + + def change do + execute("CREATE EXTENSION IF NOT EXISTS citext") + + alter table(:accounts) do + modify(:slug, :citext) + end + end +end diff --git a/elixir/apps/web/lib/web/controllers/home_controller.ex b/elixir/apps/web/lib/web/controllers/home_controller.ex index 590de982c..9142445ce 100644 --- a/elixir/apps/web/lib/web/controllers/home_controller.ex +++ b/elixir/apps/web/lib/web/controllers/home_controller.ex @@ -24,6 +24,7 @@ defmodule Web.HomeController do end def redirect_to_sign_in(conn, %{"account_id_or_slug" => account_id_or_slug} = params) do + account_id_or_slug = String.downcase(account_id_or_slug) redirect_params = take_non_empty_params(params, ["client_platform", "client_csrf_token"]) redirect(conn, to: ~p"/#{account_id_or_slug}?#{redirect_params}") diff --git a/elixir/apps/web/lib/web/live/actors/service_accounts/new_identity.ex b/elixir/apps/web/lib/web/live/actors/service_accounts/new_identity.ex index 38dd21a28..e6295f190 100644 --- a/elixir/apps/web/lib/web/live/actors/service_accounts/new_identity.ex +++ b/elixir/apps/web/lib/web/live/actors/service_accounts/new_identity.ex @@ -16,7 +16,7 @@ defmodule Web.Actors.ServiceAccounts.NewIdentity do assign(socket, actor: actor, provider: provider, - identity: nil, + encoded_token: nil, form: to_form(changeset) ) @@ -43,7 +43,7 @@ defmodule Web.Actors.ServiceAccounts.NewIdentity do Create <%= actor_type(@actor.type) %> Token <:content> -
@@ -143,13 +136,6 @@ defmodule Web.RelayGroups.NewToken do <.code_block id="code-sample-systemd6" class="w-full" phx-no-format>sudo systemctl enable firezone-relay - <.initial_connection_status - :if={@env} - type="relay" - navigate={~p"/#{@account}/sites/#{@group}"} - connected?={@connected?} - /> -
@@ -169,13 +155,28 @@ defmodule Web.RelayGroups.NewToken do <.code_block id="code-sample-systemd8" class="w-full rounded-b" phx-no-format>sudo journalctl -u firezone-relay.service + +
+ Relay not connecting? See our <.link + class="text-accent-500 hover:underline" + href="https://www.firezone.dev/kb/administer/troubleshooting#relay-not-connecting" + >relay troubleshooting guide. +
+ <.initial_connection_status + :if={@env} + type="relay" + navigate={~p"/#{@account}/relay_groups/#{@group}"} + connected?={@connected?} + /> +Set by PUBLIC_IP4_ADDR
<%= @relay.ipv4 %>
<.vertical_table_row>
- <:label>Remote IPv6
+ <:label>
+ IPv6
+ Set by PUBLIC_IP6_ADDR
<%= @relay.ipv6 %>
- <.vertical_table_row>
- <:label>Name
- <:value><%= @relay.name %>
-
<.vertical_table_row>
<:label>Status
<:value>
<.connection_status schema={@relay} />
- <.vertical_table_row>
- <:label>Location
- <:value>
- <.last_seen schema={@relay} />
-
-
<.vertical_table_row>
<:label>
Last seen
@@ -84,6 +80,12 @@ defmodule Web.Relays.Show do
<.relative_datetime datetime={@relay.last_seen_at} />
+ <.vertical_table_row>
+ <:label>Remote IP
+ <:value>
+ <.last_seen schema={@relay} />
+
+
<.vertical_table_row>
<:label>Version
<:value>
diff --git a/elixir/apps/web/lib/web/live/sites/new_token.ex b/elixir/apps/web/lib/web/live/sites/new_token.ex
index cc8db3cb3..ec0b15249 100644
--- a/elixir/apps/web/lib/web/live/sites/new_token.ex
+++ b/elixir/apps/web/lib/web/live/sites/new_token.ex
@@ -142,7 +142,7 @@ defmodule Web.Sites.NewToken do
"""
end
- defp version do
+ defp major_minor_version do
vsn =
Application.spec(:domain)
|> Keyword.fetch!(:vsn)
@@ -161,9 +161,19 @@ defmodule Web.Sites.NewToken do
[
{"FIREZONE_ID", Ecto.UUID.generate()},
{"FIREZONE_TOKEN", token},
- {"FIREZONE_ENABLE_MASQUERADE", "1"},
api_url_override,
- {"RUST_LOG", "warn"}
+ {"RUST_LOG",
+ Enum.join(
+ [
+ "firezone_gateway=trace",
+ "firezone_tunnel=trace",
+ "connlib_shared=trace",
+ "tunnel_state=trace",
+ "phoenix_channel=debug",
+ "warn"
+ ],
+ ","
+ )}
]
|> Enum.reject(&is_nil/1)
end
@@ -183,9 +193,11 @@ defmodule Web.Sites.NewToken do
"--sysctl net.ipv6.conf.all.forwarding=1",
"--sysctl net.ipv6.conf.default.forwarding=1",
"--device=\"/dev/net/tun:/dev/net/tun\"",
- Enum.map(env, fn {key, value} -> "--env #{key}=\"#{value}\"" end),
+ Enum.map(env ++ [{"FIREZONE_ENABLE_MASQUERADE", "1"}], fn {key, value} ->
+ "--env #{key}=\"#{value}\""
+ end),
"--env FIREZONE_NAME=$(hostname)",
- "#{Domain.Config.fetch_env!(:domain, :docker_registry)}/gateway:#{version()}"
+ "#{Domain.Config.fetch_env!(:domain, :docker_registry)}/gateway:#{major_minor_version()}"
]
|> List.flatten()
|> Enum.join(" \\\n ")
@@ -200,51 +212,47 @@ defmodule Web.Sites.NewToken do
[Service]
Type=simple
- ExecStartPre=/bin/sh -c 'id -u firezone &>/dev/null || useradd -r -s /bin/false firezone'
#{Enum.map_join(env, "\n", fn {key, value} -> "Environment=\"#{key}=#{value}\"" end)}
- ExecStartPre=/bin/sh -c 'set -xe; \\
- remote_version=$(curl -Ls \\
- -H "Accept: application/vnd.github+json" \\
- -H "X-GitHub-Api-Version: 2022-11-28" \\
- https://api.github.com/repos/firezone/firezone/releases/latest | \\
- grep "\\"tag_name\\": " | sed "s/.*\\"tag_name\\": \\"\\\\([^\\\\\\"]*\\\\).*/\\\\1/"); \\
- if [ -e /usr/local/bin/firezone-gateway ]; then \\
- current_version=$(/usr/local/bin/firezone-gateway --version | awk '"'"'{print $NF}'"'"'); \\
- else \\
- current_version=""; \\
- fi; \\
- if [ ! "$current_version" = "${remote_version:-latest}" ]; then \\
- echo "There is a new version of Firezone Gateway, downloading: ${remote_version:-latest}"; \\
+ ExecStartPre=/bin/sh -c 'set -xue; \\
+ if [ ! -e /usr/local/bin/firezone-gateway ]; then \\
+ FIREZONE_VERSION=$(curl -Ls \\
+ -H "Accept: application/vnd.github+json" \\
+ -H "X-GitHub-Api-Version: 2022-11-28" \\
+ "https://api.github.com/repos/firezone/firezone/releases/latest" | \\
+ grep "\\\\"tag_name\\\\":" | sed "s/.*\\\\"tag_name\\\\": \\\\"\\([^\\\\"\\\\]*\\).*/\\1/" \\
+ ); \\
+ [ "$FIREZONE_VERSION" = "" ] && echo "[Error] Can not fetch latest version, rate limited by GitHub?" && exit 1; \\
+ echo "Downloading Firezone Gateway version $FIREZONE_VERSION"; \\
arch=$(uname -m); \\
case $arch in \\
aarch64) \\
- bin_url="https://github.com/firezone/firezone/releases/download/latest/gateway-arm64" ;; \\
+ bin_url="https://github.com/firezone/firezone/releases/download/$FIREZONE_VERSION/gateway-arm64" ;; \\
armv7l) \\
- bin_url="https://github.com/firezone/firezone/releases/download/latest/gateway-arm" ;; \\
+ bin_url="https://github.com/firezone/firezone/releases/download/$FIREZONE_VERSION/gateway-arm" ;; \\
x86_64) \\
- bin_url="https://github.com/firezone/firezone/releases/download/latest/gateway-x64" ;; \\
+ bin_url="https://github.com/firezone/firezone/releases/download/$FIREZONE_VERSION/gateway-x64" ;; \\
*) \\
echo "Unsupported architecture"; \\
exit 1 ;; \\
esac; \\
wget -O /usr/local/bin/firezone-gateway $bin_url; \\
chmod +x /usr/local/bin/firezone-gateway; \\
- fi \\
+ mkdir -p /etc/firezone; \\
+ chmod 0755 /etc/firezone; \\
+ iptables-nft -A FORWARD -i tun-firezone -j ACCEPT; \\
+ iptables-nft -A FORWARD -o tun-firezone -j ACCEPT; \\
+ iptables-nft -t nat -A POSTROUTING -o eth+ -j MASQUERADE; \\
+ ip6tables-nft -A FORWARD -i tun-firezone -j ACCEPT; \\
+ ip6tables-nft -A FORWARD -o tun-firezone -j ACCEPT; \\
+ ip6tables-nft -t nat -A POSTROUTING -o eth+ -j MASQUERADE; \\
+ fi; \\
'
- ExecStartPre=/bin/sh -c 'mkdir -p /etc/firezone'
- ExecStartPre=/bin/sh -c 'chown firezone:firezone /etc/firezone'
- ExecStartPre=/bin/sh -c 'chmod 0755 /etc/firezone'
- ExecStartPre=/bin/sh -c 'chmod +x /usr/local/bin/firezone-gateway'
AmbientCapabilities=CAP_NET_ADMIN
- PrivateTmp=true
- ProtectSystem=full
- ReadWritePaths=/etc/firezone
- NoNewPrivileges=true
- TimeoutStartSec=15s
+ ExecStart=/bin/sh -c 'FIREZONE_NAME=$(hostname); /usr/local/bin/firezone-gateway'
+ TimeoutStartSec=3s
TimeoutStopSec=15s
- ExecStart=/bin/sh -c 'FIREZONE_NAME=$(hostname); sudo -u firezone -g firezone /usr/local/bin/firezone-gateway'
Restart=always
- RestartSec=3
+ RestartSec=7
[Install]
WantedBy=multi-user.target
diff --git a/elixir/apps/web/test/web/controllers/home_controller_test.exs b/elixir/apps/web/test/web/controllers/home_controller_test.exs
index 939fbcd3b..f9ddaa43e 100644
--- a/elixir/apps/web/test/web/controllers/home_controller_test.exs
+++ b/elixir/apps/web/test/web/controllers/home_controller_test.exs
@@ -53,5 +53,10 @@ defmodule Web.HomeControllerTest do
conn = post(conn, ~p"/", %{"account_id_or_slug" => id})
assert redirected_to(conn) == ~p"/#{id}"
end
+
+ test "downcases account slug on redirect", %{conn: conn} do
+ conn = post(conn, ~p"/", %{"account_id_or_slug" => "FOO"})
+ assert redirected_to(conn) == ~p"/foo"
+ end
end
end
diff --git a/elixir/apps/web/test/web/live/actors/service_accounts/new_identity_test.exs b/elixir/apps/web/test/web/live/actors/service_accounts/new_identity_test.exs
index d2dd61e78..e8ae68999 100644
--- a/elixir/apps/web/test/web/live/actors/service_accounts/new_identity_test.exs
+++ b/elixir/apps/web/test/web/live/actors/service_accounts/new_identity_test.exs
@@ -128,9 +128,11 @@ defmodule Web.Live.Actors.ServiceAccounts.NewIdentityTest do
identity: identity,
conn: conn
} do
+ expires_at = Date.utc_today() |> Date.add(3)
+
attrs = %{
provider_virtual_state: %{
- expires_at: Date.utc_today() |> Date.add(3) |> Date.to_iso8601()
+ expires_at: Date.to_iso8601(expires_at)
}
}
@@ -153,9 +155,12 @@ defmodule Web.Live.Actors.ServiceAccounts.NewIdentityTest do
remote_ip_location_lon: -120.4194
}
- # TODO: assert {:ok, _token} =
- Floki.find(html, "code")
- |> element_to_text()
- |> Domain.Auth.sign_in(context)
+ assert {:ok, subject} =
+ Floki.find(html, "code")
+ |> element_to_text()
+ |> Domain.Auth.sign_in(context)
+
+ assert subject.actor.id == actor.id
+ assert DateTime.to_date(subject.expires_at) == expires_at
end
end
diff --git a/elixir/apps/web/test/web/live/relay_groups/new_token_test.exs b/elixir/apps/web/test/web/live/relay_groups/new_token_test.exs
index 8b7698cfb..f8cc77038 100644
--- a/elixir/apps/web/test/web/live/relay_groups/new_token_test.exs
+++ b/elixir/apps/web/test/web/live/relay_groups/new_token_test.exs
@@ -43,7 +43,7 @@ defmodule Web.Live.RelayGroups.NewTokenTest do
assert_receive %Phoenix.Socket.Broadcast{topic: "relay_groups:" <> _group_id}
- assert element(lv, "#deployment-instructions")
+ assert element(lv, "#connection-status")
|> render() =~ "Connected, click to continue"
end
diff --git a/elixir/apps/web/test/web/live/relays/show_test.exs b/elixir/apps/web/test/web/live/relays/show_test.exs
index 6e6562e92..417c45bee 100644
--- a/elixir/apps/web/test/web/live/relays/show_test.exs
+++ b/elixir/apps/web/test/web/live/relays/show_test.exs
@@ -89,9 +89,9 @@ defmodule Web.Live.Relays.ShowTest do
assert table["instance group name"] =~ relay.group.name
assert table["last seen"]
- assert table["location"] =~ to_string(relay.last_seen_remote_ip)
- assert table["remote ipv4"] =~ to_string(relay.ipv4)
- assert table["remote ipv6"] =~ to_string(relay.ipv6)
+ assert table["remote ip"] =~ to_string(relay.last_seen_remote_ip)
+ assert table["ipv4 set by public_ip4_addr"] =~ to_string(relay.ipv4)
+ assert table["ipv6 set by public_ip6_addr"] =~ to_string(relay.ipv6)
assert table["status"] =~ "Offline"
assert table["user agent"] =~ relay.last_seen_user_agent
assert table["version"] =~ relay.last_seen_version
diff --git a/terraform/environments/production/versions.tf b/terraform/environments/production/versions.tf
index 0f8cc1757..c5c8e8c60 100644
--- a/terraform/environments/production/versions.tf
+++ b/terraform/environments/production/versions.tf
@@ -1,5 +1,5 @@
terraform {
- required_version = "1.6.5"
+ required_version = "1.6.6"
required_providers {
random = {
diff --git a/terraform/environments/staging/demo.tf b/terraform/environments/staging/demo.tf
index ad0cf81b1..9666df8a7 100644
--- a/terraform/environments/staging/demo.tf
+++ b/terraform/environments/staging/demo.tf
@@ -51,7 +51,6 @@ resource "google_compute_instance" "demo" {
}
# We can install any tools we need for the demo in the startup script
- # TODO: enable IPv6 for the demo VM
metadata_startup_script = <