Announce 1.0 early access (#1791)

- Add 1.0 blogpost
- Update font to `Public Sans` since it has all weights and offers
better readability
- Various layout/style fixes
- Disable kotlin draft release job

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andrew Dryga <andrew@dryga.com>
This commit is contained in:
Jamil
2023-07-17 15:48:35 -07:00
committed by GitHub
parent fc3be9a6b3
commit 504d118539
71 changed files with 2031 additions and 1533 deletions

View File

@@ -13,10 +13,6 @@ on:
workflow_dispatch:
jobs:
kotlin_draft-release:
runs-on: ubuntu-latest
steps:
- run: 'echo "no build required"'
kotlin_build:
runs-on: ubuntu-latest
steps:

View File

@@ -14,10 +14,13 @@ repos:
- id: mixed-line-ending
args: ["--fix=lf"]
description: Forces to replace line ending by the UNIX 'lf' character.
exclude: ^website/public/images/
- id: check-yaml
- id: check-merge-conflict
- id: end-of-file-fixer
exclude: ^website/public/images/
- id: trailing-whitespace
exclude: ^website/public/images/
- id: check-merge-conflict
- id: no-commit-to-branch
args:

View File

@@ -2,5 +2,6 @@
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": false
"singleQuote": false,
"proseWrap": "always"
}

View File

@@ -2,7 +2,9 @@
See the [`legacy` branch](https://github.com/firezone/firezone/tree/legacy) for the branch tracking the latest 0.7 release.
<!-- TODO: [Read the announcement](https://www.firezone.dev/blog/announcing-1.0). -->
<!-- FIXME
[Read the announcement](https://www.firezone.dev/blog/announcing-1.0).
-->
<p align="center">
<img src="https://user-images.githubusercontent.com/52545545/144147936-39f3e416-8ba0-4f24-915e-f0515f85bb64.png" alt="firezone logo" width="305"/>

View File

@@ -10,31 +10,31 @@
"lint": "next lint"
},
"dependencies": {
"@docsearch/react": "3",
"@heroicons/react": "^2.0.18",
"@docsearch/react": "^3.5.1",
"@mdx-js/loader": "^2.3.0",
"@mdx-js/react": "^2.3.0",
"@next/mdx": "^13.4.4",
"@next/mdx": "^13.4.10",
"@types/mdx": "^2.0.5",
"@types/node": "20.2.3",
"@types/react": "18.2.6",
"@types/react-dom": "18.2.4",
"@types/react-syntax-highlighter": "^15.5.7",
"asciinema-player": "^3.4.0",
"asciinema-player": "^3.5.0",
"autoprefixer": "10.4.14",
"fast-xml-parser": "^4.2.5",
"flowbite": "^1.6.5",
"flowbite-react": "^0.4.4",
"flowbite": "^1.7.0",
"flowbite-react": "^0.4.11",
"highlight.js": "^11.8.0",
"md5": "^2.3.0",
"next": "13.4.4",
"next-hubspot": "^1.1.6",
"next-sitemap": "^4.1.3",
"next-sitemap": "^4.1.8",
"postcss": "8.4.23",
"posthog-js": "^1.67.1",
"posthog-js": "^1.71.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-fast-marquee": "^1.6.0",
"react-icons": "^4.10.1",
"react-markdown": "^8.0.7",
"react-syntax-highlighter": "^15.5.0",
"rehype-autolink-headings": "^6.1.1",

949
website/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,5 @@
<svg width="294" height="184" viewBox="0 0 294 184" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M146.5 0C191.799 37.5635 144.904 120.815 161.453 154.43C127.446 105.847 173.779 64.0952 146.5 0Z" fill="#FFF9F5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M171.62 72.3025C201.229 91.4568 165.687 136.337 184.608 147.825C203.77 159.46 201.602 111.106 228.06 123.51C200.512 114.179 211.94 171.748 177.805 164.087C138.742 155.319 187.323 93.4581 171.62 72.3025Z" fill="#FFF9F5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 137.888C56.3928 93.1552 133.206 164.939 169.455 169.425C216.071 175.192 203.653 121.53 226.986 123.53C205.486 126.111 218.392 182.233 170.324 183.967C117.976 185.856 65.7497 106.395 9.64537e-05 137.888H0Z" fill="#FFF9F5"/>
</svg>

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -0,0 +1,23 @@
import Image from "next/image";
import Post from "@/components/Blog/Post";
import Content from "./readme.mdx";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Firezone 1.0 • Firezone Blog",
description: "Announcing the 1.0 early access program",
};
export default function Page() {
return (
<Post
authorName="Jamil Bou Kheir"
authorTitle="Founder & CEO"
authorEmail="jamil@firezone.dev"
title="Firezone 1.0"
date="July 14, 2023"
>
<Content />
</Post>
);
}

View File

@@ -0,0 +1,245 @@
import Image from "next/image";
<span className="font-semibold">Firezone comes from humble roots.</span>
It was born out of necessity -- as an engineer at Cisco I found myself in need
of an easy way to deploy and manage a VPN server for security automation. I had
used OpenVPN in the past and loathed it, so this time I decided to try a fast,
new contender called [WireGuard](https://www.wireguard.com).
While WireGuard itself is a marvelous feat of engineering, it provides only
basic building blocks. Users wishing to deploy WireGuard as a replacement for
their existing remote access VPN will find themselves building automation to
distribute keys, manage users, configure routing tables, and so on.
And I found myself doing just that. It wasn't particularly difficult automation
to build, but it was tedious and error-prone. Although the benefits of WireGuard
were worth the price of admission, colleagues and I agreed -- _wouldn't it be
great if a tool existed to do this for us?_
So after one particularly grueling refactoring project involving a major
dependency in an ancient codebase that had become "suddenly" deprecated, I
decided it was time for something new. I resigned, picked up a book on
Elixir/Phoenix, and, rejoicing at the opportunity to learn some new tech,
started building what became the first version of Firezone.
<Image
src="/images/nostalgia-show-hn.png"
alt="Show HN"
width={1412}
height={168}
className="mx-auto shadow rounded"
/>
When we [launched on Hacker News](https://news.ycombinator.com/item?id=28683231)
nearly two years ago, we never envisioned Firezone to be more than a simple tool
deploying your own WireGuard-based VPN server.
Fast-forward
[4,500 GitHub stars](https://github.com/firezone/firezone/stargazers), a
[Y Combinator backed funding round](https://techcrunch.com/2022/03/30/ycombinator-open-source-startups-winter-22-demo-day/),
and [130 releases](https://github.com/firezone/firezone/releases) later --
Firezone has now grown into something more than just a self-hosted tool to
manage your WireGuard configurations.
We now count over <strong>3,000</strong> Firezone instances running in the wild
(possibly much more -- we allow users to
[disable telemetry](/docs/reference/telemetry)) securing private networks for
hobbyists, schools, non-profits, and businesses with hundreds of employees.
<Image
src="/images/wai-7-2-23.png"
alt="weekly active instances"
width={600}
height={600}
className="mx-auto shadow rounded border border-neutral-200"
/>
To be clear, Firezone is successful in large part because WireGuard itself is
successful. In an industry brimming with enterprise security bloatware and
endless acronyms, WireGuard's a breath of fresh air. Every issue I've thought I
had with it turned out to be user error. How we ever got by without it is a
mystery to me.
But I could go on and on about WireGuard's strengths. Let's back up for a minute
-- what is a VPN, and why is one needed at all? To answer that we'll need to go
back to the formation of the Internet itself.
#### The purpose of a VPN
You see, the early Internet had only a handful of entities connected to it --
connecting to the Internet was expensive, after all. Typically only banks,
universities, and other large institutions could justify the cost.
So when you connected your organization to the Internet and began receiving
packets, it was clear which entity it was from based on its allocated IPv4
address range. Since there were so few entities connected, it was clear who you
communicated with. It was clear who to contact (and blame) in case any issues
arose.
But, as access to the Internet became cheaper, more types of entities could
afford to connect. As more entities connected, the number of resources on the
Internet grew, and its
[value increased quadratically](https://en.wikipedia.org/wiki/Metcalfe%27s_law).
Soon, all types of entities wanted to connect -- local governments, schools,
small businesses. Internet Service Providers began offering connections to mere
individuals. Eventually there were so many entities on the Internet that
identifying who you were communicating with was no longer trivial. Since you
couldn't easily know who you were talking to, you couldn't always trust them to
behave.
And thus, firewalls were born. Firewalls keep packets of information out from
entities you don't wish to communicate with and let packets in from those you
do.
<object type="image/svg+xml" data="/images/firewall-block.svg">
<Image
width={600}
height={400}
src="/images/firewall-block.svg"
alt="firewall animation"
className="mx-auto"
/>
</object>
And this worked well for some time. However, as the Internet grew even larger, a
problem arose: firewalls required you to know _in advance_ who you'd like to
communicate with, adding them to your configuration, and likewise removing the
ones you didn't. As you might imagine, it quickly became unwieldy to keep these
configurations up to date.
So a clever solution was developed: what if you could dynamically add and remove
entities to the firewall configuration on the fly?
And thus, stateful firewalls were born. I should pause here and clarify that
stateful firewalls are sometimes confused with
[Network Address Translation (NAT)](https://en.wikipedia.org/wiki/Network_address_translation),
since they're often found on the same device. But there's an important
distinction: A stateful firewall _remembers_ stuff it's seen in order to to
update its configuration dynamically, whereas NAT can behave statically.
Stateful firewalls exist in nearly every consumer router and datacenter gateway
connected to the Internet today. There's a very high likelihood the Internet
connection you're reading this from is behind one or several of them. They've
been largely successful at serving their intended purpose.
<object type="image/svg+xml" data="/images/stateful-firewall.svg">
<Image
width={600}
height={400}
src="/images/stateful-firewall.svg"
alt="firewall animation"
className="mx-auto"
/>
</object>
However, this post wouldn't be very interesting if we stopped there.
You see, there's still one fundamental problem with stateful firewalls,
particularly as it relates to remote access. For two-way communication to occur,
one entity (namely the one "behind" the firewall) must always initiate. This
means that entities outside the firewall can never communicate to those inside,
_even if the outside entities are trusted_. To do that, you'd have to add a
configuration rule to expect an outside entity to talk in, which means we're
back to managing firewall configurations again.
This is where VPNs come in. A VPN _disguises_ an outside entity as an inside
one, thereby allowing communication by default.
After the firewall authenticates the outside entity, they both agree to package
up the information packets between each other so that the Internet routers in
between forward them properly. This creates a kind of network within a network:
the original packets with their network attributes are packaged into another
packet with more network attributes, thus giving this technology its name:
Virtual Private Network.
So a VPN is just a technology that authenticates an outside, untrusted entity to
a protected network. And WireGuard is the best VPN technology we have so far. As
far as VPNs go, there's nothing faster, more secure, or more robust.
#### The challenge with trust
But there's a security risk with this arrangement: once the outsider is
authenticated, all of the entities inside the firewall perimeter now trust its
packets completely. What if an untrusted entity managed to obtain a VPN
connection? One misconfiguration, stolen credential, or hijacked connection
would result in a perimeter breach. Not good.
The solution to this problem is aptly named
[Zero Trust Architecture (ZTA)](https://en.wikipedia.org/wiki/Zero_trust_security_model).
The idea with ZTA is to do away with using network zone (or perceived network
zone in the case of a VPN) for determining whether to trust communication. All
network zones are considered _untrusted_ by default. Suddenly the network
perimeter we had before vanishes -- inside and outside entities are equally
untrusted.
Then how does an entity come to be trusted? We still authenticate them as usual,
but there's a key difference: with ZTA, we authenticate entities each time the
communication is requested, on the fly. Not once at the perimeter. And since the
perimeter is gone, the protected entity itself (or a proxy) authenticates the
untrusted entity. But wait, what happened to the firewall?
This presents a dilemma. If we use a firewall to protect entities, they're
shielded outside the perimeter, but left unprotected inside the perimeter. And
if we choose ZTA, we only trust entities we've authenticated directly, but must
expose ourselves to _all_ outside entities in order to do so.
#### The solution
Firezone solves this problem with a third entity, called an access broker, which
works as follows:
<object type="image/svg+xml" data="/images/firezone-1.0.svg">
<Image
width={600}
height={600}
src="/images/firezone-1.0.svg"
alt="firewall animation"
className="mx-auto"
/>
</object>
1. The protected entity is deployed behind a stateful firewall.
1. The protected entity then initiates and maintains a bi-directional control
channel to the broker.
1. Whenever an untrusted entity wants access to the protected resource, it
notifies the broker.
1. If the broker determines access is granted, it notifies the protected entity
that the now-trusted entity is allowed in.
1. The protected entity then initiates communication to the now-trusted entity
_directly_. The stateful firewall's configuration is dynamically updated,
allowing communication to happen from the now-trusted entity to the protected
entity.
So we're able to both authenticate the untrusted entity at the time of request,
yet also keep our protected entity behind a firewall to keep it invisible to the
public Internet. In fast, _both_ entities can live behind a stateful firewall
and the technique would still work -- the principles are the same.
As it turns out, this approach is nothing new. It's how web browsers and VoIP
systems have established peer to peer connections for low-latency audio and
video chat for decades.
Firezone 1.0 makes this process transparent, but also 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
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.
And while we were at it, we decided to build a slew of new features for 1.0 as
well, most notably a cloud-managed admin portal and native clients. Check our
[product roadmap](/product/roadmap) for more details on what's coming in 1.0.
#### Next steps
To help ensure a bug-free experience for our users, we'll be rolling out 1.0 in
phases, starting with an early access preview aiming to launch mid-Q3 of this
year. If you're interesting in joining the early access program,
[head here to fill out the form](/product/early-access) and we'll be in touch.
Until then, feel free to [follow our roadmap](/product/roadmap) or
[watch our GitHub repository](https://www.github.com/firezone/firezone) for
updates. Comments welcome!

View File

@@ -4,18 +4,27 @@ import Image from "next/image";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="pt-14 flex flex-col">
<div className="bg-neutral-50 mx-auto w-screen text-center">
<div className="bg-gradient-to-b from-primary-900 to-neutral-900 mx-auto w-screen text-center">
<Image
alt="Firezone logo"
width={125}
height={125}
src="/images/logo-main.svg"
alt="Firezone logo light"
width={147}
height={92}
src="/images/logo-main-light-primary.svg"
className="py-12 mx-auto"
/>
</div>
{children}
<div className="bg-neutral-50 dark:bg-neutral-800 pt-8">
<NewsletterSignup />
<div className="bg-neutral-50 w-screen">
<div className="px-4 py-8 max-w-md md:max-w-screen-lg mx-auto">
<h2 className="justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-4xl">
Firezone Newsletter
</h2>
<p className="mx-auto mb-8 text-center max-w-2xl text-neutral-900 md:mb-12 text-lg sm:text-xl">
Sign up with your email to receive roadmap updates, how-tos, and
product announcements from the Firezone team.
</p>
<NewsletterSignup />
</div>
</div>
</div>
);

View File

@@ -1,131 +1,73 @@
import { Metadata } from "next";
import gravatar from "@/lib/gravatar";
import Link from "next/link";
import Image from "next/image";
import { ArrowRightIcon } from "@heroicons/react/20/solid";
import NewsletterSignup from "@/components/NewsletterSignup";
import SummaryCard from "@/components/Blog/SummaryCard";
export const metadata: Metadata = {
title: "Blog • Firezone",
description: "Announcements, tutorials, and more from the Firezone team.",
};
export default function Page() {
return (
<section className="bg-neutral-50 dark:bg-neutral-900">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<section className="bg-neutral-100 ">
<div className="py-8 px-4 mx-auto max-w-md md:max-w-screen-md lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-sm text-center lg:mb-16 mb-8">
<h1 className="justify-center mb-4 text-3xl lg:text-6xl tracking-tight font-extrabold text-neutral-900 dark:text-white">
Firezone Blog
<h1 className="justify-center mb-4 text-3xl lg:text-6xl tracking-tight font-extrabold text-neutral-900 ">
Blog
</h1>
<p className="text-neutral-800 sm:text-xl dark:text-neutral-100">
<p className="text-neutral-900 text-lg sm:text-xl ">
Announcements, tutorials, and more from the Firezone team.
</p>
</div>
<div className="grid gap-8 lg:grid-cols-2">
<article className="p-6 bg-neutral-100 rounded-lg border border-neutral-200 shadow-md dark:bg-neutral-800 dark:border-neutral-700">
<div className="flex justify-between items-center mb-5">
<span className="bg-primary-450 text-white text-xs font-medium inline-flex items-center px-2.5 py-0.5 rounded dark:bg-primary-200 dark:text-primary-800">
<svg
className="mr-1 w-3 h-3"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M2 5a2 2 0 012-2h8a2 2 0 012 2v10a2 2 0 002 2H4a2 2 0 01-2-2V5zm3 1h6v4H5V6zm6 6H5v2h6v-2z"
clipRule="evenodd"
></path>
<path d="M15 7h1a2 2 0 012 2v5.5a1.5 1.5 0 01-3 0V7z"></path>
</svg>
Announcement
</span>
<span className="text-sm font-semibold">October 17, 2022</span>
</div>
<h2 className="mb-2 text-2xl font-bold tracking-tight text-neutral-900 dark:text-white">
<Link href="/blog/release-0-6-0">Release 0.6.0</Link>
</h2>
<p className="mb-5 font-medium text-neutral-800 dark:text-neutral-100">
Today, I'm excited to announce we've closed the{" "}
<Link href="https://github.com/firezone/firezone/issues/260">
first public issue{" "}
</Link>
on our GitHub repository, more than a year after it was originally
opened: Containerization support! We're also releasing preliminary
support for SAML 2.0 identity providers like Okta and OneLogin.
<div className="grid divide-y">
<SummaryCard
title="Firezone 1.0"
date="July 15, 2023"
href="/blog/firezone-1-0"
authorName="Jamil Bou Kheir"
authorAvatarSrc={gravatar("jamil@firezone.dev")}
type="Announcement"
>
<p className="mb-2 font-semibold">
Firezone comes from humble roots.
</p>
<div className="flex justify-between items-center">
<div className="flex items-center space-x-4">
<Image
width={28}
height={28}
className="w-7 h-7 rounded-full"
src={gravatar("jamil@firezone.dev")}
alt="Jamil Bou Kheir avatar"
/>
<span className="font-medium dark:text-white">
Jamil Bou Kheir
</span>
</div>
<Link
href="/blog/release-0-6-0"
className="inline-flex items-center font-medium text-primary-900 dark:text-primary-100 hover:underline"
>
Read more
<ArrowRightIcon className="ml-2 w-4 h-4" />
</Link>
</div>
</article>
<article className="p-6 bg-neutral-100 rounded-lg border border-neutral-200 shadow-md dark:bg-neutral-800 dark:border-neutral-700">
<div className="flex justify-between items-center mb-5 text-neutral-800">
<span className="bg-primary-450 text-white text-xs font-medium inline-flex items-center px-2.5 py-0.5 rounded dark:bg-primary-200 dark:text-primary-800">
<svg
className="mr-1 w-3 h-3"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M2 5a2 2 0 012-2h8a2 2 0 012 2v10a2 2 0 002 2H4a2 2 0 01-2-2V5zm3 1h6v4H5V6zm6 6H5v2h6v-2z"
clipRule="evenodd"
></path>
<path d="M15 7h1a2 2 0 012 2v5.5a1.5 1.5 0 01-3 0V7z"></path>
</svg>
Announcement
</span>
<span className="text-sm font-semibold">July 25, 2022</span>
</div>
<h2 className="mb-2 text-2xl font-bold tracking-tight text-neutral-900 dark:text-white">
<Link href="/blog/release-0-5-0">Release 0.5.0</Link>
</h2>
<p className="mb-5 font-medium text-neutral-800 dark:text-neutral-100">
As the first post on our new blog, we thought it'd be fitting to
kick things off with a release announcement. So without further
ado, we're excited to announce: Firezone{" "}
<Link href="https://github.com/firezone/firezone/releases">
0.5.0 is here
</Link>
! It's packed with new features, bug fixes, and other improvements
more on that below.
<p>
When we launched on Hacker News nearly two years ago, we never
envisioned Firezone to be more than a simple tool for managing
your WireGuard configurations.
</p>
<div className="flex justify-between items-center">
<div className="flex items-center space-x-4">
<Image
width={28}
height={28}
className="w-7 h-7 rounded-full"
src={gravatar("jamil@firezone.dev")}
alt="Jamil Bou Kheir avatar"
/>
<span className="font-medium dark:text-white">
Jamil Bou Kheir
</span>
</div>
<Link
href="/blog/release-0-5-0"
className="inline-flex items-center font-medium text-primary-900 dark:text-primary-100 hover:underline"
>
Read more
<ArrowRightIcon className="ml-2 w-4 h-4" />
</Link>
</div>
</article>
</SummaryCard>
<SummaryCard
title="Release 0.6.0"
date="October 17, 2022"
href="/blog/release-0-6-0"
authorName="Jamil Bou Kheir"
authorAvatarSrc={gravatar("jamil@firezone.dev")}
type="Announcement"
>
Today, I'm excited to announce we've closed the first public issue
on our GitHub repository, more than a year after it was originally
opened: Containerization support! We're also releasing preliminary
support for SAML 2.0 identity providers like Okta and OneLogin.
</SummaryCard>
<div></div>
<SummaryCard
title="Release 0.5.0"
date="July 25, 2022"
href="/blog/release-0-5-0"
authorName="Jamil Bou Kheir"
authorAvatarSrc={gravatar("jamil@firezone.dev")}
type="Announcement"
>
As the first post on our new blog, we thought it'd be fitting to
kick things off with a release announcement. So without further ado,
we're excited to announce: Firezone 0.5.0 is here! It's packed with
new features, bug fixes, and other improvements more on that
below.
</SummaryCard>
</div>
</div>
</section>

View File

@@ -7,10 +7,13 @@ import SupportOptions from "@/components/SupportOptions";
Firezone can be safely backed up and restored in a couple of minutes under most
circumstances.
<Alert color="info">
This guide is written for Firezone deployments using **Docker Engine** on
**Linux** only.
</Alert>
<Alert
color="info"
html={`
This guide is written for Firezone deployments using <strong>Docker Engine</strong>
on <strong>Linux</strong> only.
`}
/>
Unless your hosting provider supports taking live VM snapshots, you'll need to
stop Firezone before backing it up. This ensures the Postgres data directory is

View File

@@ -2,9 +2,12 @@ import Alert from "@/components/DocsAlert";
# Debug Logs
<Alert color="info">
This article is written for Docker based deployments of Firezone.
</Alert>
<Alert
color="info"
html={`
This article is written for Docker based deployments of Firezone.
`}
/>
Docker deployments of Firezone consist of 3 running containers:

View File

@@ -11,17 +11,24 @@ do so using the same bootstrap scripts that were used when installing Firezone.
## Regenerate secrets
<Alert color="warning">
Replacing the `DATABASE_ENCRYPTION_KEY` will render all encrypted data in the
database useless. This **will** break your Firezone install unless you are
starting with an empty database. You have been warned.
</Alert>
<Alert
color="danger"
html={`
Replacing the <code>DATABASE_ENCRYPTION_KEY</code> will render all encrypted data in the
database useless. This <strong>will</strong> break your Firezone install unless you are
starting with an empty database. You have been warned.
`}
/>
<Alert color="warning">
Replacing `GUARDIAN_SECRET_KEY`, `SECRET_KEY_BASE`, `LIVE_VIEW_SIGNING_SALT`,
`COOKIE_SIGNING_SALT`, and `COOKIE_ENCRYPTION_SALT` will reset all browser
sessions and REST API tokens.
</Alert>
<Alert
color="warning"
html={`
Replacing <code>GUARDIAN_SECRET_KEY</code>, <code>SECRET_KEY_BASE</code>,
<code>LIVE_VIEW_SIGNING_SALT</code>,
<code>COOKIE_SIGNING_SALT</code>, and <code>COOKIE_ENCRYPTION_SALT</code>
will reset all browser sessions and REST API tokens.
`}
/>
Use the procedure below to regenerate secrets:
@@ -51,11 +58,14 @@ sudo firezone-ctl reconfigure
## Regenerate WireGuard private key
<Alert color="warning">
<Alert
color="warning"
html={`
Replacing the WireGuard private key will render all existing device configs
invalid. Only do so if you're prepared to also regenerate device configs after
regenerating the WireGuard private key.
</Alert>
`}
/>
To regenerate WireGuard private key, simply move or rename the private key file.
Firezone will generate a new one on next start.

View File

@@ -5,9 +5,12 @@ import Alert from "@/components/DocsAlert";
Firezone can be uninstalled using the steps below.
<Alert color="warning">
This will irreversibly destroy ALL Firezone data and can't be undone.
</Alert>
<Alert
color="warning"
html={`
This will irreversibly destroy ALL Firezone data and can't be undone.
`}
/>
<TabsGroup>
<TabsItem title="Docker" active>

View File

@@ -7,11 +7,14 @@ import Image from "next/image";
Upgrading Firezone will pause all VPN sessions and temporarily bring down the
web UI.
<Alert color="info">
Automatic rollbacks are still under development. We recommend backing up
relevant [files and folders](/docs/reference/file-and-directory-locations)
before upgrading in case anything goes wrong.
</Alert>
<Alert
color="info"
html={`
Automatic rollbacks are still under development. We recommend backing up
relevant <a href="/docs/reference/file-and-directory-locations">files and folders</a>
before upgrading in case anything goes wrong.
`}
/>
Follow the steps below to upgrade Firezone:

View File

@@ -7,14 +7,17 @@ the Firezone portal. Administrators can add users and assign their passwords on
the `/users` page. See [Add users](/docs/user-guides/add-users) for more
details.
<Alert color="warning">
Although local authentication is quick and easy to get started with, you can
limit attack surface by [disabling local
authentication](#disabling-local-authentication) altogether. See our
[OIDC](/docs/authenticate/oidc) or [SAML](/docs/authenticate/saml) guides for
details. For production deployments it's usually a good idea to **disable
local authentication** and enforce MFA through your identity provider.
</Alert>
<Alert
color="warning"
html={`
Although local authentication is quick and easy to get started with, you can
limit attack surface by <a href="#disabling-local-authentication">disabling local
authentication</a> altogether. See our
<a href="/docs/authenticate/oidc">OIDC</a> or <a href="/docs/authenticate/saml">SAML
</a> guides for details. For production deployments it's usually a good idea to <strong>disable
local authentication</strong> and enforce MFA through your identity provider.
`}
/>
If you choose to keep Local authentication enabled, we recommend
[enabling TOTP-based MFA ](/docs/authenticate/multi-factor) for any accounts

View File

@@ -10,10 +10,13 @@ Firezone supports the following authentication methods:
1. [SSO authentication via OpenID Connect](/docs/authenticate/oidc)
1. [SSO authentication via SAML 2.0](/docs/authenticate/saml)
<Alert color="info">
If your Identity Provider doesn't work with the methods listed above, [contact
us](/contact/sales) about a custom integration.
</Alert>
<Alert
color="info"
html={`
If your Identity Provider doesn't work with the methods listed above,
<a href="/contact/sales">contact us</a> about a custom integration.
`}
/>
## Integrate an SSO provider
@@ -47,7 +50,8 @@ Config ID for that particular provider.
For example, the OIDC config below:
<center>
<Image className="mx-auto"
<Image
className="mx-auto"
width={509}
height={509}
alt="config-oidc"

View File

@@ -3,11 +3,14 @@ import Image from "next/image";
# Enable SSO with JumpCloud (SAML 2.0)
<Alert color="info">
This guide assumes you have completed the prerequisite steps (e.g. generate
self-signed X.509 certificates) outlined
[here](/docs/authenticate/saml#prerequisites).
</Alert>
<Alert
color="info"
html={`
This guide assumes you have completed the prerequisite steps (e.g. generate
self-signed X.509 certificates) outlined
<a href="/docs/authenticate/saml#prerequisites">here</a>.
`}
/>
Firezone supports Single Sign-On (SSO) using JumpCloud through the generic SAML
2.0 connector. This guide will walk you through how to configure the
@@ -37,7 +40,8 @@ the bottom-right.
Your JumpCloud configuration should now resemble the following:
<Image className="mx-auto"
<Image
className="mx-auto"
alt="jumpcloud saml"
width={960}
height={540}
@@ -68,7 +72,8 @@ filling out the following information:
Your Firezone configuration should now resemble the following:
<Image className="mx-auto"
<Image
className="mx-auto"
alt="firezone saml"
width={960}
height={540}

View File

@@ -3,11 +3,14 @@ import Alert from "@/components/DocsAlert";
# Enable SSO with Okta (SAML 2.0)
<Alert color="info">
This guide assumes you have completed the prerequisite steps (e.g. generate
self-signed X.509 certificates) outlined
[here](/docs/authenticate/saml#prerequisites).
</Alert>
<Alert
color="info"
html={`
This guide assumes you have completed the prerequisite steps (e.g. generate
self-signed X.509 certificates) outlined
<a href="/docs/authenticate/saml#prerequisites">here</a>.
`}
/>
Firezone supports Single Sign-On (SSO) using Okta through the generic SAML 2.0
connector. This guide will walk you through how to configure the integration.
@@ -31,7 +34,8 @@ values during setup:
[Okta's documentation](https://help.okta.com/oie/en-us/Content/Topics/Apps/Apps_App_Integration_Wizard_SAML.htm)
contains additional details on the purpose of each configuration setting.
<Image className="mx-auto"
<Image
className="mx-auto"
src="/images/okta-saml.png"
width={960}
height={540}
@@ -58,7 +62,8 @@ filling out the following information:
| Require signed envelopes | Checked. | |
| Auto create users | Default `false` | Enable this setting to automatically create users when signing in with this connector for the first time. Disable to manually create users. |
<Image className="mx-auto"
<Image
className="mx-auto"
alt="firezone saml"
width={960}
height={540}

View File

@@ -3,11 +3,14 @@ import Image from "next/image";
# Enable SSO with OneLogin (SAML 2.0)
<Alert color="info">
This guide assumes you have completed the prerequisite steps (e.g. generate
self-signed X.509 certificates) outlined
[here](/docs/authenticate/saml#prerequisites).
</Alert>
<Alert
color="info"
html={`
This guide assumes you have completed the prerequisite steps (e.g. generate
self-signed X.509 certificates) outlined
<a href="/docs/authenticate/saml#prerequisites">here</a>.
`}
/>
Firezone supports Single Sign-On (SSO) using OneLogin through the generic SAML
2.0 connector. This guide will walk you through how to configure the
@@ -35,7 +38,8 @@ The following fields should be filled out on this page:
[OneLogin's docs](https://onelogin.service-now.com/support?id=kb_article&sys_id=912bb23edbde7810fe39dde7489619de&kb_category=93e869b0db185340d5505eea4b961934)
provide a good overview of each field's purpose.
<Image className="mx-auto"
<Image
className="mx-auto"
alt="onelogin configs"
width={960}
height={540}
@@ -62,7 +66,8 @@ filling out the following information:
| Require signed envelopes | Checked. | |
| Auto create users | Default `false` | Enable this setting to automatically create users when signing in with this connector for the first time. Disable to manually create users. |
<Image className="mx-auto"
<Image
className="mx-auto"
alt="onelogin saml"
width={960}
height={540}

View File

@@ -4,38 +4,43 @@ import Alert from "@/components/DocsAlert";
Building from source allows you to bring Firezone to unsupported platforms.
<Alert color="warning">
You're entering unsupported territory. This is not for the faint of
heart and will require being able to figure out snags you may hit on your own.
<Alert
color="warning"
html={`
You're entering unsupported territory. This is not for the faint of heart and
will require being able to figure out snags you may hit on your own. If you're
very comfortable with your environment of choice, then read on to learn how to
build Firezone from source.
`}
/>
If you're very comfortable with your environment of choice, then read on to
learn how to build Firezone from source.
</Alert>
<Alert color="info">
You will need to setup your own service management for Firezone (eg.
`runit`, `systemd`, shell scripts). You will also need to install and configure
your own database (eg. `postgres`) and reverse proxy (eg. `caddy`, `nginx`).
Info about database configuration is
[here](/docs/deploy/advanced/external-database/#configure-firezone-to-connect),
<Alert
color="info"
html={`
You will need to setup your own service management for Firezone (eg. runit,
systemd, shell scripts). You will also need to install and configure your
own database (eg. postgres) and reverse proxy (eg. caddy, nginx). Info
about database configuration is
<a href="/docs/deploy/advanced/external-database/#configure-firezone-to-connect">here</a>,
and info about configuring a reverse proxy is
[here](/docs/deploy/advanced/reverse-proxy/#proxy-requirements).
</Alert>
<a href="/docs/deploy/advanced/reverse-proxy/#proxy-requirements">here</a>.
`}
/>
## Prerequisites
<Alert color="info">
Check the `.tool-versions` file
[here](https://github.com/firezone/firezone/blob/legacy/.tool-versions) for
the versions we use for Erlang, Elixir, and Node. If your system supports it,
you can install these using
[asdf-vm](https://asdf-vm.com/guide/getting-started.html) using a similar
`.tool-versions` of your own to match versions. Your system's package manager
may have them as well.
</Alert>
<Alert
color="info"
html={`
Check the <code>.tool-versions</code> file
<a href="https://github.com/firezone/firezone/blob/legacy/.tool-versions">here</a> for
the versions we use for Erlang, Elixir, and Node. If your system supports it,
you can install these using
<a href="https://asdf-vm.com/guide/getting-started.html">asdf-vm</a> using a similar
<code>.tool-versions</code> of your own to match versions. Your system's package manager
may have them as well.
`}
/>
**These must be available in the user's path that runs Firezone.**
@@ -90,9 +95,12 @@ up. Once that's done, you can use `firezone start` to start Firezone and run
it to log into Firezone from a web browser to start setting up your brand new
custom instance that you built by hand with a little bit of elbow grease :)
<Alert color="info">
As mentioned at the top, it's recommended to use some sort of service
management to start and stop Firezone easily without having to manually do it
using the `firezone` binary directly. But the choice is yours, since you're in
control!
</Alert>
<Alert
color="info"
html={`
As mentioned at the top, it's recommended to use some sort of service
management to start and stop Firezone easily without having to manually do it
using the <code>firezone</code> binary directly. But the choice is yours, since
you're in control!
`}
/>

View File

@@ -17,12 +17,15 @@ database services like Amazon RDS. See the
[configuration ](#configure-firezone-to-connect) section below for more
information configuring Firezone with an external DB.
<Alert color="warning">
Configuring Firezone to use an external database can be complicated and
error-prone. We recommend using the bundled Postgres for Omnibus-based
deployments or the official Postgres Docker image for Docker-based deployments
if possible.
</Alert>
<Alert
color="warning"
html={`
Configuring Firezone to use an external database can be complicated and
error-prone. We recommend using the bundled Postgres for Omnibus-based
deployments or the official Postgres Docker image for Docker-based deployments
if possible.
`}
/>
## Configure Firezone to Connect
@@ -48,11 +51,14 @@ the DB (fields in bold required):
For more information, see the
[environment variable reference ](/docs/reference/env-vars).
<Alert color="info">
The official `postgres` docker image can be configured by setting environment
variables for the container. See the Postgres image
[documentation](https://hub.docker.com/_/postgres) for more details.
</Alert>
<Alert
color="info"
html={`
The official <code>postgres</code> docker image can be configured by setting environment
variables for the container. See the Postgres image
<a href="https://hub.docker.com/_/postgres">documentation</a> for more details.
`}
/>
</TabsItem>
<TabsItem title="Omnibus">

View File

@@ -2,13 +2,16 @@ import Alert from "@/components/DocsAlert";
# Custom Reverse Proxy
<Alert color="warning">
Using a custom reverse proxy is an advanced configuration. The default bundled
Nginx proxy (Omnibus-based deployments) and Caddy (Docker-based deployments)
is suitable for the vast majority of use cases and is recommended for most
users. There are important security risks if the reverse proxy is not set up
correctly.
</Alert>
<Alert
color="warning"
html={`
Using a custom reverse proxy is an advanced configuration. The default bundled
Nginx proxy (Omnibus-based deployments) and Caddy (Docker-based deployments)
is suitable for the vast majority of use cases and is recommended for most
users. There are important security risks if the reverse proxy is not set up
correctly.
`}
/>
## Introduction
@@ -33,24 +36,24 @@ reverse proxy.
[X-Forwarded-For header works](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For),
this is needed to parse the actual client's IP address to prevent IP spoofing.
<Alert color="info">
The `external_trusted_proxies` list automatically implicitly includes the
<Alert color="info" html={`
The <code>external_trusted_proxies</code> list automatically implicitly includes the
following private CIDR ranges, even if they're not specified in the
configuration file:
- `127.0.0.0/8`
- `10.0.0.0/8`
- `172.16.0.0/12`
- `192.168.0.0/16`
- `::1/128`
- `fc00::/7`
<ul>
<li><code>127.0.0.0/8</code></li>
<li><code>10.0.0.0/8</code></li>
<li><code>172.16.0.0/12</code></li>
<li><code>192.168.0.0/16</code></li>
<li><code>::1/128</code></li>
<li><code>fc00::/7</code></li>
</ul>
This means any web requests originating from these IPs are automatically ignored
from the `X-Forwarded-For` headers. If you're accessing Firezone from any IPs in
this range (as seen by the Firezone web app), be sure to add them to the
`default['firezone']['phoenix']['clients']` configuration option instead.
</Alert>
from the <code>X-Forwarded-For</code> headers. If you're accessing Firezone from
any IPs in this range (as seen by the Firezone web app), be sure to add them to
the <code>default['firezone']['phoenix']['clients']</code> configuration option
instead. `} />
Read more about the configuration options
[here](/docs/reference/configuration-file).

View File

@@ -32,11 +32,14 @@ Docker offers a number of benefits over the old
- `443/tcp`: To access the web UI.
- `51820/udp`: VPN traffic listen port.
<Alert color="warning">
Before deploying Firezone in **production**, you'll need a valid DNS record
pointing to this instance. See [Prepare to
Deploy](/docs/deploy/#prepare-to-deploy) if you haven't done this already.
</Alert>
<Alert
color="warning"
html={`
Before deploying Firezone in <strong>production</strong>, you'll need a valid DNS record
pointing to this instance. See <a href="/docs/deploy/#prepare-to-deploy">Prepare to
Deploy</a> if you haven't done this already.
`}
/>
## Step 2: Install server
@@ -155,10 +158,13 @@ on start.
## Step 5: Install client apps
<Alert color="info">
Firezone currently uses WireGuard's [open-source client
apps](https://www.wireguard.com/install).
</Alert>
<Alert
color="info"
html={`
Firezone currently uses WireGuard's <a href="https://www.wireguard.com/install">
open-source client apps</a>.
`}
/>
Once successfully deployed, users and devices can be added to connect to the VPN
server:

View File

@@ -4,14 +4,15 @@ import SupportOptions from "@/components/SupportOptions";
# Install Firezone with Omnibus
<Alert color="warning">
<Alert
color="warning"
html={`
Due to Omnibus being EOL'd by Chef in 2024, Docker is now the
preferred method of deploying Firezone. See the
[Docker deployment guide](/docs/deploy/docker) to get started.
<a href="/docs/deploy/docker">Docker deployment guide</a> to get started.
Read below to continue with an Omnibus-based deployment.
</Alert>
`}
/>
Firezone can be deployed on a server running a supported
[Linux distribution ](/docs/deploy/omnibus/supported-platforms) in a few minutes
@@ -29,18 +30,24 @@ to get started.
- `443/tcp`: To access the web UI.
- `51820/udp`: VPN traffic listen port.
<Alert color="warning">
Before deploying Firezone in **production**, you'll need a valid DNS record
pointing to this instance. See [Prepare to
Deploy](/docs/deploy/#prepare-to-deploy) if you haven't done this already.
</Alert>
<Alert
color="warning"
html={`
Before deploying Firezone in <strong>production</strong>, you'll need a valid DNS
record pointing to this instance. See <a href="/docs/deploy/#prepare-to-deploy">
Prepare to Deploy</a> if you haven't done this already.
`}
/>
<Alert color="info">
Firezone modifies the kernel netfilter and routing tables. Other programs that
modify the Linux routing table or firewall may interfere with Firezones
operation. For help troubleshooting connectivity issues, see the
[troubleshooting guide](/docs/administer/troubleshoot).
</Alert>
<Alert
color="info"
html={`
Firezone modifies the kernel netfilter and routing tables. Other programs that
modify the Linux routing table or firewall may interfere with Firezones
operation. For help troubleshooting connectivity issues, see the
<a href="/docs/administer/troubleshoot">troubleshooting guide</a>.
`}
/>
## Step 2: Install server

View File

@@ -94,12 +94,13 @@ You have two options for deploying Firezone:
Docker is the easiest way to install, manage, and upgrade Firezone and is the
preferred method of deployment.
<Alert color="warning">
<Alert
color="warning"
html={`
Chef Infra Client, the configuration system Chef Omnibus relies on, has been
[scheduled for End-of-Life in 2024](https://docs.chef.io/versions). As such,
<a href="https://docs.chef.io/versions">scheduled for End-of-Life in 2024</a>. As such,
support for Omnibus-based deployments will be removed starting with Firezone
0.8. To transition to Docker from Omnibus today, follow our
[migration guide](/docs/administer/migrate).
</Alert>
<a href="/docs/administer/upgrade">migration guide</a>.
`}
/>

View File

@@ -46,11 +46,14 @@ authentication altogether by setting
deployments). Local authentication can also be disabled on the
`/settings/security` page.
<Alert color="warning">
Ensure you've set up a working [OIDC](/docs/authenticate/oidc) or
[SAML](/docs/authenticate/saml)-based authentication provider before disabling
the local authentication method.
</Alert>
<Alert
color="warning"
html={`
Ensure you've set up a working <a href="/docs/authenticate/oidc">OIDC</a>
or <a href="/docs/authenticate/saml">SAML</a>-based authentication provider before disabling
the local authentication method.
`}
/>
## Reporting security issues

View File

@@ -6,7 +6,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
<DocsSidebar />
<main className="max-w-screen-xl 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 dark:format-invert">
<article className="max-w-none format format-sm sm:format-base lg:format-lg ">
{children}
</article>
</div>

View File

@@ -2,11 +2,14 @@ import Alert from "@/components/DocsAlert";
# Omnibus configuration options
<Alert color="warning">
<Alert
color="warning"
html={`
This reference is written for Omnibus-based deployments of Firezone. For
Docker-based deployments visit the [Environment
Variables](/docs/reference/env-vars) page.
</Alert>
Docker-based deployments visit the <a href="/docs/reference/env-vars">
Environment Variables</a> page.
`}
/>
To configure Omnibus-based deployments of Firezone:

View File

@@ -20,7 +20,10 @@ its output to a file instead:
docker compose -f $HOME/.firezone/docker-compose.yml exec firezone bin/create-api-token > fz_token
```
<Alert color="warning">
API tokens generated from the CLI are owned by the primary administrator
specified by the `DEFAULT_ADMIN_EMAIL` environment variable.
</Alert>
<Alert
color="warning"
html={`
API tokens generated from the CLI are owned by the primary administrator
specified by the <code>DEFAULT_ADMIN_EMAIL</code> environment variable.
`}
/>

View File

@@ -70,13 +70,16 @@ instance of Firezone to our telemetry server:
## How to disable telemetry
<Alert color="info">
We _rely_ on product analytics to make Firezone better for everyone. Leaving
telemetry enabled is the **single most valuable contribution** you can make to
Firezones development. That said, we understand some users have higher
privacy or security requirements and would prefer to disable telemetry
altogether. If thats you, keep reading.
</Alert>
<Alert
color="info"
html={`
We <i>rely</i> on product analytics to make Firezone better for everyone. Leaving
telemetry enabled is the <code>single most valuable contribution</code> you can make to
Firezones development. That said, we understand some users have higher
privacy or security requirements and would prefer to disable telemetry
altogether. If thats you, keep reading.
`}
/>
Telemetry is enabled by default. To completely disable product telemetry:

View File

@@ -32,7 +32,8 @@ To self generate a device config file, visit the domain provided by your
Firezone administrator. This URL will be specific to your company (in this
example it is `https://firezone.example.com`)
<Image className="mx-auto"
<Image
className="mx-auto"
alt="firezone okta sso login"
src="/images/firezone-okta-sso-login.gif"
width={960}
@@ -44,7 +45,8 @@ example it is `https://firezone.example.com`)
Open the WireGuard client and import the `.conf` file. Activate the VPN session
by toggling the `Activate` switch.
<Image className="mx-auto"
<Image
className="mx-auto"
alt="activate tunnel"
src="/images/activate-tunnel.gif"
width={960}
@@ -63,7 +65,8 @@ session, follow the steps below. You will need:
### Step 1: Deactivate VPN session
<Image className="mx-auto"
<Image
className="mx-auto"
alt="wireguard deactivate"
src="/images/wireguard-deactivate.png"
width={960}
@@ -76,7 +79,8 @@ Visit the URL of your Firezone portal and sign in using credentials provided by
your network admin. If you are already logged into the portal, click the
`Reauthenticate` button, then sign in again.
<Image className="mx-auto"
<Image
className="mx-auto"
alt="re-authenticate"
width={960}
height={540}
@@ -85,7 +89,8 @@ your network admin. If you are already logged into the portal, click the
### Step 3: Activate VPN session
<Image className="mx-auto"
<Image
className="mx-auto"
alt="activate session"
src="/images/activate-session.png"
width={960}
@@ -97,15 +102,16 @@ your network admin. If you are already logged into the portal, click the
The following steps can be used on Linux devices to import the WireGuard
configuration profile using Network Manager CLI (`nmcli`).
<Alert color="info">
<Alert
color="info"
html={`
Importing the configuration file using the Network Manager GUI may fail
with the following error if the profile has IPv6 support enabled:
```
<code>
ipv6.method: method "auto" is not supported for WireGuard
```
</Alert>
</code>
`}
/>
### Step 1: Install the WireGuard tools
@@ -142,7 +148,8 @@ To self generate a device config file, visit the domain provided by your
Firezone administrator. This URL will be specific to your company (in this
example it is `https://firezone.example.com`)
<Image className="mx-auto"
<Image
className="mx-auto"
alt="firezone okta sso login"
src="/images/firezone-sso-okta-login.gif"
width={960}
@@ -157,15 +164,16 @@ Using `nmcli`, import the downloaded configuration file:
sudo nmcli connection import type wireguard file /path/to/configuration.conf
```
<Alert color="info">
<Alert
color="info"
html={`
The WireGuard connection/interface will match the name of the
configuration file. If required, the connection can be renamed after import:
```bash
<code>
nmcli connection modify [old name] connection.id [new name]
```
</Alert>
</code>
`}
/>
### Step 4: Connect/disconnect

View File

@@ -16,7 +16,8 @@ AllowedIPs can be set globally on the `/settings/default` page or individually
for each device during creation. Changes will only apply to new WireGuard tunnel
configurations generated by Firezone.
<Image className="mx-auto"
<Image
className="mx-auto"
alt="set split tunneling defaults"
src="/images/set-split-tunneling-defaults.png"
width={960}
@@ -32,10 +33,13 @@ Some examples of values in this field are:
will be routed to the VPN server. In this example, the CIDR range for the
`ap-northeast-2` AWS region was used.
<Alert color="info">
When deciding where to route a packet, Firezone chooses the egress interface
corresponding to the most specific route first.
</Alert>
<Alert
color="info"
html={`
When deciding where to route a packet, Firezone chooses the egress interface
corresponding to the most specific route first.
`}
/>
## Step 2 (optional): Set the DNS server(s)
@@ -46,10 +50,13 @@ the `/settings/default` page to override this value.
For split tunneling, this may be desired if you run a DNS server that resolves
internal hosts to private IPs reachable via Firezone.
<Alert color="info">
<Alert
color="info"
html={`
If you wish to resolve DNS queries over the encrypted VPN tunnel
(recommended), ensure the DNS IPs are included in `AllowedIPs`.
</Alert>
(recommended), ensure the DNS IPs are included in <code>AllowedIPs</code>.
`}
/>
## Step 3: Regenerate the device configurations

View File

@@ -0,0 +1,49 @@
import Link from "next/link";
export default function NotFound() {
return (
<section className="bg-neutral-100 h-max pt-24">
<div className="py-8 px-4 mx-auto max-w-screen-xl">
<div className="mx-auto max-w-screen-xs text-center">
<h1 className="mb-4 text-4xl justify-center tracking-tight font-extrabold text-neutral-900">
Page not found.
</h1>
<p className="mb-4 text-lg text-neutral-900">
Sorry, but the page you were looking for cannot be found.
</p>
<p className="mb-4 text-lg text-neutral-900">
You can go{" "}
<Link
href="/"
className="inline-flex text-accent-500 underline hover:no-underline"
>
back to the home page
</Link>
, the{" "}
<Link
href="/blog"
className="inline-flex text-accent-500 underline hover:no-underline"
>
blog home
</Link>
, the{" "}
<Link
href="/docs"
className="inline-flex text-accent-500 underline hover:no-underline"
>
docs home
</Link>
, or{" "}
<Link
href="mailto:help@firezone.dev"
className="text-accent-500 underline hover:no-underline"
>
contact us
</Link>{" "}
if you're still having trouble.
</p>
</div>
</div>
</section>
);
}

View File

@@ -4,13 +4,13 @@ import Link from "next/link";
import Image from "next/image";
import ActionLink from "@/components/ActionLink";
import {
ArrowLongRightIcon,
CheckIcon,
HomeIcon,
RocketLaunchIcon,
WrenchScrewdriverIcon,
GlobeAltIcon,
} from "@heroicons/react/24/solid";
HiArrowLongRight,
HiCheck,
HiHome,
HiRocketLaunch,
HiWrenchScrewdriver,
HiGlobeAlt,
} from "react-icons/hi2";
import JoinOurCommunity from "@/components/JoinOurCommunity";
export const metadata: Metadata = {
@@ -21,16 +21,16 @@ export const metadata: Metadata = {
export default function Page() {
return (
<>
<section className="bg-neutral-100 pt-24 dark:bg-neutral-900">
<div className="px-4 py-8 mx-auto max-w-screen-xl text-center lg:py-16 lg:px-12">
<h1 className="mb-4 text-4xl justify-center font-extrabold tracking-tight leading-none text-neutral-900 md:text-5xl lg:text-6xl dark:text-white tracking-tight">
<section className="bg-gradient-to-b from-primary-50 to-neutral-100 pt-24">
<div className="px-4 py-8 mx-auto max-w-screen-xl sm:text-center lg:py-16 lg:px-12">
<h1 className="mb-4 md:text-6xl text-5xl justify-center font-extrabold tracking-tight leading-none text-neutral-900">
Fast, effortless secure access.
</h1>
<p className="mb-8 font-normal text-neutral-800 md:text-lg lg:text-xl sm:px-16 xl:px-48 dark:text-neutral-100">
<h2 className="mb-8 text-xl tracking-tight font-medium text-neutral-900 sm:px-16 xl:px-48 ">
Firezone is an open-source remote access platform built on
WireGuard®, a modern VPN protocol that's 4-6x faster than OpenVPN.
Deploy on your infrastructure and start onboarding users in minutes.
</p>
</h2>
<div className="flex flex-col mb-8 lg:mb-16 space-y-4 sm:flex-row sm:justify-center sm:space-y-0 sm:space-x-4">
<Link href="/docs/deploy">
<button
@@ -38,7 +38,7 @@ export default function Page() {
className="inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-bold text-center text-white rounded-md bg-gradient-to-br from-accent-700 to-accent-600 hover:scale-105 duration-0 transform transition"
>
Deploy now
<ArrowLongRightIcon className="ml-2 -mr-1 w-6 h-6" />
<HiArrowLongRight className="ml-2 -mr-1 w-6 h-6" />
</button>
</Link>
</div>
@@ -58,11 +58,11 @@ export default function Page() {
</video>
</div>
<div className="flex justify-center items-center p-8 mt-8">
<h3 className="text-2xl font-bold text-neutral-800 dark:text-white">
<h3 className="text-2xl tracking-tight font-bold text-neutral-800 ">
Trusted by organizations like
</h3>
</div>
<div className="gap-8 max-w-screen-xl grid grid-cols-1 justify-items-center sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6 px-16 py-8">
<div className="gap-8 max-w-screen-xl grid justify-items-center sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6 px-16 py-8">
<Image
alt="bunq logo"
src="/images/bunq-logo.png"
@@ -106,7 +106,7 @@ export default function Page() {
{/* Features sections */}
<section className="border-t border-neutral-200 bg-gradient-to-b from-white via-neutral-50 to-white py-24">
<div className="mx-4 flex flex-col justify-center items-center">
<h2 className="justify-center mb-4 text-4xl tracking-tight font-bold text-neutral-900 dark:text-white">
<h2 className="justify-center mb-4 text-4xl tracking-tight font-bold text-neutral-900 ">
A modern alternative to legacy VPNs
</h2>
</div>
@@ -114,7 +114,7 @@ export default function Page() {
{/* Feature section 1 */}
<div className="gap-8 items-center py-8 px-4 mx-auto max-w-screen-xl lg:grid lg:grid-cols-2 xl:gap-16 sm:py-16 lg:px-6 ">
<div>
<h4 className="mb-8 text-lg font-semibold tracking-tight text-primary-450 dark:text-white">
<h4 className="mb-8 text-lg font-semibold tracking-tight text-primary-450 ">
SIMPLE TO MANAGE
</h4>
<h3 className="text-2xl font-semibold tracking-tight text-neutral-900">
@@ -129,20 +129,20 @@ export default function Page() {
</p>
<ul role="list" className="my-6 lg:mb-0 space-y-4">
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Integrate any identity provider to enforce 2FA / MFA
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Define user-scoped access rules
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Manage access with a snappy admin dashboard
</span>
</li>
@@ -157,8 +157,8 @@ export default function Page() {
</div>
{/* Feature section 2 */}
<div className="gap-8 items-center py-8 px-4 mx-auto max-w-screen-xl lg:grid lg:grid-cols-2 xl:gap-16 sm:py-16 lg:px-6 ">
<div className="flex flex-col justify-between">
<div className="gap-8 py-8 px-4 mx-auto max-w-screen-xl flex flex-col-reverse lg:grid lg:grid-cols-2 xl:gap-16 sm:py-16 lg:px-6 ">
<div className="flex flex-col">
<Image
className="rounded-md shadow-md"
width={600}
@@ -167,14 +167,14 @@ export default function Page() {
src="/images/feature-2.png"
/>
<Link
className="mt-4 mx-auto text-accent-600 hover:underline"
className="mt-4 lg:mx-auto text-accent-600 hover:underline"
href="https://core.ac.uk/download/pdf/322886318.pdf"
>
Performance comparison of VPN solutions (Osswald et al.)
</Link>
</div>
<div>
<h4 className="mb-8 text-lg font-semibold tracking-tight text-primary-450 dark:text-white">
<h4 className="mb-8 text-lg font-semibold tracking-tight text-primary-450 ">
FAST AND LIGHTWEIGHT
</h4>
<h3 className="text-2xl font-semibold tracking-tight text-neutral-900">
@@ -188,8 +188,8 @@ export default function Page() {
</p>
<ul role="list" className="my-6 lg:mb-0 space-y-4">
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
<Link
className="text-accent-600 hover:underline"
href="https://www.wireguard.com/protocol/"
@@ -199,8 +199,8 @@ export default function Page() {
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Auditable and{" "}
<Link
className="text-accent-600 hover:underline"
@@ -211,8 +211,8 @@ export default function Page() {
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
<Link
className="text-accent-600 hover:underline"
href="https://www.wireguard.com/performance/"
@@ -229,7 +229,7 @@ export default function Page() {
{/* Feature section 3 */}
<div className="gap-8 items-center pt-8 px-4 mx-auto max-w-screen-xl lg:grid lg:grid-cols-2 xl:gap-16 sm:pt-16 lg:px-6 ">
<div>
<h4 className="mb-8 text-lg font-semibold tracking-tight text-primary-450 dark:text-white">
<h4 className="mb-8 text-lg font-semibold tracking-tight text-primary-450 ">
RUN ANYWHERE
</h4>
<h3 className="text-2xl font-semibold tracking-tight text-neutral-900">
@@ -242,20 +242,20 @@ export default function Page() {
</p>
<ul role="list" className="my-6 lg:mb-0 space-y-4">
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
VPC, data center, or on-prem
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Auto-renewing SSL certs from Let's Encrypt via ACME
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Flexible and configurable
</span>
</li>
@@ -279,17 +279,17 @@ export default function Page() {
<section className="border-t border-neutral-200 bg-gradient-to-b from-neutral-100 to-primary-50 py-24">
<div className="mx-4 flex flex-col justify-center items-center">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-900 dark:text-white">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-900 ">
Integrate your identity provider to enforce 2FA / MFA
</h2>
<p className="my-4 text-xl max-w-screen-lg text-center text-primary-900 dark:text-neutral-100">
<p className="my-4 text-xl max-w-screen-lg text-center text-primary-900 ">
Only allow connections from authenticated users and automatically
disable access for employees who have left. Firezone integrates with
any OIDC and SAML 2.0 compatible identity provider for single
sign-on (SSO).
</p>
</div>
<div className="mx-auto gap-8 max-w-screen-xl grid grid-cols-1 justify-items-center sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6 px-16 pt-8">
<div className="mx-auto gap-8 max-w-screen-xl grid justify-items-center sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6 px-16 pt-8">
<Link href="/docs/authenticate/oidc/keycloak/">
<Image
width={150}
@@ -343,10 +343,10 @@ export default function Page() {
<section className="border-t border-neutral-200 py-24 bg-white">
<div className="mx-4 flex flex-col justify-center items-center">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-900 dark:text-white">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-900 ">
Who can benefit using Firezone?
</h2>
<p className="my-4 text-xl max-w-screen-lg text-center text-primary-900 dark:text-neutral-100">
<p className="my-4 text-xl max-w-screen-lg sm:text-center text-primary-900 ">
Easy to deploy and manage for individuals and organizations alike.
Only allow connections from authenticated users and automatically
disable access for employees who have left. Firezone integrates with
@@ -357,8 +357,8 @@ export default function Page() {
<div className="gap-4 items-center pt-8 px-4 mx-auto max-w-screen-xl lg:grid lg:grid-cols-2 xl:gap-8 sm:pt-16 lg:px-6 ">
<div className="bg-neutral-100 p-8 rounded-md shadow-md">
<div className="flex items-center space-x-2.5">
<HomeIcon className="flex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 dark:text-neutral-100">
<HiHome className="flex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 ">
Individuals and homelab users
</h3>
</div>
@@ -368,26 +368,26 @@ export default function Page() {
</p>
<ul role="list" className="my-6 lg:mb-0 space-y-4">
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Effortless to deploy on any infrastructure
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Community plan supports unlimited devices
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Lightweight with minimal resource usage
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Open-source and self-hosted
</span>
</li>
@@ -401,8 +401,8 @@ export default function Page() {
</div>
<div className="bg-neutral-100 p-8 rounded-md shadow-md">
<div className="flex items-center space-x-2.5">
<RocketLaunchIcon className="flex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 dark:text-neutral-100">
<HiRocketLaunch className="flex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 ">
Growing businesses
</h3>
</div>
@@ -412,26 +412,26 @@ export default function Page() {
</p>
<ul role="list" className="my-6 lg:mb-0 space-y-4">
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Integrate your identity provider
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Quickly onboard/offboard employees{" "}
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Segment access for contractors
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
High performance, reduce bottlenecks
</span>
</li>
@@ -445,8 +445,8 @@ export default function Page() {
</div>
<div className="bg-neutral-100 p-8 rounded-md shadow-md">
<div className="flex items-center space-x-2.5">
<GlobeAltIcon className=" lex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 dark:text-neutral-100">
<HiGlobeAlt className=" lex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 ">
Remote organizations
</h3>
</div>
@@ -456,26 +456,26 @@ export default function Page() {
</p>
<ul role="list" className="my-6 lg:mb-0 space-y-4">
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Require periodic re-authentication
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Enforce MFA / 2FA
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Self-serve user portal
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Export logs to your observability platform
</span>
</li>
@@ -489,8 +489,8 @@ export default function Page() {
</div>
<div className="bg-neutral-100 p-8 rounded-md shadow-md">
<div className="flex items-center space-x-2.5">
<WrenchScrewdriverIcon className=" lex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 dark:text-neutral-100">
<HiWrenchScrewdriver className=" lex-shrink-0 w-5 h-5 text-primary-450" />
<h3 className="text-xl tracking-tight font-bold text-primary-900 ">
Technical IT teams
</h3>
</div>
@@ -500,26 +500,26 @@ export default function Page() {
</p>
<ul role="list" className="my-6 lg:mb-0 space-y-4">
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Built on WireGuard®
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
No vendor lock-in
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Supports OIDC and SAML 2.0
</span>
</li>
<li className="flex space-x-2.5">
<CheckIcon className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold dark:text-primary-100" />
<span className="leading-tight text-lg text-primary-900 dark:text-neutral-100">
<HiCheck className="flex-shrink-0 w-5 h-5 text-primary-900 font-bold " />
<span className="leading-tight text-lg text-primary-900 ">
Flexible and configurable
</span>
</li>
@@ -538,10 +538,10 @@ export default function Page() {
<section className="border-t border-neutral-200 py-24 bg-gradient-to-b from-accent-800 to-accent-700">
<div className="flex flex-col justify-center items-center">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-50 dark:text-white">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-50 ">
Ready to get started?
</h2>
<p className="my-4 font-semibold text-xl max-w-screen-md text-center text-neutral-200 dark:text-neutral-100">
<p className="my-4 font-semibold text-xl max-w-screen-md text-center text-neutral-200 ">
Set up secure access and start onboarding users in minutes.
<br />
Copy and paste the command below on any Docker-supported host.
@@ -552,7 +552,7 @@ export default function Page() {
codeString="bash <(curl -fsSL https://github.com/firezone/firezone/raw/legacy/scripts/install.sh)"
/>
</div>
<p className="mt-8 border-y font-semibold text-xl w-12 max-w-screen-md text-center text-neutral-200 dark:text-neutral-100">
<p className="mt-8 border-y font-semibold text-xl w-12 max-w-screen-md text-center text-neutral-200 ">
OR
</p>
<div className="flex mt-8">
@@ -561,7 +561,7 @@ export default function Page() {
className="inline-flex shadow-lg justify-center items-center py-3 px-5 text-base font-bold text-center text-white rounded-md bg-gradient-to-br from-primary-500 to-primary-450 hover:scale-105 duration-0 transform transition"
>
<Link href="/contact/sales">Contact sales</Link>
<ArrowLongRightIcon className="ml-2 -mr-1 w-6 h-6" />
<HiArrowLongRight className="ml-2 -mr-1 w-6 h-6" />
</button>
</div>
</div>

View File

@@ -1,39 +1,40 @@
import EarlyAccessForm from "@/components/EarlyAccessForm"
import Link from "next/link"
import Image from "next/image"
import { Metadata } from "next"
import { CheckCircleIcon } from "@heroicons/react/24/solid"
import ActionLink from "@/components/ActionLink"
import EarlyAccessForm from "@/components/EarlyAccessForm";
import Link from "next/link";
import Image from "next/image";
import { Metadata } from "next";
import { HiCheckCircle } from "react-icons/hi2";
import ActionLink from "@/components/ActionLink";
export const metadata: Metadata = {
title: "1.0 Early Access • Firezone",
description: "Get early access to Firezone 1.0.",
}
title: "Early Access • Firezone",
description:
"Register for early access to try new Firezone features before they're released.",
};
export default function EarlyAccess() {
return (
<div className="bg-neutral-100 dark:bg-neutral-800">
<div className="pt-14 bg-neutral-100">
<div className="py-8 px-4 mx-auto max-w-screen-2xl lg:py-16 lg:px-6">
<div className="grid flex grid-cols-1 gap-4 lg:grid-cols-2">
<div className="flex items-center">
<div className="flex-none">
<h1 className="mb-4 text-4xl font-extrabold tracking-tight text-neutral-900 sm:text-6xl dark:text-white">
<div className="grid flex gap-4 lg:grid-cols-2">
<div className="flex items-center justify-center lg:justify-start">
<div className="flex-wrap px-2">
<h1 className="mb-4 text-4xl sm:text-5xl justify-center lg:justify-end font-extrabold tracking-tight text-neutral-900 xl:text-6xl">
Request early access
</h1>
<p className="mx-auto mb-4 text-neutral-800 sm:text-xl dark:text-neutral-100">
<strong>Firezone 1.0 is coming! </strong>
Sign up below to get early access.
</p>
{/* FIXME: Remove when announced
<p className="sm:text-xl dark:text-neutral-100">
<h2 className="flex flex-wrap mb-4 text-lg tracking-tight text-neutral-900 sm:text-xl justify-center lg:justify-end">
<strong className="mr-1">Firezone 1.0 is coming!</strong>
<span className="font-medium">
Sign up below to get early access.
</span>
</h2>
<p className="text-lg sm:text-xl lg:justify-end">
<ActionLink
href="/blog/announcing-1.0"
className="justify-end flex items-center text-accent-500 hover:no-underline underline"
href="/blog/firezone-1-0"
className="mb-8 justify-center lg:justify-end flex items-center text-accent-500 hover:no-underline underline"
>
Read the announcement
</ActionLink>
</p>
*/}
</div>
</div>
<div className="flex flex-row-reverse items-baseline space-x-reverse -space-x-8">
@@ -61,25 +62,25 @@ export default function EarlyAccess() {
<section className="bg-gradient-to-b from-white to-primary-50 border-t border-neutral-200 pb-14">
<div className="mx-auto lg:max-w-screen-lg max-w-screen-sm">
<div className="py-14 mx-auto">
<h2 className="justify-center mb-8 sm:mb-16 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-4xl dark:text-neutral-50">
<h2 className="justify-center mb-8 sm:mb-16 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-4xl">
1.0 Timeline
</h2>
<ol className="px-4 items-center sm:flex">
<li className="relative mb-6 sm:mb-0">
<div className="flex items-center">
<div className="z-10 flex items-center justify-center font-semibold w-6 h-6 bg-accent-600 text-neutral-50 rounded-full ring-0 ring-neutral-300 dark:bg-blue-900 ring-8 dark:ring-neutral-900 shrink-0">
<div className="z-10 flex items-center justify-center font-semibold w-6 h-6 bg-accent-600 text-neutral-50 rounded-full ring-0 ring-neutral-300 ring-8 shrink-0">
1
</div>
<div className="hidden sm:flex w-full bg-neutral-300 h-0.5 dark:bg-neutral-700"></div>
<div className="hidden sm:flex w-full bg-neutral-300 h-0.5"></div>
</div>
<div className="mt-3 sm:pr-8">
<h3 className="text-lg font-semibold text-neutral-900 dark:text-white">
<h3 className="text-lg font-semibold text-neutral-900">
Announcement
</h3>
<time className="block mb-2 text-sm font-normal leading-none text-neutral-700 dark:text-neutral-300">
<time className="block mb-2 text-sm font-normal leading-none text-neutral-700">
Early Q3 2023
</time>
<p className="text-base font-normal text-neutral-800 dark:text-neutral-200">
<p className="text-base font-normal text-neutral-800">
Firezone 1.0 is announced to the public. Early access
signups open.
</p>
@@ -87,38 +88,38 @@ export default function EarlyAccess() {
</li>
<li className="relative mb-6 sm:mb-0">
<div className="flex items-center">
<div className="z-10 flex items-center font-semibold justify-center w-6 h-6 text-neutral-900 bg-white rounded-full ring-0 ring-neutral-300 dark:bg-blue-900 ring-8 dark:ring-neutral-900 shrink-0">
<div className="z-10 flex items-center font-semibold justify-center w-6 h-6 text-neutral-900 bg-white rounded-full ring-0 ring-neutral-300 ring-8 shrink-0">
2
</div>
<div className="hidden sm:flex w-full bg-neutral-300 h-0.5 dark:bg-neutral-700"></div>
<div className="hidden sm:flex w-full bg-neutral-300 h-0.5"></div>
</div>
<div className="mt-3 sm:pr-8">
<h3 className="text-lg font-semibold text-neutral-900 dark:text-white">
<h3 className="text-lg font-semibold text-neutral-900">
Beta Testing
</h3>
<time className="block mb-2 text-sm font-normal leading-none text-neutral-700 dark:text-neutral-300">
<time className="block mb-2 text-sm font-normal leading-none text-neutral-700">
Mid Q3 2023
</time>
<p className="text-base font-normal text-neutral-800 dark:text-neutral-200">
<p className="text-base font-normal text-neutral-800">
Early access users are invited to beta test the 1.0 release.
</p>
</div>
</li>
<li className="relative mb-6 sm:mb-0">
<div className="flex items-center">
<div className="z-10 flex items-center font-semibold justify-center w-6 h-6 text-neutral-900 bg-white rounded-full ring-0 ring-neutral-300 dark:bg-blue-900 ring-8 dark:ring-neutral-900 shrink-0">
<div className="z-10 flex items-center font-semibold justify-center w-6 h-6 text-neutral-900 bg-white rounded-full ring-0 ring-neutral-300 ring-8 shrink-0">
3
</div>
<div className="hidden sm:flex w-full bg-neutral-300 h-0.5 dark:bg-neutral-700"></div>
<div className="hidden sm:flex w-full bg-neutral-300 h-0.5"></div>
</div>
<div className="mt-3 sm:pr-8">
<h3 className="text-lg font-semibold text-neutral-900 dark:text-white">
<h3 className="text-lg font-semibold text-neutral-900">
Public Release
</h3>
<time className="block mb-2 text-sm font-normal leading-none text-neutral-700 dark:text-neutral-300">
<time className="block mb-2 text-sm font-normal leading-none text-neutral-700">
Q4 2023
</time>
<p className="text-base font-normal text-neutral-800 dark:text-neutral-200">
<p className="text-base font-normal text-neutral-800">
Firezone 1.0 is released to the general public.
</p>
</div>
@@ -126,7 +127,7 @@ export default function EarlyAccess() {
</ol>
</div>
<div className="pt-14 mx-auto max-w-screen-lg">
<h2 className="justify-center mb-8 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-4xl dark:text-neutral-50">
<h2 className="justify-center mb-8 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-4xl">
Join our early access program
</h2>
</div>
@@ -134,5 +135,5 @@ export default function EarlyAccess() {
</div>
</section>
</div>
)
);
}

View File

@@ -0,0 +1,20 @@
import NewsletterSignup from "@/components/NewsletterSignup";
export default function Page() {
return (
<div className="bg-neutral-100 ">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-md sm:text-center">
<h1 className="justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-6xl">
Firezone Newsletter
</h1>
<p className="mx-auto mb-8 max-w-2xl text-neutral-900 md:mb-12 text-lg sm:text-xl">
Sign up with your email to receive roadmap updates, how-to guides,
and product announcements from the Firezone team.
</p>
</div>
<NewsletterSignup />
</div>
</div>
);
}

View File

@@ -1,20 +1,10 @@
import NewsletterSignup from "@/components/NewsletterSignup";
import { Metadata } from "next";
import Page from "./_page";
export default function Page() {
return (
<div className="bg-neutral-100 dark:bg-neutral-800">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-md sm:text-center">
<h1 className="justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-6xl dark:text-white">
Firezone Newsletter
</h1>
<p className="mx-auto mb-8 max-w-2xl text-neutral-800 md:mb-12 sm:text-xl dark:text-neutral-100">
Sign up with your email to receive roadmap updates, how-tos, and
product announcements from the Firezone team.
</p>
</div>
<NewsletterSignup />
</div>
</div>
);
}
export const metadata: Metadata = {
title: "Newsletter Signup • Firezone",
description:
"Sign up to receive roadmap updates, how-to guides, and product announcements from the Firezone team.",
};
export default Page;

View File

@@ -0,0 +1,370 @@
"use client";
import { Metadata } from "next";
import Link from "next/link";
import CommitMarquee from "@/components/CommitMarquee";
import ActionLink from "@/components/ActionLink";
import JoinOurCommunity from "@/components/JoinOurCommunity";
import { HiMegaphone, HiBeaker } from "react-icons/hi2";
import { XMLParser } from "fast-xml-parser";
import { useState, useEffect } from "react";
import GitHubHtml from "@/components/GitHubHtml";
export const metadata: Metadata = {
title: "Product Roadmap • Firezone",
description: "Recently shipped, in progress, and future updates to Firezone.",
};
function RoadmapItem({
title,
href,
type,
date,
entryId,
children,
}: {
href: string;
title: string;
type: string;
date?: string;
entryId?: string;
children: React.ReactNode;
}) {
function badge(type: string) {
switch (type) {
case "release":
return (
<span className="bg-accent-600 text-white text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
case "1.0":
case "feature":
return (
<span className="bg-primary-450 text-white text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
case "refactor":
case "website":
return (
<span className="bg-neutral-800 text-white text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
case "docs":
return (
<span className="bg-neutral-100 text-neutral-800 text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
}
}
return (
<li
key={entryId}
className="shadow-sm bg-white rounded-sm shadow-sm p-4 mb-4 hover:shadow-md"
>
<h5 className="text-lg font-semibold">
<Link
href={href}
className="text-accent-500 underline hover:no-underline"
>
{title}
</Link>
</h5>
<div className="pb-4">{children}</div>
<div className="flex items-center justify-between">
{date ? (
<span className="text-xs font-semibold px-2.5 py-0.5 bg-neutral-200 text-neutral-800">
{new Date(date!).toDateString()}
</span>
) : (
<span></span>
)}
{badge(type)}
</div>
</li>
);
}
export default function Page() {
const parser = new XMLParser({ ignoreAttributes: false });
const [xml, setXml] = useState<any>({ feed: { entry: [] } });
useEffect(() => {
fetch("/api/github/firezone/firezone/releases.atom")
.then((response) => response.text())
.then((str) => parser.parse(str))
.then((data) => {
setXml(data);
})
.catch((error) => console.error(error));
}, []);
return (
<div className="bg-neutral-100">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-md">
<h1 className="sm:justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-6xl ">
Product Roadmap
</h1>
<h2 className="mx-auto sm:text-center mb-8 max-w-2xl tracking-tight font-medium text-neutral-900 md:mb-12 sm:text-xl ">
Take a peek below to learn what we're working on and how you can get
involved.
</h2>
</div>
<div className="grid md:grid-cols-3 mx-auto max-w-screen-lg divide-x">
<div className="p-6">
<h3 className="text-neutral-900 tracking-tight font-bold text-2xl mb-4">
Shipped
</h3>
<p className="text-lg text-neutral-900 mb-6">
Updates we've recently shipped.
</p>
<div className="mb-4">
<h4 className="border-b border-neutral-200 mb-2 text-xl tracking-tight font-semibold text-neutral-800">
Recent Releases
</h4>
<ul className="flex flex-col">
{xml.feed.entry.slice(0, 3).map((entry: any) => {
return (
<RoadmapItem
entryId={entry.id}
title={entry.title}
href={entry.link["@_href"]}
type="release"
date={entry.updated}
>
<GitHubHtml html={entry.content["#text"]} />
</RoadmapItem>
);
})}
</ul>
</div>
{/* TODO: Consider automating this with the GitHub API */}
<div className="mb-4">
<h4 className="border-b border-neutral-200 mb-2 text-xl tracking-tight font-semibold text-neutral-800">
Website / Docs
</h4>
<ul className="flex flex-col">
<RoadmapItem
title="1.0 early access page"
href="https://github.com/firezone/firezone/pull/1733"
type="website"
date="2023-07-06T17:56:03Z"
>
We've added a new{" "}
<Link
href="/product/early-access"
className="text-accent-500 underline hover:no-underline"
>
early access page
</Link>{" "}
to allow users to sign up to test new Firezone features and
releases.
</RoadmapItem>
<RoadmapItem
title="Team page"
href="https://github.com/firezone/firezone/pull/1731"
type="website"
date="2023-07-05T16:08:36Z"
>
A new{" "}
<Link
href="/team"
className="text-accent-500 underline hover:no-underline"
>
team page
</Link>{" "}
has been added to showcase the team behind Firezone.
</RoadmapItem>
<RoadmapItem
title="Brand colors"
href="https://github.com/firezone/firezone/pull/1728"
type="website"
date="2023-07-03T23:32:41Z"
>
Our website now sports a new color palette, font, and spacing
consistent with the Firezone product.
</RoadmapItem>
</ul>
</div>
</div>
<div className="p-6">
<h3 className="text-neutral-900 tracking-tight font-bold text-2xl mb-4">
In progress
</h3>
<p className="text-lg text-neutral-900 mb-6">
Things we're actively working on and plan to ship in the next
release or two.
</p>
<div className="mb-4">
<div className="p-2 bg-primary-100 border border-primary-200 mb-4">
<HiBeaker className="inline-block w-4 h-4 mr-1 text-primary-450" />
<Link
href="/product/early-access"
className="text-accent-500 underline hover:no-underline"
>
Sign up for early access
</Link>{" "}
to test new Firezone features and releases.
</div>
<h4 className="border-b border-neutral-200 mb-2 text-xl tracking-tight font-semibold text-neutral-800">
Firezone 1.0
</h4>
<ul className="flex flex-col">
<RoadmapItem
title="Automated provisioning"
href="https://github.com/firezone/firezone/issues/1437"
type="feature"
>
Automated user and group provisioning via just-in-time (JIT)
provisioning or SCIM 2.0.
</RoadmapItem>
<RoadmapItem
title="Authentication overhaul"
href="https://github.com/firezone/firezone/issues/1123"
type="refactor"
>
More robust support for SAML 2.0, OIDC, and magic link
authentication methods.
</RoadmapItem>
<RoadmapItem
title="Group-based access policies"
href="https://github.com/firezone/firezone/issues/1157"
type="feature"
>
Control access to protected Resources on a per-group basis.
</RoadmapItem>
<RoadmapItem
title="Apple client"
href="https://github.com/firezone/firezone/issues/1763"
type="feature"
>
Native Firezone client for macOS and iOS.
</RoadmapItem>
<RoadmapItem
title="NAT traversal"
href="https://github.com/firezone/firezone/issues/1765"
type="feature"
>
Automatic holepunching and STUN/TURN discovery for Clients and
Gateways.
</RoadmapItem>
<RoadmapItem
title="Split DNS"
href="https://github.com/firezone/firezone/issues/1158"
type="feature"
>
Resolve DNS queries for protected Resources using Firezone's
built-in DNS while forwarding other queries to a configurable
upstream DNS server.
</RoadmapItem>
<RoadmapItem
title="Android client"
href="https://github.com/firezone/firezone/issues/1767"
type="feature"
>
Native Firezone client for Android.
</RoadmapItem>
<RoadmapItem
title="High availability"
href="https://github.com/firezone/firezone/issues/897"
type="feature"
>
Support for High availability (HA) deployments of the Firezone
Gateway.
</RoadmapItem>
</ul>
</div>
</div>
<div className="p-6">
<h3 className="text-neutral-900 tracking-tight font-bold text-2xl mb-4">
Under consideration
</h3>
<p className="text-lg text-neutral-900 mb-6">
Things we're still investigating, architecting, or in the process
of prioritizing.{" "}
<span className="font-semibold">(feedback welcome!)</span>
</p>
<ul className="flex flex-col">
<RoadmapItem
title="Windows client"
href="https://github.com/firezone/firezone/issues/1768"
type="feature"
>
Native Firezone client for Windows.
</RoadmapItem>
<RoadmapItem
title="Service accounts"
href="https://github.com/firezone/firezone/issues/1770"
type="feature"
>
Support for service accounts to allow automated access to
protected Resources. Requires headless clients for
Linux/Windows.
</RoadmapItem>
<RoadmapItem
title="Linux client"
href="https://github.com/firezone/firezone/issues/1762"
type="feature"
>
Native Firezone client for Linux.
</RoadmapItem>
<RoadmapItem
title="Audit logging"
href="https://github.com/firezone/firezone/issues/949"
type="feature"
>
Log admin portal configuration changes and end-user access to
protected Resources to achieve compliance with regulatory
requirements.
</RoadmapItem>
</ul>
</div>
</div>
</div>
<div className="border border-primary-200 bg-primary-100">
<div className="mx-auto max-w-screen-lg grid text-center md:grid-cols-2 text-lg sm:text-xl py-3 sm:py-6">
<div>
<HiMegaphone className="inline-flex h-5 w-5 mr-2 text-primary-450" />
Want to stay updated on our progress?
</div>
<div>
<ActionLink
href="/product/newsletter"
className="ml-8 inline-flex text-accent-500 underline hover:no-underline"
>
Subscribe to our newsletter.
</ActionLink>
</div>
</div>
</div>
<div className="border-t border-neutral-200 mx-auto bg-gradient-to-b from-white to-neutral-100 pt-14">
<h2 className="ml-2 sm:justify-center flex-wrap mb-4 text-4xl font-extrabold tracking-tight text-neutral-900">
<span>We're building Firezone</span>{" "}
<span className="text-primary-450 underline">in the open.</span>
</h2>
<p className="sm:mx-auto ml-2 max-w-xl text-neutral-900 sm:text-center mb-4 text-lg sm:text-xl">
We're open source because we believe <i>better transparency</i> leads
to <i>better security</i>. After all, how can you trust what you can't
see?
</p>
<p className="mx-auto mb-4 sm:mb-8 text-lg sm:text-xl">
<ActionLink
href="https://github.com/firezone/firezone/pulls"
className="ml-2 flex text-lg items-center sm:justify-center text-accent-500 underline hover:no-underline"
>
See what we're working on
</ActionLink>
.
</p>
<CommitMarquee xmlFeed="/api/github/firezone/firezone/commits/main.atom" />
</div>
<JoinOurCommunity />
</div>
);
}

View File

@@ -1,360 +1,9 @@
"use client";
import { Metadata } from "next";
import Page from "./_page";
import Link from "next/link";
import CommitMarquee from "@/components/CommitMarquee";
import ActionLink from "@/components/ActionLink";
import JoinOurCommunity from "@/components/JoinOurCommunity";
import { MegaphoneIcon, BeakerIcon } from "@heroicons/react/24/solid";
import { XMLParser } from "fast-xml-parser";
import { useState, useEffect } from "react";
import GitHubHtml from "@/components/GitHubHtml";
export const metadata: Metadata = {
title: "Product Roadmap • Firezone",
description: "See what we're working on and what's coming next.",
};
function RoadmapItem({
title,
href,
type,
date,
entryId,
children,
}: {
href: string;
title: string;
type: string;
date?: string;
entryId?: string;
children: React.ReactNode;
}) {
function badge(type: string) {
switch (type) {
case "release":
return (
<span className="bg-accent-600 text-white text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
case "1.0":
case "feature":
return (
<span className="bg-primary-450 text-white text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
case "refactor":
case "website":
return (
<span className="bg-neutral-800 text-white text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
case "docs":
return (
<span className="bg-neutral-100 text-neutral-800 text-xs font-semibold px-2.5 py-0.5 rounded">
{type}
</span>
);
}
}
return (
<li
key={entryId}
className="shadow-sm bg-white rounded-sm shadow-sm p-4 mb-4 hover:shadow-md"
>
<h5 className="text-lg font-semibold">
<Link
href={href}
className="text-accent-500 underline hover:no-underline"
>
{title}
</Link>
</h5>
<div className="pb-4">{children}</div>
<div className="flex items-center justify-between">
{date ? (
<span className="text-xs font-semibold px-2.5 py-0.5 bg-neutral-200 text-neutral-800">
{new Date(date!).toDateString()}
</span>
) : (
<span></span>
)}
{badge(type)}
</div>
</li>
);
}
export default function Page() {
const parser = new XMLParser({ ignoreAttributes: false });
const [xml, setXml] = useState<any>({ feed: { entry: [] } });
useEffect(() => {
fetch("/api/github/firezone/firezone/releases.atom")
.then((response) => response.text())
.then((str) => parser.parse(str))
.then((data) => {
setXml(data);
})
.catch((error) => console.error(error));
}, []);
return (
<div className="bg-neutral-100">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-md">
<h1 className="sm:justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-6xl dark:text-neutral-50">
Product Roadmap
</h1>
<p className="mx-auto sm:text-center mb-8 max-w-2xl text-neutral-900 md:mb-12 sm:text-xl dark:text-neutral-100">
Take a peek below to learn what we're working on and how you can get
involved.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 mx-auto max-w-screen-lg divide-x">
<div className="p-6">
<h3 className="text-neutral-900 tracking-tight font-bold text-2xl mb-4">
Shipped
</h3>
<p className="text-lg text-neutral-900 dark:text-neutral-50 mb-6">
Updates we've recently shipped.
</p>
<div className="mb-4">
<h4 className="border-b border-neutral-200 mb-2 text-xl tracking-tight font-semibold text-neutral-800">
Recent Releases
</h4>
<ul className="flex flex-col">
{xml.feed.entry.slice(0, 3).map((entry: any) => {
return (
<RoadmapItem
entryId={entry.id}
title={entry.title}
href={entry.link["@_href"]}
type="release"
date={entry.updated}
>
<GitHubHtml html={entry.content["#text"]} />
</RoadmapItem>
);
})}
</ul>
</div>
{/* TODO: Consider automating this with the GitHub API */}
<div className="mb-4">
<h4 className="border-b border-neutral-200 mb-2 text-xl tracking-tight font-semibold text-neutral-800">
Website / Docs
</h4>
<ul className="flex flex-col">
<RoadmapItem
title="1.0 early access page"
href="https://github.com/firezone/firezone/pull/1733"
type="website"
date="2023-07-06T17:56:03Z"
>
We've added a new{" "}
<Link
href="/product/early-access"
className="text-accent-500 underline hover:no-underline"
>
early access page
</Link>{" "}
to allow users to sign up to test new Firezone features and
releases.
</RoadmapItem>
<RoadmapItem
title="Team page"
href="https://github.com/firezone/firezone/pull/1731"
type="website"
date="2023-07-05T16:08:36Z"
>
A new{" "}
<Link
href="/team"
className="text-accent-500 underline hover:no-underline"
>
team page
</Link>{" "}
has been added to showcase the team behind Firezone.
</RoadmapItem>
<RoadmapItem
title="Brand colors"
href="https://github.com/firezone/firezone/pull/1728"
type="website"
date="2023-07-03T23:32:41Z"
>
Our website now sports a new color palette, font, and spacing
consistent with the Firezone product.
</RoadmapItem>
</ul>
</div>
</div>
<div className="p-6">
<h3 className="text-neutral-900 tracking-tight font-bold text-2xl mb-4">
In progress
</h3>
<p className="text-lg text-neutral-900 dark:text-neutral-50 mb-6">
Things we're actively working on and plan to ship in the next
release or two.
</p>
<div className="mb-4">
<div className="p-2 bg-primary-100 border border-primary-200 mb-4">
<BeakerIcon className="inline-block w-4 h-4 mr-1 text-primary-450" />
<Link
href="/product/early-access"
className="text-accent-500 underline hover:no-underline"
>
Sign up for early access
</Link>{" "}
to test new Firezone features and releases.
</div>
<h4 className="border-b border-neutral-200 mb-2 text-xl tracking-tight font-semibold text-neutral-800">
Firezone 1.0
</h4>
<ul className="flex flex-col">
<RoadmapItem
title="Automated provisioning"
href="https://github.com/firezone/firezone/issues/1437"
type="feature"
>
Automated user and group provisioning via just-in-time (JIT)
provisioning or SCIM 2.0.
</RoadmapItem>
<RoadmapItem
title="Authentication overhaul"
href="https://github.com/firezone/firezone/issues/1123"
type="refactor"
>
More robust support for SAML 2.0, OIDC, and magic link
authentication methods.
</RoadmapItem>
<RoadmapItem
title="Group-based access policies"
href="https://github.com/firezone/firezone/issues/1157"
type="feature"
>
Control access to protected Resources on a per-group basis.
</RoadmapItem>
<RoadmapItem
title="Apple client"
href="https://github.com/firezone/firezone/issues/1763"
type="feature"
>
Native Firezone client for macOS and iOS.
</RoadmapItem>
<RoadmapItem
title="NAT traversal"
href="https://github.com/firezone/firezone/issues/1765"
type="feature"
>
Automatic holepunching and STUN/TURN discovery for Clients and
Gateways.
</RoadmapItem>
<RoadmapItem
title="Split DNS"
href="https://github.com/firezone/firezone/issues/1158"
type="feature"
>
Resolve DNS queries for protected Resources using Firezone's
built-in DNS while forwarding other queries to a configurable
upstream DNS server.
</RoadmapItem>
<RoadmapItem
title="Android client"
href="https://github.com/firezone/firezone/issues/1767"
type="feature"
>
Native Firezone client for Android.
</RoadmapItem>
<RoadmapItem
title="High availability"
href="https://github.com/firezone/firezone/issues/897"
type="feature"
>
Support for High availability (HA) deployments of the Firezone
Gateway.
</RoadmapItem>
</ul>
</div>
</div>
<div className="p-6">
<h3 className="text-neutral-900 tracking-tight font-bold text-2xl mb-4">
Under consideration
</h3>
<p className="text-lg text-neutral-900 dark:text-neutral-50 mb-6">
Things we're still investigating, architecting, or in the process
of prioritizing.{" "}
<span className="font-semibold">(feedback welcome!)</span>
</p>
<ul className="flex flex-col">
<RoadmapItem
title="Windows client"
href="https://github.com/firezone/firezone/issues/1768"
type="feature"
>
Native Firezone client for Windows.
</RoadmapItem>
<RoadmapItem
title="Service accounts"
href="https://github.com/firezone/firezone/issues/1770"
type="feature"
>
Support for service accounts to allow automated access to
protected Resources. Requires headless clients for
Linux/Windows.
</RoadmapItem>
<RoadmapItem
title="Linux client"
href="https://github.com/firezone/firezone/issues/1762"
type="feature"
>
Native Firezone client for Linux.
</RoadmapItem>
<RoadmapItem
title="Audit logging"
href="https://github.com/firezone/firezone/issues/949"
type="feature"
>
Log admin portal configuration changes and end-user access to
protected Resources to achieve compliance with regulatory
requirements.
</RoadmapItem>
</ul>
</div>
</div>
</div>
<div className="mx-auto p-6 rounded-sm border border-primary-200 bg-primary-100 text-xl flex items-center justify-center">
<MegaphoneIcon className="h-5 w-5 mr-2 text-primary-450" />
Want to stay updated on our progress?
<span className="ml-2">
<ActionLink
href="/product/newsletter"
className="flex items-center justify-center text-accent-500 underline hover:no-underline"
>
Subscribe to our newsletter.
</ActionLink>
</span>
</div>
<div className="border-t border-neutral-200 mx-auto bg-gradient-to-b from-white to-neutral-100 pt-14">
<h2 className="sm:justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-4xl dark:text-neutral-50">
<span>We're building Firezone</span>{" "}
<span className="text-primary-450 underline">in the open.</span>
</h2>
<p className="mx-auto max-w-2xl text-neutral-900 sm:text-center mb-4 sm:text-xl">
We're open source because we believe <i>better transparency</i> leads
to <i>better security</i>. After all, how can you trust what you can't
see?
</p>
<p className="mx-auto mb-4 sm:mb-8 sm:text-xl">
<ActionLink
href="https://github.com/firezone/firezone/pulls"
className="flex items-center justify-center text-accent-500 underline hover:no-underline"
>
See what we're working on
</ActionLink>
.
</p>
<CommitMarquee xmlFeed="/api/github/firezone/firezone/commits/main.atom" />
</div>
<JoinOurCommunity />
</div>
);
}
export default Page;

View File

@@ -28,10 +28,10 @@ function renderTeamMember({
alt={`{name} Avatar`}
/>
<div className="text-center">
<h3 className="justify-center text-xl font-bold tracking-tight text-neutral-900 dark:text-white">
<h3 className="justify-center text-xl font-bold tracking-tight text-neutral-900 ">
{name}
</h3>
<span className="text-neutral-800 dark:text-neutral-100">{title}</span>
<span className="text-neutral-800 ">{title}</span>
<ul className="flex justify-center space-x-4 mt-4">
{twitterUrl && (
<li>
@@ -122,10 +122,10 @@ export default function Page() {
];
return (
<section className="bg-neutral-100 dark:bg-neutral-900">
<section className="bg-neutral-100 ">
<div className="py-8 px-4 mx-auto max-w-screen-lg text-center lg:py-16 lg:px-6">
<div className="text-neutral-800 sm:text-lg dark:text-neutral-100">
<h1 className="mb-14 justify-center text-6xl tracking-tight font-extrabold text-neutral-900 dark:text-white">
<div className="text-neutral-800 sm:text-lg ">
<h1 className="mb-14 justify-center text-6xl tracking-tight font-extrabold text-neutral-900 ">
People are everything.
</h1>
<p className="mb-4 sm:text-2xl">
@@ -135,22 +135,22 @@ export default function Page() {
tools they need to succeed.
</p>
</div>
<div className="text-neutral-800 sm:text-lg dark:text-neutral-100">
<h3 className="justify-center pb-4 pt-14 text-2xl tracking-tight font-bold text-neutral-900 dark:text-white border-b border-neutral-300">
<div className="text-neutral-800 sm:text-lg ">
<h3 className="justify-center pb-4 pt-14 text-2xl tracking-tight font-bold text-neutral-900 border-b border-neutral-300">
CORE TEAM
</h3>
</div>
<div className="mt-16 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 md:gap-8 lg:gap-16">
<div className="mt-16 grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 md:gap-8 lg:gap-16">
{coreTeam.map((person) => {
return renderTeamMember(person);
})}
</div>
<div className="text-neutral-800 sm:text-lg dark:text-neutral-100">
<h3 className="justify-center pb-4 pt-14 text-2xl tracking-tight font-bold text-neutral-900 dark:text-white border-b border-neutral-300">
<div className="text-neutral-800 sm:text-lg ">
<h3 className="justify-center pb-4 pt-14 text-2xl tracking-tight font-bold text-neutral-900 border-b border-neutral-300">
ADVISORS & CONSULTANTS
</h3>
</div>
<div className="mt-16 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-8 lg:gap-16">
<div className="mt-16 grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-8 lg:gap-16">
{advisors.map((person) => {
return renderTeamMember(person);
})}

View File

@@ -1,5 +1,5 @@
import Link from "next/link";
import { ArrowLongRightIcon } from "@heroicons/react/24/solid";
import { HiArrowLongRight } from "react-icons/hi2";
export default function ActionLink({
children,
@@ -13,7 +13,7 @@ export default function ActionLink({
return (
<Link href={href} className={`${className} group`}>
{children}
<ArrowLongRightIcon className="group-hover:translate-x-1 group-hover:scale-110 duration-100 transform transition ml-2 -mr-1 w-6 h-6" />
<HiArrowLongRight className="group-hover:translate-x-1 group-hover:scale-110 duration-100 transform transition ml-2 -mr-1 w-6 h-6" />
</Link>
);
}

View File

@@ -1,5 +1,5 @@
"use client";
import { XMarkIcon } from "@heroicons/react/20/solid";
import { HiXMark } from "react-icons/hi2";
import { useEffect } from "react";
import { initFlowbite } from "flowbite";
@@ -26,16 +26,16 @@ export default function Banner({
tabIndex={-1}
className={
position +
" flex top-14 z-30 gap-8 justify-between items-start py-2 px-4 w-full bg-primary-450 shadow-lg sm:items-center dark:border-neutral-700 dark:bg-neutral-800"
" flex top-14 z-30 gap-8 justify-between items-start py-2 px-4 w-full bg-primary-450 shadow-lg sm:items-center "
}
>
{children}
<button
data-collapse-toggle="banner"
type="button"
className="flex items-center text-neutral-50 hover:bg-neutral-50 hover:text-neutral-900 rounded-lg text-sm p-1.5 dark:hover:bg-neutral-900 dark:hover:text-neutral-50"
className="flex items-center text-neutral-50 hover:bg-neutral-50 hover:text-neutral-900 rounded-lg text-sm p-1.5 "
>
<XMarkIcon className="w-5 h-5" />
<HiXMark className="w-5 h-5" />
</button>
</div>
);

View File

@@ -17,12 +17,12 @@ export default function Post({
children: React.ReactNode;
}) {
return (
<main className="pb-16 lg:pb-24 bg-neutral-100 dark:bg-neutral-900">
<main className="py-14 lg:pb-24 bg-neutral-100 ">
<div className="flex justify-between px-4 mx-auto max-w-screen-xl">
<article className="mx-auto w-full max-w-2xl format format-sm sm:format-base lg:format-lg dark:format-invert">
<article className="mx-auto w-full max-w-2xl format format-sm sm:format-base lg:format-lg ">
<header className="mb-4 lg:mb-6 not-format">
<address className="flex items-center mb-6 not-italic">
<div className="inline-flex items-center mr-3 text-sm text-neutral-900 dark:text-white">
<div className="inline-flex items-center mr-3 text-sm text-neutral-900 ">
<Image
width={64}
height={64}
@@ -34,14 +34,12 @@ export default function Post({
<a
href="#"
rel="author"
className="text-xl font-bold text-neutral-900 dark:text-white"
className="text-xl font-bold text-neutral-900 "
>
{authorName}
</a>
<p className="text-base font-light text-neutral-800 dark:text-neutral-100">
{authorTitle}
</p>
<p className="text-base font-light text-neutral-800 dark:text-neutral-100">
<p className="text-base text-neutral-900 ">{authorTitle}</p>
<p className="text-base text-neutral-900 ">
<time dateTime="2022-02-08" title="February 8th, 2022">
{date}
</time>
@@ -49,11 +47,11 @@ export default function Post({
</div>
</div>
</address>
<h1 className="mb-4 text-3xl font-extrabold leading-tight text-neutral-900 lg:mb-6 lg:text-5xl dark:text-white">
<h1 className="mb-4 text-3xl font-extrabold leading-tight text-neutral-900 lg:mb-6 lg:text-5xl ">
{title}
</h1>
</header>
{children}
<div className="pt-4">{children}</div>
</article>
</div>
</main>

View File

@@ -0,0 +1,55 @@
import ActionLink from "@/components/ActionLink";
import Link from "next/link";
import Image from "next/image";
export default function SummaryCard({
children,
date,
href,
title,
authorName,
authorAvatarSrc,
type,
}: {
children: React.ReactNode;
date: string;
href: string;
title: string;
authorName: string;
authorAvatarSrc: string;
type: string;
}) {
return (
<article className="p-6">
<div className="flex justify-between items-center mb-5">
<span className="text-neutral-500 font-semibold text-xs inline-flex items-center">
{type.toUpperCase()}
</span>
<span className="text-sm font-semibold">{date}</span>
</div>
<h2 className="mb-2 text-2xl font-bold tracking-tight text-neutral-900 ">
{title}
</h2>
<div className="mb-5 font-medium text-neutral-800 ">{children}</div>
<div className="flex justify-between items-center">
<div className="flex items-center space-x-4">
<Image
width={28}
height={28}
className="w-7 h-7 rounded-full"
src={authorAvatarSrc}
alt={authorName + " avatar"}
/>
<span className="font-medium ">{authorName}</span>
</div>
<ActionLink
href={href}
className="group inline-flex items-center font-medium text-accent-500 underline hover:no-underline"
>
Read more
</ActionLink>
</div>
</article>
);
}

View File

@@ -36,7 +36,7 @@ export default function CommitMarquee({ xmlFeed }: { xmlFeed: string }) {
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 dark:text-neutral-200 font-medium text-lg">
<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"

View File

@@ -6,7 +6,7 @@ export default function DeployButton() {
<Link href="/docs/deploy">
<button
type="button"
className="text-white font-semibold tracking-tight rounded-md duration-0 hover:scale-105 transition transform shadow-md text-sm px-5 py-2.5 bg-gradient-to-br from-accent-700 to-accent-600"
className="text-white font-bold tracking-tight rounded-md duration-0 hover:scale-105 transition transform shadow-lg text-sm px-5 py-2.5 bg-gradient-to-br from-accent-700 to-accent-600"
>
Deploy now
</button>

View File

@@ -1,54 +1,50 @@
"use client";
import { Alert as FlowbiteAlert } from "flowbite-react";
import {
InformationCircleIcon,
ExclamationCircleIcon,
ExclamationTriangleIcon,
} from "@heroicons/react/24/outline";
HiOutlineInformationCircle,
HiOutlineExclamationCircle,
HiOutlineExclamationTriangle,
} from "react-icons/hi2";
function icon(color: string) {
export default function Alert({
html,
color,
}: {
html: string;
color: string;
}) {
switch (color) {
case "info":
return (
<span>
<InformationCircleIcon className="inline-block w-5 h-5 mr-2" />
<span className="text-xs font-bold">INFO</span>
</span>
<div className="mb-4 p-3 flex items-center rounded border bg-neutral-100 text-neutral-800 border-neutral-200">
<HiOutlineInformationCircle className="flex-none w-5 h-5 mr-2" />
{/* ReactMarkdown wraps this in a <p> tag if we wrap {children} as ReactNode, so we need to use string here instead. */}
<span
className="format-none text-sm"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
);
case "warning":
return (
<span>
<ExclamationCircleIcon className="inline-block w-5 h-5 mr-2" />
<span className="text-xs font-bold">WARNING</span>
</span>
<div className="mb-4 p-3 flex items-center rounded border bg-accent-100 text-accent-800 border-accent-200">
<HiOutlineExclamationCircle className="flex-none w-5 h-5 mr-2" />
{/* ReactMarkdown wraps this in a <p> tag if we wrap {children} as ReactNode, so we need to use string here instead. */}
<span
className="format-none text-sm"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
);
case "danger":
return (
<span>
<ExclamationTriangleIcon className="inline-block w-5 h-5 mr-2" />
<span className="text-xs font-bold">DANGER</span>
</span>
<div className="mb-4 p-3 flex items-center rounded border bg-primary-100 text-primary-800 border-primary-200">
<HiOutlineExclamationTriangle className="flex-none w-5 h-5 mr-2" />
{/* ReactMarkdown wraps this in a <p> tag if we wrap {children} as ReactNode, so we need to use string here instead. */}
<span
className="format-none text-sm"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
);
default:
return null;
}
}
export default function Alert({
children,
color,
}: {
children: React.ReactNode;
color: string;
}) {
return (
<div className="mb-4">
<FlowbiteAlert color={color}>
<span>
{icon(color)}
{children}
</span>
</FlowbiteAlert>
</div>
);
}

View File

@@ -1,4 +1,4 @@
import { ChevronRightIcon, ChevronDownIcon } from "@heroicons/react/20/solid";
import { HiChevronRight, HiChevronDown } from "react-icons/hi2";
import { useState } from "react";
export default function Collapse({
@@ -13,9 +13,7 @@ export default function Collapse({
const ctl = label.toLowerCase().replace(" ", "-") + "-dropdown";
const indent = "ml-3";
const hidden = expanded ? "" : "hidden";
const text = expanded
? "bg-neutral-100 dark:bg-neutral-700"
: "text-neutral-900 dark:text-white";
const text = expanded ? "bg-neutral-100 " : "text-neutral-900 ";
const [expandedState, setExpandedState] = useState(expanded);
return (
@@ -24,7 +22,7 @@ export default function Collapse({
type="button"
className={
text +
" flex items-center w-full transition duration-75 rounded-lg group hover:bg-neutral-100 dark:hover:bg-neutral-700"
" flex items-center w-full transition duration-75 rounded-lg group hover:bg-neutral-100 "
}
aria-controls={ctl}
data-collapse-toggle={ctl}
@@ -37,9 +35,9 @@ export default function Collapse({
{label}
</span>
{expandedState ? (
<ChevronDownIcon sidebar-toggle-item="true" className="w-6 h-6" />
<HiChevronDown sidebar-toggle-item="true" className="w-6 h-6" />
) : (
<ChevronRightIcon sidebar-toggle-item="true" className="w-6 h-6" />
<HiChevronRight sidebar-toggle-item="true" className="w-6 h-6" />
)}
</button>
<ul id={ctl} className={[hidden, "ml-3 py-1 space-y-0.5"].join(" ")}>

View File

@@ -5,7 +5,7 @@ export default function Item({ href, label }: { href: string; label: string }) {
const p = usePathname();
function active(path: string) {
return p == path ? "bg-neutral-100 dark:bg-neutral-700 " : "";
return p == path ? "bg-neutral-100 " : "";
}
return (
@@ -13,7 +13,7 @@ export default function Item({ href, label }: { href: string; label: string }) {
href={href}
className={[
active(href),
"flex items-center text-left rounded-lg text-base font-normal text-neutral-900 hover:bg-neutral-100 dark:text-white dark:hover:bg-neutral-700",
"flex items-center text-left rounded-lg text-base font-normal text-neutral-900 hover:bg-neutral-100 ",
].join(" ")}
>
<span className="ml-3">{label}</span>

View File

@@ -3,7 +3,7 @@ import "@docsearch/css";
export default function SearchForm() {
return (
<div className="pb-3 -ml-1 flex justify-start border-b border-neutral-200 dark:border-neutral-700">
<div className="pb-3 -ml-1 flex justify-start border-b border-neutral-200 ">
<DocSearch
appId="XXPZ9QVGFB"
apiKey="66664e8765e1645ea0b500acebb0b0c2"

View File

@@ -19,10 +19,10 @@ export default function DocsSidebar() {
id="docs-sidebar"
aria-label="Sidebar"
aria-hidden="true"
className="sticky left-0 top-0 flex-none w-64 h-screen pt-20 transition-transform -translate-x-full bg-white border-r border-neutral-200 md:translate-x-0 dark:bg-neutral-800 dark:border-neutral-700"
className="sticky left-0 top-0 flex-none w-64 h-screen pt-20 transition-transform -translate-x-full bg-white border-r border-neutral-200 md:translate-x-0 "
>
<SearchForm />
<div className="mt-5 h-full overflow-y-auto bg-white dark:bg-neutral-800 pr-3">
<div className="mt-5 h-full overflow-y-auto bg-white pr-3">
<ul className="space-y-2 font-medium">
<li>
<Item href="/docs" label="Overview" />

View File

@@ -3,21 +3,21 @@ import Link from "next/link";
export default function EarlyAccessForm() {
return (
<div className="pt-8 grid grid-cols-1 sm:grid-cols-2 gap-8 items-start">
<div className="pt-8 grid sm:grid-cols-2 gap-8 items-start">
<div className="px-4 mb-8">
<h2 className="mb-8 py-4 border-b text-2xl font-bold tracking-tight text-neutral-900 sm:text-4xl dark:text-white">
<h2 className="mb-8 py-4 border-b text-2xl font-bold tracking-tight text-neutral-900 sm:text-4xl ">
FAQ
</h2>
<h3 className="mb-4 lg:text-2xl md:text-xl font-bold tracking-tight text-neutral-900 text-lg dark:text-white">
<h3 className="mb-4 lg:text-2xl md:text-xl font-bold tracking-tight text-neutral-900 text-lg ">
Why sign up for early access?
</h3>
<ul className="md:text-xl mb-6 list-inside list-disc space-y-2">
<li>Be among the first to try Firezone 1.0</li>
<li>Shape the product roadmap with prioritized feedback</li>
<li>Accelerate the roadmap with prioritized feedback</li>
<li>Dedicated Slack channel for onboarding and support</li>
<li>Free unlimited usage during the beta period</li>
</ul>
<h3 className="mb-4 lg:text-2xl md:text-xl font-bold tracking-tight text-neutral-900 text-lg dark:text-white">
<h3 className="mb-4 lg:text-2xl md:text-xl font-bold tracking-tight text-neutral-900 text-lg ">
What's new in 1.0?
</h3>
<ul className="md:text-xl mb-6 list-inside list-disc space-y-2">
@@ -32,6 +32,15 @@ export default function EarlyAccessForm() {
<li>Automatic failover, load balancing</li>
*/}
</ul>
<h3 className="mb-4 lg:text-2xl md:text-xl font-bold tracking-tight text-neutral-900 text-lg ">
How much will it cost?
</h3>
<p className="md:text-xl mb-6">
We're still working out pricing details for the 1.0 release and will
launch an updated pricing page when we have more to share. Our goal is
to price Firezone competitively among other products in the space with
a cost that scales predictably according to the value it provides.
</p>
</div>
<div className="w-full">
<HubspotForm

View File

@@ -5,7 +5,7 @@ import { LinkedInIcon, GitHubIcon, TwitterIcon } from "@/components/Icons";
export default function Footer() {
return (
<footer className="relative bg-white dark:bg-neutral-900 border-t">
<footer className="relative bg-white border-t">
<div className="mx-auto w-full max-w-screen-xl p-4 py-6 lg:py-8">
<div className="md:flex md:justify-between">
<div className="mb-6 md:mb-0">
@@ -21,10 +21,10 @@ export default function Footer() {
</div>
<div className="grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3">
<div>
<h2 className="mb-6 text-sm font-semibold text-neutral-900 uppercase dark:text-white">
<h2 className="mb-6 text-sm font-semibold text-neutral-900 uppercase ">
Company
</h2>
<ul className="text-neutral-800 dark:text-neutral-100 font-medium">
<ul className="text-neutral-900 font-medium">
<li className="mb-4">
<Link href="/" className="hover:underline">
Home
@@ -51,10 +51,10 @@ export default function Footer() {
</ul>
</div>
<div>
<h2 className="mb-6 text-sm font-semibold text-neutral-900 uppercase dark:text-white">
<h2 className="mb-6 text-sm font-semibold text-neutral-900 uppercase ">
Resources
</h2>
<ul className="text-neutral-800 dark:text-neutral-100 font-medium">
<ul className="text-neutral-900 font-medium">
<li className="mb-4">
<Link
href="/docs"
@@ -98,10 +98,10 @@ export default function Footer() {
</ul>
</div>
<div>
<h2 className="mb-6 text-sm font-semibold text-neutral-900 uppercase dark:text-white">
<h2 className="mb-6 text-sm font-semibold text-neutral-900 uppercase ">
Community
</h2>
<ul className="text-neutral-800 dark:text-neutral-100 font-medium">
<ul className="text-neutral-900 font-medium">
<li className="mb-4">
<Link
href="https://discourse.firez.one"
@@ -146,9 +146,14 @@ export default function Footer() {
</div>
</div>
</div>
<hr className="my-6 border-neutral-200 sm:mx-auto dark:border-neutral-700 lg:my-8" />
<div className="sm:flex sm:items-center sm:justify-start mt-4">
<span className="text-xs">
WireGuard® is a registered trademark of Jason A. Donenfeld.
</span>
</div>
<hr className="mt-2 mb-6 border-neutral-200 sm:mx-auto lg:mb-8 lg:mt-4" />
<div className="sm:flex sm:items-center sm:justify-between">
<span className="text-sm text-neutral-800 sm:text-center dark:text-neutral-100">
<span className="text-sm text-neutral-900 sm:text-center ">
© 2023{" "}
<Link href="/" className="hover:underline">
Firezone, Inc.

View File

@@ -17,8 +17,8 @@ export default function HubspotForm({
});
return (
<div className="bg-white shadow-md border border-neutral-200 dark:border-neutral-700 rounded-lg p-4">
<h3 className="mb-4 lg:mb-8 text-xl font-bold tracking-tight text-neutral-900 sm:text-xl border-b dark:text-white">
<div className="bg-white shadow-md border border-neutral-200 rounded-lg p-4">
<h3 className="mb-4 lg:mb-8 text-xl font-bold tracking-tight text-neutral-900 sm:text-xl border-b ">
{title}
</h3>
<div id="hubspot-form" />

View File

@@ -4,7 +4,7 @@ export function LinkedInIcon({ url }: { url: string }) {
return (
<Link
href={url}
className="text-neutral-800 hover:text-neutral-900 dark:hover:text-white"
className="text-neutral-800 hover:text-neutral-900 "
>
<svg
aria-hidden="true"
@@ -27,7 +27,7 @@ export function GitHubIcon({ url }: { url: string }) {
return (
<Link
href={url}
className="text-neutral-800 hover:text-neutral-900 dark:hover:text-white"
className="text-neutral-800 hover:text-neutral-900 "
>
<svg
className="w-5 h-5"
@@ -50,7 +50,7 @@ export function TwitterIcon({ url }: { url: string }) {
return (
<Link
href={url}
className="text-neutral-800 hover:text-neutral-900 dark:hover:text-white"
className="text-neutral-800 hover:text-neutral-900 "
>
<svg
className="w-5 h-5"

View File

@@ -1,26 +1,22 @@
import Link from "next/link";
import {
ChatBubbleLeftRightIcon,
UserGroupIcon,
StarIcon,
} from "@heroicons/react/24/solid";
import { HiChatBubbleLeftRight, HiUserGroup, HiStar } from "react-icons/hi2";
export default function JoinOurCommunity() {
return (
<section className="border-t border-neutral-200 py-24 bg-gradient-to-b from-neutral-100 to-primary-50">
<div className="flex flex-col justify-center items-center">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-900 dark:text-white">
<h2 className="mb-4 text-4xl tracking-tight font-bold text-neutral-900 ">
Join our community
</h2>
<p className="my-4 text-xl max-w-screen-lg text-center text-primary-900 dark:text-neutral-100">
<p className="mx-2 my-4 text-xl max-w-screen-lg text-center text-primary-900 ">
Participate in Firezone's development, suggest new features, and
collaborate with other Firezone users.
</p>
</div>
<div className="gap-4 items-center pt-4 px-4 mx-auto max-w-screen-lg lg:grid lg:grid-cols-3 xl:gap-8 sm:pt-8 lg:px-6 ">
<div className="py-8 rounded-md shadow-md text-center bg-white">
<UserGroupIcon className="flex-shrink-0 w-12 h-12 mx-auto text-primary-450 dark:text-neutral-100" />
<h3 className="text-4xl my-8 font-bold justify-center tracking-tight text-primary-900 dark:text-neutral-100">
<HiUserGroup className="flex-shrink-0 w-12 h-12 mx-auto text-primary-450 " />
<h3 className="text-4xl my-8 font-bold justify-center tracking-tight text-primary-900 ">
30+
</h3>
<p className="mb-8 text-xl font-semibold">Contributors</p>
@@ -34,8 +30,8 @@ export default function JoinOurCommunity() {
</button>
</div>
<div className="py-8 rounded-md shadow-md text-center bg-white">
<StarIcon className="flex-shrink-0 w-12 h-12 mx-auto text-primary-450 dark:text-neutral-100" />
<h3 className="text-4xl my-8 font-bold justify-center tracking-tight text-primary-900 dark:text-neutral-100">
<HiStar className="flex-shrink-0 w-12 h-12 mx-auto text-primary-450 " />
<h3 className="text-4xl my-8 font-bold justify-center tracking-tight text-primary-900 ">
4,300+
</h3>
<p className="mb-8 text-xl font-semibold">GitHub stars</p>
@@ -49,8 +45,8 @@ export default function JoinOurCommunity() {
</button>
</div>
<div className="py-8 rounded-md shadow-md text-center bg-white">
<ChatBubbleLeftRightIcon className="flex-shrink-0 w-12 h-12 mx-auto text-primary-450 dark:text-neutral-100" />
<h3 className="text-4xl my-8 font-bold justify-center tracking-tight text-primary-900 dark:text-neutral-100">
<HiChatBubbleLeftRight className="flex-shrink-0 w-12 h-12 mx-auto text-primary-450 " />
<h3 className="text-4xl my-8 font-bold justify-center tracking-tight text-primary-900 ">
250+
</h3>
<p className="mb-8 text-xl font-semibold">Members</p>

View File

@@ -8,10 +8,10 @@ import Script from "next/script";
import Banner from "@/components/Banner";
import Providers from "@/components/Providers";
import Footer from "@/components/Footer";
import { Source_Sans_Pro } from "next/font/google";
const source_sans_pro = Source_Sans_Pro({
import { Public_Sans } from "next/font/google";
const public_sans = Public_Sans({
subsets: ["latin"],
weight: ["200", "300", "400", "600", "700", "900"],
weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"],
});
export default function RootLayout({
@@ -22,23 +22,23 @@ export default function RootLayout({
return (
<html lang="en">
<Providers>
<body className={source_sans_pro.className}>
<div className="h-auto antialiased">
<body className={public_sans.className}>
<div className="min-h-screen h-auto antialiased">
<RootNavbar />
<Banner active={false}>
<p className="text-md font-medium text-center w-full text-neutral-200 dark:text-neutral-800">
<Banner active>
<p className="text-md font-medium text-center w-full text-neutral-200 ">
<strong>Firezone 1.0 is coming!</strong> Rebuilt from the ground
up with a cloud dashboard, native clients, and more.{" "}
<Link
href="/blog/announcing-1.0"
className="underline text-accent-500 dark:text-accent-800 hover:no-underline"
href="/blog/firezone-1-0"
className="underline text-accent-500 hover:no-underline"
>
Read the blogpost
</Link>{" "}
or{" "}
<Link
href="/product/early-access"
className="text-accent-500 dark:text-accent-800 underline hover:no-underline"
className="text-accent-500 underline hover:no-underline"
>
request early access.
</Link>

View File

@@ -10,7 +10,7 @@ export default function SidebarToggle() {
data-drawer-target="docs-sidebar"
data-drawer-toggle="docs-sidebar"
aria-controls="docs-sidebar"
className="p-2 mr-1 text-neutral-800 rounded-lg cursor-pointer md:hidden hover:text-neutral-900 hover:bg-neutral-100 focus:bg-neutral-100 dark:focus:bg-neutral-700 focus:ring-2 focus:ring-neutral-100 dark:focus:ring-neutral-700 dark:text-neutral-100 dark:hover:bg-neutral-700 dark:hover:text-white"
className="p-2 mr-1 text-neutral-800 rounded-lg cursor-pointer md:hidden hover:text-neutral-900 hover:bg-neutral-100 focus:bg-neutral-100 focus:ring-2 focus:ring-neutral-100 "
>
<svg
aria-hidden="true"

View File

@@ -7,7 +7,7 @@ import { usePathname } from "next/navigation";
import DeployButton from "@/components/DeployButton";
import { useEffect } from "react";
import { initFlowbite, Dropdown } from "flowbite";
import { ChevronDownIcon } from "@heroicons/react/24/solid";
import { HiChevronDown } from "react-icons/hi2";
export default function RootNavbar() {
const p = usePathname() || "";
@@ -37,7 +37,7 @@ export default function RootNavbar() {
return (
<header>
<nav className="fixed top-0 left-0 right-0 bg-white border-b border-neutral-200 z-50">
<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 />
@@ -46,7 +46,7 @@ export default function RootNavbar() {
width={150}
height={150}
src="/images/logo-text.svg"
className="ml-2 mr-5"
className="w-32 sm:w-40 ml-2 mr-2 sm:mr-5"
alt="Firezone Logo"
/>
</Link>
@@ -54,7 +54,7 @@ export default function RootNavbar() {
<Link
className={
(p == "/" ? "text-neutral-900 underline" : "text-neutral-800") +
" p-1 mr-1 hover:text-neutral-900 hover:underline"
" p-0 sm:p-1 mr-1 font-medium hover:text-neutral-900 hover:underline"
}
href="/"
>
@@ -67,18 +67,18 @@ export default function RootNavbar() {
(p.startsWith("/product")
? "text-neutral-900"
: "text-neutral-800") +
" hover:text-neutral-900 flex items-center justify-between p-1 mr-1"
" hover:text-neutral-900 flex items-center justify-between p-0 sm:p-1 mr-1"
}
>
<span
className={
"hover:underline " +
"hover:underline font-medium " +
(p.startsWith("/product") ? "underline" : "")
}
>
Product
</span>
<ChevronDownIcon className="w-2.5 h-2.5 ml-1" />
<HiChevronDown className="w-3 h-3 mx-1" />
</button>
<div
id="product-dropdown-menu"
@@ -86,7 +86,6 @@ export default function RootNavbar() {
>
<ul className="py-2" aria-labelledby="product-dropdown-link">
<li>
{/* TODO: use <Link> here, toggling dropdown */}
<Link
onClick={hideDropdown}
href="/product/roadmap"
@@ -94,7 +93,7 @@ export default function RootNavbar() {
(p == "/product/roadmap"
? "text-neutral-900 underline"
: "text-neutral-800") +
" block px-4 py-2 hover:underline hover:bg-neutral-100 hover:text-neutral-900"
" block px-4 py-2 font-medium hover:underline hover:bg-neutral-100 hover:text-neutral-900"
}
>
Roadmap
@@ -109,7 +108,7 @@ export default function RootNavbar() {
(p == "/product/early-access"
? "text-neutral-900 underline"
: "text-neutral-800") +
" block px-4 py-2 hover:underline hover:bg-neutral-100 hover:text-neutral-900"
" block px-4 py-2 font-medium hover:underline hover:bg-neutral-100 hover:text-neutral-900"
}
>
Early Access
@@ -124,7 +123,7 @@ export default function RootNavbar() {
(p.startsWith("/product/newsletter")
? "text-neutral-900 underline"
: "text-neutral-800") +
" block px-4 py-2 hover:underline hover:bg-neutral-100 hover:text-neutral-900"
" block px-4 py-2 font-medium hover:underline hover:bg-neutral-100 hover:text-neutral-900"
}
>
Newsletter
@@ -137,7 +136,7 @@ export default function RootNavbar() {
(p.startsWith("/contact/sales")
? "text-neutral-900 underline"
: "text-neutral-800") +
" p-1 mr-1 hover:text-neutral-900 hover:underline"
" p-1 mr-1 font-medium hover:text-neutral-900 hover:underline"
}
href="/contact/sales"
>
@@ -150,7 +149,7 @@ export default function RootNavbar() {
(p.startsWith("/docs")
? "text-neutral-900 underline"
: "text-neutral-800") +
" p-1 mr-1 hover:text-neutral-900 hover:underline"
" p-1 mr-1 font-medium hover:text-neutral-900 hover:underline"
}
href="/docs"
>

View File

@@ -4,32 +4,32 @@ export default function SalesLeadForm() {
return (
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-md sm:text-center">
<h1 className="justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-6xl dark:text-white">
<h1 className="justify-center mb-4 text-2xl font-extrabold tracking-tight text-neutral-900 sm:text-6xl ">
Talk to a Firezone expert.
</h1>
<p className="mx-auto mb-8 max-w-2xl text-neutral-800 md:mb-12 sm:text-xl dark:text-neutral-100">
<h2 className="mx-auto mb-8 max-w-2xl tracking-tight font-medium text-neutral-900 md:mb-12 sm:text-xl ">
Ready to manage secure remote access for your organization? Learn how
Firezone can help.
</p>
</h2>
</div>
<div className="pt-8 grid grid-cols-1 sm:grid-cols-2 gap-4 items-top">
<div className="pt-8 grid sm:grid-cols-2 gap-4 items-top">
<div className="mb-8">
<h3 className="mb-4 lg:text-3xl md:text-2xl font-bold tracking-tight text-neutral-900 sm:text-xl dark:text-white">
<h3 className="mb-4 lg:text-3xl md:text-2xl font-bold tracking-tight text-neutral-900 sm:text-xl ">
Ensure business continuity
</h3>
<ul className="md:text-xl mb-4 list-inside list-disc">
<ul className="md:text-xl mb-8 list-inside list-disc">
<li>Technical support with SLAs</li>
<li>Private Slack channel</li>
<li>White-glove onboarding</li>
</ul>
<h3 className="mb-4 lg:text-3xl md:text-2xl font-bold tracking-tight text-neutral-900 sm:text-xl dark:text-white">
<h3 className="mb-4 lg:text-3xl md:text-2xl font-bold tracking-tight text-neutral-900 sm:text-xl ">
Built for privacy and compliance
</h3>
<ul className="md:text-xl mb-4 list-inside list-disc">
<ul className="md:text-xl mb-8 list-inside list-disc">
<li>Host on-prem in security sensitive environments</li>
<li>Maintain full control of your data and network traffic</li>
</ul>
<h3 className="mb-4 lg:text-3xl md:text-2xl font-bold tracking-tight text-neutral-900 sm:text-xl dark:text-white">
<h3 className="mb-4 lg:text-3xl md:text-2xl font-bold tracking-tight text-neutral-900 sm:text-xl ">
Simplify management for admins
</h3>
<ul className="md:text-xl list-inside list-disc">

View File

@@ -1,28 +0,0 @@
import Link from "next/link";
export default function Custom404() {
return (
<section className="bg-white dark:bg-neutral-900">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-sm text-center">
<h1 className="mb-4 text-7xl tracking-tight font-extrabold lg:text-9xl text-primary-900 dark:text-primary-100">
404
</h1>
<p className="mb-4 text-3xl tracking-tight font-bold text-neutral-900 md:text-4xl dark:text-white">
Something's missing.
</p>
<p className="mb-4 text-lg font-light text-neutral-800 dark:text-neutral-100">
Sorry, we can't find that page. You'll find lots to explore on the
home page.{" "}
</p>
<Link
href="/"
className="inline-flex text-white bg-primary-600 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-primary-900 my-4"
>
Back to Homepage
</Link>
</div>
</div>
</section>
);
}

View File

@@ -1,19 +0,0 @@
export default function Custom500() {
return (
<section className="bg-white dark:bg-neutral-900">
<div className="py-8 px-4 mx-auto max-w-screen-xl lg:py-16 lg:px-6">
<div className="mx-auto max-w-screen-sm text-center">
<h1 className="mb-4 text-7xl tracking-tight font-extrabold lg:text-9xl text-primary-900 dark:text-primary-100">
500
</h1>
<p className="mb-4 text-3xl tracking-tight font-bold text-neutral-900 md:text-4xl dark:text-white">
Internal Server Error.
</p>
<p className="mb-4 text-lg font-light text-neutral-800 dark:text-neutral-100">
We are already working to solve the problem.
</p>
</div>
</div>
</section>
);
}

View File

@@ -1,16 +0,0 @@
// TODO: This error layout doesn't seem to be applied...
import "@/app/globals.css";
import { Source_Sans_Pro } from "next/font/google";
const source_sans_pro = Source_Sans_Pro({
subsets: ["latin"],
weight: ["200", "300", "400", "600", "700", "900"],
});
export default function Error({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body className={source_sans_pro.className}>{children}</body>
</html>
);
}

View File

@@ -58,11 +58,9 @@ module.exports = {
typography: {
DEFAULT: {
css: {
color: firezoneColors["night-rider"][900],
a: {
color: firezoneColors["electric-violet"][500],
"&:hover": {
color: firezoneColors["electric-violet"][600],
},
},
},
},