1.x docs first iteration (#2688)

Doing a first pass over documentation and minor UI cleanup. This PR
isn't meant to represent the final state of launch docs, but instead
something that will unblock #2685 and #2675

Fixes #2729
This commit is contained in:
Jamil
2023-11-29 20:04:54 -08:00
committed by GitHub
parent 67c14c02ed
commit 79aa4cfb8e
64 changed files with 1114 additions and 206 deletions

View File

@@ -31,18 +31,19 @@ defmodule Web.Settings.DNS do
</:title>
<:content>
<p class="ml-4 mb-4 font-medium text-gray-600">
Configure the default resolver used by connected Clients in your Firezone network. Queries for
Configure the default resolver used by connected Clients in your Firezone account. Queries for
defined Resources will <strong>always</strong>
use Firezone's internal DNS. All other queries will
use the resolver configured below.
use the resolver below if configured. If no resolver is configured, the client's default system
resolver will be used.
</p>
<p class="ml-4 mb-4 font-medium text-gray-600">
<.link
class="text-blue-600 hover:underline"
href="https://www.firezone.dev/docs/architecture/dns"
href="https://www.firezone.dev/kb/administer/dns?utm_source=product"
target="_blank"
>
Read more about how DNS works in Firezone.
Read more about configuring DNS in Firezone.
<.icon name="hero-arrow-top-right-on-square" class="-ml-1 mb-3 w-3 h-3" />
</.link>
</p>

View File

@@ -44,10 +44,10 @@ defmodule Web.Settings.IdentityProviders.Index do
<p class="ml-4 mb-4 font-medium text-gray-600">
<.link
class="text-blue-600 hover:underline"
href="https://www.firezone.dev/docs/architecture/sso"
href="https://www.firezone.dev/kb/authenticate?utm_source=product"
target="_blank"
>
Read more about how SSO works in Firezone.
Read more about setting up SSO in Firezone.
<.icon name="hero-arrow-top-right-on-square" class="-ml-1 mb-3 w-3 h-3" />
</.link>
</p>

View File

@@ -114,7 +114,7 @@ defmodule Web.Settings.IdentityProviders.SAML.Components do
<p class="ml-8 text-sm text-gray-500">
<.link
class="text-blue-600 hover:underline"
href="https://www.firezone.dev/docs/authenticate/jit-provisioning#extract-group-membership-information"
href="https://www.firezone.dev/kb/authenticate/user-group-sync?utm_source=product"
target="_blank"
>
Read more about group extraction.

View File

@@ -101,8 +101,11 @@ defmodule Web.SignIn do
</div>
<div :if={is_nil(@params["client_platform"])} class="mx-auto p-6 sm:p-8">
<p class="py-2">
<%= # TODO: Add link to client instructions docs %> Meant to sign in from a client instead?
<a href="https://firezone.dev/docs" class="font-medium text-blue-600 hover:text-blue-500">
Meant to sign in from a client instead?
<a
href="https://firezone.dev/kb/user-guides?utm_source=product"
class="font-medium text-blue-600 hover:text-blue-500"
>
Read the docs.
</a>
</p>

View File

@@ -138,7 +138,7 @@ defmodule Web.SignIn.EmailTest do
assert conn.assigns.flash["error"] == "The sign in token is invalid or expired."
end
test "allows to resend magic link", %{
test "allows resending sign in link", %{
account: account,
provider: provider,
identity: identity,

View File

@@ -1,4 +1,4 @@
<svg width="65" height="65" viewBox="0 0 65 65" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M46.2476 41.0717C47.5191 40.2013 49.0104 39.7095 50.549 39.6533C52.0876 39.5971 53.6107 39.9787 54.942 40.754C56.2733 41.5293 57.3584 42.6666 58.0718 44.0344C58.7852 45.4021 59.0978 46.9443 58.9733 48.4827C55.7122 49.6252 52.2483 50.0698 48.8052 49.7878C48.7947 46.6998 47.9076 43.6758 46.2476 41.0744C44.7742 38.7579 42.7417 36.8513 40.3382 35.5312C37.9347 34.211 35.2379 33.5199 32.4972 33.5217C29.757 33.5203 27.0607 34.2117 24.6577 35.5318C22.2548 36.852 20.2227 38.7583 18.7495 41.0744M48.8025 49.7851L48.8052 49.8695C48.8052 50.4826 48.7726 51.0874 48.7047 51.6841C43.7725 54.5208 38.1835 56.0091 32.4972 56C26.5991 56 21.0626 54.4306 16.2897 51.6841C16.2199 51.0536 16.1863 50.4195 16.1892 49.7851M16.1892 49.7851C12.7472 50.0773 9.28518 49.6344 6.02654 48.4854C5.90247 46.9475 6.21515 45.4058 6.92845 44.0385C7.64175 42.6713 8.72652 41.5343 10.0573 40.7591C11.3882 39.9839 12.9107 39.6022 14.4489 39.658C15.9871 39.7137 17.4781 40.2048 18.7495 41.0744M16.1892 49.7851C16.1989 46.6973 17.0905 43.6761 18.7495 41.0744M40.6512 17.1739C40.6512 19.3418 39.7921 21.4208 38.263 22.9537C36.7338 24.4866 34.6598 25.3478 32.4972 25.3478C30.3346 25.3478 28.2606 24.4866 26.7314 22.9537C25.2023 21.4208 24.3432 19.3418 24.3432 17.1739C24.3432 15.0061 25.2023 12.927 26.7314 11.3941C28.2606 9.86118 30.3346 9 32.4972 9C34.6598 9 36.7338 9.86118 38.263 11.3941C39.7921 12.927 40.6512 15.0061 40.6512 17.1739ZM56.9593 25.3478C56.9593 26.1529 56.8011 26.95 56.4937 27.6938C56.1864 28.4376 55.7359 29.1134 55.1681 29.6827C54.6002 30.2519 53.926 30.7035 53.1841 31.0116C52.4421 31.3197 51.6468 31.4782 50.8437 31.4782C50.0406 31.4782 49.2454 31.3197 48.5034 31.0116C47.7615 30.7035 47.0873 30.2519 46.5194 29.6827C45.9515 29.1134 45.5011 28.4376 45.1937 27.6938C44.8864 26.95 44.7282 26.1529 44.7282 25.3478C44.7282 23.7219 45.3725 22.1626 46.5194 21.0129C47.6663 19.8633 49.2218 19.2174 50.8437 19.2174C52.4657 19.2174 54.0212 19.8633 55.1681 21.0129C56.3149 22.1626 56.9593 23.7219 56.9593 25.3478ZM20.2662 25.3478C20.2662 26.1529 20.108 26.95 19.8007 27.6938C19.4933 28.4376 19.0429 29.1134 18.475 29.6827C17.9071 30.2519 17.2329 30.7035 16.491 31.0116C15.749 31.3197 14.9538 31.4782 14.1507 31.4782C13.3476 31.4782 12.5523 31.3197 11.8104 31.0116C11.0684 30.7035 10.3942 30.2519 9.82634 29.6827C9.25846 29.1134 8.808 28.4376 8.50066 27.6938C8.19333 26.95 8.03515 26.1529 8.03515 25.3478C8.03515 23.7219 8.67946 22.1626 9.82634 21.0129C10.9732 19.8633 12.5287 19.2174 14.1507 19.2174C15.7726 19.2174 17.3281 19.8633 18.475 21.0129C19.6219 22.1626 20.2662 23.7219 20.2662 25.3478Z" stroke="black" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M57 65C61.4183 65 65 61.4183 65 57C65 52.5817 61.4183 49 57 49C52.5817 49 49 52.5817 49 57C49 61.4183 52.5817 65 57 65ZM58.2988 54.6508H54.7788C54.8044 53.9719 55.3516 53.3913 56.0933 53.3322C56.2034 53.3238 56.3146 53.3159 56.4257 53.3089C56.5507 53.0818 56.7394 52.8915 56.9713 52.7586C57.2032 52.6258 57.4694 52.5555 57.7407 52.5556H58.4815C58.7528 52.5555 59.019 52.6258 59.2509 52.7586C59.4828 52.8915 59.6715 53.0818 59.7965 53.3089C59.9074 53.316 60.0182 53.3237 60.1289 53.3322C60.8889 53.3923 61.4444 54.0003 61.4444 54.7011V59.1905C61.4444 59.5609 61.2883 59.9162 61.0105 60.1782C60.7327 60.4401 60.3559 60.5873 59.9629 60.5873V56.2222C59.963 55.8059 59.7877 55.4065 59.4757 55.1119C59.1636 54.8172 58.7404 54.6514 58.2988 54.6508ZM57.2169 53.4585C57.3559 53.3276 57.5443 53.254 57.7407 53.254H58.4815C58.6779 53.254 58.8663 53.3276 59.0053 53.4585C59.1442 53.5895 59.2222 53.7672 59.2222 53.9524H57C57 53.7672 57.078 53.5895 57.2169 53.4585ZM53.4815 55.3492C52.9704 55.3492 52.5555 55.7399 52.5555 56.2222V61.4603C52.5555 61.6919 52.6531 61.9139 52.8267 62.0776C53.0004 62.2414 53.2359 62.3333 53.4815 62.3333H58.2963C58.8074 62.3333 59.2222 61.9422 59.2222 61.4603V56.2222C59.2222 55.7403 58.8079 55.3492 58.2963 55.3492H53.4815ZM54.1455 57.1975C54.076 57.263 54.037 57.3518 54.037 57.4444V57.4482C54.037 57.5408 54.076 57.6296 54.1455 57.6951C54.215 57.7606 54.3092 57.7974 54.4074 57.7974H54.4113C54.5096 57.7974 54.6038 57.7606 54.6732 57.6951C54.7427 57.6296 54.7817 57.5408 54.7817 57.4482V57.4444C54.7817 57.3518 54.7427 57.263 54.6732 57.1975C54.6038 57.132 54.5096 57.0952 54.4113 57.0952H54.4074C54.3092 57.0952 54.215 57.132 54.1455 57.1975ZM55.2566 57.1975C55.1872 57.263 55.1481 57.3518 55.1481 57.4444C55.1481 57.5371 55.1872 57.6259 55.2566 57.6914C55.3261 57.7569 55.4203 57.7937 55.5185 57.7937H57.3704C57.4686 57.7937 57.5628 57.7569 57.6322 57.6914C57.7017 57.6259 57.7407 57.5371 57.7407 57.4444C57.7407 57.3518 57.7017 57.263 57.6322 57.1975C57.5628 57.132 57.4686 57.0952 57.3704 57.0952H55.5185C55.4203 57.0952 55.3261 57.132 55.2566 57.1975ZM54.1455 58.5943C54.076 58.6598 54.037 58.7487 54.037 58.8413V58.845C54.037 58.9376 54.076 59.0264 54.1455 59.0919C54.215 59.1574 54.3092 59.1942 54.4074 59.1942H54.4113C54.5096 59.1942 54.6038 59.1574 54.6732 59.0919C54.7427 59.0264 54.7817 58.9376 54.7817 58.845V58.8413C54.7817 58.7487 54.7427 58.6598 54.6732 58.5943C54.6038 58.5289 54.5096 58.4921 54.4113 58.4921H54.4074C54.3092 58.4921 54.215 58.5289 54.1455 58.5943ZM55.2566 58.5943C55.1872 58.6598 55.1481 58.7487 55.1481 58.8413C55.1481 58.9339 55.1872 59.0227 55.2566 59.0882C55.3261 59.1537 55.4203 59.1905 55.5185 59.1905H57.3704C57.4686 59.1905 57.5628 59.1537 57.6322 59.0882C57.7017 59.0227 57.7407 58.9339 57.7407 58.8413C57.7407 58.7487 57.7017 58.6598 57.6322 58.5943C57.5628 58.5289 57.4686 58.4921 57.3704 58.4921H55.5185C55.4203 58.4921 55.3261 58.5289 55.2566 58.5943ZM54.1455 59.9912C54.076 60.0567 54.037 60.1455 54.037 60.2381V60.2418C54.037 60.3344 54.076 60.4233 54.1455 60.4887C54.215 60.5542 54.3092 60.591 54.4074 60.591H54.4113C54.5096 60.591 54.6038 60.5542 54.6732 60.4887C54.7427 60.4233 54.7817 60.3344 54.7817 60.2418V60.2381C54.7817 60.1455 54.7427 60.0567 54.6732 59.9912C54.6038 59.9257 54.5096 59.8889 54.4113 59.8889H54.4074C54.3092 59.8889 54.215 59.9257 54.1455 59.9912ZM55.2566 59.9912C55.1872 60.0567 55.1481 60.1455 55.1481 60.2381C55.1481 60.3307 55.1872 60.4195 55.2566 60.485C55.3261 60.5505 55.4203 60.5873 55.5185 60.5873H57.3704C57.4686 60.5873 57.5628 60.5505 57.6322 60.485C57.7017 60.4195 57.7407 60.3307 57.7407 60.2381C57.7407 60.1455 57.7017 60.0567 57.6322 59.9912C57.5628 59.9257 57.4686 59.8889 57.3704 59.8889H55.5185C55.4203 59.8889 55.3261 59.9257 55.2566 59.9912Z" fill="#4805FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M57 65C61.4183 65 65 61.4183 65 57C65 52.5817 61.4183 49 57 49C52.5817 49 49 52.5817 49 57C49 61.4183 52.5817 65 57 65ZM56.2635 53.8561C56.7466 53.7147 57.2538 53.7146 57.7369 53.856C58.2205 53.9976 58.6695 54.278 59.0353 54.6776L59.0354 54.6778L59.2976 54.9644H58.7852C58.371 54.9644 58.0352 55.3002 58.0352 55.7144C58.0352 56.1286 58.371 56.4644 58.7852 56.4644H61C61.4143 56.4644 61.75 56.1286 61.75 55.7144V53.2944C61.75 52.8802 61.4143 52.5444 61 52.5444C60.5858 52.5444 60.25 52.8802 60.25 53.2944V53.7832L60.1421 53.6652L60.142 53.665C59.599 53.0718 58.916 52.6382 58.1583 52.4164C57.4 52.1945 56.6002 52.1945 55.8419 52.4166C55.0842 52.6385 54.4013 53.0722 53.8584 53.6655C53.3159 54.2585 52.9311 54.9909 52.7361 55.7865C52.6375 56.1888 52.8838 56.5949 53.2861 56.6935C53.6884 56.7921 54.0944 56.5458 54.193 56.1435C54.3304 55.5828 54.599 55.0782 54.9651 54.6781C55.3308 54.2784 55.7798 53.9978 56.2635 53.8561ZM61.264 58.2135C61.3625 57.8112 61.1163 57.4051 60.714 57.3065C60.3117 57.2079 59.9056 57.4542 59.8071 57.8565C59.6697 58.4172 59.4011 58.9218 59.035 59.3219C58.6693 59.7216 58.2203 60.0022 57.7366 60.1439C57.2535 60.2853 56.7463 60.2854 56.2632 60.144C55.7796 60.0024 55.3306 59.722 54.9649 59.3225L54.9647 59.3222L54.7025 59.0356H55.2153C55.6296 59.0356 55.9653 58.6998 55.9653 58.2856C55.9653 57.8714 55.6296 57.5356 55.2153 57.5356H53.0005C52.5863 57.5356 52.2505 57.8714 52.2505 58.2856V60.7056C52.2505 61.1198 52.5863 61.4556 53.0005 61.4556C53.4147 61.4556 53.7505 61.1198 53.7505 60.7056V60.2172L53.8579 60.3347L53.8581 60.335C54.4011 60.9282 55.084 61.3618 55.8418 61.5836C56.6001 61.8055 57.3999 61.8055 58.1582 61.5834C58.9159 61.3615 59.5988 60.9278 60.1417 60.3345C60.6842 59.7415 61.069 59.0091 61.264 58.2135Z" fill="#4805FF"/>
</svg>

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -226,7 +226,7 @@ goes one step further by exposing granular controls to allow or deny access
based on attributes like which group a user is a member of and so on.
Of course if you wanted to use Firezone 1.0 like a traditional perimeter-based
VPN and then transition to finer-grined access controls over time, you can do
VPN and then transition to finer-grained access controls over time, you can do
that as well. We understand the realities of legacy processes and systems, so we
designed 1.0 to be flexible enough to suit the needs of both.

View File

@@ -81,6 +81,12 @@ and configured automatically.
In most cases, you'll find clues in one or more of the following locations:
<TabsGroup>
<TabsItem title="Docker" active>
- `firezone` service logs: `docker compose logs firezone`
- `caddy` service logs: `docker compose logs caddy`
</TabsItem>
<TabsItem title="Omnibus">
- Your browser's developer tool logs, specifically the `Network` tab.

View File

@@ -7,7 +7,7 @@ Firezone supports Single Sign-On (SSO) via OpenID Connect (OIDC).
In general, most identity providers that offer OIDC support work with Firezone.
Some providers that only implement the OIDC partially or use uncommon
configurations may have issues, however. If your identity provider falls into
this category, [contact us ](/contact/sales) about a custom integration.
this category, [contact us](/contact/sales) about a custom integration.
The following OIDC providers are known to work well with Firezone:

View File

@@ -1,12 +1,21 @@
import DocsSidebar from "@/components/DocsSidebar";
import Alert from "@/components/DocsAlert";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="flex">
<DocsSidebar />
<main className="max-w-screen-xl p-4 pt-20 -ml-64 md:ml-0 lg:mx-auto">
<main className="p-4 pt-20 -ml-64 md:ml-0 lg:mx-auto">
<div className="px-4">
<article className="max-w-none format format-sm sm:format-base lg:format-lg ">
<article className="max-w-screen-md format format-sm">
<Alert
color="info"
html={`
<!-- TODO: Link to EOL blogpost -->
You're viewing documentation for the legacy version of Firezone.
<a href="/kb">View the latest docs here</a>.
`}
/>
{children}
</article>
</div>

View File

@@ -1 +1,17 @@
# Backup and Restore
In Firezone 1.x and above, all configuration is kept in the Admin portal and
therefore no backup and restore procedures are necessary. WireGuard keys are
generated ephemerally each time a Client or Gateway starts and don't need to be
(nor should they be) saved.
That said, you may want to make sure to save the following configuration
parameters in cases where you're replacing gateway VMs or headless clients tied
to service accounts:
- The `FIREZONE_TOKEN` environment variable authenticates gateways and clients
to the portal and determines which configurations to load respectively. This
is a secret that should **always** be saved in a safe place.
- The `FIREZONE_ID` environment variable identifies gateways and clients to the
portal for metadata tracking. We recommend saving this if you'd like to
maintain consistency for display in the portal.

View File

@@ -2,7 +2,7 @@ import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Gateway Deployment • Firezone Docs",
title: "Configuring DNS • Firezone Docs",
description: "Firezone Documentation",
};

View File

@@ -0,0 +1,39 @@
import PlanBadge from "@/components/PlanBadge";
import Alert from "@/components/DocsAlert";
<PlanBadge plans={["starter", "enterprise"]} />
# DNS in Firezone
Firezone creates an internal IP for all resources in your account, including
DNS-based resources. These internal IPs are used to route traffic from the
requesting client to the appropriate gateway where the DNS query is ultimately
resolved to its actual IP address.
This means that clients are automatically configured for Split DNS in Firezone
-- no other configuration is necessary other than adding the desired resources
in the admin portal.
This also means that each gateway resolves IPs for clients connecting to it, so
it's important for DNS to be setup properly on the gateways in your account.
## Configuring client DNS fallback
For DNS names that don't match a defined resource, Firezone will use the
upstream resolvers defined at `Settings` -> `DNS` in the order they are defined.
If no custom resolvers are configured, Firezone clients will fall back to their
default system resolver typically set by the DHCP server of their local network.
To add custom resolvers, enter a valid IPv4 or IPv6 address and click "Save". To
remove, delete the IP address and click "Save".
<Alert
color="info"
html={`
Custom resolvers such as <a href="https://developers.cloudflare.com/1.1.1.1/setup/#1111-for-families">
Cloudflare</a> or <a href="https://nextdns.io">NextDNS</a> can be used to block
malware, ads, adult material and other content for all users in your Firezone
account.
`}
/>

View File

@@ -1 +1,29 @@
# Viewing Logs
# Diagnostic logs
Firezone maintains diagnostic log files in various locations depending on the
component and operating system. Logs are scrubbed for sensitive and
personally-identifiable information before being written to disk.
Diagnostic logs are used primarily by the Firezone team for troubleshooting
connectivity and other issues.
Below is a table listing the various log directories used by each component.
| Component | Log directory |
| ----------------------- | --------------------------------------------------------------------------------------- |
| macOS client | `~/Library/Group Containers/47R2M6779T.group.dev.firezone.firezone/Library/Caches/logs` |
| iOS client | N/A |
| Android/ChromeOS client | `/data/data/dev.firezone.android/caches/logs` |
| Linux client | Set by the user via the `LOG_DIR` environment variable |
| Gateway | Logs are written to STDOUT by default |
## Exporting logs
Log files can be conveniently exported from the macOS, iOS, Android, and
ChromeOS clients from the in-app Settings screen.
## Clearing logs
Simply delete the files in the log directories listed above. For macOS, iOS,
Android, and ChromeOS clients, log directies can be cleared in the "Advanced"
portion of the in-app Settings screen.

View File

@@ -1 +1,14 @@
import SupportOptions from "@/components/SupportOptions";
# Troubleshooting Guide
Start with this guide for solutions to common issues faced by Firezone admins
and end-users.
1. macOS client troubleshooting guide
1. iOS client troubleshooting guide
1. Android/ChromeOS troubleshooting guide
1. Linux client troubleshooting guide
1. Gateway troubleshooting guide
<SupportOptions />

View File

@@ -1 +1,57 @@
import { HiCheck } from "react-icons/hi2";
import { TabsItem, TabsGroup } from "@/components/DocsTabs";
# Upgrading Firezone
Upgrading Firezone consists of upgrading the client applications and gateways.
Read more below to understand how our versioning system works, how you can
auto-update these components, and suggestions for an upgrade strategy in
high-availability deployments.
## How versioning works in Firezone
Firezone uses a semantic versioning scheme in the standard
`MAJOR`.`MINOR`.`PATCH` format with the following structure:
| Version type | Example | Explanation |
| ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MAJOR` | `1` | Marketing version. Updates to this version generally constitute a new architecture or product. Updated every few years on average. |
| `MINOR` | `20231001` | API version. Clients and gateways **must** be the same API version to function together. The Firezone admin portal supports the latest **two** API versions at the same time. Updated every 6 months on average. |
| `PATCH` | `11` | Patch version. Represents backwards-compatible bug fixes and updates that are generally recommended for all users. Updated on average every week. |
All Firezone components follow the structure above, so it is trivial to
determine which clients work with which gateways and for how long.
## Auto-updates
In general we recommend keeping clients and gateways as up-to-date as possible.
See below for auto-update details for each client.
<TabsGroup>
<TabsItem title="macOS" active>
Enable auto-updates in Settings.app.
</TabsItem>
<TabsItem title="iOS">Enable auto-updates in Settings.app.</TabsItem>
<TabsItem title="Android">Enable app auto-updates in Settings.</TabsItem>
<TabsItem title="ChromeOS">Enable app auto-updates in Settings.</TabsItem>
<TabsItem title="Linux">
Linux auto-updates are configured by default if you deployed using the Linux
client deployment guide.
</TabsItem>
<TabsItem title="Gateway">
Gateway auto-updates are configured by default if you deployed using the
Linux client deployment guide.
</TabsItem>
</TabsGroup>
## Upgrading gateways with minimal downtime
Gateways deployed in the same site will automatically
[failover](/kb/deploy/gateways#failover) for each other. By upgrading gateways
one-by-one, clients connected to the gateway being upgraded will automatically
reconnect to an available gateway.
Currently the failover timeout is maximum 120 seconds, so upgrades should be
performed during a scheduled maintenance window to ensure minimal disruption.
Other than a possible short-term connection interruption to in-use resources,
users won't be impacted by upgrading high-availability gateways.

View File

@@ -2,7 +2,7 @@ import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Email Auth • Firezone Docs",
title: "Email Authentication Firezone Docs",
description: "Firezone Documentation",
};

View File

@@ -1 +1,33 @@
# Email Authentication
import PlanBadge from "@/components/PlanBadge";
import Alert from "@/components/DocsAlert";
<PlanBadge plans={["starter", "enterprise"]} />
# Email authentication
Firezone supports email authentication using a one-time password (OTP).
This connector is enabled by default for all plans and is designed to get you up
and running with Firezone quickly. For production deployments, we highly
recommend setting up [OIDC](/kb/authenticate/oidc) or
[Google Workspace](/kb/authenticate/google).
Firezone's OTP-based email authentication connector sends a one-time password to
the user's email each time authentication is requested. This password is
short-lived and can only be used to authenticate once.
<Alert
color="info"
html={`
Users authenticated via the email connector will need to be added and removed
from groups manually.
`}
/>
## Disabling email authentication
The email authentication connector can be **disabled completely** for your
account, forcing all users and admins to authenticate with another connector.
However, this can lead to issues signing in if one of your other authentication
connectors stops working. For that reason, you may want to leave the email
authentication connector enabled with at least one admin for recovery purposes.

View File

@@ -2,7 +2,7 @@ import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Google Auth Firezone Docs",
title: "Google Workspace Authentication Firezone Docs",
description: "Firezone Documentation",
};

View File

@@ -1 +1,42 @@
# Google Authentication
import Alert from "@/components/DocsAlert";
import PlanBadge from "@/components/PlanBadge";
<PlanBadge plans={["enterprise"]} />
# SSO with Google Workspace
Firezone supports authenticating users to Google Workspace using our custom
Google Workspace connector. Use this guide if you're looking to setup SSO with
Google Workspace for your Firezone Enterprise account.
<Alert
color="info"
html={`
Google Workspace integration is available in the Enterprise plan.
To authenticate users to your Google Workspace account in the Starter
plan <strong>without</strong> automatic user/group sync, use our
<a href="/kb/authenticate/oidc" class="text-accent-500 hover:underline">
universal OIDC connector
</a> instead.
`}
/>
## Overview
The Firezone Google Workspace connector integrates with Google's identity APIs
to support user authentication and automatic user/group sync.
Users, groups, and organizational units are synced every few minutes to ensure
that your Firezone account remains up-to-date with the latest identity data from
your Google Workspace account.
[Read more about user / group sync here](/kb/authenticate/user-group-sync).
## Setup
To set up the Google workspace connector, go to `Settings` ->
`Identity Providers` -> `Add Identity Provider` and follow the prompts from
there.
Setting up the Google Workspace connector is similar to the process of setting
up a universal OIDC connector. The main difference is the addition of a few
extra scopes needed to enable user/group sync.

View File

@@ -2,7 +2,7 @@ import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "OIDC Auth • Firezone Docs",
title: "OIDC Authentication Firezone Docs",
description: "Firezone Documentation",
};

View File

@@ -1 +1,23 @@
# OpenID Connect (OIDC) Authentication
import PlanBadge from "@/components/PlanBadge";
<PlanBadge plans={["starter", "enterprise"]} />
# SSO with OpenID Connect (OIDC)
Firezone supports authenticating users with a universal OIDC connector. Use this
connector to enable SSO for any OIDC-capable identity provider.
{/* FIXME: detailed instructions per provider */}
## Setting up the universal OIDC connector
To set up the universal OIDC connector, go to `Settings` -> `Identity Providers`
-> `Add Identity Provider` and follow the prompts from there.
In general, you should follow your identity provider's documentation for setting
up an OIDC client. If the option is available, be sure to enable PKCE as well.
For more detailed guides specific to each provider, see the
[Firezone legacy documentation](/docs/authenticate/oidc). Firezone 1.x uses the
same OIDC connector under the hood as our legacy version, so those guides should
apply for 1.x as well.

View File

@@ -0,0 +1,12 @@
import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Authentication Overview • Firezone Docs",
description:
"Firezone supports Google Workspace, OIDC, and email authentication methods.",
};
export default function Page() {
return <Content />;
}

View File

@@ -0,0 +1,7 @@
# Authentication
Firezone supports the following authentication connectors:
1. [Email (OTP)](/kb/authenticate/email)
1. [OpenID Connect (OIDC)](/kb/authenticate/oidc)
1. [Google Workspace](/kb/authenticate/google)

View File

@@ -1 +1,80 @@
import Alert from "@/components/DocsAlert";
import PlanBadge from "@/components/PlanBadge";
<PlanBadge plans={["enterprise"]} />
# User / Group Sync
Firezone supports user / group sync from Google Workspace. This feature is
**automatically enabled** for the
[Google Workspace connector](/kb/authenticate/google). Once the connector is
activated, users, groups, and organizational units will be synced from your
Google Workspace account every few minutes.
<Alert
color="info"
html={`
User / group sync is only supported with the Google Workspace connector
at this time. Support for more providers is currently
<a href="https://github.com/firezone/firezone/issues/2016">in development</a>.
`}
/>
## Deleting entities
To preserve audit log trails, Firezone <strong>never</strong> deletes synced
users or groups.
### Deleting or suspending users
When a user is deleted or suspended in your Google Workspace account, Firezone
will disable the user and clear all active client and admin portal web sessions
for that user upon the next user/group sync. The user will be **signed out of
all clients** and forced to reauthenticate.
This ensures terminated employees will have all Firezone access revoked within a
few minutes of deleting or suspending them in your Google Workspace account.
### Deleting a group or organizational unit
Deleting a group or organizational unit in Google Workspace will hide the group
and associated policy in Firezone.
## Nested groups and organizational units
Firezone flattens nested groups and organizational units synced from Google
Workspace. User membership is determined **only** by its immediate parent. At
this time, Firezone does not recursively sync members from nested groups and
organizational units.
<Alert
color="warning"
html={`
Need to sync users under nested groups or organizational units? Leave your
feedback on <a href="https://github.com/firezone/firezone/issues/2743">
this GitHub issue</a> so we can prioritize it on our roadmap.
`}
/>
For example, if you had the following group structure in your Google Workspace
account:
```
- Product
- steve@company.com
- Engineering
- bob@company.com
- alice@company.com
- Support
- patrick@company.com
```
In Firezone, you would see the follow groups after sync:
```
- Group:Product
- steve@company.com
- Group:Engineering
- Group:Support
- patrick@company.com
```

View File

@@ -2,7 +2,7 @@ import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Client Deployment • Firezone Docs",
title: "Clients • Firezone Deploy Docs",
description: "Firezone Documentation",
};

View File

@@ -1 +1,19 @@
# Deploy Clients
Firezone provides clients for all major platforms.
During beta, the Firezone team will provide you with invite links you can
forward to your end-users to install clients on macOS, iOS, and Android
platforms.
On Windows and Linux platforms, you can find the latest clients published at our
[main repository releases page](https://github.com/firezone/firezone/releases).
## End-user instructions
Users can find more specific instructions for their respective platform below:
1. [Apple client](/kb/user-guides/apple-client)
1. [Android client](/kb/user-guides/android-client)
1. [Windows client](/kb/user-guides/windows-client)
1. [Linux client](/kb/user-guides/linux-client)

View File

@@ -1 +0,0 @@
# Deploy a Gateway

View File

@@ -0,0 +1,11 @@
import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Gateways • Firezone Deploy Docs",
description: "Firezone Documentation",
};
export default function Page() {
return <Content />;
}

View File

@@ -0,0 +1,77 @@
import Alert from "@/components/DocsAlert";
# Deploy a Gateway
This guide covers deployment of the Firezone gateway.
Gateways expect to have unobstructed network-level access to resources within
the same site.
## Prerequisites
- Any Linux distribution with kernel 5.0 or higher
- Docker Engine (for docker-based installs)
- Systemd (for systemd-based installs)
## Resource considerations
Gateways, like the rest of Firezone's data plane stack, are written in Rust and
are thus resource efficient by nature. A single gateway running on a 2 vCPU VM
with 1 GB of memory should be able to handle hundreds of client connections
under typical usage patterns.
Network throughput is usually constrained by single-thread performance due to
the WireGuard state machine and overhead in the kernel network stack. Still,
most gateways should be able to saturate 1 Gbps with relative ease. Faster
speeds can be achieved with syscall optimization and multi-threaded
optimizations, both of which are currently being worked on.
## Deploy a single gateway
Deployed a single gateway can be accomplished in the admin portal.
Go to `Sites` -> `<site>` -> `Deploy a Gateway` and follow the prompts to deploy
for your preferred environment. This will deploy a single gateway.
See the [upgrading guide](/kb/administer/upgrading) for information on keeping
your gateway up-to-date.
## Deploy multiple gateways
When deploying a gateway from the admin portal, a `FIREZONE_TOKEN` environment
variable is shown. This variable can be reused to deploy multiple gateways
within the same site.
This means you can automate deployment of the gateway using your automation
method of choice, adding as many gateways as necessary for failover and load
balancing.
<Alert
color="warning"
html={`
<strong>Note:</strong> Be sure to set a unique <code>FIREZONE_ID</code> for each
gateway you deploy. This can be any non-empty string and is used to
identify the gateway in the portal for audit trail and logging purposes.
`}
/>
## Failover
Two or more Gateways deployed in the same site will automatically fail over and
load balance for each other.
When the portal detects a particular gateway is unhealthy, it will stop using it
for new connection requests to resources in the site. Fail over takes around 60
to 120 seconds for clients to time out their existing gateway connections and
fail over to a healthy one. During this time, connection to resources will be
interrupted, so it's important to plan gateway downtime appropriately.
## Load balancing
Load balancing happens automatically each time a client requests a connection to
a resource and uses a round-robin approach which selects a random gateway in the
site to serve the resource being requested.
This effectively shards client connections across all gateways in a site,
achieving higher overall throughput than otherwise possible with a single
gateway.

View File

@@ -0,0 +1,11 @@
import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Policies • Firezone Deploy Docs",
description: "Firezone Documentation",
};
export default function Page() {
return <Content />;
}

View File

@@ -0,0 +1,19 @@
import Alert from "@/components/DocsAlert";
# Create Policies
Policies are what grant users access to resources.
To define a policy, go to `Policies` -> `Add Policy`.
Policies define a single group access to a single resource.
<Alert
color="warning"
html={`
<strong>Note:</strong> To preserve audit trails, policy
access cannot be changed once a policy is created.
Double-check to ensure the group and resource selected
are correct before creating the policy.
`}
/>

View File

@@ -1 +1,12 @@
# Deploy Firezone
Looking to get up and running quickly? See our
[Quickstart guide](/kb/quickstart).
For more detailed step-by-step instructions, follow the steps below.
1. [Create a Site](/kb/deploy/sites)
1. [Deploy a Gateway](/kb/deploy/gateways)
1. [Create a Resource](/kb/deploy/resources)
1. [Create a Policy](/kb/deploy/policies)
1. [Install Clients](/kb/deploy/clients)

View File

@@ -0,0 +1,11 @@
import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Resources • Firezone Deploy Docs",
description: "Firezone Documentation",
};
export default function Page() {
return <Content />;
}

View File

@@ -0,0 +1,20 @@
import Alert from "@/components/DocsAlert";
# Create Resources
Resources define subnets, IP addresses, or DNS names you wish to manage access
for.
To create a resource, go to `Sites` -> `<site>` -> `Add a resource`. Resources
are expected to be reachable by all gateways in the same site.
DNS-based resources match the address entered and all subdomains.
<Alert
color="warning"
html={`
<strong>Note:</strong> To preserve audit trails, once a resource is created,
its address cannot be changed. Double-check to ensure the address entered
is correct before creating the resource.
`}
/>

View File

@@ -0,0 +1,11 @@
import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Sites • Firezone Deploy Docs",
description: "Firezone Documentation",
};
export default function Page() {
return <Content />;
}

View File

@@ -0,0 +1,17 @@
# Sites
Sites represent a shared network environment that gateways and resources exist
in. All gateways and resources in a site should be able to reach each other.
## Data routing
Firezone allows you to select how data is routed to a particular site.
Choose "Firezone Managed Relays" (Enterprise plans only) to allow data to
potentially route through the Firezone-managed Relay network when NAT hole
punching fails. Connections in Firezone are end-to-end encrypted; we can never
decrypt your traffic.
Choose "Direct only" to enforce peer to peer connections between clients and
gateways for this site. If NAT holepunching fails for gateways in the site,
clients will be unable to connect to resources and gateways defined in the site.

View File

@@ -1,12 +1,20 @@
import KbSidebar from "@/components/KbSidebar";
import Alert from "@/components/DocsAlert";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="flex">
<KbSidebar />
<main className="max-w-screen-xl p-4 pt-20 -ml-64 md:ml-0 lg:mx-auto">
<main className="p-4 pt-20 -ml-64 md:ml-0 lg:mx-auto">
<div className="px-4">
<article className="max-w-none format format-sm sm:format-base lg:format-lg ">
<article className="max-w-screen-md format format-sm">
<Alert
color="info"
html={`
You're viewing documentation for the upcoming 1.x version of Firezone, currently in beta.
<a href="/docs">View the legacy docs here</a>.
`}
/>
{children}
</article>
</div>

View File

@@ -12,77 +12,103 @@ Welcome to the quickstart guide for Firezone
className="mx-auto shadow rounded"
/>
## Prerequisites
* Firezone account (Don't have an account? Get one here https://app.firezone.dev/sign_up)
* Resource you want to give users secure access to (e.g. prod server, database, SaaS application, subnet, etc...)
* Server or VM (with the ability to deploy a docker container or Linux application) that can connect to both the resource, and the internet
- Firezone account (Don't have an account?
[Request early access](/product/early-access))
- Resource you want to give users secure access to (e.g. prod server, database,
SaaS application, subnet, etc...)
- Server or VM (with the ability to deploy a docker container or Linux
application) that can connect to both the resource, and the internet
## Summary
1. **Sign in to your Firezone Admin Portal**
1. **Create a Site** - Sites are where admins manage resources, and gateways that enable access to those resources (e.g. US-West, Chicago-office).
1. **Deploy a Gateway** - Gateways are site-specific, and provide connectivity between the Firezone client and resources in a Site.
1. **Add a Resource** - A resource is anything you'd like to give users secure access to (e.g. a server/VM, database, subnet).
1. **Create a Policy for each Resource** - A policy defines which user-groups can access a Resource (note: access is default-deny, which means a user can't access a Resource until a Policy permitting access is created).
1. **Sign in to your Firezone Admin Portal** (e.g.
https://app.firezone.dev/example_company)
1. **Create a Site** - Sites are where admins manage resources, and gateways
that enable access to those resources (e.g. US-West, Chicago-office).
1. **Deploy a Gateway** - Gateways are Site-specific, and provide connectivity
between the Firezone client and resources in a Site.
1. **Add a Resource** - A resource is anything you'd like to give users secure
access to (e.g. a server/VM, database, subnet).
1. **Create a Policy for each Resource** - A policy defines which user-groups
can access a Resource (note: access is default-deny, which means a user can't
access a Resource until a Policy permitting access is created).
1. **Download the Firezone Client**
This quickstart guide illustrates a simple Firezone setup. Firezone supports more complex deployments, but we like to start with the basics.
Instructions below follow the same order as the summary above. If you follow the instructions sequentially from top to bottom, you should end up with a working Firezone network that looks like the architecture diagram at the top of this guide.
This quickstart guide illustrates a simple Firezone setup. Firezone supports
more complex deployments, but we like to start with the basics.
Instructions below follow the same order as the summary above. If you follow the
instructions sequentially from top to bottom, you should end up with a working
Firezone network that looks like the architecture diagram at the top of this
guide.
### Signing In
In your browser, visit your custom sign-in URL, which can be found in the "Welcome to Firezone" email sent after you created your account. Once on the sign-in page, enter your email and click the sign-in button. You'll receive another email with a magic link and a token. You may either click the magic link to be signed in automatically or you may copy the token value and enter it in to the form on the sign-in page.
In your browser, visit your unique sign-in URL, which can be found in the
"Welcome to Firezone" email sent after you created your account. Once on the
sign-in page, enter your email and click the sign-in button. You'll receive
another email with a sign in link and token. You may either click the link to be
signed in automatically on the device you're using, or copy the token value and
enter it in to the form on the sign-in page.
### Create a Site
When you log in to the admin portal, you'll land on the Sites page. The first step will be to create a Site by clicking the 'Add Site' button. We'll auto-generate a name for the site, but you should consider renaming it something relevant like `Production`, `US-West`, or `Chicago-office`. After the site is created, you'll be forwarded to the Site Details page where you can continue the setup process.
When you log in to the admin portal, you'll land on the Sites page. The first
step will be to create a Site by clicking the 'Add Site' button. We'll
auto-generate a name for the site, but you should consider renaming it something
relevant like `Production`, `US-West`, or `Chicago-office`. After the site is
created, you'll be forwarded to the Site Details page where you can continue the
setup process.
### Deploy a Gateway
Gateways run on your infrastructure (server, VM, etc.) and must have access to the internet as well as the resource you'd like to share.
Gateways run on your infrastructure (server, VM, etc.) and must have access to
the internet as well as the resource you'd like to share via Firezone.
On the Site Details page, click the 'Deploy a Gateway' button. You will be shown 2 options to deploy a Gateway: `Docker` or `Systemd` (choose whichever method you prefer, and follow the instruction on that page).
When a Gateway has been successfully deployed, you will be notified deployment page and given the option to be redirected to the Site Details page where the gateway will now be listed and shown as online.
Clicking "Deploy a Gateway" on the Site Details page will give you two options
for deploying a Gateway: `Docker` or `Systemd` (choose whichever method you
prefer, and follow the instruction on that page).
When a Gateway has been successfully deployed, you will be redirected to the
Site Details page where the gateway will now be listed and shown as online.
### Add a Resource
A Resource is anything the site-gateway can reach, that you'd like to give users access to. Examples include servers, databases, subnets, etc...
A Resource is anything the site-gateway can reach, that you'd like to give users
access to. Examples include servers, databases, subnets, etc...
On the Site Details page, click on the 'Create a Resource' button. You will now be able to enter the `name` and `address` for a Resource. The `name` can be anything you choose, and the `address` must be one of the following:
On the Site Details page, click on the 'Create a Resource' button. You will now
be able to enter the `name` and `address` for a Resource. The `name` can be
anything you choose, and the `address` must be one of the following:
- IP address
- Fully Qualified Domain Name (FQDN)
- CIDR Range
After creation, you'll need to create a policy authorizing user-group(s) to access the resource. Users cannot access a resource unless they are members of a group that has access.
After adding a Resource, you'll need to create a policy authorizing one or more
user-groups to access that resource. End-users cannot access a resource unless
they are members of a group that has explicit access to that resource.
### Create a Policy
Navigate to the Policies page by clicking the 'Policies' button in the left-side menu bar. Select a resource, and choose which groups can access that resource. Save the policy.
Navigate to the Policies page by clicking the 'Policies' button in the left-side
menu bar. Select a Resource, and choose which groups can access that Resource.
Save the policy.
### Install the Firezone Client
### Download the Firezone Client
When you're finished in the Admin Portal, end-users can connect to available
resources by
[installing the Firezone client for your platform](/kb/deploy/clients), and
signing in.
When you're finished in the Admin Portal, you can connect to available resources by downloading the Firezone Client App, and signing in.
After installing the client, go to 'Settings' and enter your 'Account ID' (aka
account slug), and apply changes. If you don't recall your Account ID, you can
refer back to the "Welcome to Firezone" email that was sent when you signed up.
To download the app...
After installing the app, go to 'Settings' and enter your 'Account ID' (aka account slug), and apply changes. If you don't recall your Account ID, you can refer back to the "Welcome to Firezone" email that was sent when you signed up.
To sign in, close the settings window, click "Sign In" in the Firezone app, and authenticate your account.
To sign in, close the settings window, click "Sign In" in the Firezone app, and
authenticate your account.
You now have secure access to resources shown in the "Resources" section. Enjoy!

View File

@@ -3,6 +3,4 @@ import Image from "next/image";
# Docs Overview
Welcome to the Firezone Documentation! Use the sections below to get started.
{/* TODO */}
Welcome to the Firezone Documentation! Use the sidebar to get started.

View File

@@ -1 +1,19 @@
# Android Client
Firezone supports Android and ChromeOS with a native client available in the
Google Play Store.
## Prerequisites
- Android / ChromeOS 11 or higher (third party OSes like LineageOS or GrapheneOS
may work too but are **not** supported)
- Google Chrome browser installed
## Installation
The Android client is currently in beta. Your Firezone administrator will
provide you with an invite link to install and setup the Firezone Android beta
on your device.
For more information on being an Android tester, see
[Google's documentation](https://firebase.google.com/docs/app-distribution/get-set-up-as-a-tester?platform=android).

View File

@@ -2,7 +2,7 @@ import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Apple Client • Firezone Docs",
title: "Apple Clients • Firezone Docs",
description: "Firezone Documentation",
};

View File

@@ -1 +1,18 @@
# Apple Client (macOS / iOS)
Firezone supports macOS and iOS with native clients available in the macOS App
Store and iOS App Stores respectively. The iOS app also works for iPad.
## Prerequisites
- macOS 12 or higher, iOS 15 or higher, or iPadOS 15 or higher
- Intel and Apple silicon Macs are supported
## Installation
The Apple clients are currently in beta. Your Firezone administrator will
provide you with an invite link to install and setup the beta clients for your
device.
For more information on being an Apple tester, see
[Apple's documentation](https://testflight.apple.com/).

View File

@@ -1 +1,16 @@
# Linux Client
Firezone supports Linux with a native, headless client for ARM, ARM64, and Intel
x64 architectures.
## Prerequisites
- Any Linux-based OS with kernel 5.0 or higher
- ARM64, ARMv8, or Intel x64 CPU
- Administrator access to your Firezone account in order to create a Service
Account
## Installation
The Linux client is currently in beta and can be downloaded from our
[main repository's releases page](https://github.com/firezone/firezone/releases).

View File

@@ -0,0 +1,12 @@
import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "User Guides • Firezone Docs",
description:
"Guides designed to help end-users accomplish common tasks in Firezone.",
};
export default function Page() {
return <Content />;
}

View File

@@ -0,0 +1,8 @@
# User Guides
Guides for common end-user workflows in Firezone.
- [Android / ChromeOS client](/kb/user-guides/android-client)
- [macOS and iOS clients](/kb/user-guides/apple-client)
- [Windows client](/kb/user-guides/windows-client)
- [Linux client](/kb/user-guides/linux-client)

View File

@@ -1 +1,14 @@
# Windows Client
Firezone supports Microsoft Windows with a native client for ARM64 and Intel x64
architectures.
## Prerequisites
- Windows 10 or higher
- arm64 or x64 CPU
## Installation
The Windows client is currently in beta and can be downloaded from our
[main repository's releases page](https://github.com/firezone/firezone/releases).

View File

@@ -37,7 +37,7 @@ export default function Page() {
<Link href="/contact/sales">
<button
type="button"
className="inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-bold text-center text-white rounded bg-accent-600 hover:bg-accent-700 hover:scale-105 duration-0 transform transition"
className="inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-bold text-center text-white rounded bg-accent-450 hover:bg-accent-700 hover:scale-105 duration-0 transform transition"
>
Request demo
<HiArrowLongRight className="ml-2 -mr-1 w-6 h-6" />
@@ -547,7 +547,7 @@ export default function Page() {
<div className="w-full max-w-screen-sm flex justify-between mt-8">
<button
type="button"
className="w-64 inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-normal text-center text-neutral-900 rounded bg-neutral-50 hover:scale-105 duration-0 transform transition"
className="w-64 inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-semibold text-center text-neutral-900 rounded bg-neutral-50 hover:scale-105 duration-0 transform transition"
>
<Link href="/product/early-access">
Register for early access
@@ -555,7 +555,7 @@ export default function Page() {
</button>
<button
type="button"
className="w-64 inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-bold text-center text-white rounded bg-gradient-to-br from-primary-500 to-primary-450 hover:scale-105 duration-0 transform transition"
className="w-64 inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-bold text-center text-white rounded bg-primary-450 hover:scale-105 duration-0 transform transition"
>
<Link href="/contact/sales">Request demo</Link>
<HiArrowLongRight className="ml-2 -mr-1 w-6 h-6" />

View File

@@ -37,7 +37,7 @@ export default function Page() {
<Link href="/product/early-access">
<button
type="button"
className="w-64 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-lg px-5 py-2.5 bg-gradient-to-br from-accent-700 to-accent-600"
className="w-64 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-lg px-5 py-2.5 bg-accent-450 hover:bg-accent-700"
>
Request early access
</button>
@@ -60,7 +60,7 @@ export default function Page() {
<li className="flex space-x-2.5">
<HiCheck className="flex-shrink-0 w-5 h-5 text-neutral-900" />
<span className="leading-tight text-neutral-900 ">
Authenticate with magic link and OIDC
Authenticate with email and OIDC
</span>
</li>
<li className="flex space-x-2.5">
@@ -91,7 +91,7 @@ export default function Page() {
<Link href="/contact/sales">
<button
type="button"
className="w-64 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-lg px-5 py-2.5 bg-gradient-to-br from-accent-700 to-accent-600"
className="w-64 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-lg px-5 py-2.5 bg-accent-450 hover:bg-accent-700"
>
Request a demo
</button>

View File

@@ -381,7 +381,7 @@ export default function PlanTable() {
<Link href="/product/early-access">
<button
type="button"
className="w-48 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-md py-2.5 bg-gradient-to-br from-accent-700 to-accent-600"
className="w-48 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-md py-2.5 bg-accent-450 hover:bg-accent-700"
>
Request early access
</button>
@@ -391,7 +391,7 @@ export default function PlanTable() {
<Link href="/contact/sales">
<button
type="button"
className="w-48 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-md py-2.5 bg-gradient-to-br from-accent-700 to-accent-600"
className="w-48 text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-md py-2.5 bg-accent-450 hover:bg-accent-700"
>
Request a demo
</button>

View File

@@ -1,72 +0,0 @@
"use client";
import Link from "next/link";
import Image from "next/image";
import { XMLParser } from "fast-xml-parser";
import { useState, useEffect } from "react";
import Marquee from "react-fast-marquee";
export default function CommitMarquee({ xmlFeed }: { xmlFeed: string }) {
const parser = new XMLParser({ ignoreAttributes: false });
const [xml, setXml] = useState<any>({ feed: { title: "", entry: [] } });
useEffect(() => {
fetch(xmlFeed)
.then((response) => response.text())
.then((str) => parser.parse(str))
.then((data) => {
setXml(data);
})
.catch((error) => console.error(error));
}, []);
return (
<div className="h-64">
<h3 className="justify-center sm:text-2xl text-xl font-semibold tracking-tight text-neutral-900 mb-4 sm:mb-6 border-b pb-2 border-neutral-200">
{xml.feed.title}
</h3>
<Marquee
gradient
pauseOnHover
gradientWidth={100}
gradientColor={"#f8f7f7"}
>
{xml.feed.entry.map((entry: any) => (
<div
key={entry.id}
className="text-center w-64 h-full items-top mx-2 py-2 px-2"
>
<h4 className="justify-center mb-2 text-neutral-800 font-medium text-lg">
<Link
href={entry.link["@_href"]}
className="text-accent-500 underline hover:no-underline"
>
{entry.title.replace(/\(#.*\)/, "")}
</Link>
</h4>
<p className="mb-2 text-center">
<Image
className="rounded-full mx-auto"
width={entry["media:thumbnail"]["@_width"]}
height={entry["media:thumbnail"]["@_height"]}
src={entry["media:thumbnail"]["@_url"]}
alt="user avatar"
/>
</p>
<p className="mb-2 text-sm">
<Link
href={entry.author.uri}
className="text-accent-500 underline hover:no-underline"
>
{entry.author.name}
</Link>{" "}
</p>
<p className="font-semibold text-xs">
{new Date(entry.updated).toDateString()}
</p>
</div>
))}
</Marquee>
</div>
);
}

View File

@@ -12,16 +12,13 @@ export default function Collapse({
}) {
const ctl = label.toLowerCase().replace(" ", "-") + "-dropdown";
const indent = "ml-3";
const hidden = expanded ? "" : "hidden";
const text = expanded ? "bg-neutral-100 " : "text-neutral-900 ";
const [expandedState, setExpandedState] = useState(expanded);
const [expandedState, setExpandedState] = useState(false);
return (
<>
<button
type="button"
className={
text +
" flex items-center w-full transition duration-75 rounded group hover:bg-neutral-100 "
}
aria-controls={ctl}
@@ -29,18 +26,24 @@ export default function Collapse({
onClick={() => setExpandedState(!expandedState)}
>
<span
className="ml-3 flex-1 text-left whitespace-nowrap"
className="ml-3 flex-1 text-left whitespace-nowrap font-semibold"
sidebar-toggle-item="true"
>
{label}
</span>
{expandedState ? (
<HiChevronDown sidebar-toggle-item="true" className="w-6 h-6" />
<HiChevronDown sidebar-toggle-item="true" className="w-5 h-5" />
) : (
<HiChevronRight sidebar-toggle-item="true" className="w-6 h-6" />
<HiChevronRight sidebar-toggle-item="true" className="w-5 h-5" />
)}
</button>
<ul id={ctl} className={[hidden, "ml-3 py-1 space-y-0.5"].join(" ")}>
<ul
id={ctl}
className={[
expandedState ? "" : "hidden",
"ml-3 py-1 space-y-0.5",
].join(" ")}
>
{children}
</ul>
</>

View File

@@ -1,10 +1,76 @@
"use client";
import { Tabs as FlowbiteTabs } from "flowbite-react";
import type { CustomFlowbiteTheme } from "flowbite-react";
// Copied from https://www.flowbite-react.com/docs/components/tabs and then modified
const customTheme: CustomFlowbiteTheme["tab"] = {
base: "flex flex-col gap-2",
tablist: {
base: "flex text-center",
styles: {
default: "flex-wrap border-b border-neutral-200",
underline: "flex-wrap -mb-px border-b border-neutral-200",
pills: "flex-wrap font-medium text-sm text-neutral-500 space-x-2",
fullWidth:
"w-full text-sm font-medium divide-x divide-neutral-200 shadow grid grid-flow-colrounded-none",
},
tabitem: {
base: "flex items-center justify-center p-4 rounded-t-lg text-sm font-medium first:ml-0 disabled:cursor-not-allowed disabled:text-neutral-400",
styles: {
default: {
base: "rounded-t-lg",
active: {
on: "bg-neutral-100 text-neutral-600",
off: "text-neutral-500 hover:bg-neutral-50 hover:text-neutral-600",
},
},
underline: {
base: "rounded-t-lg",
active: {
on: "text-accent-600 rounded-t-lg border-b-2 border-accent-600 active",
off: "border-b-2 border-transparent text-neutral-500 hover:border-accent-200 hover:text-accent-600",
},
},
pills: {
base: "",
active: {
on: "rounded-lg bg-neutral-600 text-white",
off: "rounded-lg hover:text-neutral-900 hover:bg-neutral-100",
},
},
fullWidth: {
base: "ml-0 first:ml-0 w-full rounded-none flex",
active: {
on: "p-4 text-neutral-900 bg-neutral-100 active rounded-none",
off: "bg-white hover:text-neutral-700 hover:bg-neutral-50 rounded-none",
},
},
},
icon: "mr-2 h-5 w-5",
},
},
tabitemcontainer: {
base: "",
styles: {
default: "",
underline: "",
pills: "",
fullWidth: "",
},
},
tabpanel: "p-3",
};
function TabsGroup({ children }: { children: React.ReactNode }) {
return (
<div className="mb-4">
<FlowbiteTabs.Group className="shadow">{children}</FlowbiteTabs.Group>
<FlowbiteTabs.Group
theme={customTheme}
style="underline"
className="bg-neutral-50 rounded shadow"
>
{children}
</FlowbiteTabs.Group>
</div>
);
}

View File

@@ -198,7 +198,7 @@ export default function Footer() {
<div className="flex mt-4 space-x-6 sm:justify-center sm:mt-0">
<TwitterIcon url="https://twitter.com/firezonehq" />
<GitHubIcon url="https://github.com/firezone" />
<LinkedInIcon url="https://linkedin.com/comppany/firezonehq" />
<LinkedInIcon url="https://linkedin.com/company/firezonehq" />
</div>
</div>
</div>

View File

@@ -12,16 +12,13 @@ export default function Collapse({
}) {
const ctl = label.toLowerCase().replace(" ", "-") + "-dropdown";
const indent = "ml-3";
const hidden = expanded ? "" : "hidden";
const text = expanded ? "bg-neutral-100 " : "text-neutral-900 ";
const [expandedState, setExpandedState] = useState(expanded);
const [expandedState, setExpandedState] = useState(false);
return (
<>
<button
type="button"
className={
text +
" flex items-center w-full transition duration-75 rounded group hover:bg-neutral-100 "
}
aria-controls={ctl}
@@ -29,18 +26,24 @@ export default function Collapse({
onClick={() => setExpandedState(!expandedState)}
>
<span
className="ml-3 flex-1 text-left whitespace-nowrap"
className="ml-3 flex-1 text-left whitespace-nowrap font-semibold"
sidebar-toggle-item="true"
>
{label}
</span>
{expandedState ? (
<HiChevronDown sidebar-toggle-item="true" className="w-6 h-6" />
<HiChevronDown sidebar-toggle-item="true" className="w-5 h-5" />
) : (
<HiChevronRight sidebar-toggle-item="true" className="w-6 h-6" />
<HiChevronRight sidebar-toggle-item="true" className="w-5 h-5" />
)}
</button>
<ul id={ctl} className={[hidden, "ml-3 py-1 space-y-0.5"].join(" ")}>
<ul
id={ctl}
className={[
expandedState ? "" : "hidden",
"ml-3 py-1 space-y-0.5",
].join(" ")}
>
{children}
</ul>
</>

View File

@@ -7,12 +7,14 @@ import SearchForm from "./SearchForm";
import { usePathname } from "next/navigation";
export default function KbSidebar() {
const p = usePathname() || "";
useEffect(() => {
// Manually init flowbite's data-toggle listeners since we're using custom components
initFlowbite();
}, []);
const p = usePathname() || "";
console.log(p);
return (
<aside
@@ -23,7 +25,120 @@ export default function KbSidebar() {
>
<SearchForm />
<div className="mt-5 h-full overflow-y-auto bg-white pr-3">
<ul className="space-y-2 font-medium">{/* FIXME */}</ul>
<ul className="space-y-2 font-medium">
<li>
<Item href="/kb" label="Overview" />
</li>
<li>
<Item href="/kb/quickstart" label="Quickstart" />
</li>
<li>
<Collapse expanded={p.startsWith("/kb/deploy")} label="Deploy">
<li>
<Item href="/kb/deploy" label="Overview" />
</li>
<li>
<Item href="/kb/deploy/sites" label="Sites" />
</li>
<li>
<Item href="/kb/deploy/gateways" label="Gateways" />
</li>
<li>
<Item href="/kb/deploy/resources" label="Resources" />
</li>
<li>
<Item href="/kb/deploy/policies" label="Policies" />
</li>
<li>
<Item href="/kb/deploy/clients" label="Clients" />
</li>
</Collapse>
</li>
<li>
<Collapse
expanded={p.startsWith("/kb/authenticate")}
label="Authenticate"
>
<li>
<Item href="/kb/authenticate" label="Overview" />
</li>
<li>
<Item href="/kb/authenticate/email" label="Email (OTP)" />
</li>
<li>
<Item
href="/kb/authenticate/oidc"
label="OpenID Connect (OIDC)"
/>
</li>
<li>
<Item href="/kb/authenticate/google" label="Google Workspace" />
</li>
<li>
<Item
href="/kb/authenticate/user-group-sync"
label="User / Group sync"
/>
</li>
</Collapse>
</li>
<li>
<Collapse
expanded={p.startsWith("/kb/administer")}
label="Administer"
>
<li>
<Item href="/kb/administer/upgrading" label="Upgrading" />
</li>
<li>
<Item href="/kb/administer/dns" label="Configure DNS" />
</li>
<li>
<Item
href="/kb/administer/backup-restore"
label="Backup and restore"
/>
</li>
<li>
<Item
href="/kb/administer/logs"
label="Logs and troubleshooting"
/>
</li>
</Collapse>
</li>
<li>
<Collapse
expanded={p.startsWith("/kb/user-guides")}
label="User guides"
>
<li>
<Item
href="/kb/user-guides/apple-client"
label="macOS / iOS client"
/>
</li>
<li>
<Item
href="/kb/user-guides/windows-client"
label="Windows client"
/>
</li>
<li>
<Item
href="/kb/user-guides/android-client"
label="Android / ChromeOS client"
/>
</li>
<li>
<Item
href="/kb/user-guides/linux-client"
label="Linux client"
/>
</li>
</Collapse>
</li>
</ul>
</div>
</aside>
);

View File

@@ -0,0 +1,26 @@
function planBadge(plan: string) {
switch (plan.toLowerCase()) {
case "enterprise":
return (
<span
className="bg-primary-500 text-white text-xs font-semibold me-2 px-2.5 py-0.5 rounded"
title="Feature available on the Enterprise plan"
>
ENTERPRISE
</span>
);
case "starter":
return (
<span
className="bg-neutral-200 text-neutral-900 text-xs font-semibold me-2 px-2.5 py-0.5 rounded"
title="Feature available on the Starter plan"
>
STARTER
</span>
);
}
}
export default function PlanBadge({ plans }: { plans: Array<string> }) {
const plansHtml = plans.map((plan) => planBadge(plan));
return <div className="w-full justify-end flex">{plansHtml}</div>;
}

View File

@@ -6,7 +6,7 @@ export default function RequestAccessButton() {
<Link href="/product/early-access">
<button
type="button"
className="text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-sm px-5 py-2.5 bg-accent-600 hover:bg-accent-700"
className="text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-sm px-5 py-2.5 bg-accent-450 hover:bg-accent-700"
>
Request early access
</button>

View File

@@ -6,7 +6,7 @@ export default function RequestDemoButton() {
<Link href="/contact/sales">
<button
type="button"
className="text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-sm px-5 py-2.5 bg-accent-600 hover:bg-accent-700"
className="text-white font-bold tracking-tight rounded duration-0 hover:scale-105 transition transform shadow-lg text-sm px-5 py-2.5 bg-accent-450 hover:bg-accent-700"
>
Request demo
</button>

View File

@@ -1,7 +1,7 @@
import { usePathname } from "next/navigation";
import { HiBars3 } from "react-icons/hi2";
export default function SidebarToggle() {
export default function DocsSidebarToggle() {
const p = usePathname() || "";
if (p.startsWith("/docs")) {

View File

@@ -0,0 +1,23 @@
import { usePathname } from "next/navigation";
import { HiBars3 } from "react-icons/hi2";
export default function KbSidebarToggle() {
const p = usePathname() || "";
if (p.startsWith("/kb")) {
return (
<button
type="button"
data-drawer-target="kb-sidebar"
data-drawer-toggle="kb-sidebar"
aria-controls="kb-sidebar"
className="py-2 ml-2 text-neutral-800 rounded cursor-pointer md:hidden hover:text-neutral-900 hover:bg-neutral-100 focus:bg-neutral-100 focus:ring-2 focus:ring-neutral-100 "
>
<HiBars3 aria-hidden="true" className="w-6 h-6" />
<span className="sr-only">Toggle sidebar</span>
</button>
);
} else {
return null;
}
}

View File

@@ -1,7 +1,8 @@
"use client";
import Image from "next/image";
import Link from "next/link";
import SidebarToggle from "./SidebarToggle";
import DocsSidebarToggle from "./DocsSidebarToggle";
import KbSidebarToggle from "./KbSidebarToggle";
import { Navbar } from "flowbite-react";
import { usePathname } from "next/navigation";
import RequestDemoButton from "@/components/RequestDemoButton";
@@ -11,28 +12,43 @@ import { HiChevronDown } from "react-icons/hi2";
export default function RootNavbar() {
const p = usePathname() || "";
let dropdown: any = null;
let productDropdown: any = null;
let docsDropdown: any = null;
useEffect(() => {
if (!dropdown) {
dropdown = new Dropdown(
if (!productDropdown) {
productDropdown = new Dropdown(
document.getElementById("product-dropdown-menu"),
document.getElementById("product-dropdown-link")
);
}
if (!docsDropdown) {
docsDropdown = new Dropdown(
document.getElementById("docs-dropdown-menu"),
document.getElementById("docs-dropdown-link")
);
}
// Manually init flowbite's data-toggle listeners since we're using custom components
initFlowbite();
}, []);
const hideDropdown = () => {
if (!dropdown) {
dropdown = new Dropdown(
if (!productDropdown) {
productDropdown = new Dropdown(
document.getElementById("product-dropdown-menu"),
document.getElementById("product-dropdown-link")
);
}
dropdown.hide();
if (!docsDropdown) {
docsDropdown = new Dropdown(
document.getElementById("docs-dropdown-menu"),
document.getElementById("docs-dropdown-link")
);
}
productDropdown.hide();
docsDropdown.hide();
};
return (
@@ -40,7 +56,8 @@ export default function RootNavbar() {
<nav className="h-14 fixed top-0 left-0 right-0 bg-white border-b items-center flex border-neutral-200 z-50">
<div className="w-full flex flex-wrap py-2 justify-between items-center">
<div className="flex justify-start items-center">
<SidebarToggle />
{p.startsWith("/docs") ? <DocsSidebarToggle /> : null}
{p.startsWith("/kb") ? <KbSidebarToggle /> : null}
<Link href="/">
<Image
width={150}
@@ -79,28 +96,6 @@ export default function RootNavbar() {
</span>
<HiChevronDown className="w-3 h-3 mx-1" />
</button>
<Link
className={
(p.startsWith("/docs")
? "text-neutral-900 underline"
: "text-neutral-800") +
" p-2 mr-4 font-medium hover:text-neutral-900 hover:underline"
}
href="/docs"
>
Docs
</Link>
<Link
className={
(p.startsWith("/blog")
? "text-neutral-900 underline"
: "text-neutral-800") +
" p-2 mr-4 font-medium hover:text-neutral-900 hover:underline"
}
href="/blog"
>
Blog
</Link>
<div
id="product-dropdown-menu"
className="z-10 hidden bg-white divide-y divide-gray-100 rounded shadow-lg w-44"
@@ -116,7 +111,6 @@ export default function RootNavbar() {
</Link>
</li>
<li>
{/* TODO: use <Link> here, toggling dropdown */}
<Link
onClick={hideDropdown}
href="/product/early-access"
@@ -131,7 +125,6 @@ export default function RootNavbar() {
</Link>
</li>
<li>
{/* TODO: use <Link> here, toggling dropdown */}
<Link
onClick={hideDropdown}
href="/product/newsletter"
@@ -157,6 +150,73 @@ export default function RootNavbar() {
</li>
</ul>
</div>
<Link
className={
(p.startsWith("/blog")
? "text-neutral-900 underline"
: "text-neutral-800") +
" p-2 mr-4 font-medium hover:text-neutral-900 hover:underline"
}
href="/blog"
>
Blog
</Link>
<button
id="docs-dropdown-link"
className={
(p.startsWith("/docs") || p.startsWith("/kb")
? "text-neutral-900"
: "text-neutral-800") +
" hover:text-neutral-900 flex items-center justify-between p-0 sm:p-1 mr-1"
}
>
<span
className={
"hover:underline font-medium " +
(p.startsWith("/docs") || p.startsWith("/kb")
? "underline"
: "")
}
>
Docs
</span>
<HiChevronDown className="w-3 h-3 mx-1" />
</button>
<div
id="docs-dropdown-menu"
className="z-10 hidden bg-white divide-y divide-gray-100 rounded shadow-lg w-44"
>
<ul className="py-2" aria-labelledby="product-dropdown-link">
<li>
<Link
onClick={hideDropdown}
href="/kb"
className={
(p.startsWith("/kb")
? "text-neutral-900 underline"
: "text-neutral-800") +
" block px-4 py-2 font-medium hover:underline hover:bg-neutral-100 hover:text-neutral-900"
}
>
Latest Docs
</Link>
</li>
<li>
<Link
onClick={hideDropdown}
href="/docs"
className={
(p.startsWith("/docs")
? "text-neutral-900 underline"
: "text-neutral-800") +
" block px-4 py-2 font-medium hover:underline hover:bg-neutral-100 hover:text-neutral-900"
}
>
Legacy (0.7) Docs
</Link>
</li>
</ul>
</div>
<Link
className={
(p == "/pricing"

View File

@@ -6,13 +6,13 @@ export default function SupportOptions() {
<ul>
<li>
<a href="https://discourse.firez.one/?utm_source=docs.firezone.dev">
Discussion Forums
Discussion forums
</a>
: Ask questions, report bugs, and suggest features.
</li>
<li>
<a href="https://join.slack.com/t/firezone-users/shared_invite/zt-111043zus-j1lP_jP5ohv52FhAayzT6w">
Public Slack Group
Public Slack group
</a>
: join discussions, meet other users, and meet the contributors
</li>

View File

@@ -58,7 +58,7 @@ module.exports = {
typography: {
DEFAULT: {
css: {
color: firezoneColors["night-rider"][900],
color: firezoneColors["night-rider"][800],
a: {
color: firezoneColors["electric-violet"][500],
},