diff --git a/.markdownlint.json b/.markdownlint.json
index bfb7908c5..90b0cce36 100644
--- a/.markdownlint.json
+++ b/.markdownlint.json
@@ -1,3 +1,7 @@
{
- "MD002": false
+ "MD002": false,
+ "MD013": {
+ "code_blocks": false,
+ "tables": false
+ }
}
diff --git a/apps/fz_http/lib/fz_http_web/templates/layout/admin.html.heex b/apps/fz_http/lib/fz_http_web/templates/layout/admin.html.heex
index 469d7a93c..b0b08c16c 100644
--- a/apps/fz_http/lib/fz_http_web/templates/layout/admin.html.heex
+++ b/apps/fz_http/lib/fz_http_web/templates/layout/admin.html.heex
@@ -53,10 +53,10 @@
-
+
-
+
diff --git a/docs/docs/administer/manage.md b/docs/docs/administer/manage.md
index baf0c0e25..124ee4355 100644
--- a/docs/docs/administer/manage.md
+++ b/docs/docs/administer/manage.md
@@ -6,8 +6,6 @@ sidebar_position: 2
Your Firezone installation can be managed via the `firezone-ctl` command, as
shown below. Most subcommands require prefixing with `sudo`.
-
-
```text
root@demo:~# firezone-ctl
I don't know that command.
@@ -65,5 +63,3 @@ Service Management Commands:
usr2
Send the services a USR2.
```
-
-
diff --git a/docs/docs/administer/security-considerations.md b/docs/docs/administer/security-considerations.md
index 94e04ac41..0e12409d8 100644
--- a/docs/docs/administer/security-considerations.md
+++ b/docs/docs/administer/security-considerations.md
@@ -12,8 +12,6 @@ detailed [below](#production-deployments).
Shown below is a table of ports used by Firezone services.
-
-
| Service | Default port | Listen address | Description |
| ------ | --------- | ------- | --------- |
| Nginx | `443` | `all` | Public HTTPS port for administering Firezone and facilitating authentication. |
@@ -22,8 +20,6 @@ Shown below is a table of ports used by Firezone services.
| Postgresql | `15432` | `127.0.0.1` | Local-only port used for bundled Postgresql server. |
| Phoenix | `13000` | `127.0.0.1` | Local-only port used by upstream elixir app server. |
-
-
## Production deployments
For production and public-facing deployments where a single administrator
diff --git a/docs/docs/administer/troubleshoot.md b/docs/docs/administer/troubleshoot.md
index ce8da0a2f..7c4a249e7 100644
--- a/docs/docs/administer/troubleshoot.md
+++ b/docs/docs/administer/troubleshoot.md
@@ -4,10 +4,51 @@ sidebar_position: 5
---
For any problems that arise, a good first bet is to check the Firezone logs.
+Firezone logs are stored in `/var/log/firezone` and can be viewed with
+`sudo firezone-ctl tail`.
-To view Firezone logs, run `sudo firezone-ctl tail`.
+## Debugging Portal Websocket Connectivity Issues
-## Debugging Connectivity Issues
+The portal UI requires a secure websocket connection to function. To facilitate
+this, the Firezone phoenix service checks the `Host` header for inbound
+websocket connections and only permits the connection if it matches the host
+portion of your `default['firezone']['external_url']` variable.
+
+If a secure websocket connection can't be established, you'll see a red dot
+indicator in the upper-right portion of the Firezone web UI and a corresponding
+message when you hover over it:
+
+```text
+Secure websocket not connected! ...
+```
+
+If you're accessing Firezone using the same URL defined in your
+`default['firezone']['external_url']` variable from above, the issue is likely
+to be in your reverse proxy configuration.
+
+In most cases, you'll find clues in one or more of the following locations:
+
+* Your browser's developer tool logs, specifically the `Network` tab.
+* `sudo firezone-ctl tail nginx`
+* `sudo firezoen-ctl tail phoenix`
+
+If the websocket connection is successful, you should see output in the
+`phoenix` service logs similar the following:
+
+```text
+2022-09-23_15:05:47.29158 15:05:47.291 [info] CONNECTED TO Phoenix.LiveView.Socket in 24µs
+2022-09-23_15:05:47.29160 Transport: :websocket
+2022-09-23_15:05:47.29160 Serializer: Phoenix.Socket.V2.JSONSerializer
+2022-09-23_15:05:47.29161 Parameters: %{"_csrf_token" => "XFEFCHQ2fRQABQwtKQdCJDlFAzEcCCJvn7LqDsMXE4eGZtsBzuwVRCJ6", "_mounts" => "0", "_track_static" => %{"0" => "https://demo.firez.one/dist/admin-02fabe0f543c64122dbf5bc5b3451e51.css?vsn=d", "1" => "https://demo.firez.one/dist/admin-04e75c78295062c2c07af61be50248b0.js?vsn=d"}, "vsn" => "2.0.0"}
+2022-09-23_15:05:47.33655 15:05:47.336 [info] CONNECTED TO FzHttpWeb.UserSocket in 430µs
+2022-09-23_15:05:47.33657 Transport: :websocket
+2022-09-23_15:05:47.33658 Serializer: Phoenix.Socket.V2.JSONSerializer
+2022-09-23_15:05:47.33658 Parameters: %{"token" => "SFMyNTY.g2gDYQFuBgB6HeJqgwFiAAFRgA.qKoC2bi9DubPkE0tfaRSPERWUFyQQPQV5n4nFKVppxc", "vsn" => "2.0.0"}
+2022-09-23_15:05:47.35063 15:05:47.350 [info] JOINED notification:session in 636µs
+2022-09-23_15:05:47.35065 Parameters: %{"token" => "SFMyNTY.g2gDYQFuBgB6HeJqgwFiAAFRgA.zSG7pefm-Vgf_zvduxa5E9VK4s8PKqzc0xBDGNx5FQE", "user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0"}
+```
+
+## Debugging WireGuard Connectivity Issues
Most connectivity issues with Firezone are caused by other `iptables` or
`nftables` rules which interfere with Firezone's operation. If you have rules
@@ -52,11 +93,12 @@ To Action From
## Need additional help?
-If you're looking for help installing, configuring, or using Firezone, we're
-happy to help.
+Try asking on one of our community-powered support channels:
* [Discussion Forums](https://discourse.firez.one/): ask questions, report bugs,
and suggest features
* [Public Slack Group](https://join.slack.com/t/firezone-users/shared_invite/zt-111043zus-j1lP_jP5ohv52FhAayzT6w):
join discussions, meet other users, and meet the contributors
-* [Email Us](mailto:team@firezone.dev): we're always happy to chat
+
+We highly recommend considering [priority support](https://firezone.dev/pricing)
+if you're deploying Firezone in a production capacity.
diff --git a/docs/docs/authenticate/zitadel.md b/docs/docs/authenticate/zitadel.md
index f44d1010e..a3896f746 100644
--- a/docs/docs/authenticate/zitadel.md
+++ b/docs/docs/authenticate/zitadel.md
@@ -25,44 +25,54 @@ to provide Firezone with the user's email in the returned claims.

## Requirements
- - Setup your own Zitadel Cloud account: https://zitadel.cloud/
- - Create your first Zitadel instance the Zitadel Customerportal https://zitadel.cloud/admin/instances
- - Login to your Zitadel instance and create a project (i.e. "Internal")
-More information about these steps: https://docs.zitadel.com/docs/guides/start/quickstart#try-out-zitadel-cloud
+* Setup your own [Zitadel Cloud](https://zitadel.cloud/) account.
+* Create your first Zitadel instance in the
+ [Zitadel Customer portal](https://zitadel.cloud/admin/instances)
+* Login to your Zitadel instance and create a project (i.e. "Internal")
+
+More information about these steps can be found in
+[Zitadel's documentation](https://docs.zitadel.com/docs/guides/start/quickstart#try-out-zitadel-cloud).
## Create Zitadel Application
-In the Instance Console, go to **Projects** and select the project you want. Click
-**New**.
+In the Instance Console, go to **Projects** and select the project you want,
+then click **New**.

-Give the application a name (i.e. "Firezone") and select the application type **WEB**.
+Give the application a name (e.g. "Firezone") and select **WEB**
+for the application type.

Select **CODE** for the authentication method.

-Specify the redirect URI and post logout URI. The redirect URI will be of the form `EXTERNAL_URL + /auth/oidc/zitadel/callback/`. The post logout URI can just be the `EXTERNAL_URL`.
+Specify the redirect URI and post logout URI. The redirect URI will be of the
+form `EXTERNAL_URL + /auth/oidc/zitadel/callback/`. The post logout URI can
+just be the `EXTERNAL_URL`.

-Check all the overview of the configuration and clich on **Create**.
+Double-check the configuration, then click **Create**.

-Copy the **ClientId** and **ClientSecret** as it will be used for the firezone configuration.
+Copy the **ClientId** and **ClientSecret** as it will be used for the Firezone
+configuration.

-In the application **Configuration** click on **Refresh Token** and then on **Save**. The refresh token is optional for some features of firezone.
+In the application **Configuration** click **Refresh Token** and then on
+**Save**. The refresh token is optional for some features of Firezone.

-In the application **Token Settings** select **User roles inside ID Token** and **User Info inside ID Token**. Save it with a click on **Save**.
+In the application **Token Settings** select **User roles inside ID Token** and
+**User Info inside ID Token**. Save it with a click on **Save**.

## Integrate With Firezone
-Edit `/etc/firezone/firezone.rb` to include the options below. Your `discovery_document_url`
-will be `/.well-known/openid-configuration` appended to the end of your zitadel instance domain.
-You can find this domain for example in the application under **Urls**.
+Edit `/etc/firezone/firezone.rb` to include the options below. Your
+`discovery_document_url` will be `/.well-known/openid-configuration` appended
+to the end of your Zitadel instance domain. You can find this domain for
+example in the application under **Urls**.
```ruby
# Using Zitadel as the SSO identity provider
@@ -83,9 +93,10 @@ Run `firezone-ctl reconfigure` to update the application.
You should now see a **Sign in with Zitadel** button at the root Firezone URL.

-
## Restricting Access to only Users with Roles
-Zitadel can limit the users with access to the Firezone app. To do this,
-go to the project where your created your application in. In **General** you can find **Check authorization on Authentication** which allows only user to login, and thus use firezone, if they have assigned at least one role.
+Zitadel can limit which users have access to Firezone. To do this,
+go to the project where your created your application. In **General** you can
+find **Check Authorization on Authentication** which allows only users with at
+least one role to login to Firezone.

diff --git a/docs/docs/deploy/supported-platforms.md b/docs/docs/deploy/supported-platforms.md
index fd592e739..c1982c974 100644
--- a/docs/docs/deploy/supported-platforms.md
+++ b/docs/docs/deploy/supported-platforms.md
@@ -5,8 +5,6 @@ sidebar_position: 1
Firezone currently supports the following platforms:
-
-
| OS | Architectures | Status | Notes |
| --- | --- | --- | --- |
| AmazonLinux 2 | `amd64` `arm64` | **Fully-supported** | See [AmazonLinux 2 Notes](#amazonlinux-2-notes) |
@@ -26,8 +24,6 @@ Firezone currently supports the following platforms:
| Ubuntu 22.04 | `amd64` `arm64` | **Fully-supported** | Works as-is |
| openSUSE Leap 15.3 | `amd64` | **Fully-supported** | See [openSUSE Notes](#opensuse-notes) |
-
-
If your distro isn't listed here please try using a package for the closest
distro first. For example, since Raspberry Pi OS is based on Debian, try using
the Debian Firezone package.
diff --git a/docs/docs/reference/configuration-file.md b/docs/docs/reference/configuration-file.md
index 7d9d2e601..4b5742dd8 100644
--- a/docs/docs/reference/configuration-file.md
+++ b/docs/docs/reference/configuration-file.md
@@ -6,7 +6,6 @@ sidebar_position: 1
Shown below is a complete listing of the configuration options available in
`/etc/firezone/firezone.rb`.
-
@@ -172,6 +171,5 @@ Shown below is a complete listing of the configuration options available in
| `default['firezone']['connectivity_checks']['enabled']` | Enable or disable the Firezone connectivity checks service. | `true` |
| `default['firezone']['connectivity_checks']['interval']` | Interval between connectivity checks in seconds. | `3_600` |
-
diff --git a/docs/docs/reference/file-and-directory-locations.md b/docs/docs/reference/file-and-directory-locations.md
index b1074d80f..40c2a954e 100644
--- a/docs/docs/reference/file-and-directory-locations.md
+++ b/docs/docs/reference/file-and-directory-locations.md
@@ -7,8 +7,6 @@ Here you'll find a listing of files and directories related to a typical
Firezone installation. These could change depending on changes to your
configuration file.
-
-
| path | description |
| --- | --- |
| `/var/opt/firezone` | Top-level directory containing data and generated configuration for Firezone bundled services. |
@@ -16,5 +14,3 @@ configuration file.
| `/usr/bin/firezone-ctl` | `firezone-ctl` utility for managing your Firezone installation. |
| `/etc/systemd/system/firezone-runsvdir-start.service` | systemd unit file for starting the Firezone runsvdir supervisor process. |
| `/etc/firezone` | Firezone configuration files. |
-
-
diff --git a/docs/docs/reference/firewall-templates/nftables.md b/docs/docs/reference/firewall-templates/nftables.md
index 0326f3ad9..c9cceb208 100644
--- a/docs/docs/reference/firewall-templates/nftables.md
+++ b/docs/docs/reference/firewall-templates/nftables.md
@@ -46,8 +46,6 @@ firezone-ctl restart phoenix
#### Base Firewall Template
-
-
```shell
#!/usr/sbin/nft -f
@@ -318,8 +316,6 @@ table inet nat {
}
```
-
-
#### Usage
The firewall should be stored in the relevant location for the Linux distribution
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index a6908a3d0..25fdca464 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -18,7 +18,7 @@ const config = {
// If you aren't using GitHub pages, you don't need these.
organizationName: "firezone", // Usually your GitHub org/user name.
projectName: "firezone", // Usually your repo name.
- trailingSlash: false,
+ trailingSlash: true,
// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want