mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 02:18:47 +00:00
Merge blog site into docs, serve at subpaths (#1419)
- [x] Move all docs to be served under `/docs` prefix - [x] Merge blog articles and serve under `/blog` prefix - [x] Remove docs side bar for blog content - [x] Remake marketing site pages in markdown/react - [x] Serve marketing site under root path - [x] Update all old links and paths to use new prefixes
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
skip = ./www/docs/reference/api/*.mdx,./erl_crash.dump,./apps/fz_http/erl_crash.dump,./cover,./vendor,./omnibus,*.json,yarn.lock,seeds.exs,./**/node_modules,./deps,./priv/static,./priv/plts,./**/priv/static,./.git,./www/build,./_build
|
||||
ignore-words-list = keypair,keypairs,iif,statics,wee
|
||||
ignore-words-list = crate,keypair,keypairs,iif,statics,wee
|
||||
|
||||
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
- Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
- The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
@@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
|
||||
@@ -5,25 +5,25 @@ started.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Developer Environment Setup](#developer-environment-setup)
|
||||
* [Docker Setup](#docker-setup)
|
||||
* [Docker Caveat](#docker-caveat)
|
||||
* [Local HTTPS](#local-https)
|
||||
* [asdf-vm](#asdf-vm)
|
||||
* [Pre-commit](#pre-commit)
|
||||
* [The .env File](#the-env-file)
|
||||
* [Bootstrapping](#bootstrapping)
|
||||
* [Ensure Everything Works](#ensure-everything-works)
|
||||
* [Reporting Bugs](#reporting-bugs)
|
||||
* [Opening a Pull Request](#opening-a-pull-request)
|
||||
* [Run Tests](#run-tests)
|
||||
* [Unit Tests](#unit-tests)
|
||||
* [End-to-end Tests](#end-to-end-tests)
|
||||
* [Use Detailed Commit Messages](#use-detailed-commit-messages)
|
||||
* [Ensure Static Analysis Checks Pass](#ensure-static-analysis-checks-pass)
|
||||
* [Code of Conduct](#code-of-conduct)
|
||||
* [Asking for Help](#asking-for-help)
|
||||
- [Overview](#overview)
|
||||
- [Developer Environment Setup](#developer-environment-setup)
|
||||
- [Docker Setup](#docker-setup)
|
||||
- [Docker Caveat](#docker-caveat)
|
||||
- [Local HTTPS](#local-https)
|
||||
- [asdf-vm](#asdf-vm)
|
||||
- [Pre-commit](#pre-commit)
|
||||
- [The .env File](#the-env-file)
|
||||
- [Bootstrapping](#bootstrapping)
|
||||
- [Ensure Everything Works](#ensure-everything-works)
|
||||
- [Reporting Bugs](#reporting-bugs)
|
||||
- [Opening a Pull Request](#opening-a-pull-request)
|
||||
- [Run Tests](#run-tests)
|
||||
- [Unit Tests](#unit-tests)
|
||||
- [End-to-end Tests](#end-to-end-tests)
|
||||
- [Use Detailed Commit Messages](#use-detailed-commit-messages)
|
||||
- [Ensure Static Analysis Checks Pass](#ensure-static-analysis-checks-pass)
|
||||
- [Code of Conduct](#code-of-conduct)
|
||||
- [Asking for Help](#asking-for-help)
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -50,8 +50,7 @@ environment with working nftables and WireGuard subsystems for live development.
|
||||
|
||||
### Docker Setup
|
||||
|
||||
We recommend [Docker Desktop](
|
||||
https://docs.docker.com/engine/install/#desktop)
|
||||
We recommend [Docker Desktop](https://docs.docker.com/engine/install/#desktop)
|
||||
even if you're developing on Linux. This is what the Firezone core devs use and
|
||||
comes with `compose` included.
|
||||
|
||||
@@ -61,8 +60,7 @@ Routing packets from the host's WireGuard client through the Firezone compose
|
||||
cluster and out to the external network will not work. This is because Docker
|
||||
Desktop
|
||||
[rewrites the source address from containers to appear as if they originated the
|
||||
host](
|
||||
https://www.docker.com/blog/how-docker-desktop-networking-works-under-the-hood/)
|
||||
host](https://www.docker.com/blog/how-docker-desktop-networking-works-under-the-hood/)
|
||||
, causing a routing loop:
|
||||
|
||||
1. Packet originates on Host
|
||||
@@ -138,8 +136,8 @@ Firezone Docker services. By connecting to Firezone from the `client`
|
||||
container, you can test the WireGuard tunnel is set up correctly by pinging the
|
||||
`caddy` container:
|
||||
|
||||
* `docker compose exec client ping 172.28.0.99`
|
||||
* `docker compose exec client curl -k 172.28.0.99:8443/hello`: this
|
||||
- `docker compose exec client ping 172.28.0.99`
|
||||
- `docker compose exec client curl -k 172.28.0.99:8443/hello`: this
|
||||
should return `HELLO` text.
|
||||
|
||||
If the above commands indicate success, you should be good to go!
|
||||
@@ -154,19 +152,19 @@ issues as well.
|
||||
|
||||
If it's not there, please open a new issue and include the following:
|
||||
|
||||
* Description of the problem
|
||||
* Expected behavior
|
||||
* Steps to reproduce
|
||||
* Estimated impact: High/Medium/Low
|
||||
* Firezone version
|
||||
* Platform architecture (amd64, aarch64, etc)
|
||||
* Linux distribution
|
||||
* Linux kernel version
|
||||
- Description of the problem
|
||||
- Expected behavior
|
||||
- Steps to reproduce
|
||||
- Estimated impact: High/Medium/Low
|
||||
- Firezone version
|
||||
- Platform architecture (amd64, aarch64, etc)
|
||||
- Linux distribution
|
||||
- Linux kernel version
|
||||
|
||||
## Opening a Pull Request
|
||||
|
||||
We love pull requests! To ensure your pull request gets reviewed and merged
|
||||
swiftly, please read the below *before* opening a pull request.
|
||||
swiftly, please read the below _before_ opening a pull request.
|
||||
|
||||
### Run Tests
|
||||
|
||||
@@ -218,5 +216,4 @@ pre-commit run --all-files
|
||||
|
||||
## Asking For Help
|
||||
|
||||
If you get stuck, don't hesitate to ask for help on our [community forums](
|
||||
https://discourse.firez.one/?utm_source=contributing).
|
||||
If you get stuck, don't hesitate to ask for help on our [community forums](https://discourse.firez.one/?utm_source=contributing).
|
||||
|
||||
@@ -77,7 +77,7 @@ community support options:
|
||||
or make a contribution to Firezone.
|
||||
|
||||
If you need help deploying or maintaining Firezone for your business, consider
|
||||
[contacting us about our paid support plan](https://www.firezone.dev/contact/sales?utm_source=readme).
|
||||
[contacting us about our paid support plan](https://www.firezone.dev/sales?utm_source=readme).
|
||||
|
||||
## Star History
|
||||
|
||||
|
||||
@@ -108,6 +108,6 @@ defmodule FzHttpWeb.SettingLive.Account do
|
||||
|
||||
defp subscribe_link do
|
||||
tid = Application.get_env(:fz_http, :telemetry_id)
|
||||
"https://www.firezone.dev/contact/sales?utm_source=product&uid=#{tid}"
|
||||
"https://www.firezone.dev/sales?utm_source=product&uid=#{tid}"
|
||||
end
|
||||
end
|
||||
|
||||
138
www/blog/2022-07-25-release-0-5-0/index.mdx
Normal file
138
www/blog/2022-07-25-release-0-5-0/index.mdx
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
slug: release-0-5-0
|
||||
title: Release 0.5.0
|
||||
authors: [jamil]
|
||||
tags: [release, beta, acme, reverse proxy, docs]
|
||||
---
|
||||
|
||||
## Firezone 0.5 Released!
|
||||
|
||||
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](https://github.com/firezone/firezone/releases)! It's packed with new
|
||||
features, bug fixes, and other improvements — more on that below.
|
||||
|
||||
But first, we'd like to clarify our plan for plan for pricing.
|
||||
|
||||
### Free as in… forever?
|
||||
|
||||
One question we often get asked is, how much does Firezone cost? Well, now
|
||||
we're able to offer some clarification around pricing. **Starting with 0.5.0,
|
||||
Firezone will be entering public beta.** What's that mean for you? Two things:
|
||||
|
||||
- We'll be experimenting with different tiers and pricing structures based on
|
||||
an open-core business model. We plan to **always** have a version of the
|
||||
product free to use, forever. See our [new pricing
|
||||
page](https://firezone.dev/pricing) for more information.
|
||||
- **Edit**: The Beta program is now closed. Thanks to all who participated!
|
||||
~~Anyone participating in the public beta program **will receive a license key good
|
||||
for up to one year of** Firezone Team or Business. It's our way of saying
|
||||
thanks for being an early adopter and joining the program.~~
|
||||
|
||||
Now that that's out of the way, let's talk about all the new features in
|
||||
0.5.0!
|
||||
|
||||
### User-scoped egress rules
|
||||
|
||||
Rules can now optionally receive a user scope, limiting the rule's application
|
||||
only to devices owned by that user. This allows you to selectively allow or
|
||||
deny traffic from a particular user to an IP, set of IPs, or CIDR range.
|
||||
|
||||
### Auto-renewed, ECDSA-backed, ACME-powered SSL certificates
|
||||
|
||||
One of our most-requested features is now available — Firezone 0.5.0 supports
|
||||
ACME SSL certificate renewal backed by Let's Encrypt's new ECDSA key type.
|
||||
Other providers and key types are available too. See all ACME configuration
|
||||
options in our [configuration file
|
||||
reference](/docs/reference/configuration-file/).
|
||||
|
||||
**Note**: ACME is disabled by default to remain compatible with existing
|
||||
Firezone installations. To enable, set the following in your config file:
|
||||
|
||||
```
|
||||
default['firezone']['ssl']['acme']['enabled'] = true
|
||||
```
|
||||
|
||||
### BYORP: Bring Your Own Reverse Proxy
|
||||
|
||||
Want to disable Nginx and deploy Firezone under your own reverse proxy or HTTP
|
||||
load balancer? Well, now you can! We've documented the required headers and
|
||||
other configuration necessary to make this happen. [Check the
|
||||
docs](/docs/deploy/advanced/reverse-proxy) for some configuration
|
||||
examples for popular proxies. In short:
|
||||
|
||||
Set the
|
||||
`default['firezone']['phoenix']['external_trusted_proxies']`
|
||||
configuration variable to a comma-separated list containing the proxies
|
||||
you'd like to receive forwarded requests from. If your proxy uses an
|
||||
[RFC1918 address](https://en.wikipedia.org/wiki/Private_network), add its
|
||||
IP to `default['firezone']['phoenix']['private_clients']` instead of
|
||||
`default['firezone']['phoenix']['external_trusted_proxies']`.
|
||||
Update your proxy's configuration to point to Firezone, making sure to set
|
||||
the `X-Forwarded-For` header and enable WebSocket connection upgrades.
|
||||
|
||||
**Note:** ACME support is tied to Nginx. If you disable the bundled
|
||||
Firezone Nginx service, you'll need to provide your own SSL certificates
|
||||
(or configure ACME renewal manually).
|
||||
|
||||
**Additional note:** If you go this route, you'll need to terminate SSL
|
||||
yourself — Firezone sets the secure attribute on all cookies and thus
|
||||
requires the downstream proxy to terminate SSL.
|
||||
|
||||
### Runtime configuration available in the UI
|
||||
|
||||
Some Firezone configuration settings are now configurable in the product UI
|
||||
under the Security settings. This will override anything you have set in the
|
||||
config file. Moving runtime configuration into the application itself brings us
|
||||
a step closer to Docker-based deployments (coming Soon™).
|
||||
|
||||
### New and improved documentation
|
||||
|
||||
Our docs have been migrated from Jekyll to [Docusaurus](https://docusaurus.io).
|
||||
Aside from all the Formatting is improved, user guides are updated and many
|
||||
pages have been edited for clarify and further detail. As an added bonus, our
|
||||
docs are feature improved search thanks to the powerful search functionality
|
||||
provided by [DocSearch by Algolia](https://docsearch.algolia.com/).
|
||||
Contributions welcome!
|
||||
|
||||
### Red Hat and Debian package repositories
|
||||
|
||||
If you're on one of our [supported
|
||||
distros](/docs/deploy/omnibus/supported-platforms/) (or its
|
||||
derivatives), the one-line install script will automatically install Firezone
|
||||
from our package repository and track further updates from there. This means
|
||||
your Firezone installation can be managed like any other package on your system
|
||||
and will be marked for upgrades by the same apt and yum tools you're already
|
||||
familiar with. Be sure to check the [upgrade
|
||||
notes](/docs/administer/upgrade/) prior to each
|
||||
upgrade in case there are any backwards-incompatible changes or manual steps
|
||||
involved.
|
||||
|
||||
If you've got an existing installation and still want to add our package
|
||||
repository for easier package management, just follow the [relevant
|
||||
section](/docs/deploy/omnibus) in the manual
|
||||
install guide.
|
||||
|
||||
### Smaller package sizes
|
||||
|
||||
Speaking of packages, we've done a bit of work reducing the size of our Omnibus
|
||||
release package. The Nodejs, Python, Erlang, and Elixir runtimes have all been
|
||||
removed, reducing the package size by 50% and total installed size by even
|
||||
more. There's still lots of work to be done to be done here — we expect
|
||||
package sizes to be reduced even further moving forward.
|
||||
|
||||
### Custom landing page logo
|
||||
|
||||
In the first round of what we hope to be the start of a full-featured
|
||||
customization experience, it's now possible to change the landing page logo.
|
||||
Upload an image up to 1 MB or specify a URL to an image your end users will see
|
||||
when landing at your Firezone portal.
|
||||
|
||||
## Conclusion
|
||||
|
||||
That's all we've got for now. If you'd like to spin up Firezone to try it out,
|
||||
head to the [deploy guide](/docs/deploy) in our docs.
|
||||
|
||||
If you're interested in using Firezone in production for your Team or Business,
|
||||
[contact us](/sales) about our Business tier.
|
||||
127
www/blog/2022-10-17-release-0-6-0/index.mdx
Normal file
127
www/blog/2022-10-17-release-0-6-0/index.mdx
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
slug: release-0-6-0
|
||||
title: Release 0.6.0
|
||||
authors: [jamil]
|
||||
tags: [release, docker, saml]
|
||||
---
|
||||
|
||||
## Firezone 0.6 Released!
|
||||
|
||||
Today, I'm excited to announce we've closed the [first public issue
|
||||
](https://github.com/firezone/firezone/issues/260) 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.
|
||||
|
||||
### Docker Support
|
||||
|
||||
Docker is now the preferred method for deploying Firezone. Our [
|
||||
automatic install script](https://raw.githubusercontent.com/firezone/firezone/master/scripts/docker_install.sh)
|
||||
now uses Docker by default, and we even have a new [Docker migration script
|
||||
](https://raw.githubusercontent.com/firezone/firezone/master/scripts/docker_migrate.sh)
|
||||
that will non-destructively migrate your Omnibus-based Firezone installation
|
||||
to a Docker-based one with minimal downtime.
|
||||
|
||||
#### How to Deploy
|
||||
|
||||
You can now deploy Firezone complete with valid SSL certificates and a
|
||||
provisioned administrator in just a couple minutes:
|
||||
|
||||
<AsciinemaPlayer
|
||||
src="https://asciinema.org/a/530197.cast"
|
||||
autoplay={true}
|
||||
rows={30}
|
||||
idleTimeLimit={3}
|
||||
preload={true}
|
||||
/>
|
||||
|
||||
This also means Firezone runs on any platform that supports Docker,
|
||||
like my Mac in the video above. The automatic install script will _probably_
|
||||
barf on Windows, though. In that case, try the
|
||||
[manual install method](/docs/deploy/docker/#option-2-manual-install)!
|
||||
|
||||
#### Why Docker?
|
||||
|
||||
Docker offers a number of benefits over the old Omnibus-based method of deploying
|
||||
Firezone:
|
||||
|
||||
- **Simpler, more robust upgrades**: In most cases, simply pull the latest `firezone/firezone`
|
||||
image and restart the container.
|
||||
- **Simpler configuration**: Most day-to-day configuration of Firezone can now
|
||||
be done in the web UI instead of the `/etc/firezone/firezone.rb` configuration
|
||||
file. All other configuration variables can be specified as ENV vars to the
|
||||
Firezone container.
|
||||
- **Smaller footprint**: The Firezone image weighs in at a couple dozen
|
||||
megabytes versus hundreds of megabytes for the Omnibus package.
|
||||
- **Portability**: Firezone now runs on any platform that supports Docker.
|
||||
- **Security**: Containerization providers better security isolation than
|
||||
simply running as an unprivileged local user.
|
||||
|
||||
It also makes it easier to build and test Firezone. CI pipelines rejoice!
|
||||
No more 4-hour long compiles and intermittent build failures.
|
||||
|
||||
#### What about Omnibus?
|
||||
|
||||
[Chef Omnibus](https://github.com/chef/omnibus) is a Ruby-based build system
|
||||
designed to make building and distributing complex software easier. You define
|
||||
your dependencies as source tarballs, configure options, and platform-specific
|
||||
build flags, and Omnibus automatically fetches, builds, and links all your
|
||||
dependencies automagically, emitting an OS-native installer artifact when
|
||||
complete.
|
||||
|
||||
Omnibus was a popular choice for distributing self-hosted software before
|
||||
Docker was popular -- GitLab and Mattermost are two popular self-hosted products
|
||||
that still support Omnibus-based deployments today. It's still used in many
|
||||
cases where Docker can't be used (on the \*BSDs, for example).
|
||||
|
||||
But, since Omnibus is [effectively EOL in 2024](https://docs.chef.io/versions/)
|
||||
due to its reliance on Chef Infra Client, we've decided to deprioritize
|
||||
reliance on it, and dedicate those resources to containerized deployments
|
||||
instead.
|
||||
|
||||
**Note**: Beginning with 0.6, Omnibus support in Firezone is **deprecated**.
|
||||
We'll be removing support for it completely in a future Firezone release.
|
||||
|
||||
#### How to migrate from Omnibus to Docker
|
||||
|
||||
We've written an in-depth migration guide to migrate your instance from Omnibus
|
||||
to Docker:
|
||||
|
||||
https://www.firezone.dev/docs/administer/migrate
|
||||
|
||||
Most instances will migrate without issue. If you're running Firezone in production
|
||||
for your team or business, [contact us](/sales)
|
||||
so we can better understand how we can help with your migration.
|
||||
|
||||
### SAML 2.0
|
||||
|
||||
Also in 0.6 is preliminary support for SAML 2.0 authentication. You'll need the
|
||||
IdP Metadata XML document to set it up. In most cases the identity provider
|
||||
will provide it for you. If not, you should be able to build it manually or
|
||||
using a tool such as
|
||||
[this nifty online IdP builder](https://www.samltool.com/idp_metadata.php).
|
||||
|
||||
In general we recommend using OpenID Connect integration over SAML whenever possible.
|
||||
It's simpler, tends to be implemented more consistently across identity providers,
|
||||
and much easier to debug when things go wrong.
|
||||
|
||||
Speaking of OIDC, 0.6 also introduces a couple improvements to make integrating
|
||||
your identity provider a more pleasant experience:
|
||||
|
||||
- `auto_create_oidc_users` is now a per-provider configuration setting. Enable or disable
|
||||
autocreation of users when logging into Firezone via that provider.
|
||||
- New web form for entering OIDC details, with improved validation and error checking:
|
||||
|
||||
<center>
|
||||
<img
|
||||
width="500"
|
||||
src="https://user-images.githubusercontent.com/167144/196735853-b2c8d505-285f-40ac-9d73-4b568358c5c3.png"
|
||||
alt="OIDC Form"
|
||||
/>
|
||||
</center>
|
||||
|
||||
#### IdP not supported?
|
||||
|
||||
If your IdP isn't supported or you'd like to learn about your options for
|
||||
custom integrations, [contact us](/sales) to
|
||||
learn more about our Business plan features.
|
||||
138
www/blog/2023-01-10-first-offsite/index.mdx
Normal file
138
www/blog/2023-01-10-first-offsite/index.mdx
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
slug: first-offsite-retro
|
||||
title: Lessons from Firezone’s first off-site
|
||||
description: In December, Firezone organized an off-site in California. Here's what we learned.
|
||||
authors: [jason]
|
||||
tags: [company, off-site]
|
||||
---
|
||||
|
||||
My first tech job was at [Strong](https://www.strong.app/), a workout journal app that was pretty popular at the time. The founders were “digital nomads,” and the team was fully remote.
|
||||
|
||||
Back in 2016, this was highly uncommon.
|
||||
|
||||
We spent a lot of time creating processes to work together effectively on opposite sides of the world. One of these was meeting up in person regularly.
|
||||
|
||||
<center>
|
||||
<img
|
||||
width="800"
|
||||
src="https://user-images.githubusercontent.com/52545545/211626078-6f64a4f4-ec37-40cd-8bb5-a6b9b122f351.png"
|
||||
alt="digital nomads"
|
||||
/>
|
||||
</center>
|
||||
|
||||
At first, it was by accident. Since everyone was traveling anyway, we would coordinate being in the same city at the same time.
|
||||
|
||||
After working in person, we quickly noticed the way we worked remotely improved. People were more comfortable sharing their ideas, better at giving constructive criticism, and happier in general.
|
||||
|
||||
It just _felt_ better to work together in person.
|
||||
|
||||
## Why try this at Firezone?
|
||||
|
||||
If you believe Firezone can take a sizable bite out of the usual suspects of legacy remote access products, we’ll need to use every advantage.
|
||||
|
||||
As a startup, our biggest advantage is the ability to move quickly as a team.
|
||||
|
||||
This is much easier when everyone is comfortable sharing ideas and engaging in lively debate. Plus, it’s a lot more fun.
|
||||
|
||||
So we decided to try it out. After much planning, canceled bookings, and a few long flights, our team met in Santa Rosa, California.
|
||||
|
||||
<center>
|
||||
<img
|
||||
width="600"
|
||||
src="https://user-images.githubusercontent.com/52545545/216130487-bde66005-e3e0-4d88-a2d0-f9a842efc715.png"
|
||||
alt="offsite office"
|
||||
/>
|
||||
</center>
|
||||
|
||||
## What did we do?
|
||||
|
||||
Our itinerary included architecture planning, a multi-day hackathon, and plenty of fun activities around the Bay Area.
|
||||
|
||||
<center>
|
||||
<img
|
||||
width="600"
|
||||
src="https://user-images.githubusercontent.com/52545545/211988059-02f3083a-116b-462e-a5ff-90af4fab63fc.png"
|
||||
alt="offsite office"
|
||||
/>
|
||||
</center>
|
||||
|
||||
The focus of the off-site was building. We each defined a few tasks that could realistically be completed by the end of the trip. So what did we work on?
|
||||
|
||||
- A new Firezone gateway (coming in 0.8!) that will eventually allow decoupling the web portal from the WireGuard data plane. A single Firezone web portal will soon be able to manage hundreds or even thousands of little Firezone gateways securing access to their respective private resources. More details to come!
|
||||
- A [new REST API in 0.7](https://github.com/firezone/firezone/releases) to allow configuring Firezone in a more automatable way. Users love our snappy web portal, but nothing beats the power of an API for automation.
|
||||
- Various documentation improvements to improve consistency between Omnibus and Docker sections, detail logging, and implement a v1 style guide.
|
||||
|
||||
Of course, no visit to the Bay Area would be complete without a tour of San Francisco. It rained most of the time, so we missed out on much of the picturesque hiking. But we still managed to snap some photos of the Golden Gate bridge and devour a few In-N-Out burgers.
|
||||
|
||||
Of special mention are the team dinners. Remote companies lack that familiar bond typically formed over team lunches in the office, so we sought to recreate that when we met in person. As an added bonus, we also split cooking duties. In many ways preparing food for your teammates is like opening a pull request: make something, request feedback on it, then merge and enjoy.
|
||||
|
||||
As someone whose culinary talents rival his passion for building security products, our resident chef [Jamil](https://twitter.com/jamilbk) led most of the culinary endeavors, including a 2-hour drive around Santa Rosa in search of live Dungeness crab.
|
||||
|
||||
<center>
|
||||
<img
|
||||
width="400"
|
||||
src="https://user-images.githubusercontent.com/167144/214394961-ecbff7d8-2f9c-48a6-a906-c387366169f3.jpeg"
|
||||
alt="team dinner"
|
||||
/>
|
||||
</center>
|
||||
|
||||
## Lessons learned for next time
|
||||
|
||||
Since this was our first off-site, some things could have gone better. Here’s a small list of hiccups and other things we’d do differently next time.
|
||||
|
||||
### Turn on low power mode
|
||||
|
||||
<center>
|
||||
<img
|
||||
width="400"
|
||||
src="https://user-images.githubusercontent.com/52545545/211503302-4b2e2e74-06e8-4929-aa5b-a336af25a450.png"
|
||||
alt="team dinner"
|
||||
/>
|
||||
</center>
|
||||
|
||||
If you’re booking an Airbnb, check for planned maintenance and outages! We were notified three days before arrival the power would be out during two full workdays.
|
||||
|
||||
Fortunately, we had a small power bank and mobile hotspot with unlimited data. Unfortunately, our lead Rust engineer’s beefy Linux machine only gets a single hour of battery life on a full charge.
|
||||
|
||||
When his machine died, we migrated to our local coffee shop, where power and WiFi were surprisingly abundant. _Editor’s note: Coffee shops in Santa Rosa are much more accommodating as a makeshift office than most in San Francisco._
|
||||
|
||||
When you’re building software, electricity and internet are vital -- splurge for that bigger battery bank and faster hotspot!
|
||||
|
||||
### Lumbar support is underrated
|
||||
|
||||
You’ll sacrifice some ergonomics when you work out of an Airbnb. Put a premium on large work surfaces, open common areas, and comfortable chairs. After a few days of working hunched over on a sofa, we learned the hard way.
|
||||
|
||||
Even better, leave heads down work until after the off-site. Instead, prioritize architecture discussions, brainstorming sessions, and design sprints.
|
||||
|
||||
### Stock the right fuel
|
||||
|
||||
We got carried away at Costco. Our out-of-town guests had never witnessed the spectacle of an American snack aisle. Fortunately, our talented engineers can turn Funyuns into elegant lines of Rust code (shoutout [@Gabi](https://github.com/conectado)).
|
||||
|
||||
All jokes aside, you’ll need the right fuel for your hackathons and deep product discussions. We recommend stocking up with plenty of coffee and healthy snacks.
|
||||
|
||||
### Plan ahead: it’ll pay off
|
||||
|
||||
As is often the case with startups, we planned the trip on short notice. This meant many last-minute restaurant bookings and trips to the store for basic supplies.
|
||||
|
||||
So, make a shopping list, book a few restaurants in advance, and have a backup plan. If you’re looking for a template, take a look at this [guide](https://posthog.com/handbook/company/offsites#how-to-plan-an-offsite-in-8-weeks---a-checklist) from our friends at PostHog. A great checklist is hard to beat.
|
||||
|
||||
## What’s next?
|
||||
|
||||
In a few short days, we:
|
||||
|
||||
- Aligned on Firezone’s product direction
|
||||
- Made critical architecture decisions for the gateway and client apps
|
||||
- Made significant progress on a few key features
|
||||
- Bonded over great food, conversation, and Mario Kart
|
||||
|
||||
We could have accomplished some of these over a few long Zoom calls and chat threads, but not as quickly. There’s something about mind melding over a few days of intense work that’s hard to replicate.
|
||||
|
||||
So, will we have another off-site? Definitely!
|
||||
|
||||
Until next time!
|
||||
|
||||
:::info 👋 thanks for reading
|
||||
Firezone secures remote access to private resources. This post doesn't have much to do about security, networking, or a fancy new feature. But hey, our product improves the remote work experience - organizing a great off-site helps too.
|
||||
|
||||
If you want to try it out, our [Docker install script](/docs/deploy) gets Firezone running in just a few minutes.
|
||||
:::
|
||||
8
www/blog/_2022-10-21-3000-stars/index.mdx
Normal file
8
www/blog/_2022-10-21-3000-stars/index.mdx
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
slug: 3000-stars
|
||||
title: 3,000 GitHub Stars
|
||||
authors: [jamil]
|
||||
tags: [open-source, github]
|
||||
---
|
||||
|
||||
## 3,000 GitHub Stars
|
||||
181
www/blog/_2022-12-23-yc-as-oss-company/index.mdx
Normal file
181
www/blog/_2022-12-23-yc-as-oss-company/index.mdx
Normal file
@@ -0,0 +1,181 @@
|
||||
---
|
||||
slug: yc-oss-experience
|
||||
title: Going through YC as an open source company
|
||||
authors: [jason]
|
||||
tags: [open-source, ycombinator, company]
|
||||
---
|
||||
|
||||
# Going through YC as an open source company
|
||||
|
||||
During YC's three-month bootcamp, your goal is simple. Make meaningful progress.
|
||||
|
||||
In our batch, we met a company that made powdered breast milk. Multiple hospital networks as customers and $150k+ of MRR. Their problems were scaling production and FDA approval.
|
||||
|
||||
Firezone, our company, had launched a few weeks prior on HN. We had no revenue and only a small handful of users.
|
||||
|
||||
YC's challenge is to give advice that helps these two companies and everything in between.
|
||||
|
||||
Open-source security is a relatively new category for YC investments. About half of the 240 open-source YC investments made by YC since S05 (17 years ago) were made in the past 2 years. Only 7 are security companies.
|
||||
|
||||
During the batch, we had come up with our own interpretation of advice meant for traditional enterprise Saas or B2B freemium software companies. This post is my attempt at sharing what we did and learned in our journey.
|
||||
|
||||
## How it all started
|
||||
|
||||
As a business guy, I have long felt the business pains of a slow, clunky VPN.
|
||||
|
||||
Slow VPN speeds are an eroding pain. One that makes every task 10% slower. Like loading my Kibana dashboard, and having to wait an extra few seconds, so I go check my email or my phone. A 2 second wait that triggers a few minutes of lost productivity. A hiccup of 1 minute at the start of every zoom call that throws off all the prep I had coming into it. “How does my mic sound?”.
|
||||
|
||||
Big pains come from blockers. Halting the onboarding of a new contractor because our internal resources have not been segmented for least privilege. The contractor needs to build a website, but would get access to customer data and network access to production servers. There was no way we'd adopt a new tool for just this problem. In a past company we spent weeks installing a firewall appliance
|
||||
|
||||
When I met my co-founder Jamil last summer, he showed me a solution to these problems. A new faster VPN protocol called WireGuard (read more about that here) and a modern UX built for end users. One that's easy to self-serve for IT admins, SREs, and DevOps engineers.
|
||||
|
||||
The latter may seem like a silly differentiator, but it isn't. In the past software was sold top-down to large companies. The buyer was often not the user, so products with a laundry list of features won. They checked all the boxes.
|
||||
|
||||
In fact, for many of Firezone's users, a VPN was a checkbox. A feature that came with their legacy firewall that's cumbersome to deploy and configure. Not to mention that firewall is now sitting in an empty office as employees move to remote work.
|
||||
|
||||
This wasn't apparent to us at the beginning, but after we posted our project to HN, we quickly realized technical IT staff needed a product like Firezone.
|
||||
|
||||
## Why open-source?
|
||||
|
||||
Firezone is core IT infrastructure. It deals with network security and cryptography, and runs in pretty sensitive environments. On your employee's laptops and behind firewalls on your servers. Private data about your company and customers flow through our gateways and apps. And with remote work, almost every employee relies on it to get work done.
|
||||
|
||||
We don't expect many organization to run such critical software without knowing what's in it.
|
||||
|
||||
We also don't expect all organizations to leave control of their network to a third party. One that can experience outages, be targeted by hackers, or even snoop on your data themselves.
|
||||
|
||||
So we leave it all open for you to see and make it easy to host yourself.
|
||||
|
||||
Of course, there are other benefits of building in the open. We hired world class engineers, but with such a complex product mistakes can happen. More eyes on our code means vulnerabilities are spotted and resolved faster. As we've grown, we are even getting contributions from the community.
|
||||
|
||||
## Why Y Combinator?
|
||||
|
||||
After our ShowHN, a long list of feature requests appeared in our GitHub repo. A list we couldn't close alone. At least not within a reasonable amount of time.
|
||||
|
||||
For a new product with no revenue (yet), VC funding seemed to fit. It would allow us to create something for the community and in parallel investigate the right model to build a sustainable business. As first time founders, YC seemed like a good fit. After all, they helped GitLab and Mattermost get off the ground.
|
||||
|
||||
A brief summary for those that don't know. For a stake in your company, YC offers 3 things: capital, advice, and community.
|
||||
|
||||
When we accepted the invitation, YC's investment was $125k for 7% of our company. A few weeks into the batch we were offered an additional $375k as an uncapped MFN safe. Lucky us! You can read more about it here.
|
||||
|
||||
Advice comes in the form of interactive workshops and long-form posts. They are invaluable resources and often come with snappy titles, like “how not to fail”.
|
||||
|
||||
Community is YC's magic. Thousands of past founders who can make introductions to investors, give advice, and even become users of your product. They can help you understand what “how not to fail” should mean to an open-source security company. Same with general advice on setting metrics, talking to users, and pricing.
|
||||
|
||||
Here's some of our learnings.
|
||||
|
||||
## Should I collect telemetry?
|
||||
|
||||
As a VC backed-startup, probably yes.
|
||||
|
||||
Even with a crystal ball on what users want, metrics can still help identify reliability issues and add insight to reported bugs.
|
||||
|
||||
From a business point of view, they tell you who and how many people like your product and which features are getting used.
|
||||
|
||||
It's a great way to focus the team on what matters.
|
||||
|
||||
Best of all when the data-points start lining up like a hockey stick, it can get you the funding you need to build a great product.
|
||||
|
||||
YC's advice is to set a primary metric that accurately captures the value you're delivering to users. This primary metric should be paired with secondary metrics that drive the primary metric and you can actionably move and iterate on.
|
||||
|
||||
In case you're curious, we've set users in production as our primary metric. Our secondary metrics help add context to the growth.
|
||||
|
||||
For example, here are 3 different graphs of our progress near demo day. Our star count, number of live instances, and number of devices. Each graph tells a slightly different story. Star count shows growing awareness in the open-source community. Instances show steady growth in actual adoption. Number of users tell us more about the deployments of Firezone. Since it outpaced the growth of instances, we knew larger teams were adopting Firezone over time and existing deployments were growing inside organizations.
|
||||
|
||||

|
||||
|
||||
So, how do you measure usage? Not as simple as you think.
|
||||
|
||||
For most software products, telemetry is a small script in the header of your website and an annoying cookie banner. Sometimes it's also a few lines of code sprinkled through the backend. Most users expect to be tracked by the hosted services they use. They may not like it, but they generally won't fuss about it.
|
||||
|
||||
Open-source is different.
|
||||
|
||||
Though it's getting more common, not everyone expects a self-hosted open-source project to report their usage. We had to be careful what we tracked, how we anonymized it, and how we communicate it to users.
|
||||
|
||||
We spoke to a few other open source companies we respected. Here's the advice we received.
|
||||
|
||||
- Explain why you do it: Document what you track, how it's stored, and what you use it for. We took heavy inspiration from companies like Mattermost and made our own page in our documentation.
|
||||
- Make it clear and easy to opt-out: To make it simple for users, we created a deployment script that streamlines the install process. In the script we explicitly ask for permission and make it easy to switch off later directly in the UI.
|
||||
- Don't unnecessarily expose user data to third parties: Those annoying cookie banners on websites you visit generally mean one thing. You're being tracked, and your information is being sent to third party tools like CRMs and ad platforms. If you've signed up for an account and checked the box for terms and conditions, you're agreeing to that as well. With Firezone, we try to use open-source and self-hosted products whenever possible. This includes our telemetry platform as well.
|
||||
|
||||
So, now we know about users in aggregate.
|
||||
|
||||
But, our product is early and legacy VPNs are painful in many ways. We need more information to prioritize what to build first. The best way to do that is by talking to users.
|
||||
|
||||
## We don't know who our users are
|
||||
|
||||
“Write code and talk to users” is consistently echoed during YC.
|
||||
|
||||
A great summary why is in “do things that don't scale”. I recommend reading the article, but it boils down to this:
|
||||
|
||||
You often build the initial product for yourself. The MVP is usually not good enough - it's never quite right. You should get it in front of users as soon as it provides utility so you can get feedback to iterate and improve.
|
||||
|
||||
The average user of Firezone is technical. Usually a system admin, IT manager, or DevOps engineer. They're fully capable of setting up Firezone and reading our docs to figure out what the product can do.
|
||||
|
||||
We get frequent GitHub issues and Discourse posts pointing at issues or desired features. Sometimes they'll even fix it for us!
|
||||
|
||||
However, Firezone does not require a valid email to sign up. It's hosted entirely on your infrastructure. It would be weird to lock anything behind a signup.
|
||||
|
||||
I would be equally distasteful to hijack discussions with requests for a user interview.
|
||||
|
||||
So, to generate more conversations, we increased the surface area of how users can reach us. It's important to note who you're getting feedback from as well. Often for developer facing products, the person that's deploying the product is not the person who decides what to use, what the budget is, or even the only one benefiting from it.
|
||||
|
||||
Firezone ties into security playbooks, compliance requirements, hiring plans for contractors globally, and risk planning from risk departments.
|
||||
|
||||
Here's how we're currently reaching them:
|
||||
Source Types of conversations Who we speak with
|
||||
Install script email (opt-in) Deployment issues ICs, IT Managers
|
||||
Slack Group and Discourse threads Deployment and configuration issues ICs, IT Managers
|
||||
GitHub issues Feature requests ICs, IT Managers, IT Leaders
|
||||
Inbound sales leads Required functionality, pricing discussions CTO, CISO, IT Leaders
|
||||
Outbound leads Problem discovery, product roadmap planning CTO, CISO, IT Leaders
|
||||
|
||||
One example of why it's important to dig deeper involves a request to “load a custom logo”. When we got on a Zoom call, we would uncover a group of re-sellers who want to white-label our product with their clients. Turns out they have other requirements they'd be happy to pay for if we had them.
|
||||
|
||||
These conversations helped make the product better and form our view on our business model.
|
||||
|
||||
This leads into the final piece of advice from YC, pricing.
|
||||
|
||||
## Paying user feedback > free users
|
||||
|
||||
Figuring out your pricing model and generating meaningful revenue is the great filter between early MVPs and successful companies.
|
||||
|
||||
The main question however is when.
|
||||
|
||||
With limited resources, generating revenue is almost always a tradeoff. Less growth, slower development of features, and the potential to ruin a perfectly good story for investors. Queue Silicon Valley:
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/BzAdXyPYKQo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
||||
So, when to figure out revenue?
|
||||
|
||||
For B2B software, the answer should probably be “right now”.
|
||||
|
||||
Steering early user conversations toward pricing tells you if the product is viable and solves a big enough pain. YC echoes this advice.
|
||||
|
||||
A startup I previously worked at, Kite, failed partly because we punted the question of “will people pay?” too many times. It was an AI powered co-pilot, an early iteration of GitHub Copilot.
|
||||
|
||||
When we finally tried, it was clear the product needed to evolve to generate meaningful revenue. By the time we realized that, it was too late. Adam, the founder of Kite and an investor in Firezone, recently open-sourced the codebase and wrote a great post-mortem:
|
||||
|
||||
https://www.kite.com/blog/product/kite-is-saying-farewell/
|
||||
|
||||
For self-hosted open-source software the answer is not as clear.
|
||||
|
||||
[As a self-hosted security product, layering feature gating logic into the core product is problematic. Feature flags are complex to write, and even harder to maintain as our product evolves. Being critical infrastructure for remote work, we also don't want your company to come to a halt when your credit card expires. There's more to say here, but I'll leave this to a future deep-dive from my co-founder, Jamil.]
|
||||
|
||||
So, similar to other successful open-source projects, our early goal was to grow the community. During YC we focused on building out the core parts of our platform, driving adoption, and optimizing for learning from our users. One of things we wanted to learn was how to build a business around Firezone.
|
||||
|
||||
As usage grew, a pattern emerged when talking to users. Our largest deployments all started with an individual spinning Firezone up without ever speaking to us.
|
||||
|
||||
As usage grew, they reached out to inquire about additional features and services.
|
||||
|
||||
As we continue to develop our pricing model, we want to ensure the following:
|
||||
- Individuals and hobbyists can use Firezone for free
|
||||
- Small teams can use Firezone for free (if they support it themselves)
|
||||
- Large organizations can run a PoC without any calls with sales
|
||||
|
||||
If this sounds familiar, it's similar to how GitLab thinks about their pricing. We're obviously big fans.
|
||||
|
||||
## Paying it forward (still writing this part...)
|
||||
|
||||
[not sure how to end this]
|
||||
|
||||
- https://a16z.com/2019/10/04/open-source-from-community-to-commercialization/
|
||||
544
www/blog/_2023-02-13-ebpf-firewall/index.mdx
Normal file
544
www/blog/_2023-02-13-ebpf-firewall/index.mdx
Normal file
@@ -0,0 +1,544 @@
|
||||
---
|
||||
slug: ebpf-firewall
|
||||
title: How We Built an eBPF-based General Purpose Packet Filter
|
||||
authors: [conectado]
|
||||
tags: [ebpf, firewall, rust, aya]
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
As part of our migration to multi-site in Firezone the VPN and Firewall were rewritten in Rust. As part of that rewrite we decided to improve how we were handling the firewall.
|
||||
|
||||
In the past we were using [nftables](https://netfilter.org/projects/nftables/), the way we did this was shelling-out to the console and use the nft cli.
|
||||
|
||||
This has a number of problems, for one shelling out can be prone to error, inefficient and hard to unit-test, also there's no Rust lib to call into nftables and even the existing libraries in C can be too complicated to use. Furthermore, we were limited to nft's data structure which meant doing a lot of work to not mess up the rules, this in turn made doing improvements really slow.
|
||||
|
||||
So after a lot of consideration we decided that creating our own firewall using [ebpf](https://ebpf.io/).
|
||||
|
||||
## eBPF
|
||||
|
||||
We will briefly go into what eBPF is, however If you want a more detailed introduction you can take a look at [the official introduction](https://ebpf.io/what-is-ebpf).
|
||||
|
||||
### What is eBPF
|
||||
|
||||
eBPF stands for extended Berkeley Packet Filter, which is an upgrade from BPF(Berkely Packet Filter), while eBPF brings a lot of improvements over BPF the gist is the same, run user-defined packet-filtering code inside of the kernel as part of the packet processing pipeline.
|
||||
|
||||
This is an oversimplification because eBPF programs can be hooked into multiple different events in the kernel but for our intent and purposes, we just want to hook into the packet-classifier pipeline.
|
||||
|
||||
|
||||
### How the kernel safely run user-defined code
|
||||
|
||||
eBPF has its own ISA and there is a runtime for said ISA in the kernel (JIT'd), the instructions allows calling into parts of the kernel that we might need and gives us the necessary context to process a given packet.
|
||||
|
||||
Furthermore, to prevent crashes in the kernel and hogging out resources before an eBPF program gets loaded into the kernel it goes through a verification process, a verificator program sets a bunch of limitations to the program to prevent situations like infinite loops and crashes:
|
||||
|
||||
* It sets an upper-bound for the number of times a loop within the code can run (or strictly prohibits them in older kernel versions).
|
||||
* An upper-bound in the number of instructions the program can execute in total.
|
||||
* Keeps tracks of read/writes to know that you are using valid memory locations.
|
||||
|
||||
To know the specifics of how it works, you should take a look at the [kernel's doc](https://www.kernel.org/doc/Documentation/networking/filter.txt) and even more in details you can take a look at [cillium's docs](https://docs.cilium.io/en/stable/bpf/#bpf-guide).
|
||||
|
||||
### Packet pipeline
|
||||
|
||||
Without getting into the specific an eBPF program can be hooked into different hooks on the packet processing pipeline for the linux kernel. eBPF allows hooking into [XDP](https://www.iovisor.org/technology/xdp) which runs just after the packet reached the NIC. However, [XDP doesn't support Wireguard](https://lore.kernel.org/netdev/20200813195816.67222-1-Jason@zx2c4.com/T/) since wireguard doesn't have L2 headers, for more info on this see [this fly.io blogpost](https://fly.io/blog/bpf-xdp-packet-filters-and-udp/#xdp).
|
||||
|
||||
Fret not, for eBPF can also hook into the network's [TC Ingress](https://man7.org/linux/man-pages/man8/tc-bpf.8.html) that doesn't make any assumption about the packet's header.
|
||||
|
||||
### Maps
|
||||
|
||||
Maps are the kernel structures that enables us to share data between the eBPF kernel program and a user-space program. Maps, as their name suggest allow us to store relations as `Key -> Value` the types of maps offered by eBPF is limited however there are a lot of them. For our use case we just need to concern us with [trie](https://github.com/torvalds/linux/blob/master/kernel/bpf/lpm_trie.c) and hash maps.
|
||||
|
||||
Again I reffer to [cillium's documentation](https://docs.cilium.io/en/v1.12/bpf/#maps) for more information.
|
||||
|
||||
### TL;DR
|
||||
|
||||
eBPF is an ISA and its corresponding implementation for user-defined programs that run in the kernel that we used for filtering packets, however, the programs we can run have some severe limitations so that they don't crash the kernel.
|
||||
|
||||
## Firewall
|
||||
|
||||
With this in mind we wanted to write a Firewall that can allow/deny traffic based on the following:
|
||||
|
||||
- Destination CIDR
|
||||
- Possibly multiple sender IPs
|
||||
- Possibly a port-range along associated with UDP, TCP or both
|
||||
|
||||
We took an additional simplification to make the implementation easier(we will see why further along), you can configure the firewall to allow all or deny all, then when a packet match a rule it'd invert that behavior:
|
||||
> A firewall that denies all traffic with a rule for destination `10.20.30.40`, would deny all traffic from all sources to all destinations except for traffic for `10.20.30.40` from any destination.
|
||||
|
||||
### Aya
|
||||
|
||||
When implementing the firewall in Rust two possible libraries:
|
||||
|
||||
- [aya](https://github.com/aya-rs/aya)
|
||||
- [redbpf](https://github.com/foniod/redbpf)
|
||||
|
||||
`redbpf` relies on bindings to `libbpf` while `aya` only relies on `libc`, also, aya's tooling seems to be easier to use and it uses cargo's target for ebpf instead of relying on `cargo bpf` which is easier when writing the Firewall as a library.
|
||||
|
||||
So taking that into account we went with `aya`.
|
||||
|
||||
Normally, the way an aya program is structured: we have a user-space crate that loads the eBPF program and is a proxy between it and the user and a crate that targets eBPF which has more limitations(such as being `no-std`).
|
||||
|
||||
Aya normally expects to be run as a binary and not as a library or as a separate userspace/bpf library, so we needed to do some tuning for the template to be able to run it as we wanted, a single library crate that you include.
|
||||
|
||||
More about how we did this in a separate blogpost.
|
||||
|
||||
### Architecture
|
||||
|
||||
** TODO: ** Add diagrams
|
||||
|
||||
So, with this information, we can plan an architecture.
|
||||
|
||||
Thinking about the steps how ideally, the firewall would work:
|
||||
|
||||
1. A packet arrives
|
||||
2. The source is classified into a `user_id` if any
|
||||
3. Check existing rules if match
|
||||
4. Decide REJECT/ACCEPT action based on previous step
|
||||
|
||||
Let's go over how we can achieve this.
|
||||
|
||||
### The anatomy of a rule
|
||||
|
||||
As we said before a rule has 3 components
|
||||
|
||||
- Associated `user_id`
|
||||
- Destination CIDR
|
||||
- Destination Port Ranges
|
||||
|
||||
The `user_id` is an arbitrary name, the idea is that a single rule can associate multiple source ips, so we can associate a rule with an `id` and then we can update the `id` association with multiple ips during runtime.
|
||||
|
||||
Rules need to be stored in eBPF's maps, that way we can update the maps during run-time from userspace to be able to update the rules.
|
||||
|
||||
And we need to be able to lookup those maps using information from the incoming packets.
|
||||
|
||||
The way we did this is having the following maps:
|
||||
|
||||
- `SOURCE_MAP`: A hashmap mapping source ips to `id`s
|
||||
- `RULE_MAP`: A trie mapping CIDR to port ranges
|
||||
|
||||
** Note: ** There is actually an ipv6 and ipv4 version for both of those maps, so we have 4 maps in total.
|
||||
|
||||
### `SOURCE_MAP`
|
||||
|
||||
The `SOURCE_MAP` is really simple, we store the mapping IP -> ID, so we can associate let's say IP `10.10.10.3` and `10.10.10.4` with id `4` and `10.1.1.5` with id `7`. Now when a packet comes from `10.10.10.4` we lookup the map and get `4` and for `10.1.1.5` we get `7`.
|
||||
|
||||
### `RULE_MAP`
|
||||
|
||||
[Tries](https://en.wikipedia.org/wiki/Trie) are prefix-matching trees, they let us efficiently store and lookup ranges grouped by prefix. For ips this is exactly how [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) works.
|
||||
|
||||
The nodes in the trie tree correspond to a an ip and a prefix, so `10.5.8.0/24` corresponds to to the bits of `10.5.8.0` and 24 bits so that node would match with `10.5.8.0` to `10.5.8.255` but if you store `10.5.8.128/25` that'd match with `10.5.8.128` to `10.5.8.255`.
|
||||
|
||||
Both nodes, `10.5.8.0/24 and `10.5.8.128/25`, could be stored but the `lookup` method in the `trie` only allows us to find the node with the most specific match. so `10.5.8.110` would match with `10.5.8.0/24` and `10.5.8.170` would match with `10.5.8.128/25` but we would never learn that it also match with `10.5.8.0/24`.
|
||||
|
||||
So a trie would give us a way to associate CIDR with... something? The question is what's this "something".
|
||||
|
||||
Well, we don't need an action, since we know the action is just inverting the default one. What we still lack to know if the rule matches is a port-range(With its protocol) and the associated `id`.
|
||||
|
||||
However, if we store multiple rules, all associated with the same destination IP we would need to lookup all the rules for each packet and this is incredibly inefficient. But there's a solution, we can easily store the ID and protocol in the key!
|
||||
|
||||
So instead of storing as the key `10.5.8.0/24` and when we do lookup we get all the other data we store as the key `6.TCP.10.5.8.0` and the prefix instead of 24 is 33, 4 extra bytes for the id, 1 for the protocol(We use the protocol number).
|
||||
|
||||
If this is still unclear we will see more when we discuss the specific of the code, just know that we store the id and protocol as part of the key, so we can compose the number `id.protocol.ip` with the prefix and look that up.
|
||||
|
||||
The result value will be the port range, which we have to map to the port of the incoming packet, we will talk more about how we do this below.
|
||||
|
||||
For sources with no id we use `0` as the id. For non-TCP/UDP packets, we store the rule in both the TCP and UDP key and look up TCP(arbitrarily) but only match for port 0 (which we use to encode all ports), for rules with both protocols, we store the rule twice once for TCP and once for UDP.
|
||||
|
||||
### Another look at the ip matching
|
||||
|
||||
Let's look again at the steps when a packet arrives:
|
||||
|
||||
1. Packet arrives
|
||||
2. Lookup destination IP get an ID or use 0
|
||||
3. Create the lookup key (ID.PROTOCOL.DESTINATION_IP)
|
||||
4. Use the lookup key to get the port ranges
|
||||
5. Lookup the port in the port ranges
|
||||
6. REJECT/ACCEPT based on that
|
||||
|
||||
Basically, this is a high-level on how the ebpf side works. Now, let's take a look at the userspace-side.
|
||||
|
||||
### Userspace
|
||||
|
||||
Now that we know how we access the rules let's see how we need to store them from userspace.
|
||||
|
||||
Remember, that the Trie map provided by the kernel, for search, only have its lookup method that let us know the longest prefix. So let's think about this scenario:
|
||||
|
||||
We store these rules:
|
||||
|
||||
```
|
||||
10.0.0.0/24 port 80 Allowed
|
||||
10.0.0.1/32 port 23 Allowed
|
||||
```
|
||||
|
||||
now a packet comes from 10.0.0.1 with port 80, and we use the Trie lookup method to see if it's allowed, the lookup method returns all the ports from the longest prefix, meaning port 23 is allowed but the packet has port 80 so it's denied.
|
||||
|
||||
This is of course, erroneous because IP `10.0.0.1` is part of range `10.0.0.0/24` which has port 80 is allowed. So what do we do about this? Changing the trie API is impossible without modifying the kernel and even if we submit the PR for that the new API would only be included in the latest kernels.
|
||||
|
||||
We could lookup manually each range before deciding an action, so when packet with `10.0.0.1` comes we check `10.0.0.1/32` then `10.0.0.0/31` the `10.0.0.0/30` so on and so on before taking a decision. The performance of this is bad, specially if we are going to do that about each packet.
|
||||
|
||||
What we can do, is from userspace present an API that when adding rules, it propagates them to all pertinent ips, so:
|
||||
|
||||
If you have:
|
||||
|
||||
```
|
||||
10.0.0.1/32 port 23 Allowed
|
||||
```
|
||||
|
||||
and you want to add `10.0.0.0/24 port 80`, the API would automatically propagate it to:
|
||||
|
||||
```
|
||||
10.0.0.1/32 port 23, 80 Allowed
|
||||
10.0.0.0/24 port 80 Allowed
|
||||
```
|
||||
|
||||
and if you have:
|
||||
|
||||
```
|
||||
10.0.0.0/24 port 80 Allowed
|
||||
```
|
||||
|
||||
then you add `10.0.0.1/32 port 23` the api actually updates the rules like:
|
||||
|
||||
```
|
||||
10.0.0.1/32 port 23, 80 Allowed
|
||||
10.0.0.0/24 port 80 allowed
|
||||
```
|
||||
|
||||
So you see, how the api automatically propagates rules to have a consistent table.
|
||||
|
||||
### Port Ranges
|
||||
|
||||
## At last, CODE!
|
||||
|
||||
With the previous section you should have a clear picture at the architecture of what we built and why but from now on we will **need** to see code.
|
||||
|
||||
Will not go over how Aya's API or eBPF code works, hopefully it will be self-evident with the explanations until now enough to understand the gist of it.
|
||||
|
||||
### Code structure
|
||||
|
||||
We have 3 crates in our repo:
|
||||
* Userspace
|
||||
* Common (This contains the codebase shared by both)
|
||||
* eBPF
|
||||
|
||||
From userspace we have the `Firewall` which is the entrypoint for everything. You first initialize and load a firewall by calling `Firewall::new` for a given interface.
|
||||
|
||||
The most interesting part is the `RuleTracker` this is an internal struct (which is almost directly exposed by `Firewall` using pass-through methods), this is where the magic happens, userspace `Rule`s are converted into valid eBPF `Rule`, we keep track of them to propagate them and obviously add them to the maps in eBPF.
|
||||
|
||||
So let's see how that happens.
|
||||
|
||||
### A rule
|
||||
|
||||
#### eBPF
|
||||
|
||||
So, how does a rule looks in reality:
|
||||
|
||||
```rs
|
||||
#[repr(C)]
|
||||
pub struct RuleStore {
|
||||
// Sorted non-overlapping ranges
|
||||
// bit 0-15: port-start
|
||||
// bit 16-31: port-end
|
||||
rules: [u32; MAX_RULES],
|
||||
rules_len: u32,
|
||||
}
|
||||
```
|
||||
|
||||
Structs in eBPF need to be `repr(C)`, which just means it uses C's ABI, eBPF structs need to be simple array of bytes (with no padding to convince the eBPF verifier that we never read uninitialized memory).
|
||||
|
||||
So, let's analyze this struct, this is the value that we are going to store in the map. This only need to be the port-ranges (remember that the key already stores the `id`, `destination`, `protocol`).
|
||||
|
||||
So we store the rules as an array of port-ranges. With a range being the inclusive intervals of the port covered by the rule. we use the first 2 bytes for the starting port and the last 2 bytes for the ending port.
|
||||
|
||||
Then in `rules_len` we just have the number of rules stored (the rest is padded with 0).
|
||||
|
||||
#### Useraspace
|
||||
|
||||
From userspace we have many different structs that represent a rule at different stage of processing, these are not complex but we have different parts of the code that require different information for what to do with the rule.
|
||||
|
||||
But for user-facing API a rule looks like:
|
||||
|
||||
```rs
|
||||
pub enum Rule {
|
||||
V4(RuleImpl<Ipv4Net>),
|
||||
V6(RuleImpl<Ipv6Net>),
|
||||
}
|
||||
```
|
||||
|
||||
Alright, not very interesting without knowing how `RuleImpl` looks:
|
||||
|
||||
```rs
|
||||
pub struct RuleImpl<T> {
|
||||
pub(crate) id: Option<u32>,
|
||||
pub(crate) dest: T,
|
||||
pub(crate) port_range: Option<PortRange>,
|
||||
}
|
||||
```
|
||||
|
||||
So we see that a rule in userspace contains all the information for a rule but the important part is:
|
||||
|
||||
```rs
|
||||
pub(crate) struct PortRange {
|
||||
pub(crate) ports: RangeInclusive<u16>,
|
||||
pub(crate) proto: Protocol,
|
||||
}
|
||||
```
|
||||
|
||||
Cool! Use rust's `RangeInclusive<T>` to represent ports with `u16` as a port and a `Protocol` (which is just an enum to indicate the kind of rule)
|
||||
|
||||
So when we do `Firewall::add_rule(rule)` we need to make it arrive to eBPF with the struct we previously saw.
|
||||
|
||||
We also need to propagate correctly like we saw in the previous userspace architecture, so let's walk through how does that work!
|
||||
|
||||
#### Translation
|
||||
|
||||
So at some point we want to add the `rule` to the eBPF map. For that, we first need to determine the key that we are going to use.
|
||||
|
||||
That's easy:
|
||||
|
||||
```rs
|
||||
// Convert the id to big endian bytes
|
||||
let key_id = id.to_be_bytes();
|
||||
|
||||
// Convert the ip to bytes
|
||||
let key_cidr = ip.normalize().as_octets();
|
||||
let mut key_data = [0u8; N];
|
||||
|
||||
// Store in a new `key_data`: protocol.id.ip
|
||||
let (left_key_data, cidr) = key_data.split_at_mut(5);
|
||||
let (id, prot) = left_key_data.split_at_mut(4);
|
||||
prot[0] = proto;
|
||||
id.copy_from_slice(&key_id);
|
||||
cidr.copy_from_slice(key_cidr.as_ref());
|
||||
|
||||
// Calculate the prefix and return the eBPF key
|
||||
Key::new(
|
||||
u32::from(ip.prefix()) + (left_key_data.len() * 8) as u32,
|
||||
key_data,
|
||||
)
|
||||
```
|
||||
|
||||
Cool, this is the key that we are going to insert to the eBPF map
|
||||
|
||||
Now we need to calculate the value that we are going to insert.
|
||||
|
||||
Remember that the `rule` field in the ebpf `RuleStore` looked like this:
|
||||
|
||||
```rs
|
||||
rules: [u32; MAX_RULES],
|
||||
```
|
||||
|
||||
So we have a maximum number of rules, one reason for this, is that we need to store an array, we can't store a vector (we can't share heap allocations). But this number is also limited by the lookup algorithm.
|
||||
|
||||
Remember, that the verifier imposes a limit on the number of times a loop can run, so if we linearly search all ranges we were getting capped at around 1000 intervals we would reach the upper limit on loops, this is okay, this would be enough but we can do better.
|
||||
|
||||
If we can somehow sort the port ranges we could do binary search, this means less loop iterations and faster lookup in general. But how to sort it exactly?
|
||||
|
||||
This is actually the reason each rule, doesn't have an Accept/Reject instead it only inverts the default behavior, also why we store all UDP rules together and TCP rules together.
|
||||
|
||||
To sort, we just need to merge intervals. Merging intervals is a well studied problem that can be done in `O(N)` and since it's from userspace we could afford worse performance.
|
||||
|
||||
Mergining intervals just means that from the existing intervals we create a series of new non-overlapping intervals that cover the same area and we sort them.
|
||||
|
||||
So `[10-20, 15-30, 6-9]` would become `[6-9, 10-30]`. Then we can do binary search on this interval. We will see below the specific of that but this is the code to get the intervals from a series of port ranges:
|
||||
|
||||
|
||||
```rs
|
||||
fn resolve_overlap(port_ranges: &mut [&PortRange<T>]) -> Vec<(u16, u16)>
|
||||
{
|
||||
let mut res = Vec::new();
|
||||
|
||||
// Sort the ranges by the starting potr
|
||||
port_ranges.sort_by_key(|p| p.ports.ports.start());
|
||||
|
||||
Get the first prot into the result
|
||||
if let Some(range) = port_ranges.first() {
|
||||
res.push((*range.ports.ports.start(), *range.ports.ports.end()));
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
|
||||
// Go through each range
|
||||
for range in &port_ranges[1..] {
|
||||
let last_res = res
|
||||
.last_mut()
|
||||
.expect("should contain at least the first element of port_ranges");
|
||||
|
||||
// If the new range fall within the last one extend it
|
||||
if last_res.1 >= *range.ports.ports.start() {
|
||||
*last_res = (last_res.0, last_res.1.max(*range.ports.ports.end()));
|
||||
// Otherwise, add a new range
|
||||
} else {
|
||||
res.push((*range.ports.ports.start(), *range.ports.ports.end()));
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
```
|
||||
|
||||
As you see doing this is really easy. We still need to do some small work to get it from `Vec<(u16, u16)>` to `[u32; RULE_MAX]` but you can imagine it's pretty trivial.
|
||||
|
||||
### Propagating Rules
|
||||
|
||||
Then the last interesting part from userspace is how to propagate the rules.
|
||||
|
||||
So when you insert a new rule, you need to keep track of all the rules that would include it, since when a lookup happen it would return the new rule because it's more specific. So basically the gist is traverse all rules and include all the port ranges from those "above" in the new rule.
|
||||
|
||||
```rs
|
||||
(The code here requires a lot of context on the specifics of how we did this but it's nothing interesting, check if you can rewrite it in a "context-free" way)
|
||||
```
|
||||
|
||||
And then there could be more specific rules that are included in the new rule, you need to propagate the new rule (the port-range) to those.
|
||||
|
||||
```rs
|
||||
(The code here requires a lot of context on the specifics of how we did this but it's nothing interesting, check if you can rewrite it in a "context-free" way)
|
||||
```
|
||||
|
||||
### eBPF Rule lookup
|
||||
|
||||
|
||||
When a packet arrives we first extract the network headers (source, destination, protocol and port).
|
||||
|
||||
```rs
|
||||
let (source, dest, proto) = load_ntw_headers(&ctx, version)?;
|
||||
let port = get_port(&ctx, version, proto)?;
|
||||
let class = source_class(source_map, source);
|
||||
let action = get_action(class, dest, rule_map, port, proto);
|
||||
```
|
||||
|
||||
Then, we get the source id:
|
||||
|
||||
```rs
|
||||
unsafe fn source_class<const N: usize>(
|
||||
source_map: &HashMap<[u8; N], u32>,
|
||||
address: [u8; N],
|
||||
) -> Option<[u8; 4]> {
|
||||
source_map.get(&address).map(|x| u32::to_be_bytes(*x))
|
||||
}
|
||||
```
|
||||
Then we try to calculate what action we should take:
|
||||
|
||||
```rs
|
||||
fn get_action<const N: usize, const M: usize>(
|
||||
group: Option<[u8; 4]>,
|
||||
address: [u8; N],
|
||||
rule_map: &LpmTrie<[u8; M], RuleStore>,
|
||||
port: u16,
|
||||
proto: u8,
|
||||
) -> i32 {
|
||||
let proto = if port == 0 { TCP } else { proto };
|
||||
let default_action = get_default_action();
|
||||
|
||||
let rule_store = rule_map.get(&Key::new((M * 8) as u32, get_key(group, proto, address)));
|
||||
if is_stored(&rule_store, port) {
|
||||
return invert_action(default_action);
|
||||
}
|
||||
|
||||
if group.is_some() {
|
||||
let rule_store = rule_map.get(&Key::new((M * 8) as u32, get_key(None, proto, address)));
|
||||
if is_stored(&rule_store, port) {
|
||||
return invert_action(default_action);
|
||||
}
|
||||
}
|
||||
|
||||
default_action
|
||||
}
|
||||
```
|
||||
|
||||
Here we try to extract the action from the existing map, we get the `RuleStore` by constructing the key corresponding to that packet:
|
||||
|
||||
```rs
|
||||
fn get_key<const N: usize, const M: usize>(
|
||||
group: Option<[u8; 4]>,
|
||||
proto: u8,
|
||||
address: [u8; N],
|
||||
) -> [u8; M] {
|
||||
let group = group.unwrap_or_default();
|
||||
let mut res = [0; M];
|
||||
let (res_left, res_address) = res.split_at_mut(5);
|
||||
let (res_group, res_proto) = res_left.split_at_mut(4);
|
||||
res_group.copy_from_slice(&group);
|
||||
res_proto[0] = proto;
|
||||
res_address.copy_from_slice(&address);
|
||||
res
|
||||
}
|
||||
```
|
||||
And most importantly we lookup in the rulestore if the `port` that arrived exists.
|
||||
|
||||
```rs
|
||||
pub fn lookup(&self, val: u16) -> bool {
|
||||
// 0 means all ports
|
||||
if self.rules_len > 0 {
|
||||
// SAFETY: We know that rules_len < MAX_RULES
|
||||
if start(*unsafe { self.rules.get_unchecked(0) }) == 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We test for 0 in all non tcp/udp packets
|
||||
// it's worth returning early for those cases.
|
||||
if val == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reimplementation of partition_point to satisfy verifier
|
||||
let mut size = self.rules_len as usize;
|
||||
// appeasing the verifier
|
||||
if size >= MAX_RULES {
|
||||
return false;
|
||||
}
|
||||
let mut left = 0;
|
||||
let mut right = size;
|
||||
#[cfg(not(feature = "user"))]
|
||||
let mut i = 0;
|
||||
while left < right {
|
||||
let mid = left + size / 2;
|
||||
|
||||
// This can never happen but we need the verifier to believe us
|
||||
let r = if mid < MAX_RULES {
|
||||
// SAFETY: We are already bound checking
|
||||
*unsafe { self.rules.get_unchecked(mid) }
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
let cmp = start(r) <= val;
|
||||
if cmp {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid;
|
||||
}
|
||||
size = right - left;
|
||||
|
||||
#[cfg(not(feature = "user"))]
|
||||
{
|
||||
i += 1;
|
||||
// This should never happen, here just to satisfy verifier
|
||||
if i >= MAX_ITER {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if left == 0 {
|
||||
false
|
||||
} else {
|
||||
let indx = left - 1;
|
||||
if indx >= MAX_RULES {
|
||||
return false;
|
||||
}
|
||||
// SAFETY: Again, we are already bound checking
|
||||
end(*unsafe { self.rules.get_unchecked(indx) }) >= val
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If 0 is included we consider it to be "all ports".
|
||||
|
||||
Otherwise we basically do binary search on the starting port to see the maximum starting port that is less than the port we are checking for and then we check for the ending port to see if it's more than the port we are checking.
|
||||
|
||||
Binary search for the maximum that keeps a predicate as true is an algorithm that already exists in Rust called partition point, we needed to reimplement it to make it compatible with eBPF due to the verifier limitations.
|
||||
|
||||
## Conclusion
|
||||
|
||||
ebpf is awesome but complicated! (something along those lines) and future for firezone rearchitecture and check it out!
|
||||
16
www/blog/authors.yml
Normal file
16
www/blog/authors.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
jamil:
|
||||
name: Jamil Bou Kheir
|
||||
title: Co-founder
|
||||
url: https://github.com/jamilbk
|
||||
image_url: https://www.gravatar.com/avatar/3c8434814eec26026718e992322648c8
|
||||
|
||||
jason:
|
||||
name: Jason Gong
|
||||
title: Co-founder
|
||||
url: https://github.com/gongjason
|
||||
image_url: https://www.gravatar.com/avatar/d688e2280a36287f61c4426334dce065
|
||||
|
||||
conectado:
|
||||
name: Gabriel Steinberg
|
||||
title: Senior Rust Engineer
|
||||
url: https://github.com/conectado
|
||||
@@ -3,7 +3,7 @@ title: Overview
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
[Firezone](https://www.firezone.dev/?utm_source=docs.firezone.dev) is an open-source secure remote access
|
||||
[Firezone](/) is an open-source secure remote access
|
||||
platform that can be deployed on your own infrastructure in minutes.
|
||||
Use it to **quickly and easily** secure access to
|
||||
your private network and internal applications from an intuitive web UI.
|
||||
@@ -15,28 +15,28 @@ These docs explain how to deploy, configure, and use Firezone.
|
||||
## Quick start
|
||||
|
||||
1. [Deploy](deploy): A step-by-step walk-through setting up Firezone.
|
||||
Start here if you are new.
|
||||
Start here if you are new.
|
||||
1. [Authenticate](authenticate): Set up authentication using local
|
||||
email/password, OpenID Connect, or SAML 2.0 and optionally enable
|
||||
TOTP-based MFA.
|
||||
email/password, OpenID Connect, or SAML 2.0 and optionally enable
|
||||
TOTP-based MFA.
|
||||
1. [Administer](administer): Day to day administration of the Firezone
|
||||
server.
|
||||
server.
|
||||
1. [User Guides](user-guides): Useful guides to help you learn how to use
|
||||
Firezone and troubleshoot common issues. Consult this section
|
||||
Firezone and troubleshoot common issues. Consult this section
|
||||
after you successfully deploy the Firezone server.
|
||||
|
||||
## Common configuration guides
|
||||
|
||||
1. [Split Tunneling](./user-guides/use-cases/split-tunnel):
|
||||
Only route traffic to certain IP ranges through the VPN.
|
||||
Only route traffic to certain IP ranges through the VPN.
|
||||
1. [Setting up a NAT Gateway with a Static IP](./user-guides/use-cases/nat-gateway):
|
||||
Configure Firezone with a static IP address to provide
|
||||
a single egress IP for your team's traffic.
|
||||
Configure Firezone with a static IP address to provide
|
||||
a single egress IP for your team's traffic.
|
||||
1. [Reverse Tunnels](./user-guides/use-cases/reverse-tunnel):
|
||||
Establish tunnels between multiple peers.
|
||||
Establish tunnels between multiple peers.
|
||||
|
||||
import SupportOptions from '@site/src/partials/_support_options.mdx';
|
||||
<SupportOptions />
|
||||
import SupportOptions from "@site/src/partials/_support_options.mdx";
|
||||
<SupportOptions />;
|
||||
|
||||
## Contribute to firezone
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ running Firezone instance will **most likely** result in data loss when restored
|
||||
you have been warned.
|
||||
|
||||
After stopping Firezone, backing up Firezone is mostly a matter of copying the relevant
|
||||
[files and directories](/reference/file-and-directory-locations/) to a location of your
|
||||
[files and directories](/docs/reference/file-and-directory-locations/) to a location of your
|
||||
choosing.
|
||||
|
||||
See the steps below for specific examples for Docker and Omnibus.
|
||||
@@ -33,11 +33,14 @@ directory along with the Postgres data directory, typically located at
|
||||
Docker compose template.
|
||||
|
||||
1. Stop Firezone (warning: this **will** disconnect any users connected to the VPN):
|
||||
|
||||
```
|
||||
docker compose -f $HOME/.firezone/docker-compose.yml down
|
||||
```
|
||||
|
||||
2. Copy relevant files and folders. If your made any customizations to `/etc/docker/daemon.json`
|
||||
(for example, for IPv6 support), be sure to include that in the backup as well.
|
||||
(for example, for IPv6 support), be sure to include that in the backup as well.
|
||||
|
||||
```
|
||||
tar -zcvfp $HOME/firezone-back-$(date +'%F-%H-%M').tgz $HOME/.firezone /var/lib/docker/volumes/firezone_postgres-data
|
||||
```
|
||||
@@ -47,10 +50,13 @@ A backup file named `firezone-back-TIMESTAMP.tgz` will then be stored in `$HOME/
|
||||
### Restore
|
||||
|
||||
1. Copy the files back to their original location:
|
||||
|
||||
```
|
||||
tar -zxvfp /path/to/firezone-back.tgz -C / --numeric-owner
|
||||
```
|
||||
|
||||
2. Optionally, enable Docker to boot on startup:
|
||||
|
||||
```
|
||||
systemctl enable docker
|
||||
```
|
||||
@@ -61,10 +67,13 @@ systemctl enable docker
|
||||
### Backup
|
||||
|
||||
1. Stop Firezone (warning: this **will** disconnect any users connected to the VPN):
|
||||
|
||||
```
|
||||
firezone-ctl stop
|
||||
```
|
||||
|
||||
2. Copy relevant files and folders:
|
||||
|
||||
```
|
||||
tar -zcvfp $HOME/firezone-back-$(date +'%F-%H-%M').tgz /var/opt/firezone /opt/firezone /usr/bin/firezone-ctl /etc/systemd/system/firezone-runsvdir-start.service /etc/firezone
|
||||
```
|
||||
@@ -74,10 +83,13 @@ A backup file named `firezone-back-TIMESTAMP.tgz` will then be stored in `$HOME/
|
||||
### Restore
|
||||
|
||||
1. Copy the files back to their original location:
|
||||
|
||||
```
|
||||
tar -zxvfp /path/to/firezone-back.tgz -C / --numeric-owner
|
||||
```
|
||||
|
||||
2. Reconfigure Firezone to ensure configuration is applied to the host system:
|
||||
|
||||
```
|
||||
firezone-ctl reconfigure
|
||||
```
|
||||
@@ -85,5 +97,5 @@ firezone-ctl reconfigure
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
import SupportOptions from '@site/src/partials/_support_options.mdx';
|
||||
<SupportOptions />
|
||||
import SupportOptions from "@site/src/partials/_support_options.mdx";
|
||||
<SupportOptions />;
|
||||
|
||||
@@ -13,7 +13,7 @@ This article is written for Docker based deployments of Firezone.
|
||||
Docker deployments of Firezone consist of 3 running containers:
|
||||
|
||||
| Container | Function | Example logs |
|
||||
|-----------|---------------|-----------------------------------------------|
|
||||
| --------- | ------------- | --------------------------------------------- |
|
||||
| firezone | Web portal | HTTP requests received and responses provided |
|
||||
| postgres | Database | |
|
||||
| caddy | Reverse proxy | |
|
||||
@@ -32,7 +32,7 @@ See additional options of the `docker compose logs` command
|
||||
:::note
|
||||
Audit logs are in early Beta on the Enterprise plan. These track configuration
|
||||
changes by admins and network activity by users.
|
||||
[Contact us](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev)
|
||||
[Contact us](/sales)
|
||||
to learn more.
|
||||
:::
|
||||
|
||||
@@ -51,11 +51,11 @@ to collect information from running containers and services.
|
||||
|
||||
Examples of popular plugins, configurations, and use cases are:
|
||||
|
||||
* Export container logs to your SIEM or observability platform (i.e.
|
||||
[Splunk](https://docs.docker.com/config/containers/logging/splunk/)
|
||||
or
|
||||
[Google Cloud Logging](https://docs.docker.com/config/containers/logging/gcplogs/)
|
||||
)
|
||||
* Enable log rotation and max file size.
|
||||
* [Customize log driver output](https://docs.docker.com/config/containers/logging/log_tags/)
|
||||
with tags.
|
||||
- Export container logs to your SIEM or observability platform (i.e.
|
||||
[Splunk](https://docs.docker.com/config/containers/logging/splunk/)
|
||||
or
|
||||
[Google Cloud Logging](https://docs.docker.com/config/containers/logging/gcplogs/)
|
||||
)
|
||||
- Enable log rotation and max file size.
|
||||
- [Customize log driver output](https://docs.docker.com/config/containers/logging/log_tags/)
|
||||
with tags.
|
||||
|
||||
@@ -35,23 +35,25 @@ Estimated time to complete: **2 hours**.
|
||||
## Steps to migrate
|
||||
|
||||
1. **Back up** your server. This ensures you have a working state to roll back to
|
||||
in case anything goes terribly wrong. At a _bare minimum_ you'll want to back up the
|
||||
[file and directories Firezone uses
|
||||
](/reference/file-and-directory-locations/), but we recommend taking a full
|
||||
snapshot of your VPS if possible.
|
||||
in case anything goes terribly wrong. At a _bare minimum_ you'll want to back up the
|
||||
[file and directories Firezone uses
|
||||
](/docs/reference/file-and-directory-locations/), but we recommend taking a full
|
||||
snapshot of your VPS if possible.
|
||||
1. Ensure you're running the latest version of Firezone. See our [upgrade guide
|
||||
](/administer/upgrade/) if not.
|
||||
](/docs/administer/upgrade/) if not.
|
||||
1. Install the latest version of [**Docker**
|
||||
](https://docs.docker.com/engine/install/) and [Docker Compose
|
||||
](https://docs.docker.com/compose/install/linux/#install-compose)
|
||||
for your OS. **Docker Compose version 2 or higher is required**.
|
||||
We recommend using Docker Server for Linux. Docker Desktop will work too, but is not
|
||||
preferred for production use cases at this time because it rewrites packets under
|
||||
some conditions and may cause unexpected issues with Firezone.
|
||||
](https://docs.docker.com/engine/install/) and [Docker Compose
|
||||
](https://docs.docker.com/compose/install/linux/#install-compose)
|
||||
for your OS. **Docker Compose version 2 or higher is required**.
|
||||
We recommend using Docker Server for Linux. Docker Desktop will work too, but is not
|
||||
preferred for production use cases at this time because it rewrites packets under
|
||||
some conditions and may cause unexpected issues with Firezone.
|
||||
1. Download and run the migration script:
|
||||
|
||||
```bash
|
||||
bash <(curl -fsSL https://github.com/firezone/firezone/raw/master/scripts/docker_migrate.sh)
|
||||
```
|
||||
|
||||
This will ask you a few questions, then attempt to migrate your installation to
|
||||
Docker. If all goes well, your Firezone instance should be running with Docker, data intact.
|
||||
|
||||
@@ -65,9 +67,8 @@ docker-compose down
|
||||
sudo firezone-ctl start
|
||||
```
|
||||
|
||||
If you've found a bug, please [open a GitHub issue](
|
||||
https://github.com/firezone/firezone/issues) with the error output and
|
||||
If you've found a bug, please [open a GitHub issue](https://github.com/firezone/firezone/issues) with the error output and
|
||||
any steps needed to reproduce.
|
||||
|
||||
import SupportOptions from '@site/src/partials/_support_options.mdx';
|
||||
<SupportOptions />
|
||||
import SupportOptions from "@site/src/partials/_support_options.mdx";
|
||||
<SupportOptions />;
|
||||
|
||||
@@ -83,9 +83,9 @@ In most cases, you'll find clues in one or more of the following locations:
|
||||
<Tabs>
|
||||
<TabItem value="omnibus" label="Omnibus">
|
||||
|
||||
* Your browser's developer tool logs, specifically the `Network` tab.
|
||||
* `sudo firezone-ctl tail nginx`
|
||||
* `sudo firezone-ctl tail phoenix`
|
||||
- Your browser's developer tool logs, specifically the `Network` tab.
|
||||
- `sudo firezone-ctl tail nginx`
|
||||
- `sudo firezone-ctl tail phoenix`
|
||||
|
||||
If the websocket connection is successful, you should see output in the
|
||||
`phoenix` service logs similar the following:
|
||||
@@ -185,13 +185,13 @@ sudo firezone-ctl create-or-reset-admin
|
||||
|
||||
## Re-enable local authentication via CLI
|
||||
|
||||
If you've configured an [OIDC](/authenticate/oidc/) or [SAML](/authenticate/saml/)
|
||||
If you've configured an [OIDC](/docs/authenticate/oidc/) or [SAML](/docs/authenticate/saml/)
|
||||
provider, you can consider disabling local authentication for additional security.
|
||||
|
||||
If, however, issues arise with your identity provider integration, it's possible you
|
||||
could be locked out of the admin portal. To re-enable local authentication so
|
||||
you can log in and resolve the issue, you can temporarily re-enable local authentication
|
||||
via the [REST API](/reference/rest-api/configurations).
|
||||
via the [REST API](/docs/reference/rest-api/configurations).
|
||||
|
||||
If that's not an option, you can re-enable local authentication by
|
||||
running the following commands on the host of your Firezone instance:
|
||||
@@ -201,5 +201,5 @@ cd $HOME/.firezone
|
||||
docker compose exec postgres psql -U postgres -h 127.0.0.1 -d firezone -c "UPDATE configurations SET local_auth_enabled = 't'"
|
||||
```
|
||||
|
||||
import SupportOptions from '@site/src/partials/_support_options.mdx';
|
||||
<SupportOptions />
|
||||
import SupportOptions from "@site/src/partials/_support_options.mdx";
|
||||
<SupportOptions />;
|
||||
|
||||
@@ -8,7 +8,7 @@ down the web UI.
|
||||
|
||||
:::info
|
||||
Automatic rollbacks are still under development. We recommend backing up
|
||||
relevant [files and folders](/reference/file-and-directory-locations/)
|
||||
relevant [files and folders](/docs/reference/file-and-directory-locations/)
|
||||
before upgrading in case anything goes wrong.
|
||||
:::
|
||||
|
||||
@@ -18,18 +18,23 @@ Follow the steps below to upgrade Firezone:
|
||||
<TabItem label="Docker" value="docker" default>
|
||||
|
||||
1. Change to your Firezone installation directory, by default `$HOME/.firezone`:
|
||||
|
||||
```
|
||||
cd $HOME/.firezone
|
||||
```
|
||||
|
||||
1. If your `.env` file has a `VERSION` variable, update it to the desired version.
|
||||
By default `latest` is assumed if not set. This variable is read in newer versions
|
||||
of the docker-compose.yml template to populate the `image:` key for the `firezone`
|
||||
service.
|
||||
By default `latest` is assumed if not set. This variable is read in newer versions
|
||||
of the docker-compose.yml template to populate the `image:` key for the `firezone`
|
||||
service.
|
||||
1. Update service images:
|
||||
|
||||
```
|
||||
docker compose pull
|
||||
```
|
||||
|
||||
1. Re-up the services (**warning: this will restart updated services**):
|
||||
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
@@ -38,9 +43,11 @@ docker compose up -d
|
||||
<TabItem label="Omnibus" value="omnibus">
|
||||
|
||||
1. If not setup already, install our package repository based on your distro's
|
||||
package format:
|
||||
- [deb packages](https://cloudsmith.io/~firezone/repos/firezone/setup/#formats-deb)
|
||||
- [rpm packages](https://cloudsmith.io/~firezone/repos/firezone/setup/#formats-rpm)
|
||||
package format:
|
||||
|
||||
- [deb packages](https://cloudsmith.io/~firezone/repos/firezone/setup/#formats-deb)
|
||||
- [rpm packages](https://cloudsmith.io/~firezone/repos/firezone/setup/#formats-rpm)
|
||||
|
||||
1. Upgrade the `firezone` package using your distro's package manager.
|
||||
1. Run `firezone-ctl reconfigure` to pick up the new changes.
|
||||
1. Run `firezone-ctl restart` to restart services.
|
||||
@@ -53,7 +60,7 @@ issue](https://github.com/firezone/firezone/issues/new/choose).
|
||||
|
||||
## Upgrading to 0.7.x
|
||||
|
||||
Firezone 0.7.0 introduces a new [REST API](/reference/rest-api/) that allows administrators
|
||||
Firezone 0.7.0 introduces a new [REST API](/docs/reference/rest-api/) that allows administrators
|
||||
to automate much of the day to day configuration of Firezone.
|
||||
|
||||
The REST API `/v0/configuration` endpoint supersedes some of the previous environment
|
||||
@@ -64,12 +71,12 @@ If you're running Firezone < 0.6, we recommend updating to the latest
|
||||
are properly parsed and migrated into the DB as runtime `configurations`.
|
||||
|
||||
**Note**: Omnibus deployments are deprecated in 0.7.x and will be removed in Firezone
|
||||
0.8 and above. We recommend [migrating your installation](/administer/migrate/) to
|
||||
0.8 and above. We recommend [migrating your installation](/docs/administer/migrate/) to
|
||||
Docker if you haven't done so already.
|
||||
|
||||
## Upgrading to >= 0.6.12
|
||||
|
||||
### WIREGUARD_* env vars
|
||||
### WIREGUARD\_\* env vars
|
||||
|
||||
Firezone 0.6.12 moves the `WIREGUARD_ALLOWED_IPS`, `WIREGUARD_PERSISTENT_KEEPALIVE`,
|
||||
and `WIREGUARD_DNS` environment variables to the database to be configured in the
|
||||
@@ -84,7 +91,7 @@ variables to the DB.
|
||||
|
||||
Similar to the `WIREGUARD_*` env vars above, the `AUTH_OIDC_JSON` env var has similarly
|
||||
been moved to the database and can be configured at `/settings/site`. In Firezone 0.7 this
|
||||
is now configurable via the [REST API](/reference/rest-api/configurations) as well.
|
||||
is now configurable via the [REST API](/docs/reference/rest-api/configurations) as well.
|
||||
|
||||
### Fix IPv6
|
||||
|
||||
@@ -107,8 +114,7 @@ networks:
|
||||
- gateway: 2001:3990:3990::1
|
||||
```
|
||||
|
||||
You also need to update the Docker daemon to enable IPv6. See our [IPv6 guide](
|
||||
https://docs.firezone.dev/deploy/docker/#step-4-enable-ipv6-optional) for more info.
|
||||
You also need to update the Docker daemon to enable IPv6. See our [IPv6 guide](/docs/deploy/docker/#step-4-enable-ipv6-optional) for more info.
|
||||
|
||||
## Upgrading from 0.5.x to 0.6.x
|
||||
|
||||
@@ -118,13 +124,13 @@ more granular user provisioning options, and a slew of minor improvements and bu
|
||||
### Migrate to Docker
|
||||
|
||||
Docker is now the preferred way to deploy and manage Firezone. See the [migration
|
||||
guide](/administer/migrate/) to migrate today. In most cases this can be done in a few minutes
|
||||
guide](/docs/administer/migrate/) to migrate today. In most cases this can be done in a few minutes
|
||||
using our automatic migration script.
|
||||
|
||||
### Update Configuration
|
||||
|
||||
Some configuration variables have recently moved to the DB in order to be configurable
|
||||
at runtime. Check the [configure guide](/deploy/configure/) for more information.
|
||||
at runtime. Check the [configure guide](/docs/deploy/configure/) for more information.
|
||||
|
||||
## Upgrading from < 0.5.0 to >= 0.5.0
|
||||
|
||||
@@ -140,7 +146,7 @@ by setting `default['firezone']['nginx']['enabled'] = false` and pointing your
|
||||
reverse proxy directly to the Phoenix app on port 13000 (by default).
|
||||
|
||||
Read more about setting up a custom reverse proxy
|
||||
[here](/deploy/advanced/reverse-proxy/).
|
||||
[here](/docs/deploy/advanced/reverse-proxy/).
|
||||
|
||||
### ACME protocol support
|
||||
|
||||
@@ -186,7 +192,7 @@ default['firezone']['authentication']['google']['client_secret']
|
||||
default['firezone']['authentication']['google']['redirect_uri']
|
||||
```
|
||||
|
||||
Then, follow the instructions [here](/authenticate/oidc/google/) to configure Google
|
||||
Then, follow the instructions [here](/docs/authenticate/oidc/google/) to configure Google
|
||||
as an OIDC provider.
|
||||
|
||||
#### Existing Okta OAuth configuration
|
||||
@@ -201,7 +207,7 @@ default['firezone']['authentication']['okta']['client_secret']
|
||||
default['firezone']['authentication']['okta']['site']
|
||||
```
|
||||
|
||||
Then, follow the instructions [here](/authenticate/oidc/okta/) to configure Okta as
|
||||
Then, follow the instructions [here](/docs/authenticate/oidc/okta/) to configure Okta as
|
||||
an OIDC provider.
|
||||
|
||||
## Upgrading from 0.3.x to >= 0.3.16
|
||||
@@ -230,17 +236,17 @@ users authenticated through your OIDC provider.
|
||||
|
||||
If this does not work, you will need to delete your existing OAuth app
|
||||
and repeat the OIDC setup steps to
|
||||
[create a new app integration](/authenticate/oidc/) .
|
||||
[create a new app integration](/docs/authenticate/oidc/) .
|
||||
|
||||
### I have an existing OAuth integration
|
||||
|
||||
Prior to 0.3.11, Firezone used pre-configured OAuth2 providers. Follow the
|
||||
instructions [here](/authenticate/oidc/) to migrate to OIDC.
|
||||
instructions [here](/docs/authenticate/oidc/) to migrate to OIDC.
|
||||
|
||||
### I have not integrated an identity provider
|
||||
|
||||
No action needed. You can follow the instructions
|
||||
[here](/authenticate/oidc)
|
||||
[here](/docs/authenticate/oidc)
|
||||
to enable SSO through an OIDC provider.
|
||||
|
||||
## Upgrading from 0.3.1 to >= 0.3.2
|
||||
@@ -252,7 +258,7 @@ default to `https://` + the FQDN of your server.
|
||||
|
||||
Reminder, the configuration file can be found at `/etc/firezone/firezone.rb`.
|
||||
For an exhaustive list of configuration variables and their descriptions, see the
|
||||
[configuration file reference](/reference/configuration-file).
|
||||
[configuration file reference](/docs/reference/configuration-file).
|
||||
|
||||
## Upgrading from 0.2.x to 0.3.x
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Firezone supports the following authentication methods:
|
||||
|
||||
:::note
|
||||
If your Identity Provider doesn't work with the methods listed above,
|
||||
[contact us](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev) about custom integrations.
|
||||
[contact us](/sales) about custom integrations.
|
||||
:::
|
||||
|
||||
## Integrate an SSO provider
|
||||
@@ -19,14 +19,14 @@ If your Identity Provider doesn't work with the methods listed above,
|
||||
We've included instructions on how to set up Firezone with several popular
|
||||
identity providers using our Generic OIDC integration:
|
||||
|
||||
* [Okta](oidc/okta)
|
||||
* [Azure Active Directory](oidc/azuread)
|
||||
* [Google](oidc/google)
|
||||
* [Onelogin](oidc/onelogin)
|
||||
* [JumpCloud](saml/jumpcloud)
|
||||
* [Keycloak](oidc/keycloak)
|
||||
* [Zitadel](oidc/zitadel)
|
||||
* [Auth0](oidc/auth0)
|
||||
- [Okta](oidc/okta)
|
||||
- [Azure Active Directory](oidc/azuread)
|
||||
- [Google](oidc/google)
|
||||
- [Onelogin](oidc/onelogin)
|
||||
- [JumpCloud](saml/jumpcloud)
|
||||
- [Keycloak](oidc/keycloak)
|
||||
- [Zitadel](oidc/zitadel)
|
||||
- [Auth0](oidc/auth0)
|
||||
|
||||
If your identity provider is not listed above, but has a generic OIDC or SAML
|
||||
connector, please consult their documentation to find instructions on obtaining
|
||||
@@ -46,12 +46,16 @@ where `CONFIG_ID` is the OIDC Config ID for that particular provider.
|
||||
For example, the OIDC config below:
|
||||
|
||||
<center>
|
||||
<img width="509" alt="config-oidc" src="https://user-images.githubusercontent.com/167144/216438674-a2b64b3b-2ed6-43dc-b554-de9c055dc741.png"/>
|
||||
<img
|
||||
width="509"
|
||||
alt="config-oidc"
|
||||
src="https://user-images.githubusercontent.com/167144/216438674-a2b64b3b-2ed6-43dc-b554-de9c055dc741.png"
|
||||
/>
|
||||
</center>
|
||||
|
||||
would generate the following OIDC login URL:
|
||||
|
||||
* `https://firezone.example.com/auth/oidc/google`
|
||||
- `https://firezone.example.com/auth/oidc/google`
|
||||
|
||||
This URL could then be distributed to end users for direct navigation to
|
||||
the identity provider's login portal for authentication to Firezone.
|
||||
@@ -80,10 +84,10 @@ See detailed Client Instructions on how to re-authenticate your session
|
||||
A user's connection status is shown on the Users page under the table column
|
||||
`VPN Connection`. The connection statuses are:
|
||||
|
||||
* ENABLED - The connection is enabled.
|
||||
* DISABLED - The connection is disabled by an administrator or OIDC refresh failure.
|
||||
* EXPIRED - The connection is disabled due to authentication expiration or a user
|
||||
has not signed in for the first time.
|
||||
- ENABLED - The connection is enabled.
|
||||
- DISABLED - The connection is disabled by an administrator or OIDC refresh failure.
|
||||
- EXPIRED - The connection is disabled due to authentication expiration or a user
|
||||
has not signed in for the first time.
|
||||
|
||||
import SupportOptions from '@site/src/partials/_support_options.mdx';
|
||||
<SupportOptions />
|
||||
import SupportOptions from "@site/src/partials/_support_options.mdx";
|
||||
<SupportOptions />;
|
||||
|
||||
@@ -7,24 +7,24 @@ sidebar_position: 1
|
||||
|
||||
By default, Firezone will use local email / password for authenticating users to
|
||||
the Firezone portal. Administrators can add users and assign their passwords on
|
||||
the `/users` page. See [Add users](/user-guides/add-users/) for more details.
|
||||
the `/users` page. See [Add users](/docs/user-guides/add-users/) for more details.
|
||||
|
||||
:::caution
|
||||
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](/authenticate/oidc/) or [SAML](/authenticate/saml/) guides
|
||||
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.
|
||||
:::
|
||||
|
||||
If you choose to keep Local authentication enabled, we recommend [enabling TOTP-based MFA
|
||||
](/authenticate/multi-factor/) for any accounts that use the local authentication method.
|
||||
](/docs/authenticate/multi-factor/) for any accounts that use the local authentication method.
|
||||
|
||||
## Disabling local authentication
|
||||
|
||||
Local authentication can be enabled or disabled from the `/settings/security` page
|
||||
or via the [REST API](/reference/rest-api/configurations).
|
||||
or via the [REST API](/docs/reference/rest-api/configurations).
|
||||
If you've disabled local authentication and can no longer authenticate to the portal
|
||||
to re-enable it, see our [troubleshooting guide
|
||||
](/administer/troubleshoot#re-enable-local-authentication-via-cli) for re-enabling
|
||||
](/docs/administer/troubleshoot#re-enable-local-authentication-via-cli) for re-enabling
|
||||
local authentication from the CLI.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
title: OpenID Connect
|
||||
sidebar_position: 10
|
||||
description:
|
||||
Setup single sign-on with your identity provider. Integrate
|
||||
description: Setup single sign-on with your identity provider. Integrate
|
||||
providers like Okta, Google, Azure, and JumpCloud using Firezone's
|
||||
OpenID Connect (OIDC) connector.
|
||||
---
|
||||
@@ -16,20 +15,20 @@ Firezone supports Single Sign-On (SSO) via OpenID Connect (OIDC).
|
||||
In general, most identity providers that offer OIDC support work with Firezone. Some providers
|
||||
that only implement the OIDC partially or use uncommon configurations may have
|
||||
issues, however. If your identity provider falls into this category, [contact us
|
||||
](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev) about a custom integration.
|
||||
](/sales) about a custom integration.
|
||||
|
||||
The following OIDC providers are known to work well with Firezone:
|
||||
|
||||
| Provider | Support Status | Notes |
|
||||
| --- | --- | --- |
|
||||
| [Azure Active Directory](azuread) | **Fully tested and supported** | Ensure the [`email` claim](https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims) is present in the token. |
|
||||
| [Okta](okta) | **Fully tested and supported** | |
|
||||
| [Onelogin](onelogin) | **Fully tested and supported** | |
|
||||
| [Keycloak](https://www.keycloak.org/) | **Fully tested and supported** | |
|
||||
| [Auth0](auth0) | **Fully tested and supported** | Auth0 does not provide an `end_session_uri` in its OIDC discovery document. Signing out of Auth0 from Firezone is not supported. |
|
||||
| [Google Workspace](google) | **Fully tested and supported** | Google does not provide an `end_session_uri` in its OIDC discovery document. Signing out of Google Workspace from Firezone is not supported. |
|
||||
| [Zitadel](zitadel) | Untested but known to work | |
|
||||
| [Authentik](https://goauthentik.io/) | Untested but known to work | |
|
||||
| Provider | Support Status | Notes |
|
||||
| ------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| [Azure Active Directory](azuread) | **Fully tested and supported** | Ensure the [`email` claim](https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims) is present in the token. |
|
||||
| [Okta](okta) | **Fully tested and supported** | |
|
||||
| [Onelogin](onelogin) | **Fully tested and supported** | |
|
||||
| [Keycloak](https://www.keycloak.org/) | **Fully tested and supported** | |
|
||||
| [Auth0](auth0) | **Fully tested and supported** | Auth0 does not provide an `end_session_uri` in its OIDC discovery document. Signing out of Auth0 from Firezone is not supported. |
|
||||
| [Google Workspace](google) | **Fully tested and supported** | Google does not provide an `end_session_uri` in its OIDC discovery document. Signing out of Google Workspace from Firezone is not supported. |
|
||||
| [Zitadel](zitadel) | Untested but known to work | |
|
||||
| [Authentik](https://goauthentik.io/) | Untested but known to work | |
|
||||
|
||||
## General setup guide
|
||||
|
||||
@@ -37,18 +36,18 @@ If you're using an OIDC provider not listed above, the following OIDC attributes
|
||||
are required for setting up an OIDC provider in Firezone:
|
||||
|
||||
1. `discovery_document_uri`: The
|
||||
[OpenID Connect provider configuration URI](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
|
||||
which returns a JSON document used to construct subsequent requests to this
|
||||
OIDC provider. Some providers refer to this as the "well-known URL".
|
||||
[OpenID Connect provider configuration URI](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
|
||||
which returns a JSON document used to construct subsequent requests to this
|
||||
OIDC provider. Some providers refer to this as the "well-known URL".
|
||||
1. `client_id`: The client ID of the application.
|
||||
1. `client_secret`: The client secret of the application.
|
||||
1. `redirect_uri`: Instructs OIDC provider where to redirect after authentication.
|
||||
This should be your Firezone `EXTERNAL_URL + /auth/oidc/<provider_key>/callback/`
|
||||
(e.g. `https://firezone.example.com/auth/oidc/google/callback/`).
|
||||
This should be your Firezone `EXTERNAL_URL + /auth/oidc/<provider_key>/callback/`
|
||||
(e.g. `https://firezone.example.com/auth/oidc/google/callback/`).
|
||||
1. `response_type`: Set to `code`.
|
||||
1. `scope`: [OIDC scopes](https://openid.net/specs/openid-connect-basic-1_0.html#Scopes)
|
||||
to obtain from your OIDC provider. At a minimum, Firezone requires the `openid`
|
||||
and `email` scopes.
|
||||
to obtain from your OIDC provider. At a minimum, Firezone requires the `openid`
|
||||
and `email` scopes.
|
||||
1. `label`: The button label text displayed on the Firezone portal login page.
|
||||
|
||||
### PKCE
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
title: SAML 2.0
|
||||
sidebar_position: 11
|
||||
description:
|
||||
Enforce single sign-on with your identity provider. Integrate
|
||||
description: Enforce single sign-on with your identity provider. Integrate
|
||||
providers like Okta, Google, OneLogin, and JumpCloud using Firezone's
|
||||
SAML 2.0 connector.
|
||||
---
|
||||
@@ -17,15 +16,14 @@ In general, most identity providers that support SAML 2.0 should work with
|
||||
Firezone.
|
||||
|
||||
| Provider | Support Status | Notes |
|
||||
| --- | --- | --- |
|
||||
| -------------------------- | ------------------------ | ---------------------------------- |
|
||||
| [Okta](okta) | **Tested and supported** | |
|
||||
| [Google Workspace](google) | **Tested and supported** | Uncheck `Require signed envelopes` |
|
||||
| [OneLogin](onelogin) | **Tested and supported** | |
|
||||
| [JumpCloud](jumpcloud) | **Tested and supported** | Uncheck `Require signed envelopes` |
|
||||
|
||||
Occasionally, providers that don't implement the full SAML 2.0 standard or use
|
||||
uncommon configurations may be problematic. If this is the case, [contact us](
|
||||
https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev) about a custom integration.
|
||||
uncommon configurations may be problematic. If this is the case, [contact us](/sales) about a custom integration.
|
||||
|
||||
## Custom SAML cert and keyfile
|
||||
|
||||
@@ -91,4 +89,4 @@ e.g. `https://firezone.company.com/auth/saml/sp/consume/okta`.
|
||||
The Firezone Entity ID can be configured with the `SAML_ENTITY_ID` environment variable
|
||||
and defaults to `urn:firezone.dev:firezone-app` if not set.
|
||||
|
||||
See the [environment variable reference](/reference/env-vars) for more information.
|
||||
See the [environment variable reference](/docs/reference/env-vars) for more information.
|
||||
|
||||
@@ -11,7 +11,7 @@ description:
|
||||
|
||||
:::note
|
||||
This guide assumes you have completed the prerequisite steps
|
||||
(e.g. generate self-signed X.509 certificates) outlined [here](/authenticate/saml#prerequisites).
|
||||
(e.g. generate self-signed X.509 certificates) outlined [here](/docs/authenticate/saml#prerequisites).
|
||||
:::
|
||||
|
||||
Firezone supports Single Sign-On (SSO) using JumpCloud through the generic SAML 2.0 connector.
|
||||
@@ -25,16 +25,16 @@ the SSO tab. At the bottom of the popup window, click `Custom SAML App`.
|
||||
After entering your desired value for `Display Label`, click the `SSO` tab,
|
||||
then use the following configuration values:
|
||||
|
||||
| Setting | Value |
|
||||
| --- | --- |
|
||||
| IdP Entity ID | Any unique string will work, e.g. `firezone-jumpcloud`. |
|
||||
| SP Entity ID | This should be the same as your Firezone `SAML_ENTITY_ID`, defaults to `urn:firezone.dev:firezone-app`. |
|
||||
| ACS URL | This is your Firezone `EXTERNAL_URL/auth/saml/sp/consume/:config_id`, e.g. `https://firezone.company.com/auth/saml/sp/consume/jumpcloud`. |
|
||||
| SAMLSubject NameID | `email` |
|
||||
| SAMLSubject NameID Format | Leave at the default. |
|
||||
| Signature Algorithm | `RSA-SHA256` |
|
||||
| Sign Assertion | **Checked**. |
|
||||
| Login URL | This is your Firezone `EXTERNAL_URL/auth/saml/auth/signin/:config_id`, e.g. `https://firezone.company.com/auth/saml/auth/signin/jumpcloud`|
|
||||
| Setting | Value |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| IdP Entity ID | Any unique string will work, e.g. `firezone-jumpcloud`. |
|
||||
| SP Entity ID | This should be the same as your Firezone `SAML_ENTITY_ID`, defaults to `urn:firezone.dev:firezone-app`. |
|
||||
| ACS URL | This is your Firezone `EXTERNAL_URL/auth/saml/sp/consume/:config_id`, e.g. `https://firezone.company.com/auth/saml/sp/consume/jumpcloud`. |
|
||||
| SAMLSubject NameID | `email` |
|
||||
| SAMLSubject NameID Format | Leave at the default. |
|
||||
| Signature Algorithm | `RSA-SHA256` |
|
||||
| Sign Assertion | **Checked**. |
|
||||
| Login URL | This is your Firezone `EXTERNAL_URL/auth/saml/auth/signin/:config_id`, e.g. `https://firezone.company.com/auth/saml/auth/signin/jumpcloud` |
|
||||
|
||||
Leave the rest of the settings unchanged, then click the `activate` button at the bottom-right.
|
||||
|
||||
@@ -52,7 +52,7 @@ In the Firezone portal, add a SAML identity provider under the Security tab
|
||||
by filling out the following information:
|
||||
|
||||
| Setting | Value | Notes |
|
||||
| --- | --- | --- |
|
||||
| ------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Config ID | `jumpcloud` | Firezone uses this value to construct endpoints required in the SAML authentication flow (e.g., receiving assertions, login requests). |
|
||||
| Label | `JumpCloud` | Appears on the sign in button for authentication. |
|
||||
| Base URL | Leave unchanged. | |
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
title: Okta
|
||||
sidebar_position: 1
|
||||
description:
|
||||
Enforce 2FA/MFA using Okta for users of Firezone's WireGuard®-based
|
||||
description: Enforce 2FA/MFA using Okta for users of Firezone's WireGuard®-based
|
||||
secure access platform. This guide walks through integrating Okta
|
||||
for single sign-on using the SAML 2.0 connector.
|
||||
---
|
||||
@@ -11,7 +10,7 @@ description:
|
||||
|
||||
:::note
|
||||
This guide assumes you have completed the prerequisite steps
|
||||
(e.g. generate self-signed X.509 certificates) outlined [here](/authenticate/saml#prerequisites).
|
||||
(e.g. generate self-signed X.509 certificates) outlined [here](/docs/authenticate/saml#prerequisites).
|
||||
:::
|
||||
|
||||
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.
|
||||
@@ -22,15 +21,15 @@ In the Okta admin portal, create a new app integration under
|
||||
the Application tab. Select `SAML 2.0` as the authentication method.
|
||||
Use the following config values during setup:
|
||||
|
||||
| Setting | Value |
|
||||
|--------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| App name | Firezone |
|
||||
| App logo | [save link as](https://user-images.githubusercontent.com/52545545/155907625-a4f6c8c2-3952-488d-b244-3c37400846cf.png) |
|
||||
| Single sign on URL | This is your Firezone `EXTERNAL_URL/auth/saml/sp/consume/:config_id` (e.g., `https://firezone.company.com/auth/saml/sp/consume/okta`).|
|
||||
| Audience (EntityID) | This should be the same as your Firezone `SAML_ENTITY_ID`, defaults to `urn:firezone.dev:firezone-app`. |
|
||||
| Name ID format | EmailAddress |
|
||||
| Application username | Email |
|
||||
| Update application username on | Create and update |
|
||||
| Setting | Value |
|
||||
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| App name | Firezone |
|
||||
| App logo | [save link as](https://user-images.githubusercontent.com/52545545/155907625-a4f6c8c2-3952-488d-b244-3c37400846cf.png) |
|
||||
| Single sign on URL | This is your Firezone `EXTERNAL_URL/auth/saml/sp/consume/:config_id` (e.g., `https://firezone.company.com/auth/saml/sp/consume/okta`). |
|
||||
| Audience (EntityID) | This should be the same as your Firezone `SAML_ENTITY_ID`, defaults to `urn:firezone.dev:firezone-app`. |
|
||||
| Name ID format | EmailAddress |
|
||||
| Application username | Email |
|
||||
| Update application username on | Create and update |
|
||||
|
||||
[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.
|
||||
@@ -46,16 +45,16 @@ to copy-paste the contents of this document into the Firezone portal in the next
|
||||
In the Firezone portal, add a SAML identity provider under the Security tab
|
||||
by filling out the following information:
|
||||
|
||||
| Setting | Value | Notes |
|
||||
| --------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| Config ID | Okta | Used to construct endpoints required in the SAML authentication flow (e.g., receiving assertions, login requests). |
|
||||
| Label | Okta | Appears on the sign in button for authentication. |
|
||||
| Metadata | see note | Paste the contents of the SAML metadata document you downloaded in the previous step from Okta. |
|
||||
| Sign assertions | Checked. | |
|
||||
| Sign metadata | Checked. | |
|
||||
| Require signed assertions | Checked. | |
|
||||
| Required 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. |
|
||||
| Setting | Value | Notes |
|
||||
| ------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Config ID | Okta | Used to construct endpoints required in the SAML authentication flow (e.g., receiving assertions, login requests). |
|
||||
| Label | Okta | Appears on the sign in button for authentication. |
|
||||
| Metadata | see note | Paste the contents of the SAML metadata document you downloaded in the previous step from Okta. |
|
||||
| Sign assertions | Checked. | |
|
||||
| Sign metadata | Checked. | |
|
||||
| Require signed assertions | Checked. | |
|
||||
| Required 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. |
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ description:
|
||||
|
||||
:::note
|
||||
This guide assumes you have completed the prerequisite steps
|
||||
(e.g. generate self-signed X.509 certificates) outlined [here](/authenticate/saml#prerequisites).
|
||||
(e.g. generate self-signed X.509 certificates) outlined [here](/docs/authenticate/saml#prerequisites).
|
||||
:::
|
||||
|
||||
Firezone supports Single Sign-On (SSO) using OneLogin through the generic SAML 2.0 connector.
|
||||
@@ -26,7 +26,7 @@ configuration settings under the under the configuration tab.
|
||||
The following fields should be filled out on this page:
|
||||
|
||||
| Setting | Value |
|
||||
|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Audience (EntityID) | This should be the same as your Firezone `SAML_ENTITY_ID`, defaults to `urn:firezone.dev:firezone-app`. |
|
||||
| Recipient | This is your Firezone `EXTERNAL_URL/auth/saml/sp/consume/:config_id` (e.g., `https://firezone.company.com/auth/saml/sp/consume/onelogin`). |
|
||||
| ACS URL Validator | This field is regex to ensure OneLogin posts the response to the correct URL. For the sample URL below, we can use `^https:\/\/firezone\.company\.com\/auth\/saml\/sp\/consume\/onelogin` |
|
||||
@@ -51,7 +51,7 @@ In the Firezone portal, add a SAML identity provider under the Security tab
|
||||
by filling out the following information:
|
||||
|
||||
| Setting | Value | Notes |
|
||||
| --- | --- | --- |
|
||||
| ------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Config ID | `onelogin` | Used to construct endpoints required in the SAML authentication flow (e.g., receiving assertions, login requests). |
|
||||
| Label | `OneLogin` | Appears on the sign in button for authentication. |
|
||||
| Metadata | see note | Paste the contents of the SAML metadata document you downloaded in the previous step from OneLogin. |
|
||||
|
||||
@@ -102,6 +102,6 @@ preferred method of deployment.
|
||||
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,
|
||||
support for Omnibus-based deployments will be removed starting with Firezone 0.8.
|
||||
Firezone. To transition to Docker from Omnibus today, follow our [migration guide
|
||||
To transition to Docker from Omnibus today, follow our [migration guide
|
||||
](../administer/migrate).
|
||||
:::
|
||||
|
||||
@@ -76,7 +76,7 @@ The known commands are:
|
||||
|
||||
Most deployment-related configuration is handled with environment variables.
|
||||
You'll probably want to at least set variables related to your reverse proxy
|
||||
and database. See the [ENV var reference](/reference/env-vars/) for an exhaustive list.
|
||||
and database. See the [ENV var reference](/docs/reference/env-vars/) for an exhaustive list.
|
||||
|
||||
Now all you need are the database and reverse proxy that you've previously set up.
|
||||
Once that's done, you can use `firezone start` to start Firezone and run
|
||||
|
||||
@@ -26,7 +26,7 @@ if possible.
|
||||
|
||||
:::info
|
||||
Need help deploying or maintaining Firezone with an external database? Consider
|
||||
[contacting us about our Enterprise Plan](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev) for
|
||||
[contacting us about our Enterprise Plan](/sales) for
|
||||
recommended configurations, white-glove deployment assistance, and more.
|
||||
:::
|
||||
|
||||
@@ -39,7 +39,7 @@ The Firezone Docker image uses the following environment
|
||||
variables to connect to the DB (fields in bold required):
|
||||
|
||||
| Name | Description | Format | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------------------------------------ |
|
||||
| **`DATABASE_ENCRYPTION_KEY`** | The base64-encoded symmetric encryption key used to encrypt and decrypt sensitive fields. | base64-encoded String | None -- must be generated on install |
|
||||
| `DATABASE_HOST` | Database host | IP or hostname | `postgres` |
|
||||
| `DATABASE_PORT` | Database port | Integer | `5432` |
|
||||
@@ -52,7 +52,7 @@ variables to connect to the DB (fields in bold required):
|
||||
| `DATABASE_PARAMETERS` | Map of parameters to send to the `:parameters` option when connecting to the database. See [Ecto.Adapters.Postgres documentation](https://hexdocs.pm/ecto_sql/Ecto.Adapters.Postgres.html#module-connection-options). | JSON-encoded String | `{}` |
|
||||
|
||||
For more information, see the [environment variable reference
|
||||
](/reference/env-vars/).
|
||||
](/docs/reference/env-vars/).
|
||||
|
||||
:::note
|
||||
The official `postgres` docker image can be configured by setting
|
||||
@@ -67,7 +67,7 @@ The following configuration options are used to configure the bundled Postgres
|
||||
for Omnibus-based deployments:
|
||||
|
||||
| Config Key | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
||||
| `default['firezone']['database']['user']` | Specifies the username Firezone will use to connect to the DB. | `node['firezone']['postgresql']['username']` |
|
||||
| `default['firezone']['database']['password']` | If using an external DB, specifies the password Firezone will use to connect to the DB. | `'change_me'` |
|
||||
| `default['firezone']['database']['name']` | Database that Firezone will use. Will be created if it doesn't exist. | `'firezone'` |
|
||||
@@ -80,7 +80,7 @@ for Omnibus-based deployments:
|
||||
| `default['firezone']['database']['extensions']` | Database extensions to enable. | `{ 'plpgsql' => true, 'pg_trgm' => true }` |
|
||||
|
||||
For more details, see the [configuration file reference
|
||||
](/reference/configuration-file/).
|
||||
](/docs/reference/configuration-file/).
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
@@ -11,7 +11,7 @@ There are important security risks if the reverse proxy is not set up correctly.
|
||||
:::
|
||||
|
||||
For help deploying Firezone with a custom reverse proxy, consider [contacting us
|
||||
for support](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev).
|
||||
for support](/sales).
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -27,13 +27,12 @@ reverse proxy.
|
||||
|
||||
### Firezone configuration requirements
|
||||
|
||||
* Disable the bundled Nginx by setting `default['firezone']['nginx']['enabled']`
|
||||
- Disable the bundled Nginx by setting `default['firezone']['nginx']['enabled']`
|
||||
to `false` in the config file.
|
||||
* If you have any immediate proxies between your primary reverse proxy and the
|
||||
- If you have any immediate proxies between your primary reverse proxy and the
|
||||
Firezone web app, add their IPs to
|
||||
`default['firezone']['phoenix']['external_trusted_proxies']`. Because of the
|
||||
way the [X-Forwarded-For header works](
|
||||
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For),
|
||||
way the [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.
|
||||
|
||||
@@ -42,12 +41,12 @@ The `external_trusted_proxies` 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`
|
||||
- `127.0.0.0/8`
|
||||
- `10.0.0.0/8`
|
||||
- `172.16.0.0/12`
|
||||
- `192.168.0.0/16`
|
||||
- `::1/128`
|
||||
- `fc00::/7`
|
||||
|
||||
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
|
||||
@@ -56,36 +55,34 @@ this range (as seen by the Firezone web app), be sure to add them to the
|
||||
:::
|
||||
|
||||
Read more about the configuration options
|
||||
[here](/reference/configuration-file/).
|
||||
[here](/docs/reference/configuration-file/).
|
||||
|
||||
### Proxy requirements
|
||||
|
||||
* All your proxies need to configure the `X-Forwarded-For` header as explained
|
||||
[here](
|
||||
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
|
||||
* Your proxy should also set the `X-Forwarded-Proto` to `https`.
|
||||
* Your proxy (or another downstream proxy) **must** terminate SSL since we
|
||||
enforce [secure cookies](
|
||||
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies).
|
||||
* Firezone requires the use of WebSockets to establish realtime connections. We
|
||||
- All your proxies need to configure the `X-Forwarded-For` header as explained
|
||||
[here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
|
||||
- Your proxy should also set the `X-Forwarded-Proto` to `https`.
|
||||
- Your proxy (or another downstream proxy) **must** terminate SSL since we
|
||||
enforce [secure cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies).
|
||||
- Firezone requires the use of WebSockets to establish realtime connections. We
|
||||
recommend following your proxy's specific documentation for supporting
|
||||
WebSockets as each proxy varies. In general, your proxy needs to be able to
|
||||
proxy HTTP 1.1 connections, and the Firezone web app expects the following
|
||||
headers to be set:
|
||||
* `Connection: upgrade`
|
||||
* `Upgrade: websocket`
|
||||
- `Connection: upgrade`
|
||||
- `Upgrade: websocket`
|
||||
|
||||
## Security considerations
|
||||
|
||||
In addition to the headers above, we recommend adding the following headers for
|
||||
security purposes:
|
||||
|
||||
* `X-XSS-Protection: 1; mode=block`
|
||||
* `X-Content-Type-Options nosniff`
|
||||
* `Referrer-Policy no-referrer-when-downgrade`
|
||||
* `Content-Security-Policy: default-src 'self' ws: wss: http: https: data: blob:
|
||||
'unsafe-inline'; frame-ancestors 'self';`
|
||||
* `Permissions-Policy: interest-cohort=()`
|
||||
- `X-XSS-Protection: 1; mode=block`
|
||||
- `X-Content-Type-Options nosniff`
|
||||
- `Referrer-Policy no-referrer-when-downgrade`
|
||||
- `Content-Security-Policy: default-src 'self' ws: wss: http: https: data: blob:
|
||||
'unsafe-inline'; frame-ancestors 'self';`
|
||||
- `Permissions-Policy: interest-cohort=()`
|
||||
|
||||
Since the upstream Firezone web app expects plain HTTP traffic, any requests the
|
||||
proxy forwards is sent over HTTP and thus is **not encrypted**. In most cases,
|
||||
@@ -97,9 +94,9 @@ reverse proxy to proxy to that instead.
|
||||
|
||||
## Example configurations
|
||||
|
||||
* [Apache](/reference/reverse-proxy-templates/apache/)
|
||||
* [Traefik](/reference/reverse-proxy-templates/traefik/)
|
||||
* [HAProxy](/reference/reverse-proxy-templates/haproxy/)
|
||||
- [Apache](/docs/reference/reverse-proxy-templates/apache/)
|
||||
- [Traefik](/docs/reference/reverse-proxy-templates/traefik/)
|
||||
- [HAProxy](/docs/reference/reverse-proxy-templates/haproxy/)
|
||||
|
||||
These configurations are written to be as simple as possible. They're designed
|
||||
to function as a simple template which you can customize further to suit your
|
||||
|
||||
@@ -7,15 +7,15 @@ sidebar_position: 5
|
||||
|
||||
There are two types of configuration in Firezone:
|
||||
|
||||
* [Runtime configuration](#runtime-configuration): Application configuration
|
||||
- [Runtime configuration](#runtime-configuration): Application configuration
|
||||
related to day-to-day operation of Firezone.
|
||||
* [Deployment configuration](#deployment-configuration): Deployment or
|
||||
- [Deployment configuration](#deployment-configuration): Deployment or
|
||||
infrastructure-related configuration relevant to running Firezone on-prem.
|
||||
|
||||
## Runtime configuration
|
||||
|
||||
Most day-to-day configuration of Firezone can be done via the Web UI or
|
||||
[REST API](/reference/rest-api/configurations).
|
||||
[REST API](/docs/reference/rest-api/configurations).
|
||||
This type of configuration can be expected to be changed **with no downtime**
|
||||
in a production deployment.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Shown below is a table of default ports used by Firezone services.
|
||||
<TabItem label="Docker" value="docker" default>
|
||||
|
||||
| Service | Port | Listen address | Description |
|
||||
| ------ | --------- | ------- | --------- |
|
||||
| ---------- | ----------- | -------------- | ----------------------------------------------------------------------------- |
|
||||
| Caddy | `443/tcp` | `all` | Public HTTPS port for administering Firezone and facilitating authentication. |
|
||||
| Caddy | `80/tcp` | `all` | Public HTTP port used for ACME. Disabled when ACME is disabled. |
|
||||
| WireGuard | `51820/udp` | `all` | Public WireGuard port used for VPN sessions. |
|
||||
@@ -29,7 +29,7 @@ Shown below is a table of default ports used by Firezone services.
|
||||
<TabItem label="Omnibus" value="omnibus">
|
||||
|
||||
| Service | Port | Listen address | Description |
|
||||
| ------ | --------- | ------- | --------- |
|
||||
| ---------- | ----------- | -------------- | ----------------------------------------------------------------------------- |
|
||||
| Nginx | `443/tcp` | `all` | Public HTTPS port for administering Firezone and facilitating authentication. |
|
||||
| Nginx | `80/tcp` | `all` | Public HTTP port used for ACME. Disabled when ACME is disabled. |
|
||||
| WireGuard | `51820/udp` | `all` | Public WireGuard port used for VPN sessions. |
|
||||
@@ -47,7 +47,7 @@ altogether by setting `default['firezone']['authentication']['local']['enabled']
|
||||
Local authentication can also be disabled on the `/settings/security` page.
|
||||
|
||||
:::caution
|
||||
Ensure you've set up a working [OIDC](/authenticate/oidc/) or [SAML](/authenticate/saml/)-based
|
||||
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.
|
||||
:::
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ sidebar_position: 2
|
||||
|
||||
:::note
|
||||
Audit logs are in early Beta on the Enterprise plan.
|
||||
[Contact us](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev)
|
||||
[Contact us](/sales)
|
||||
to learn more.
|
||||
:::
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ To configure Omnibus-based deployments of Firezone:
|
||||
1. Edit `/etc/firezone/firezone.rb` with your changes.
|
||||
1. Run `sudo firezone-ctl reconfigure` to process the changes and restart affected services.
|
||||
|
||||
Read more about configuring Firezone in the [configure guide](/deploy/configure).
|
||||
Read more about configuring Firezone in the [configure guide](/docs/deploy/configure).
|
||||
|
||||
## Configuration file reference
|
||||
|
||||
@@ -25,162 +25,162 @@ Shown below is a complete listing of the configuration options available in
|
||||
<!-- markdownlint-disable MD033 -->
|
||||
<!-- markdownlint-disable MD034 -->
|
||||
|
||||
| Option | Description | Default Value |
|
||||
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
||||
| `default['firezone']['external_url']` | URL used to access the web portal of this Firezone instance. | <code>"https://#{node['fqdn'] || node['hostname']}"</code> |
|
||||
| `default['firezone']['config_directory']` | Top-level directory for Firezone configuration. | `'/etc/firezone'` |
|
||||
| `default['firezone']['install_directory']` | Top-level directory to install Firezone to. | `'/opt/firezone'` |
|
||||
| `default['firezone']['app_directory']` | Top-level directory to install the Firezone web application. | `"#{node['firezone']['install_directory']}/embedded/service/firezone"` |
|
||||
| `default['firezone']['log_directory']` | Top-level directory for Firezone logs. | `'/var/log/firezone'` |
|
||||
| `default['firezone']['var_directory']` | Top-level directory for Firezone runtime files. | `'/var/opt/firezone'` |
|
||||
| `default['firezone']['user']` | Name of unprivileged Linux user most services and files will belong to. | `'firezone'` |
|
||||
| `default['firezone']['group']` | Name of Linux group most services and files will belong to. | `'firezone'` |
|
||||
| `default['firezone']['admin_email']` | Email address for initial Firezone user. | `"firezone@localhost"` |
|
||||
| `default['firezone']['max_devices_per_user']` | Maximum number of devices a user can have. | `10` |
|
||||
| `default['firezone']['allow_unprivileged_device_management']` | Allows non-admin users to create and delete devices. | `true` |
|
||||
| `default['firezone']['allow_unprivileged_device_configuration']` | Allows non-admin users to modify device configurations. When disabled, prevents unprivileged users from changing all device fields except for `name` and `description`. | `true` |
|
||||
| `default['firezone']['egress_interface']` | Interface name where tunneled traffic will exit. If nil, the default route interface will be used. | `nil` |
|
||||
| `default['firezone']['fips_enabled']` | Enable or disable OpenSSL FIPs mode. | `nil` |
|
||||
| `default['firezone']['logging']['enabled']` | Enable or disable logging across Firezone. Set to `false` to disable logging entirely. | `true` |
|
||||
| `default['enterprise']['name']` | Name used by the Chef 'enterprise' cookbook. | `'firezone'` |
|
||||
| `default['firezone']['install_path']` | Install path used by Chef 'enterprise' cookbook. Should be set to the same as the `install_directory` above. | `node['firezone']['install_directory']` |
|
||||
| `default['firezone']['sysvinit_id']` | An identifier used in `/etc/inittab`. Must be a unique sequence of 1-4 characters. | `'SUP'` |
|
||||
| `default['firezone']['authentication']['local']['enabled']` | Enable or disable local email/password authentication. | `true` |
|
||||
| `default['firezone']['authentication']['disable_vpn_on_oidc_error']` | Disable a user's VPN if an error is detected trying to refresh their OIDC token. | `false` |
|
||||
| `default['firezone']['authentication']['oidc']` | OpenID Connect config, in the format of `{"provider" => [config...]}` - See [OpenIDConnect documentation](https://hexdocs.pm/openid_connect/readme.html) for config examples. | `{}` |
|
||||
| `default['firezone']['nginx']['enabled']` | Enable or disable the bundled nginx server. | `true` |
|
||||
| `default['firezone']['nginx']['ssl_port']` | HTTPS listen port. | `443` |
|
||||
| `default['firezone']['nginx']['directory']` | Directory to store Firezone-related nginx virtual host configuration. | `"#{node['firezone']['var_directory']}/nginx/etc"` |
|
||||
| `default['firezone']['nginx']['log_directory']` | Directory to store Firezone-related nginx log files. | `"#{node['firezone']['log_directory']}/nginx"` |
|
||||
| `default['firezone']['nginx']['log_rotation']['file_maxbytes']` | File size at which to rotate Nginx log files. | `104857600` |
|
||||
| `default['firezone']['nginx']['log_rotation']['num_to_keep']` | Number of Firezone nginx log files to keep before discarding. | `10` |
|
||||
| `default['firezone']['nginx']['log_x_forwarded_for']` | Whether to log Firezone nginx `x-forwarded-for` header. | `true` |
|
||||
| `default['firezone']['nginx']['hsts_header']['enabled']` | Enable or disable [HSTS](https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/). | `true` |
|
||||
| `default['firezone']['nginx']['hsts_header']['include_subdomains']` | Enable or disable `includeSubDomains` for the HSTS header. | `true` |
|
||||
| `default['firezone']['nginx']['hsts_header']['max_age']` | Max age for the HSTS header. | `31536000` |
|
||||
| `default['firezone']['nginx']['redirect_to_canonical']` | Whether to redirect URLs to the canonical FQDN specified above | `false` |
|
||||
| `default['firezone']['nginx']['cache']['enabled']` | Enable or disable the Firezone nginx cache. | `false` |
|
||||
| `default['firezone']['nginx']['cache']['directory']` | Directory for Firezone nginx cache. | `"#{node['firezone']['var_directory']}/nginx/cache"` |
|
||||
| `default['firezone']['nginx']['user']` | Firezone nginx user. | `node['firezone']['user']` |
|
||||
| `default['firezone']['nginx']['group']` | Firezone nginx group. | `node['firezone']['group']` |
|
||||
| `default['firezone']['nginx']['dir']` | Top-level nginx configuration directory. | `node['firezone']['nginx']['directory']` |
|
||||
| `default['firezone']['nginx']['log_dir']` | Top-level nginx log directory. | `node['firezone']['nginx']['log_directory']` |
|
||||
| `default['firezone']['nginx']['pid']` | Location for nginx pid file. | `"#{node['firezone']['nginx']['directory']}/nginx.pid"` |
|
||||
| `default['firezone']['nginx']['daemon_disable']` | Disable nginx daemon mode so we can monitor it instead. | `true` |
|
||||
| `default['firezone']['nginx']['gzip']` | Turn nginx gzip compression on or off. | `'on'` |
|
||||
| `default['firezone']['nginx']['gzip_static']` | Turn nginx gzip compression on or off for static files. | `'off'` |
|
||||
| `default['firezone']['nginx']['gzip_http_version']` | HTTP version to use for serving static files. | `'1.0'` |
|
||||
| `default['firezone']['nginx']['gzip_comp_level']` | nginx gzip compression level. | `'2'` |
|
||||
| `default['firezone']['nginx']['gzip_proxied']` | Enables or disables gzipping of responses for proxied requests depending on the request and response. | `'any'` |
|
||||
| `default['firezone']['nginx']['gzip_vary']` | Enables or disables inserting the “Vary: Accept-Encoding” response header. | `'off'` |
|
||||
| `default['firezone']['nginx']['gzip_buffers']` | Sets the number and size of buffers used to compress a response. If `nil`, nginx default is used. | `nil` |
|
||||
| `default['firezone']['nginx']['gzip_types']` | MIME types to enable gzip compression for. | `['text/plain', 'text/css','application/x-javascript', 'text/xml', 'application/xml', 'application/rss+xml', 'application/atom+xml', 'text/javascript', 'application/javascript', 'application/json']` |
|
||||
| `default['firezone']['nginx']['gzip_min_length']` | Minimum file length to enable file gzip compression for. | `1000` |
|
||||
| `default['firezone']['nginx']['gzip_disable']` | User-agent matcher to disable gzip compression for. | `'MSIE [1-6]\.'` |
|
||||
| `default['firezone']['nginx']['keepalive']` | Activates cache for connection to upstream servers. | `'on'` |
|
||||
| `default['firezone']['nginx']['keepalive_timeout']` | Timeout in seconds for keepalive connection to upstream servers. | `65` |
|
||||
| `default['firezone']['nginx']['worker_processes']` | Number of nginx worker processes. | `node['cpu'] && node['cpu']['total'] ? node['cpu']['total'] : 1` |
|
||||
| `default['firezone']['nginx']['worker_connections']` | Max number of simultaneous connections that can be opened by a worker process. | `1024` |
|
||||
| `default['firezone']['nginx']['worker_rlimit_nofile']` | Changes the limit on the maximum number of open files for worker processes. Uses nginx default if nil. | `nil` |
|
||||
| `default['firezone']['nginx']['multi_accept']` | Whether workers should accept one connection at a time or multiple. | `true` |
|
||||
| `default['firezone']['nginx']['event']` | Specifies the connection processing method to use inside nginx events context. | `'epoll'` |
|
||||
| `default['firezone']['nginx']['server_tokens']` | Enables or disables emitting nginx version on error pages and in the “Server” response header field. | `nil` |
|
||||
| `default['firezone']['nginx']['server_names_hash_bucket_size']` | Sets the bucket size for the server names hash tables. | `64` |
|
||||
| `default['firezone']['nginx']['sendfile']` | Enables or disables the use of nginx's `sendfile()`. | `'on'` |
|
||||
| `default['firezone']['nginx']['access_log_options']` | Sets nginx access log options. | `nil` |
|
||||
| `default['firezone']['nginx']['error_log_options']` | Sets nginx error log options. | `nil` |
|
||||
| `default['firezone']['nginx']['disable_access_log']` | Disables nginx access log. | `false` |
|
||||
| `default['firezone']['nginx']['types_hash_max_size']` | nginx types hash max size. | `2048` |
|
||||
| `default['firezone']['nginx']['types_hash_bucket_size']` | nginx types hash bucket size. | `64` |
|
||||
| `default['firezone']['nginx']['proxy_read_timeout']` | nginx proxy read timeout. Set to `nil` to use nginx default. | `nil` |
|
||||
| `default['firezone']['nginx']['client_body_buffer_size']` | nginx client body buffer size. Set to `nil` to use nginx default. | `nil` |
|
||||
| `default['firezone']['nginx']['client_max_body_size']` | nginx client max body size. | `'250m'` |
|
||||
| `default['firezone']['nginx']['default']['modules']` | Specify additional nginx modules. | `[]` |
|
||||
| `default['firezone']['nginx']['enable_rate_limiting']` | Enable or disable nginx rate limiting. | `true` |
|
||||
| `default['firezone']['nginx']['rate_limiting_zone_name']` | Nginx rate limiting zone name. | `'firezone'` |
|
||||
| `default['firezone']['nginx']['rate_limiting_backoff']` | Nginx rate limiting backoff. | `'10m'` |
|
||||
| `default['firezone']['nginx']['rate_limit']` | Nginx rate limit. | `'10r/s'` |
|
||||
| `default['firezone']['nginx']['ipv6']` | Allow nginx to listen for HTTP requests for IPv6 in addition to IPv4. | `true` |
|
||||
| `default['firezone']['postgresql']['enabled']` | Enable or disable bundled Postgresql. Set to `false` and fill in the `database` options below to use your own Postgresql instance. | `true` |
|
||||
| `default['firezone']['postgresql']['username']` | Username for Postgresql. | `node['firezone']['user']` |
|
||||
| `default['firezone']['postgresql']['data_directory']` | Postgresql data directory. | `"#{node['firezone']['var_directory']}/postgresql/13.3/data"` |
|
||||
| `default['firezone']['postgresql']['log_directory']` | Postgresql log directory. | `"#{node['firezone']['log_directory']}/postgresql"` |
|
||||
| `default['firezone']['postgresql']['log_rotation']['file_maxbytes']` | Postgresql log file maximum size before it's rotated. | `104857600` |
|
||||
| `default['firezone']['postgresql']['log_rotation']['num_to_keep']` | Number of Postgresql log files to keep. | `10` |
|
||||
| `default['firezone']['postgresql']['checkpoint_completion_target']` | Postgresql checkpoint completion target. | `0.5` |
|
||||
| `default['firezone']['postgresql']['checkpoint_segments']` | Number of Postgresql checkpoint segments. | `3` |
|
||||
| `default['firezone']['postgresql']['checkpoint_timeout']` | Postgresql checkpoint timeout. | `'5min'` |
|
||||
| `default['firezone']['postgresql']['checkpoint_warning']` | Postgresql checkpoint warning time in seconds. | `'30s'` |
|
||||
| `default['firezone']['postgresql']['effective_cache_size']` | Postgresql effective cache size. | `'128MB'` |
|
||||
| `default['firezone']['postgresql']['listen_address']` | Postgresql listen address. | `'127.0.0.1'` |
|
||||
| `default['firezone']['postgresql']['max_connections']` | Postgresql max connections. | `350` |
|
||||
| `default['firezone']['postgresql']['md5_auth_cidr_addresses']` | Postgresql CIDRs to allow for md5 auth. | `['127.0.0.1/32', '::1/128']` |
|
||||
| `default['firezone']['postgresql']['port']` | Postgresql listen port. | `15432` |
|
||||
| `default['firezone']['postgresql']['shared_buffers']` | Postgresql shared buffers size. | `"#{(node['memory']['total'].to_i / 4) / 1024}MB"` |
|
||||
| `default['firezone']['postgresql']['shmmax']` | Postgresql shmmax in bytes. | `17179869184` |
|
||||
| `default['firezone']['postgresql']['shmall']` | Postgresql shmall in bytes. | `4194304` |
|
||||
| `default['firezone']['postgresql']['work_mem']` | Postgresql working memory size. | `'8MB'` |
|
||||
| `default['firezone']['database']['user']` | Specifies the username Firezone will use to connect to the DB. | `node['firezone']['postgresql']['username']` |
|
||||
| `default['firezone']['database']['password']` | If using an external DB, specifies the password Firezone will use to connect to the DB. | `'change_me'` |
|
||||
| `default['firezone']['database']['name']` | Database that Firezone will use. Will be created if it doesn't exist. | `'firezone'` |
|
||||
| `default['firezone']['database']['host']` | Database host that Firezone will connect to. | `node['firezone']['postgresql']['listen_address']` |
|
||||
| `default['firezone']['database']['port']` | Database port that Firezone will connect to. | `node['firezone']['postgresql']['port']` |
|
||||
| `default['firezone']['database']['pool']` | Database pool size Firezone will use. | `[10, Etc.nprocessors].max` |
|
||||
| `default['firezone']['database']['ssl']` | Whether to connect to the database over SSL. | `false` |
|
||||
| `default['firezone']['database']['ssl_opts']` | Hash of options to send to the `:ssl_opts` option when connecting over SSL. See [Ecto.Adapters.Postgres documentation](https://hexdocs.pm/ecto_sql/Ecto.Adapters.Postgres.html#module-connection-options). | `{}` |
|
||||
| `default['firezone']['database']['parameters']` | Hash of parameters to send to the `:parameters` option when connecting to the database. See [Ecto.Adapters.Postgres documentation](https://hexdocs.pm/ecto_sql/Ecto.Adapters.Postgres.html#module-connection-options). | `{}` |
|
||||
| `default['firezone']['database']['extensions']` | Database extensions to enable. | `{ 'plpgsql' => true, 'pg_trgm' => true }` |
|
||||
| `default['firezone']['phoenix']['enabled']` | Enable or disable the Firezone web application. | `true` |
|
||||
| `default['firezone']['phoenix']['listen_address']` | Firezone web application listen address. This will be the upstream listen address that nginx proxies. | `'127.0.0.1'` |
|
||||
| `default['firezone']['phoenix']['port']` | Firezone web application listen port. This will be the upstream port that nginx proxies. | `13000` |
|
||||
| `default['firezone']['phoenix']['log_directory']` | Firezone web application log directory. | `"#{node['firezone']['log_directory']}/phoenix"` |
|
||||
| `default['firezone']['phoenix']['log_rotation']['file_maxbytes']` | Firezone web application log file size. | `104857600` |
|
||||
| `default['firezone']['phoenix']['log_rotation']['num_to_keep']` | Number of Firezone web application log files to keep. | `10` |
|
||||
| `default['firezone']['phoenix']['crash_detection']['enabled']` | Enable or disable bringing down the Firezone web application when a crash is detected. | `true` |
|
||||
| `default['firezone']['phoenix']['external_trusted_proxies']` | List of trusted reverse proxies formatted as an Array of IPs and/or CIDRs. | `[]` |
|
||||
| `default['firezone']['phoenix']['private_clients']` | List of private network HTTP clients, formatted an Array of IPs and/or CIDRs. | `[]` |
|
||||
| `default['firezone']['wireguard']['enabled']` | Enable or disable bundled WireGuard management. | `true` |
|
||||
| `default['firezone']['wireguard']['log_directory']` | Log directory for bundled WireGuard management. | `"#{node['firezone']['log_directory']}/wireguard"` |
|
||||
| `default['firezone']['wireguard']['log_rotation']['file_maxbytes']` | WireGuard log file max size. | `104857600` |
|
||||
| `default['firezone']['wireguard']['log_rotation']['num_to_keep']` | Number of WireGuard log files to keep. | `10` |
|
||||
| `default['firezone']['wireguard']['interface_name']` | WireGuard interface name. **Changing this parameter may cause a temporary loss in VPN connectivity**. | `'wg-firezone'` |
|
||||
| `default['firezone']['wireguard']['port']` | WireGuard listen port. | `51820` |
|
||||
| `default['firezone']['wireguard']['persistent_keepalive']` | Default PersistentKeepalive setting for generated device configurations. A value of 0 disables. | `0` |
|
||||
| `default['firezone']['wireguard']['ipv4']['enabled']` | Enable or disable IPv4 for WireGuard network. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv4']['masquerade']` | Enable or disable masquerade for packets leaving the IPv4 tunnel. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv4']['network']` | WireGuard network IPv4 address pool. | `'10.3.2.0/24'` |
|
||||
| `default['firezone']['wireguard']['ipv4']['address']` | WireGuard interface IPv4 address. Must be within WireGuard address pool. | `'10.3.2.1'` |
|
||||
| `default['firezone']['wireguard']['ipv6']['enabled']` | Enable or disable IPv6 for WireGuard network. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv6']['masquerade']` | Enable or disable masquerade for packets leaving the IPv6 tunnel. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv6']['network']` | WireGuard network IPv6 address pool. | `'fd00::3:2:0/120'` |
|
||||
| `default['firezone']['wireguard']['ipv6']['address']` | WireGuard interface IPv6 address. Must be within IPv6 address pool. | `'fd00::3:2:1'` |
|
||||
| `default['firezone']['runit']['svlogd_bin']` | Runit svlogd bin location. | `"#{node['firezone']['install_directory']}/embedded/bin/svlogd"` |
|
||||
| `default['firezone']['ssl']['directory']` | SSL directory for storing generated certs. | `'/var/opt/firezone/ssl'` |
|
||||
| `default['firezone']['ssl']['email_address']` | Email address to use for self-signed certs and ACME protocol renewal notices. | `'you@example.com'` |
|
||||
| `default['firezone']['ssl']['acme']['enabled']` | Enable ACME for automatic SSL cert provisioning. | `false` |
|
||||
| `default['firezone']['ssl']['acme']['server']` | ACME server to use for certificate issuance/renewal. Can be any [valid acme.sh server](https://github.com/acmesh-official/acme.sh/wiki/Server) | `letsencrypt` |
|
||||
| `default['firezone']['ssl']['acme']['keylength']` | Specify the key type and length for SSL certificates. See [here](https://github.com/acmesh-official/acme.sh#10-issue-ecc-certificates) | `ec-256` |
|
||||
| `default['firezone']['ssl']['certificate']` | Path to the certificate file for your FQDN. Overrides ACME setting above if specified. If both ACME and this are `nil` a self-signed cert will be generated. | `nil` |
|
||||
| `default['firezone']['ssl']['certificate_key']` | Path to the certificate file. | `nil` |
|
||||
| `default['firezone']['ssl']['ssl_dhparam']` | nginx ssl dh_param. | `nil` |
|
||||
| `default['firezone']['ssl']['country_name']` | Country name for self-signed cert. | `'US'` |
|
||||
| `default['firezone']['ssl']['state_name']` | State name for self-signed cert. | `'CA'` |
|
||||
| `default['firezone']['ssl']['locality_name']` | Locality name for self-signed cert. | `'San Francisco'` |
|
||||
| `default['firezone']['ssl']['company_name']` | Company name self-signed cert. | `'My Company'` |
|
||||
| `default['firezone']['ssl']['organizational_unit_name']` | Organizational unit name for self-signed cert. | `'Operations'` |
|
||||
| `default['firezone']['ssl']['ciphers']` | SSL ciphers for nginx to use. | `'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'` |
|
||||
| `default['firezone']['ssl']['fips_ciphers']` | SSL ciphers for FIPs mode. | `'FIPS@STRENGTH:!aNULL:!eNULL'` |
|
||||
| `default['firezone']['ssl']['protocols']` | TLS protocols to use. | `'TLSv1 TLSv1.1 TLSv1.2'` |
|
||||
| `default['firezone']['ssl']['session_cache']` | SSL session cache. | `'shared:SSL:4m'` |
|
||||
| `default['firezone']['ssl']['session_timeout']` | SSL session timeout. | `'5m'` |
|
||||
| `default['firezone']['robots_allow']` | nginx robots allow. | `'/'` |
|
||||
| `default['firezone']['robots_disallow']` | nginx robots disallow. | `nil` |
|
||||
| `default['firezone']['outbound_email']['from']` | Outbound email from address. | `nil` |
|
||||
| `default['firezone']['outbound_email']['provider']` | Outbound email service provider. | `nil` |
|
||||
| `default['firezone']['outbound_email']['configs']` | Outbound email provider configs. | see `omnibus/cookbooks/firezone/attributes/default.rb` |
|
||||
| `default['firezone']['telemetry']['enabled']` | Enable or disable anonymized product telemetry. | `true` |
|
||||
| `default['firezone']['connectivity_checks']['enabled']` | Enable or disable the Firezone connectivity checks service. | `true` |
|
||||
| `default['firezone']['connectivity_checks']['interval']` | Interval between connectivity checks in seconds. | `3_600` |
|
||||
| Option | Description | Default Value |
|
||||
| -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `default['firezone']['external_url']` | URL used to access the web portal of this Firezone instance. | <code>"https://#{node['fqdn'] || node['hostname']}"</code> |
|
||||
| `default['firezone']['config_directory']` | Top-level directory for Firezone configuration. | `'/etc/firezone'` |
|
||||
| `default['firezone']['install_directory']` | Top-level directory to install Firezone to. | `'/opt/firezone'` |
|
||||
| `default['firezone']['app_directory']` | Top-level directory to install the Firezone web application. | `"#{node['firezone']['install_directory']}/embedded/service/firezone"` |
|
||||
| `default['firezone']['log_directory']` | Top-level directory for Firezone logs. | `'/var/log/firezone'` |
|
||||
| `default['firezone']['var_directory']` | Top-level directory for Firezone runtime files. | `'/var/opt/firezone'` |
|
||||
| `default['firezone']['user']` | Name of unprivileged Linux user most services and files will belong to. | `'firezone'` |
|
||||
| `default['firezone']['group']` | Name of Linux group most services and files will belong to. | `'firezone'` |
|
||||
| `default['firezone']['admin_email']` | Email address for initial Firezone user. | `"firezone@localhost"` |
|
||||
| `default['firezone']['max_devices_per_user']` | Maximum number of devices a user can have. | `10` |
|
||||
| `default['firezone']['allow_unprivileged_device_management']` | Allows non-admin users to create and delete devices. | `true` |
|
||||
| `default['firezone']['allow_unprivileged_device_configuration']` | Allows non-admin users to modify device configurations. When disabled, prevents unprivileged users from changing all device fields except for `name` and `description`. | `true` |
|
||||
| `default['firezone']['egress_interface']` | Interface name where tunneled traffic will exit. If nil, the default route interface will be used. | `nil` |
|
||||
| `default['firezone']['fips_enabled']` | Enable or disable OpenSSL FIPs mode. | `nil` |
|
||||
| `default['firezone']['logging']['enabled']` | Enable or disable logging across Firezone. Set to `false` to disable logging entirely. | `true` |
|
||||
| `default['enterprise']['name']` | Name used by the Chef 'enterprise' cookbook. | `'firezone'` |
|
||||
| `default['firezone']['install_path']` | Install path used by Chef 'enterprise' cookbook. Should be set to the same as the `install_directory` above. | `node['firezone']['install_directory']` |
|
||||
| `default['firezone']['sysvinit_id']` | An identifier used in `/etc/inittab`. Must be a unique sequence of 1-4 characters. | `'SUP'` |
|
||||
| `default['firezone']['authentication']['local']['enabled']` | Enable or disable local email/password authentication. | `true` |
|
||||
| `default['firezone']['authentication']['disable_vpn_on_oidc_error']` | Disable a user's VPN if an error is detected trying to refresh their OIDC token. | `false` |
|
||||
| `default['firezone']['authentication']['oidc']` | OpenID Connect config, in the format of `{"provider" => [config...]}` - See [OpenIDConnect documentation](https://hexdocs.pm/openid_connect/readme.html) for config examples. | `{}` |
|
||||
| `default['firezone']['nginx']['enabled']` | Enable or disable the bundled nginx server. | `true` |
|
||||
| `default['firezone']['nginx']['ssl_port']` | HTTPS listen port. | `443` |
|
||||
| `default['firezone']['nginx']['directory']` | Directory to store Firezone-related nginx virtual host configuration. | `"#{node['firezone']['var_directory']}/nginx/etc"` |
|
||||
| `default['firezone']['nginx']['log_directory']` | Directory to store Firezone-related nginx log files. | `"#{node['firezone']['log_directory']}/nginx"` |
|
||||
| `default['firezone']['nginx']['log_rotation']['file_maxbytes']` | File size at which to rotate Nginx log files. | `104857600` |
|
||||
| `default['firezone']['nginx']['log_rotation']['num_to_keep']` | Number of Firezone nginx log files to keep before discarding. | `10` |
|
||||
| `default['firezone']['nginx']['log_x_forwarded_for']` | Whether to log Firezone nginx `x-forwarded-for` header. | `true` |
|
||||
| `default['firezone']['nginx']['hsts_header']['enabled']` | Enable or disable [HSTS](https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/). | `true` |
|
||||
| `default['firezone']['nginx']['hsts_header']['include_subdomains']` | Enable or disable `includeSubDomains` for the HSTS header. | `true` |
|
||||
| `default['firezone']['nginx']['hsts_header']['max_age']` | Max age for the HSTS header. | `31536000` |
|
||||
| `default['firezone']['nginx']['redirect_to_canonical']` | Whether to redirect URLs to the canonical FQDN specified above | `false` |
|
||||
| `default['firezone']['nginx']['cache']['enabled']` | Enable or disable the Firezone nginx cache. | `false` |
|
||||
| `default['firezone']['nginx']['cache']['directory']` | Directory for Firezone nginx cache. | `"#{node['firezone']['var_directory']}/nginx/cache"` |
|
||||
| `default['firezone']['nginx']['user']` | Firezone nginx user. | `node['firezone']['user']` |
|
||||
| `default['firezone']['nginx']['group']` | Firezone nginx group. | `node['firezone']['group']` |
|
||||
| `default['firezone']['nginx']['dir']` | Top-level nginx configuration directory. | `node['firezone']['nginx']['directory']` |
|
||||
| `default['firezone']['nginx']['log_dir']` | Top-level nginx log directory. | `node['firezone']['nginx']['log_directory']` |
|
||||
| `default['firezone']['nginx']['pid']` | Location for nginx pid file. | `"#{node['firezone']['nginx']['directory']}/nginx.pid"` |
|
||||
| `default['firezone']['nginx']['daemon_disable']` | Disable nginx daemon mode so we can monitor it instead. | `true` |
|
||||
| `default['firezone']['nginx']['gzip']` | Turn nginx gzip compression on or off. | `'on'` |
|
||||
| `default['firezone']['nginx']['gzip_static']` | Turn nginx gzip compression on or off for static files. | `'off'` |
|
||||
| `default['firezone']['nginx']['gzip_http_version']` | HTTP version to use for serving static files. | `'1.0'` |
|
||||
| `default['firezone']['nginx']['gzip_comp_level']` | nginx gzip compression level. | `'2'` |
|
||||
| `default['firezone']['nginx']['gzip_proxied']` | Enables or disables gzipping of responses for proxied requests depending on the request and response. | `'any'` |
|
||||
| `default['firezone']['nginx']['gzip_vary']` | Enables or disables inserting the “Vary: Accept-Encoding” response header. | `'off'` |
|
||||
| `default['firezone']['nginx']['gzip_buffers']` | Sets the number and size of buffers used to compress a response. If `nil`, nginx default is used. | `nil` |
|
||||
| `default['firezone']['nginx']['gzip_types']` | MIME types to enable gzip compression for. | `['text/plain', 'text/css','application/x-javascript', 'text/xml', 'application/xml', 'application/rss+xml', 'application/atom+xml', 'text/javascript', 'application/javascript', 'application/json']` |
|
||||
| `default['firezone']['nginx']['gzip_min_length']` | Minimum file length to enable file gzip compression for. | `1000` |
|
||||
| `default['firezone']['nginx']['gzip_disable']` | User-agent matcher to disable gzip compression for. | `'MSIE [1-6]\.'` |
|
||||
| `default['firezone']['nginx']['keepalive']` | Activates cache for connection to upstream servers. | `'on'` |
|
||||
| `default['firezone']['nginx']['keepalive_timeout']` | Timeout in seconds for keepalive connection to upstream servers. | `65` |
|
||||
| `default['firezone']['nginx']['worker_processes']` | Number of nginx worker processes. | `node['cpu'] && node['cpu']['total'] ? node['cpu']['total'] : 1` |
|
||||
| `default['firezone']['nginx']['worker_connections']` | Max number of simultaneous connections that can be opened by a worker process. | `1024` |
|
||||
| `default['firezone']['nginx']['worker_rlimit_nofile']` | Changes the limit on the maximum number of open files for worker processes. Uses nginx default if nil. | `nil` |
|
||||
| `default['firezone']['nginx']['multi_accept']` | Whether workers should accept one connection at a time or multiple. | `true` |
|
||||
| `default['firezone']['nginx']['event']` | Specifies the connection processing method to use inside nginx events context. | `'epoll'` |
|
||||
| `default['firezone']['nginx']['server_tokens']` | Enables or disables emitting nginx version on error pages and in the “Server” response header field. | `nil` |
|
||||
| `default['firezone']['nginx']['server_names_hash_bucket_size']` | Sets the bucket size for the server names hash tables. | `64` |
|
||||
| `default['firezone']['nginx']['sendfile']` | Enables or disables the use of nginx's `sendfile()`. | `'on'` |
|
||||
| `default['firezone']['nginx']['access_log_options']` | Sets nginx access log options. | `nil` |
|
||||
| `default['firezone']['nginx']['error_log_options']` | Sets nginx error log options. | `nil` |
|
||||
| `default['firezone']['nginx']['disable_access_log']` | Disables nginx access log. | `false` |
|
||||
| `default['firezone']['nginx']['types_hash_max_size']` | nginx types hash max size. | `2048` |
|
||||
| `default['firezone']['nginx']['types_hash_bucket_size']` | nginx types hash bucket size. | `64` |
|
||||
| `default['firezone']['nginx']['proxy_read_timeout']` | nginx proxy read timeout. Set to `nil` to use nginx default. | `nil` |
|
||||
| `default['firezone']['nginx']['client_body_buffer_size']` | nginx client body buffer size. Set to `nil` to use nginx default. | `nil` |
|
||||
| `default['firezone']['nginx']['client_max_body_size']` | nginx client max body size. | `'250m'` |
|
||||
| `default['firezone']['nginx']['default']['modules']` | Specify additional nginx modules. | `[]` |
|
||||
| `default['firezone']['nginx']['enable_rate_limiting']` | Enable or disable nginx rate limiting. | `true` |
|
||||
| `default['firezone']['nginx']['rate_limiting_zone_name']` | Nginx rate limiting zone name. | `'firezone'` |
|
||||
| `default['firezone']['nginx']['rate_limiting_backoff']` | Nginx rate limiting backoff. | `'10m'` |
|
||||
| `default['firezone']['nginx']['rate_limit']` | Nginx rate limit. | `'10r/s'` |
|
||||
| `default['firezone']['nginx']['ipv6']` | Allow nginx to listen for HTTP requests for IPv6 in addition to IPv4. | `true` |
|
||||
| `default['firezone']['postgresql']['enabled']` | Enable or disable bundled Postgresql. Set to `false` and fill in the `database` options below to use your own Postgresql instance. | `true` |
|
||||
| `default['firezone']['postgresql']['username']` | Username for Postgresql. | `node['firezone']['user']` |
|
||||
| `default['firezone']['postgresql']['data_directory']` | Postgresql data directory. | `"#{node['firezone']['var_directory']}/postgresql/13.3/data"` |
|
||||
| `default['firezone']['postgresql']['log_directory']` | Postgresql log directory. | `"#{node['firezone']['log_directory']}/postgresql"` |
|
||||
| `default['firezone']['postgresql']['log_rotation']['file_maxbytes']` | Postgresql log file maximum size before it's rotated. | `104857600` |
|
||||
| `default['firezone']['postgresql']['log_rotation']['num_to_keep']` | Number of Postgresql log files to keep. | `10` |
|
||||
| `default['firezone']['postgresql']['checkpoint_completion_target']` | Postgresql checkpoint completion target. | `0.5` |
|
||||
| `default['firezone']['postgresql']['checkpoint_segments']` | Number of Postgresql checkpoint segments. | `3` |
|
||||
| `default['firezone']['postgresql']['checkpoint_timeout']` | Postgresql checkpoint timeout. | `'5min'` |
|
||||
| `default['firezone']['postgresql']['checkpoint_warning']` | Postgresql checkpoint warning time in seconds. | `'30s'` |
|
||||
| `default['firezone']['postgresql']['effective_cache_size']` | Postgresql effective cache size. | `'128MB'` |
|
||||
| `default['firezone']['postgresql']['listen_address']` | Postgresql listen address. | `'127.0.0.1'` |
|
||||
| `default['firezone']['postgresql']['max_connections']` | Postgresql max connections. | `350` |
|
||||
| `default['firezone']['postgresql']['md5_auth_cidr_addresses']` | Postgresql CIDRs to allow for md5 auth. | `['127.0.0.1/32', '::1/128']` |
|
||||
| `default['firezone']['postgresql']['port']` | Postgresql listen port. | `15432` |
|
||||
| `default['firezone']['postgresql']['shared_buffers']` | Postgresql shared buffers size. | `"#{(node['memory']['total'].to_i / 4) / 1024}MB"` |
|
||||
| `default['firezone']['postgresql']['shmmax']` | Postgresql shmmax in bytes. | `17179869184` |
|
||||
| `default['firezone']['postgresql']['shmall']` | Postgresql shmall in bytes. | `4194304` |
|
||||
| `default['firezone']['postgresql']['work_mem']` | Postgresql working memory size. | `'8MB'` |
|
||||
| `default['firezone']['database']['user']` | Specifies the username Firezone will use to connect to the DB. | `node['firezone']['postgresql']['username']` |
|
||||
| `default['firezone']['database']['password']` | If using an external DB, specifies the password Firezone will use to connect to the DB. | `'change_me'` |
|
||||
| `default['firezone']['database']['name']` | Database that Firezone will use. Will be created if it doesn't exist. | `'firezone'` |
|
||||
| `default['firezone']['database']['host']` | Database host that Firezone will connect to. | `node['firezone']['postgresql']['listen_address']` |
|
||||
| `default['firezone']['database']['port']` | Database port that Firezone will connect to. | `node['firezone']['postgresql']['port']` |
|
||||
| `default['firezone']['database']['pool']` | Database pool size Firezone will use. | `[10, Etc.nprocessors].max` |
|
||||
| `default['firezone']['database']['ssl']` | Whether to connect to the database over SSL. | `false` |
|
||||
| `default['firezone']['database']['ssl_opts']` | Hash of options to send to the `:ssl_opts` option when connecting over SSL. See [Ecto.Adapters.Postgres documentation](https://hexdocs.pm/ecto_sql/Ecto.Adapters.Postgres.html#module-connection-options). | `{}` |
|
||||
| `default['firezone']['database']['parameters']` | Hash of parameters to send to the `:parameters` option when connecting to the database. See [Ecto.Adapters.Postgres documentation](https://hexdocs.pm/ecto_sql/Ecto.Adapters.Postgres.html#module-connection-options). | `{}` |
|
||||
| `default['firezone']['database']['extensions']` | Database extensions to enable. | `{ 'plpgsql' => true, 'pg_trgm' => true }` |
|
||||
| `default['firezone']['phoenix']['enabled']` | Enable or disable the Firezone web application. | `true` |
|
||||
| `default['firezone']['phoenix']['listen_address']` | Firezone web application listen address. This will be the upstream listen address that nginx proxies. | `'127.0.0.1'` |
|
||||
| `default['firezone']['phoenix']['port']` | Firezone web application listen port. This will be the upstream port that nginx proxies. | `13000` |
|
||||
| `default['firezone']['phoenix']['log_directory']` | Firezone web application log directory. | `"#{node['firezone']['log_directory']}/phoenix"` |
|
||||
| `default['firezone']['phoenix']['log_rotation']['file_maxbytes']` | Firezone web application log file size. | `104857600` |
|
||||
| `default['firezone']['phoenix']['log_rotation']['num_to_keep']` | Number of Firezone web application log files to keep. | `10` |
|
||||
| `default['firezone']['phoenix']['crash_detection']['enabled']` | Enable or disable bringing down the Firezone web application when a crash is detected. | `true` |
|
||||
| `default['firezone']['phoenix']['external_trusted_proxies']` | List of trusted reverse proxies formatted as an Array of IPs and/or CIDRs. | `[]` |
|
||||
| `default['firezone']['phoenix']['private_clients']` | List of private network HTTP clients, formatted an Array of IPs and/or CIDRs. | `[]` |
|
||||
| `default['firezone']['wireguard']['enabled']` | Enable or disable bundled WireGuard management. | `true` |
|
||||
| `default['firezone']['wireguard']['log_directory']` | Log directory for bundled WireGuard management. | `"#{node['firezone']['log_directory']}/wireguard"` |
|
||||
| `default['firezone']['wireguard']['log_rotation']['file_maxbytes']` | WireGuard log file max size. | `104857600` |
|
||||
| `default['firezone']['wireguard']['log_rotation']['num_to_keep']` | Number of WireGuard log files to keep. | `10` |
|
||||
| `default['firezone']['wireguard']['interface_name']` | WireGuard interface name. **Changing this parameter may cause a temporary loss in VPN connectivity**. | `'wg-firezone'` |
|
||||
| `default['firezone']['wireguard']['port']` | WireGuard listen port. | `51820` |
|
||||
| `default['firezone']['wireguard']['persistent_keepalive']` | Default PersistentKeepalive setting for generated device configurations. A value of 0 disables. | `0` |
|
||||
| `default['firezone']['wireguard']['ipv4']['enabled']` | Enable or disable IPv4 for WireGuard network. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv4']['masquerade']` | Enable or disable masquerade for packets leaving the IPv4 tunnel. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv4']['network']` | WireGuard network IPv4 address pool. | `'10.3.2.0/24'` |
|
||||
| `default['firezone']['wireguard']['ipv4']['address']` | WireGuard interface IPv4 address. Must be within WireGuard address pool. | `'10.3.2.1'` |
|
||||
| `default['firezone']['wireguard']['ipv6']['enabled']` | Enable or disable IPv6 for WireGuard network. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv6']['masquerade']` | Enable or disable masquerade for packets leaving the IPv6 tunnel. | `true` |
|
||||
| `default['firezone']['wireguard']['ipv6']['network']` | WireGuard network IPv6 address pool. | `'fd00::3:2:0/120'` |
|
||||
| `default['firezone']['wireguard']['ipv6']['address']` | WireGuard interface IPv6 address. Must be within IPv6 address pool. | `'fd00::3:2:1'` |
|
||||
| `default['firezone']['runit']['svlogd_bin']` | Runit svlogd bin location. | `"#{node['firezone']['install_directory']}/embedded/bin/svlogd"` |
|
||||
| `default['firezone']['ssl']['directory']` | SSL directory for storing generated certs. | `'/var/opt/firezone/ssl'` |
|
||||
| `default['firezone']['ssl']['email_address']` | Email address to use for self-signed certs and ACME protocol renewal notices. | `'you@example.com'` |
|
||||
| `default['firezone']['ssl']['acme']['enabled']` | Enable ACME for automatic SSL cert provisioning. | `false` |
|
||||
| `default['firezone']['ssl']['acme']['server']` | ACME server to use for certificate issuance/renewal. Can be any [valid acme.sh server](https://github.com/acmesh-official/acme.sh/wiki/Server) | `letsencrypt` |
|
||||
| `default['firezone']['ssl']['acme']['keylength']` | Specify the key type and length for SSL certificates. See [here](https://github.com/acmesh-official/acme.sh#10-issue-ecc-certificates) | `ec-256` |
|
||||
| `default['firezone']['ssl']['certificate']` | Path to the certificate file for your FQDN. Overrides ACME setting above if specified. If both ACME and this are `nil` a self-signed cert will be generated. | `nil` |
|
||||
| `default['firezone']['ssl']['certificate_key']` | Path to the certificate file. | `nil` |
|
||||
| `default['firezone']['ssl']['ssl_dhparam']` | nginx ssl dh_param. | `nil` |
|
||||
| `default['firezone']['ssl']['country_name']` | Country name for self-signed cert. | `'US'` |
|
||||
| `default['firezone']['ssl']['state_name']` | State name for self-signed cert. | `'CA'` |
|
||||
| `default['firezone']['ssl']['locality_name']` | Locality name for self-signed cert. | `'San Francisco'` |
|
||||
| `default['firezone']['ssl']['company_name']` | Company name self-signed cert. | `'My Company'` |
|
||||
| `default['firezone']['ssl']['organizational_unit_name']` | Organizational unit name for self-signed cert. | `'Operations'` |
|
||||
| `default['firezone']['ssl']['ciphers']` | SSL ciphers for nginx to use. | `'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'` |
|
||||
| `default['firezone']['ssl']['fips_ciphers']` | SSL ciphers for FIPs mode. | `'FIPS@STRENGTH:!aNULL:!eNULL'` |
|
||||
| `default['firezone']['ssl']['protocols']` | TLS protocols to use. | `'TLSv1 TLSv1.1 TLSv1.2'` |
|
||||
| `default['firezone']['ssl']['session_cache']` | SSL session cache. | `'shared:SSL:4m'` |
|
||||
| `default['firezone']['ssl']['session_timeout']` | SSL session timeout. | `'5m'` |
|
||||
| `default['firezone']['robots_allow']` | nginx robots allow. | `'/'` |
|
||||
| `default['firezone']['robots_disallow']` | nginx robots disallow. | `nil` |
|
||||
| `default['firezone']['outbound_email']['from']` | Outbound email from address. | `nil` |
|
||||
| `default['firezone']['outbound_email']['provider']` | Outbound email service provider. | `nil` |
|
||||
| `default['firezone']['outbound_email']['configs']` | Outbound email provider configs. | see `omnibus/cookbooks/firezone/attributes/default.rb` |
|
||||
| `default['firezone']['telemetry']['enabled']` | Enable or disable anonymized product telemetry. | `true` |
|
||||
| `default['firezone']['connectivity_checks']['enabled']` | Enable or disable the Firezone connectivity checks service. | `true` |
|
||||
| `default['firezone']['connectivity_checks']['interval']` | Interval between connectivity checks in seconds. | `3_600` |
|
||||
|
||||
<!-- markdownlint-enable MD033 -->
|
||||
<!-- markdownlint-enable MD034 -->
|
||||
|
||||
@@ -12,7 +12,7 @@ For Docker-based deployments, deployment-related or infrastructure-related
|
||||
config of Firezone is done through environment variables passed to the
|
||||
Firezone image upon launch.
|
||||
|
||||
Read more about configuring Firezone in our [configure guide](/deploy/configure).
|
||||
Read more about configuring Firezone in our [configure guide](/docs/deploy/configure).
|
||||
|
||||
## Environment Variable Listing
|
||||
|
||||
@@ -20,7 +20,7 @@ We recommend setting these in your Docker ENV file (`$HOME/.firezone/.env` by
|
||||
default). Required fields in **bold**.
|
||||
|
||||
| Name | Description | Format | Default |
|
||||
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| **`EXTERNAL_URL`** | The external URL the web UI will be accessible at. Must be a valid FQDN for ACME SSL issuance to function. | String | |
|
||||
| **`ADMIN_EMAIL`** | Primary administrator email. | String | |
|
||||
| **`DEFAULT_ADMIN_PASSWORD`** | Default password that will be used for creating or resetting the primary administrator account. | String | Randomly generated upon install with `docker run firezone/firezone bin/gen-env`. |
|
||||
@@ -61,4 +61,4 @@ default). Required fields in **bold**.
|
||||
| `WIREGUARD_MTU` | MTU to use for the server-side WireGuard MTU interface. | String | `1280` |
|
||||
| `WIREGUARD_PORT` | Port to listen on for WireGuard connections. | Integer | `51820` |
|
||||
| `SECURE_COOKIES` | Enable or disable requiring secure cookies. Required for HTTPS. | Boolean | `true` |
|
||||
| `TELEMETRY_ENABLED` | Enable / disable product telemetry. Read more about [what that means here](/reference/telemetry). | Boolean | `true` |
|
||||
| `TELEMETRY_ENABLED` | Enable / disable product telemetry. Read more about [what that means here](/docs/reference/telemetry). | Boolean | `true` |
|
||||
|
||||
@@ -11,7 +11,7 @@ your installation.
|
||||
<TabItem label="Docker" value="docker" default>
|
||||
|
||||
| Default path | Description |
|
||||
| --- | --- |
|
||||
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `$HOME/.firezone/.env` | Firezone secrets used for encryption, cookies, and sessions. **Losing this file will result in irrecoverable data loss**. |
|
||||
| `$HOME/.firezone/docker-compose.yml` | Docker Compose file used to manage Firezone services. |
|
||||
| `$HOME/.firezone/firezone` | Top-level directory containing Firezone-related persisted data |
|
||||
@@ -22,7 +22,7 @@ your installation.
|
||||
<TabItem label="Omnibus" value="omnibus">
|
||||
|
||||
| Path | Description |
|
||||
| --- | --- |
|
||||
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| `/var/opt/firezone` | Top-level directory containing data and generated configuration for Firezone bundled services. |
|
||||
| `/opt/firezone` | Top-level directory containing built libraries, binaries and runtime files needed by Firezone. |
|
||||
| `/usr/bin/firezone-ctl` | `firezone-ctl` utility for managing your Firezone installation. |
|
||||
@@ -34,4 +34,4 @@ your installation.
|
||||
|
||||
## Backup and restore
|
||||
|
||||
See our [backup guide](/administer/backup).
|
||||
See our [backup guide](/docs/administer/backup).
|
||||
|
||||
@@ -4,7 +4,6 @@ sidebar_position: 2
|
||||
toc_max_heading_level: 4
|
||||
---
|
||||
|
||||
|
||||
This endpoint allows an administrator to manage Users.
|
||||
|
||||
## Auto-Create Users from OpenID or SAML providers
|
||||
@@ -17,11 +16,11 @@ If `auto_create_users` is `false`, then you need to provision users with `passwo
|
||||
otherwise they will have no means to log in.
|
||||
|
||||
## API Documentation
|
||||
|
||||
### List all Users [`GET /v0/users`]
|
||||
|
||||
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X GET "https://{firezone_host}/v0/users" \
|
||||
@@ -76,18 +75,18 @@ Content-Type: application/json; charset=utf-8
|
||||
]
|
||||
}
|
||||
```
|
||||
### Create a User [`POST /v0/users`]
|
||||
|
||||
### Create a User [`POST /v0/users`]
|
||||
|
||||
Create a new User.
|
||||
|
||||
This endpoint is useful in two cases:
|
||||
|
||||
1. When [Local Authentication](/authenticate/local-auth/) is enabled (discouraged in
|
||||
production deployments), it allows an administrator to provision users with their passwords;
|
||||
2. When `auto_create_users` in the associated OpenID or SAML configuration is disabled,
|
||||
it allows an administrator to provision users with their emails beforehand, effectively
|
||||
whitelisting specific users for authentication.
|
||||
1. When [Local Authentication](/docs/authenticate/local-auth/) is enabled (discouraged in
|
||||
production deployments), it allows an administrator to provision users with their passwords;
|
||||
2. When `auto_create_users` in the associated OpenID or SAML configuration is disabled,
|
||||
it allows an administrator to provision users with their emails beforehand, effectively
|
||||
whitelisting specific users for authentication.
|
||||
|
||||
If `auto_create_users` is `true` in the associated OpenID or SAML configuration, there is no need
|
||||
to provision users; they will be created automatically when they log in for the first time using
|
||||
@@ -95,14 +94,15 @@ the associated OpenID or SAML provider.
|
||||
|
||||
#### User Attributes
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `role` | `admin` or `unprivileged` (default) | No | User role. |
|
||||
| `email` | `string` | Yes | Email which will be used to identify the user. |
|
||||
| `password` | `string` | No | A password that can be used for login-password authentication. |
|
||||
| `password_confirmation` | `string` | -> | Is required when the `password` is set. |
|
||||
| Attribute | Type | Required | Description |
|
||||
| ----------------------- | ----------------------------------- | -------- | -------------------------------------------------------------- |
|
||||
| `role` | `admin` or `unprivileged` (default) | No | User role. |
|
||||
| `email` | `string` | Yes | Email which will be used to identify the user. |
|
||||
| `password` | `string` | No | A password that can be used for login-password authentication. |
|
||||
| `password_confirmation` | `string` | -> | Is required when the `password` is set. |
|
||||
|
||||
#### Example
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X POST "https://{firezone_host}/v0/users" \
|
||||
@@ -136,7 +136,9 @@ Location: /v0/users/86616e3e-13f0-4177-bc8e-1a0e588f0be8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Provision an unprivileged OpenID User
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X POST "https://{firezone_host}/v0/users" \
|
||||
@@ -168,7 +170,9 @@ Location: /v0/users/6e7962a7-c183-4afb-8569-9001bdfd0d87
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Provision an admin OpenID User
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X POST "https://{firezone_host}/v0/users" \
|
||||
@@ -200,7 +204,9 @@ Location: /v0/users/dedc4dcc-0f65-4110-ad7f-9c354e36e5e5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Error due to invalid parameters
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X POST "https://{firezone_host}/v0/users" \
|
||||
@@ -227,14 +233,15 @@ Content-Type: application/json; charset=utf-8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GET /v0/users/{id}
|
||||
|
||||
|
||||
|
||||
#### An email can be used instead of ID.
|
||||
|
||||
**URI Parameters:**
|
||||
|
||||
- `id`: `test-1481@test`
|
||||
- `id`: `test-1481@test`
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X GET "https://{firezone_host}/v0/users/{id}" \
|
||||
@@ -257,15 +264,17 @@ Content-Type: application/json; charset=utf-8
|
||||
}
|
||||
}
|
||||
```
|
||||
### Update a User [`PATCH /v0/users/{id}`]
|
||||
|
||||
### Update a User [`PATCH /v0/users/{id}`]
|
||||
|
||||
For details please see [Create a User](#create-a-user-post-v0users) section.
|
||||
|
||||
#### Update by email
|
||||
|
||||
**URI Parameters:**
|
||||
|
||||
- `id`: `test-3618@test`
|
||||
- `id`: `test-3618@test`
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X PUT "https://{firezone_host}/v0/users/{id}" \
|
||||
@@ -293,10 +302,13 @@ Content-Type: application/json; charset=utf-8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Update by ID
|
||||
|
||||
**URI Parameters:**
|
||||
|
||||
- `id`: `8dd4eff5-3d2f-4868-94cd-73abb6f130dc`
|
||||
- `id`: `8dd4eff5-3d2f-4868-94cd-73abb6f130dc`
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X PUT "https://{firezone_host}/v0/users/{id}" \
|
||||
@@ -324,14 +336,15 @@ Content-Type: application/json; charset=utf-8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /v0/users/{id}
|
||||
|
||||
|
||||
|
||||
#### Example
|
||||
|
||||
**URI Parameters:**
|
||||
|
||||
- `id`: `fc0b513f-bd4b-4015-ac71-29b59c678a20`
|
||||
- `id`: `fc0b513f-bd4b-4015-ac71-29b59c678a20`
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X DELETE "https://{firezone_host}/v0/users/{id}" \
|
||||
@@ -340,10 +353,13 @@ $ curl -i \
|
||||
|
||||
HTTP/1.1 204
|
||||
```
|
||||
|
||||
#### An email can be used instead of ID.
|
||||
|
||||
**URI Parameters:**
|
||||
|
||||
- `id`: `test-3816@test`
|
||||
- `id`: `test-3816@test`
|
||||
|
||||
```bash
|
||||
$ curl -i \
|
||||
-X DELETE "https://{firezone_host}/v0/users/{id}" \
|
||||
|
||||
@@ -8,7 +8,7 @@ self-hosted instance and how to disable it.
|
||||
|
||||
## Why Firezone collects telemetry
|
||||
|
||||
We *rely* on telemetry to prioritize our roadmap and optimize the engineering
|
||||
We _rely_ on telemetry to prioritize our roadmap and optimize the engineering
|
||||
resources we have to make Firezone better for everyone.
|
||||
|
||||
The telemetry we collect aims to answer the following questions:
|
||||
@@ -17,7 +17,7 @@ The telemetry we collect aims to answer the following questions:
|
||||
- What features are most valuable, and which ones don’t see any use?
|
||||
- What functionality needs the most improvement?
|
||||
- When something breaks, why did it break, and how can we prevent it from happening
|
||||
in the future?
|
||||
in the future?
|
||||
|
||||
## How we collect telemetry
|
||||
|
||||
@@ -31,7 +31,7 @@ In each of these three contexts, we capture the minimum amount of data necessary
|
||||
to answer the questions in the section above.
|
||||
|
||||
Admin emails are collected **only if** you explicitly opt-in to product updates.
|
||||
Otherwise, personally-identifiable information is ***never*** collected.
|
||||
Otherwise, personally-identifiable information is **_never_** collected.
|
||||
|
||||
We store telemetry in [PostHog](https://posthog.com) only accessible by the Firezone team.
|
||||
Here is an example of a telemetry event that is sent from your instance of
|
||||
@@ -39,41 +39,39 @@ Firezone to our telemetry server:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "0182272d-0b88-0000-d419-7b9a413713f1",
|
||||
"timestamp": "2022-07-22T18:30:39.748000+00:00",
|
||||
"event": "fz_http_started",
|
||||
"distinct_id": "1ec2e794-1c3e-43fc-a78f-1db6d1a37f54",
|
||||
"properties": {
|
||||
"$geoip_city_name": "Ashburn",
|
||||
"$geoip_continent_code": "NA",
|
||||
"$geoip_continent_name": "North America",
|
||||
"$geoip_country_code": "US",
|
||||
"$geoip_country_name": "United States",
|
||||
"$geoip_latitude": 39.0469,
|
||||
"$geoip_longitude": -77.4903,
|
||||
"$geoip_postal_code": "20149",
|
||||
"$geoip_subdivision_1_code": "VA",
|
||||
"$geoip_subdivision_1_name": "Virginia",
|
||||
"$geoip_time_zone": "America/New_York",
|
||||
"$ip": "52.200.241.107",
|
||||
"$plugins_deferred": [],
|
||||
"$plugins_failed": [],
|
||||
"$plugins_succeeded": [
|
||||
"GeoIP (3)"
|
||||
],
|
||||
"distinct_id": "1zc2e794-1c3e-43fc-a78f-1db6d1a37f54",
|
||||
"fqdn": "awsdemo.firezone.dev",
|
||||
"kernel_version": "linux 5.13.0",
|
||||
"version": "0.4.6"
|
||||
},
|
||||
"elements_chain": ""
|
||||
"id": "0182272d-0b88-0000-d419-7b9a413713f1",
|
||||
"timestamp": "2022-07-22T18:30:39.748000+00:00",
|
||||
"event": "fz_http_started",
|
||||
"distinct_id": "1ec2e794-1c3e-43fc-a78f-1db6d1a37f54",
|
||||
"properties": {
|
||||
"$geoip_city_name": "Ashburn",
|
||||
"$geoip_continent_code": "NA",
|
||||
"$geoip_continent_name": "North America",
|
||||
"$geoip_country_code": "US",
|
||||
"$geoip_country_name": "United States",
|
||||
"$geoip_latitude": 39.0469,
|
||||
"$geoip_longitude": -77.4903,
|
||||
"$geoip_postal_code": "20149",
|
||||
"$geoip_subdivision_1_code": "VA",
|
||||
"$geoip_subdivision_1_name": "Virginia",
|
||||
"$geoip_time_zone": "America/New_York",
|
||||
"$ip": "52.200.241.107",
|
||||
"$plugins_deferred": [],
|
||||
"$plugins_failed": [],
|
||||
"$plugins_succeeded": ["GeoIP (3)"],
|
||||
"distinct_id": "1zc2e794-1c3e-43fc-a78f-1db6d1a37f54",
|
||||
"fqdn": "awsdemo.firezone.dev",
|
||||
"kernel_version": "linux 5.13.0",
|
||||
"version": "0.4.6"
|
||||
},
|
||||
"elements_chain": ""
|
||||
}
|
||||
```
|
||||
|
||||
## How to disable telemetry
|
||||
|
||||
:::note
|
||||
We *rely* on product analytics to make Firezone better for everyone.
|
||||
We _rely_ on product analytics to make Firezone better for everyone.
|
||||
Leaving telemetry enabled is the **single most valuable contribution** you can
|
||||
make to Firezone’s development. That said, we understand some users have higher
|
||||
privacy or security requirements and would prefer to disable telemetry altogether.
|
||||
@@ -103,6 +101,6 @@ default['firezone']['telemetry']['enabled'] = false
|
||||
|
||||
:::note
|
||||
If you’re looking for support running Firezone in air-gapped or other
|
||||
restrictive environments, [contact us](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev) about our
|
||||
[Enterprise](https://www.firezone.dev/pricing?utm_source=docs.firezone.dev) functionality.
|
||||
restrictive environments, [contact us](/sales) about our
|
||||
[Enterprise](/pricing) functionality.
|
||||
:::
|
||||
|
||||
@@ -11,7 +11,7 @@ be shown again once it is no longer displayed.
|
||||
|
||||
**We recommend asking end users to generate their own device configs so the
|
||||
WireGuard private key is not exposed.** Users can follow instructions
|
||||
on the [Client Instructions](/user-guides/client-instructions/) page to
|
||||
on the [Client Instructions](/docs/user-guides/client-instructions/) page to
|
||||
generate their own WireGuard configs.
|
||||
|
||||
## Admin device config generation
|
||||
@@ -24,9 +24,9 @@ clicking the "Add Device" button on the user profile page found in `/users`.
|
||||
Once the device profile is created, the admin can download and send the
|
||||
WireGuard configuration file to the user over a secure channel.
|
||||
|
||||
See [Add Users](/user-guides/add-users/) for more information on how to add a
|
||||
See [Add Users](/docs/user-guides/add-users/) for more information on how to add a
|
||||
user.
|
||||
|
||||
## Related guides
|
||||
|
||||
* [Client Instructions](/user-guides/client-instructions/)
|
||||
- [Client Instructions](/docs/user-guides/client-instructions/)
|
||||
|
||||
@@ -7,18 +7,18 @@ sidebar_position: 1
|
||||
|
||||
Once you have successfully installed Firezone you'll need to add users to grant
|
||||
them access to your network. This can be done through the Web UI or the
|
||||
[REST API](/reference/rest-api/users).
|
||||
[REST API](/docs/reference/rest-api/users).
|
||||
|
||||
## Web UI
|
||||
|
||||
Add a user by clicking the "Add User" button under `/users`. You will be asked
|
||||
to specify an email and a password for the user. Firezone can also integrate and
|
||||
sync with an identity provider to automatically grant access to users in your
|
||||
organization. See [Authenticate](/authenticate/) for more
|
||||
organization. See [Authenticate](/docs/authenticate/) for more
|
||||
information.
|
||||
|
||||

|
||||
|
||||
## Related guides
|
||||
|
||||
* [Authenticate](/authenticate/)
|
||||
- [Authenticate](/docs/authenticate/)
|
||||
|
||||
@@ -10,10 +10,10 @@ Firezone can be used as NAT gateway in order to provide a single,
|
||||
static egress IP for all of your team's traffic to flow out of.
|
||||
This is commonly used in the following scenarios:
|
||||
|
||||
* Consulting engagements: Ask your client to whitelist a single static
|
||||
- Consulting engagements: Ask your client to whitelist a single static
|
||||
IP address associated with your engagement instead of your employees'
|
||||
individual device IPs.
|
||||
* Masking your device IP or proxying your source IP for privacy or
|
||||
- Masking your device IP or proxying your source IP for privacy or
|
||||
security reasons.
|
||||
|
||||
This guide will walk through a simple example restricting access for a
|
||||
@@ -38,14 +38,14 @@ In this example the protected resource and Firezone are in separate VPC regions.
|
||||
|
||||
In this example, a Firezone instance has been set up on a `tc2.micro`
|
||||
EC2 instance. See the
|
||||
[Deployment Guide](/deploy/)
|
||||
[Deployment Guide](/docs/deploy/)
|
||||
for details on deploying Firezone. Specific to AWS, ensure:
|
||||
|
||||
1. The security group of the Firezone EC2 instance allows outbound traffic to the
|
||||
IP of the protected resource.
|
||||
IP of the protected resource.
|
||||
1. An Elastic IP is associated with the Firezone instance. This will be the
|
||||
source IP address of traffic routed through the Firezone instance to external destinations.
|
||||
In this case, the IP is `52.202.88.54`.
|
||||
source IP address of traffic routed through the Firezone instance to external destinations.
|
||||
In this case, the IP is `52.202.88.54`.
|
||||
|
||||

|
||||
|
||||
@@ -66,6 +66,6 @@ party to allow traffic from the static IP set in Step 1 (in this case `52.202.88
|
||||
By default, all traffic from team members will be routed through Firezone
|
||||
and will originate from the static IP set in Step 1 (in this case `52.202.88.54`).
|
||||
However, if
|
||||
[split tunneling](/user-guides/use-cases/split-tunnel/)
|
||||
[split tunneling](/docs/user-guides/use-cases/split-tunnel/)
|
||||
has been enabled, configuration may be required to ensure the destination IP of
|
||||
the protected resource is included in the `Allowed IPs`.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
title: Reverse Tunnel
|
||||
sidebar_position: 2
|
||||
description:
|
||||
Configure Firezone as a relay to connect two or more devices.
|
||||
description: Configure Firezone as a relay to connect two or more devices.
|
||||
---
|
||||
|
||||
This guide will walk through using Firezone as a relay to connect
|
||||
@@ -19,7 +18,7 @@ between Device A and Device B.
|
||||
Start by creating Device A and Device B by navigating to `/users/[user_id]/new_device`.
|
||||
In the settings for each device, ensure the following parameters are set to the
|
||||
values listed below. You can set device settings when creating the device config
|
||||
(see [Add Devices](/user-guides/add-devices/)).
|
||||
(see [Add Devices](/docs/user-guides/add-devices/)).
|
||||
If you need to update settings on an existing device, you can do so by generating
|
||||
a new device config.
|
||||
|
||||
@@ -50,7 +49,7 @@ administrator or engineer accessing multiple resources
|
||||
|
||||
In the settings for each device, ensure the following parameters are set to the
|
||||
values listed below. You can set device settings when creating the device config
|
||||
(see [Add Devices](/user-guides/add-devices/)).
|
||||
(see [Add Devices](/docs/user-guides/add-devices/)).
|
||||
If you need to update settings on an existing device, you can do so by generating
|
||||
a new device config.
|
||||
|
||||
@@ -81,4 +80,4 @@ Device D
|
||||
|
||||
## Related guides
|
||||
|
||||
- [NAT Gateway](/user-guides/use-cases/nat-gateway/)
|
||||
- [NAT Gateway](/docs/user-guides/use-cases/nat-gateway/)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
title: Split Tunnel VPN
|
||||
sidebar_position: 1
|
||||
description:
|
||||
Configure Firezone for split tunneling. Route some network traffic
|
||||
description: Configure Firezone for split tunneling. Route some network traffic
|
||||
from end users through the encrypted WireGuard® tunnel.
|
||||
---
|
||||
|
||||
@@ -27,10 +26,10 @@ Some examples of values in this field are:
|
||||
|
||||
- `0.0.0.0/0, ::/0` - all network traffic will be routed to the VPN server.
|
||||
- `192.0.2.3/32` - only traffic to a single IP address
|
||||
will be routed to the VPN server.
|
||||
will be routed to the VPN server.
|
||||
- `3.5.140.0/22` - only traffic to IPs in the `3.5.140.1 - 3.5.143.254` range
|
||||
will be routed to the VPN server.
|
||||
In this example, the CIDR range for the `ap-northeast-2` AWS region was used.
|
||||
will be routed to the VPN server.
|
||||
In this example, the CIDR range for the `ap-northeast-2` AWS region was used.
|
||||
|
||||
:::note
|
||||
When deciding where to route a packet, Firezone chooses the egress
|
||||
@@ -59,4 +58,4 @@ future device configurations generated by Firezone.
|
||||
Users need to regenerate device configurations to update existing devices
|
||||
for the updated configuration changes to `AllowedIPs`, `DNS`, `PersistentKeepalive`, `MTU`, and `Endpoint`.
|
||||
|
||||
See [add device](/user-guides/add-devices/) for instructions.
|
||||
See [add device](/docs/user-guides/add-devices/) for instructions.
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
// @ts-check
|
||||
// Note: type annotations allow type checking and IDEs autocompletion
|
||||
|
||||
const lightCodeTheme = require('prism-react-renderer/themes/github');
|
||||
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
|
||||
const lightCodeTheme = require("prism-react-renderer/themes/github");
|
||||
const darkCodeTheme = require("prism-react-renderer/themes/dracula");
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: 'Firezone',
|
||||
tagline: 'Open-source VPN server and Linux firewall built on WireGuard®',
|
||||
url: 'https://docs.firezone.dev',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
title: "firezone",
|
||||
tagline: "Open-source secure remote access built on WireGuard®",
|
||||
url: "https://www.firezone.dev",
|
||||
baseUrl: "/",
|
||||
onBrokenLinks: "throw",
|
||||
onBrokenMarkdownLinks: "warn",
|
||||
trailingSlash: true,
|
||||
favicon: 'img/favicon.ico',
|
||||
favicon: "img/favicon.ico",
|
||||
|
||||
// GitHub pages deployment config.
|
||||
// If you aren't using GitHub pages, you don't need these.
|
||||
organizationName: 'firezone', // Usually your GitHub org/user name.
|
||||
projectName: 'firezone', // Usually your repo name.
|
||||
organizationName: "firezone", // Usually your GitHub org/user name.
|
||||
projectName: "firezone", // Usually your repo name.
|
||||
|
||||
// Even if you don't use internalization, you can use this field to set useful
|
||||
// metadata like html lang. For example, if your site is Chinese, you may want
|
||||
// to replace 'en' with 'zh-Hans'.
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
defaultLocale: "en",
|
||||
locales: ["en"],
|
||||
},
|
||||
|
||||
// An array of scripts to load. The values can be either strings or plain
|
||||
@@ -38,9 +38,14 @@ const config = {
|
||||
// add async: true/defer: true to the objects.
|
||||
scripts: [
|
||||
{
|
||||
src: '/js/posthog.js',
|
||||
async: true
|
||||
}
|
||||
src: "/js/posthog.js",
|
||||
async: true,
|
||||
},
|
||||
{
|
||||
src: "//js.hs-scripts.com/23723443.js",
|
||||
async: true,
|
||||
defer: true,
|
||||
},
|
||||
],
|
||||
|
||||
plugins: [],
|
||||
@@ -49,17 +54,26 @@ const config = {
|
||||
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
"classic",
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
({
|
||||
pages: {
|
||||
routeBasePath: "/",
|
||||
},
|
||||
docs: {
|
||||
routeBasePath: '/',
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
editUrl: 'https://github.com/firezone/firezone/tree/master/www',
|
||||
docLayoutComponent: "@theme/DocPage"
|
||||
routeBasePath: "/docs",
|
||||
sidebarPath: require.resolve("./sidebars.js"),
|
||||
editUrl: "https://github.com/firezone/firezone/tree/master/www/docs",
|
||||
docLayoutComponent: "@theme/DocPage",
|
||||
},
|
||||
blog: {
|
||||
routeBasePath: "/blog",
|
||||
blogSidebarTitle: "All posts",
|
||||
blogSidebarCount: "ALL",
|
||||
showReadingTime: true,
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve('./src/css/custom.css'),
|
||||
customCss: require.resolve("./src/css/custom.css"),
|
||||
},
|
||||
}),
|
||||
],
|
||||
@@ -69,70 +83,75 @@ const config = {
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
navbar: {
|
||||
title: 'Documentation',
|
||||
title: "firezone",
|
||||
logo: {
|
||||
alt: 'Firezone Logo',
|
||||
src: 'img/logo.svg',
|
||||
alt: "Firezone Logo",
|
||||
src: "img/logo.svg",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
href: 'https://discourse.firez.one/?utm_source=docs.firezone.dev',
|
||||
label: 'Ask a Question',
|
||||
position: 'right',
|
||||
'aria-label': 'GitHub repository',
|
||||
href: "/docs",
|
||||
label: "Documentation",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
href: 'https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev',
|
||||
label: 'Contact sales',
|
||||
position: 'right',
|
||||
'aria-label': 'Contact sales',
|
||||
href: "/blog",
|
||||
label: "Blog",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/firezone/firezone',
|
||||
className: 'header-github-link',
|
||||
position: 'right',
|
||||
'aria-label': 'GitHub repository',
|
||||
href: "/pricing",
|
||||
label: "Pricing",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
href: "/sales",
|
||||
label: "Contact sales",
|
||||
position: "right",
|
||||
"aria-label": "Contact sales",
|
||||
},
|
||||
{
|
||||
html: '<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/firezone/firezone?label=Stars&style=social" style="margin-top: 6px;" height="24">',
|
||||
href: "https://github.com/firezone/firezone",
|
||||
position: "right",
|
||||
"aria-label": "GitHub repository",
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'light',
|
||||
style: "light",
|
||||
links: [
|
||||
{
|
||||
title: 'Company',
|
||||
title: "Company",
|
||||
items: [
|
||||
{
|
||||
label: 'Homepage',
|
||||
href: 'https://www.firezone.dev/?utm_source=docs.firezone.dev',
|
||||
label: "Home",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
label: 'Pricing',
|
||||
href: 'https://www.firezone.dev/pricing?utm_source=docs.firezone.dev',
|
||||
},
|
||||
{
|
||||
label: 'About',
|
||||
href: 'https://www.firezone.dev/about?utm_source=docs.firezone.dev',
|
||||
label: "Pricing",
|
||||
href: "/pricing",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
title: "Community",
|
||||
items: [
|
||||
{
|
||||
label: 'Support Forums',
|
||||
href: 'https://discourse.firez.one/?utm_source=docs.firezone.dev',
|
||||
label: "Support Forums",
|
||||
href: "https://discourse.firez.one/?utm_source=docs.firezone.dev",
|
||||
},
|
||||
{
|
||||
label: 'Slack',
|
||||
href: 'https://www.firezone.dev/slack?utm_source=docs.firezone.dev',
|
||||
label: "Slack",
|
||||
href: "https://join.slack.com/t/firezone-users/shared_invite/zt-19jd956j4-rWcCqiKMh~ikPGsUFbvZiA",
|
||||
},
|
||||
{
|
||||
label: 'Github',
|
||||
href: 'https://github.com/firezone/firezone?utm_source=docs.firezone.dev',
|
||||
label: "Github",
|
||||
href: "https://github.com/firezone/firezone?utm_source=docs.firezone.dev",
|
||||
},
|
||||
{
|
||||
label: 'Twitter',
|
||||
href: 'https://twitter.com/firezonehq?utm_source=docs.firezone.dev',
|
||||
label: "Twitter",
|
||||
href: "https://twitter.com/firezonehq?utm_source=docs.firezone.dev",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -142,24 +161,20 @@ const config = {
|
||||
prism: {
|
||||
theme: lightCodeTheme,
|
||||
darkTheme: darkCodeTheme,
|
||||
additionalLanguages: ['ruby', 'elixir']
|
||||
additionalLanguages: ["ruby", "elixir"],
|
||||
},
|
||||
algolia: {
|
||||
// The application ID provided by Algolia
|
||||
appId: 'XXPZ9QVGFB',
|
||||
appId: "XXPZ9QVGFB",
|
||||
|
||||
start_urls: [
|
||||
'https://docs.firezone.dev/'
|
||||
],
|
||||
start_urls: ["https://www.firezone.dev/"],
|
||||
|
||||
sitemap_urls: [
|
||||
'https://docs.firezone.dev/sitemap.xml'
|
||||
],
|
||||
sitemap_urls: ["https://www.firezone.dev/sitemap.xml"],
|
||||
|
||||
// Public API key: it is safe to commit it
|
||||
apiKey: '66664e8765e1645ea0b500acebb0b0c2',
|
||||
apiKey: "66664e8765e1645ea0b500acebb0b0c2",
|
||||
|
||||
indexName: 'firezone',
|
||||
indexName: "firezone",
|
||||
|
||||
// Optional: see doc section below
|
||||
// Requires more configuration and setup to work, so disabling. See
|
||||
@@ -167,11 +182,17 @@ const config = {
|
||||
contextualSearch: true,
|
||||
|
||||
// Optional: path for search page that enabled by default (`false` to disable it)
|
||||
searchPagePath: 'search',
|
||||
searchPagePath: "search",
|
||||
|
||||
//... other Algolia params
|
||||
},
|
||||
metadata: [{name: 'keywords', content: 'wireguard, vpn, firewall, remote access, network, documentation'}],
|
||||
metadata: [
|
||||
{
|
||||
name: "keywords",
|
||||
content:
|
||||
"wireguard, vpn, firewall, remote access, network, documentation",
|
||||
},
|
||||
],
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
"write-heading-ids": "docusaurus write-heading-ids",
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^2.1.0",
|
||||
@@ -26,7 +27,17 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "2.1.0",
|
||||
"css-minimizer-webpack-plugin": "4.1.0"
|
||||
"@tsconfig/docusaurus": "^1.0.5",
|
||||
"asciinema-player": "^3.0.1",
|
||||
"css-minimizer-webpack-plugin": "4.1.0",
|
||||
"remark-cli": "^11.0.0",
|
||||
"remark-lint": "^9.1.1",
|
||||
"remark-lint-list-item-indent": "^3.1.1",
|
||||
"remark-mdx": "^2.1.5",
|
||||
"remark-preset-lint-consistent": "^5.1.1",
|
||||
"remark-preset-lint-markdown-style-guide": "^5.1.2",
|
||||
"remark-preset-lint-recommended": "^6.1.2",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
44
www/src/components/AsciinemaPlayer/index.tsx
Normal file
44
www/src/components/AsciinemaPlayer/index.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
|
||||
type AsciinemaPlayerProps = {
|
||||
src: string;
|
||||
// START asciinemaOptions
|
||||
cols: string;
|
||||
rows: string;
|
||||
autoPlay: boolean
|
||||
preload: boolean;
|
||||
loop: boolean | number;
|
||||
startAt: number | string;
|
||||
speed: number;
|
||||
idleTimeLimit: number;
|
||||
theme: string;
|
||||
poster: string;
|
||||
fit: string;
|
||||
fontSize: string;
|
||||
// END asciinemaOptions
|
||||
};
|
||||
|
||||
const AsciinemaPlayer: React.FC<AsciinemaPlayerProps> = ({
|
||||
src,
|
||||
...asciinemaOptions
|
||||
}) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
return (
|
||||
<BrowserOnly fallback={<div>Loading...</div>}>
|
||||
{() => {
|
||||
const AsciinemaPlayerLibrary = require('asciinema-player');
|
||||
|
||||
useEffect(() => {
|
||||
const currentRef = ref.current;
|
||||
AsciinemaPlayerLibrary.create(src, currentRef, asciinemaOptions);
|
||||
}, [src]);
|
||||
|
||||
return <div ref={ref} />
|
||||
}}
|
||||
</BrowserOnly>
|
||||
);
|
||||
};
|
||||
|
||||
export default AsciinemaPlayer;
|
||||
70
www/src/components/HomepageFeatures/index.tsx
Normal file
70
www/src/components/HomepageFeatures/index.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
type FeatureItem = {
|
||||
title: string;
|
||||
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
|
||||
description: JSX.Element;
|
||||
};
|
||||
|
||||
const FeatureList: FeatureItem[] = [
|
||||
{
|
||||
title: 'Easy to Use',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Docusaurus was designed from the ground up to be easily installed and
|
||||
used to get your website up and running quickly.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Focus on What Matters',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Docusaurus lets you focus on your docs, and we'll do the chores. Go
|
||||
ahead and move your docs into the <code>docs</code> directory.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Powered by React',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Extend or customize your website layout by reusing React. Docusaurus can
|
||||
be extended while reusing the same header and footer.
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
function Feature({title, Svg, description}: FeatureItem) {
|
||||
return (
|
||||
<div className={clsx('col col--4')}>
|
||||
<div className="text--center">
|
||||
<Svg className={styles.featureSvg} role="img" />
|
||||
</div>
|
||||
<div className="text--center padding-horiz--md">
|
||||
<h3>{title}</h3>
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HomepageFeatures(): JSX.Element {
|
||||
return (
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<Feature key={idx} {...props} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
11
www/src/components/HomepageFeatures/styles.module.css
Normal file
11
www/src/components/HomepageFeatures/styles.module.css
Normal file
@@ -0,0 +1,11 @@
|
||||
.features {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.featureSvg {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
34
www/src/components/HubspotForm/index.tsx
Normal file
34
www/src/components/HubspotForm/index.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
|
||||
class HubspotForm extends React.Component<{
|
||||
portalId: string;
|
||||
formId: string;
|
||||
region: string;
|
||||
}> {
|
||||
componentDidMount() {
|
||||
const script = document.createElement("script");
|
||||
script.src = "https://js.hsforms.net/forms/v2.js";
|
||||
document.body.appendChild(script);
|
||||
|
||||
script.addEventListener("load", () => {
|
||||
// @ts-ignore
|
||||
if (window.hbspt) {
|
||||
// @ts-ignore
|
||||
window.hbspt.forms.create({
|
||||
target: "#hubspot-form",
|
||||
...this.props,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div id="hubspot-form" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HubspotForm;
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Open+Sans:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap');
|
||||
@import "asciinema-player/dist/bundle/asciinema-player.css";
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
|
||||
384
www/src/pages/index.mdx
Normal file
384
www/src/pages/index.mdx
Normal file
@@ -0,0 +1,384 @@
|
||||
---
|
||||
title: Firezone • Open Source Remote Access
|
||||
description: Deploy in minutes to secure remote access to your private resources.
|
||||
---
|
||||
|
||||
<div className="hero">
|
||||
<div className="container">
|
||||
<h1 className="hero__title">Fast, effortless secure access</h1>
|
||||
<p>
|
||||
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>
|
||||
<center>
|
||||
<a className="button button--primary" href="/docs/deploy">
|
||||
Deploy now
|
||||
</a>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="container">
|
||||
<img
|
||||
alt="Overview gif"
|
||||
src="https://user-images.githubusercontent.com/167144/218759566-acaffd2e-ef37-4b42-a014-bfaa8d33e655.gif"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<hr className="margin-vert--xl" />
|
||||
|
||||
<center>
|
||||
<h2 className="margin-bottom--lg">Trusted by organizations like</h2>
|
||||
</center>
|
||||
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="bunq logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763171-3b768826-eddf-499c-9b84-5ad365e8da6e.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="tribe logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763181-61c8b4a7-4367-41a6-a790-0fa2b2a34461.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="poughkeepsie logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763199-69def673-f37d-4e6b-aee9-13eac24ad93b.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="rebank logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763213-265a562c-1ed0-4206-8a9f-6726aaaaeed4.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="square1 logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763233-ac4fd4f2-c58b-4136-a3b1-ceeb09a4f954.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="db11 logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763247-e75a2410-baa0-45f8-bd5f-aa33d5fd0898.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-vert--xl" />
|
||||
|
||||
<div className="hero">
|
||||
<div className="container">
|
||||
<h1 className="hero__title">An alternative to old VPNs</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Feature 1 -->
|
||||
|
||||
<div className="container">
|
||||
<center>
|
||||
<h2 className="margin-bottom--lg">
|
||||
Streamline workflows. Reduce total cost of ownership.
|
||||
</h2>
|
||||
</center>
|
||||
</div>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<p>
|
||||
Legacy VPNs are cumbersome to manage and take weeks to configure
|
||||
correctly. Firezone takes minutes to deploy and the Web GUI makes
|
||||
managing secure access effortless for admins.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Integrate any identity provider to enforce 2FA / MFA</li>
|
||||
<li>Define user-scoped access rules</li>
|
||||
<li>Manage users with a snappy admin dashboard</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<img
|
||||
alt="Feature 1"
|
||||
src="https://user-images.githubusercontent.com/167144/218778243-37f22d1e-0bdf-4f3d-8859-4b81dd91878a.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-vert--xl" />
|
||||
|
||||
<!-- Feature 2 -->
|
||||
|
||||
<div className="container">
|
||||
<center>
|
||||
<h2 className="margin-bottom--lg">
|
||||
High throughput and low latency. Up to 4-6x faster than OpenVPN.
|
||||
</h2>
|
||||
</center>
|
||||
</div>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<img
|
||||
alt="Feature 2"
|
||||
src="https://user-images.githubusercontent.com/167144/218778241-c2baa6d1-499a-4da3-a9d3-7e0d4590f75f.png"
|
||||
/>
|
||||
<p>
|
||||
<a href="https://core.ac.uk/download/pdf/322886318.pdf">
|
||||
Performance comparison of VPN solutions (Osswald et al.)
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<p>
|
||||
Increase productivity and decrease connection issues for your remote
|
||||
team. Firezone uses kernel WireGuard® to be efficient, reliable, and
|
||||
performant in any environment.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.wireguard.com/protocol/">
|
||||
State-of-the-art cryptography
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.wireguard.com/formal-verification/">
|
||||
Auditable and formally verified
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.wireguard.com/performance/">Multi-threaded</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-vert--xl" />
|
||||
|
||||
<!-- Feature 3 -->
|
||||
|
||||
<div className="container">
|
||||
<center>
|
||||
<h2 className="margin-bottom--lg">
|
||||
Firezone runs entirely on your infrastructure. No vendor lock-in.
|
||||
</h2>
|
||||
</center>
|
||||
</div>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
Deploy Firezone on any platform that supports Docker. There's no need to
|
||||
risk breaches by sending data to third parties.
|
||||
<ul>
|
||||
<li>VPC, data center, or on-prem</li>
|
||||
<li>Auto-renewing SSL certs from Let's Encrypt via ACME</li>
|
||||
<li>Flexible and configurable</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<img
|
||||
alt="Feature 3"
|
||||
src="https://user-images.githubusercontent.com/167144/218778234-b8150dcb-5af1-410a-8c16-95c660171d81.png"
|
||||
/>
|
||||
<a href="/docs/deploy">Explore the deployment documentation ></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-vert--xl" />
|
||||
|
||||
<div className="container">
|
||||
<center>
|
||||
<h2 className="margin-bottom--lg">
|
||||
Integrate your identity provider for SSO to enforce 2FA / MFA.
|
||||
</h2>
|
||||
</center>
|
||||
<p>
|
||||
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="container">
|
||||
<div className="row">
|
||||
<div className="col col--2">
|
||||
<a href="/docs/authenticate/oidc/keycloak/">
|
||||
<img
|
||||
width="109px"
|
||||
height="41px"
|
||||
alt="keycloak logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218770941-2d8cdf09-d1f4-48bb-9049-b8dc486d909a.png"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<a href="/docs/authenticate/oidc/google/">
|
||||
<img
|
||||
width="109px"
|
||||
height="41px"
|
||||
src="google logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218770954-e41318d4-a8b1-40e5-ab4a-3343d63013a0.png"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<a href="/docs/authenticate/oidc/okta/">
|
||||
<img
|
||||
width="109px"
|
||||
height="41px"
|
||||
alt="okta logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218770967-9615c64a-c948-448b-9019-0226c1e3e086.png"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<a href="/docs/authenticate/oidc/onelogin/">
|
||||
<img
|
||||
width="109px"
|
||||
height="41px"
|
||||
alt="onelogin logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218770990-6959fb55-ebf3-417e-a75b-1981cf86bab0.png"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<a href="/docs/authenticate/oidc/azuread/">
|
||||
<img
|
||||
width="109px"
|
||||
height="41px"
|
||||
alt="azure logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218771000-ff5616d7-f391-4c75-9806-09e5bf1a6a91.png"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<a href="/docs/authenticate/saml/jumpcloud/">
|
||||
<img
|
||||
width="109px"
|
||||
height="41px"
|
||||
alt="jumpcloud logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218771019-fb525e97-ec0c-465e-8160-a547a54feab2.png"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-vert--xl" />
|
||||
|
||||
<div className="container">
|
||||
<center>
|
||||
<h2 className="margin-bottom--lg">Who can benefit from Firezone?</h2>
|
||||
</center>
|
||||
<p>
|
||||
Easy to deploy and manage for individuals. For organizations, get priority
|
||||
support, white-glove onboarding, and powerful integrations with the{" "}
|
||||
<a href="/pricing">Enterprise Plan</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="container margin-top--lg">
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<center>
|
||||
<h4>Individuals and home lab users</h4>
|
||||
</center>
|
||||
<p>
|
||||
Lightweight and fast. Access your home network securely when on the
|
||||
road.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Effortless to deploy on any infrastructure</li>
|
||||
<li>Community plan supports unlimited devices</li>
|
||||
<li>Open-source and self-hosted</li>
|
||||
</ul>
|
||||
<a href="/docs">Access your personal project ></a>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<center>
|
||||
<h4>Growing businesses</h4>
|
||||
</center>
|
||||
<p>
|
||||
Keep up with increasing network and compliance demands as you scale your
|
||||
team and infrastructure.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Integrate your identity provider</li>
|
||||
<li>Quickly onboard/offboard employees</li>
|
||||
<li>Segment access for contractors</li>
|
||||
<li>High performance, reduce bottlenecks</li>
|
||||
</ul>
|
||||
<a href="/pricing">Scale your secure access ></a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row margin-top--md">
|
||||
<div className="col col--6">
|
||||
<center>
|
||||
<h4>Remote organizations</h4>
|
||||
</center>
|
||||
<p>
|
||||
Transitioning to remote? Perfect timing to replace the legacy VPN.
|
||||
Improve your security posture and reduce support tickets.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Require periodic re-authentication</li>
|
||||
<li>Enforce MFA / 2FA</li>
|
||||
<li>Self-serve user portal</li>
|
||||
<li>Export logs to your observability platform</li>
|
||||
</ul>
|
||||
<a href="/pricing">Secure your remote workforce ></a>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<center>
|
||||
<h4>Technical IT teams</h4>
|
||||
</center>
|
||||
<p>
|
||||
Firezone runs on your infrastructure. Customize it to suit your needs
|
||||
and architecture.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Built on WireGuard®</li>
|
||||
<li>No vendor lock-in</li>
|
||||
<li>Supports OIDC and SAML 2.0</li>
|
||||
<li>Flexible and configurable</li>
|
||||
</ul>
|
||||
<a href="/docs">Explore the documentation ></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-vert--xl" />
|
||||
|
||||
<center>
|
||||
<h2>Ready to get started?</h2>
|
||||
</center>
|
||||
|
||||
<p>
|
||||
Set up secure access and start onboarding users in minutes. Run the install
|
||||
script on a supported host to deploy Firezone with Docker. Copy the one-liner
|
||||
below to install Firezone in minutes.
|
||||
</p>
|
||||
|
||||
<InstallBlock />
|
||||
168
www/src/pages/pricing.mdx
Normal file
168
www/src/pages/pricing.mdx
Normal file
@@ -0,0 +1,168 @@
|
||||
---
|
||||
title: Firezone • Pricing
|
||||
description: Explore Firezone's pricing.
|
||||
---
|
||||
|
||||
<div className="hero shadow--lw">
|
||||
<div className="container">
|
||||
<h1 className="hero__title">Firezone pricing</h1>
|
||||
<p>
|
||||
Firezone works with teams of all sizes to deliver fast, low-latency access
|
||||
to private networks and resources.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="margin-vert--lg">Enterprise plan</h2>
|
||||
|
||||
<p>
|
||||
Direct support from the team that built Firezone and additional features built
|
||||
for larger teams.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Get immediate assistance from a <strong>dedicated support engineer</strong>{" "}
|
||||
through email and your own <strong>private Slack channel</strong>.
|
||||
</li>
|
||||
<li>
|
||||
Ensure business continuity and reduce risk with SLAs and{" "}
|
||||
<strong>expert guidance</strong> from the creators of Firezone.
|
||||
</li>
|
||||
<li>
|
||||
Maintain privacy and control by <strong>hosting on-prem</strong> in
|
||||
security-sensitive environments.
|
||||
</li>
|
||||
<li>
|
||||
Shape Firezone's future roadmap and <strong>accelerate development</strong>{" "}
|
||||
of the features you need.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="container">
|
||||
<div className="row margin-vert--lg">
|
||||
<div className="col col--12">
|
||||
<center>
|
||||
<h4>
|
||||
Hundreds of organizations trust Firezone to secure access for their
|
||||
team.
|
||||
</h4>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row margin-vert--lg">
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="bunq logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763171-3b768826-eddf-499c-9b84-5ad365e8da6e.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="tribe logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763181-61c8b4a7-4367-41a6-a790-0fa2b2a34461.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="poughkeepsie logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763199-69def673-f37d-4e6b-aee9-13eac24ad93b.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="rebank logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763213-265a562c-1ed0-4206-8a9f-6726aaaaeed4.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="square1 logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763233-ac4fd4f2-c58b-4136-a3b1-ceeb09a4f954.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
<div className="col col--2">
|
||||
<img
|
||||
alt="db11 logo"
|
||||
src="https://user-images.githubusercontent.com/167144/218763247-e75a2410-baa0-45f8-bd5f-aa33d5fd0898.png"
|
||||
width="100px"
|
||||
height="55px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col col--2 col--offset-10">
|
||||
<a className="button button--primary" href="/sales">
|
||||
Get in touch
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-bottom--xl" />
|
||||
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--1">
|
||||
<img src="/img/github_light.svg" />
|
||||
</div>
|
||||
<div className="col col--11">
|
||||
<h3>Looking for the free, open-source version of Firezone?</h3>
|
||||
<p>
|
||||
The Community Plan is perfect for individuals and small teams with basic
|
||||
secure access needs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col col--2 col--offset-10">
|
||||
<a href="https://github.com/firezone/firezone">Visit GitHub </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr className="margin-bottom--xl" />
|
||||
|
||||
<center>
|
||||
<h1>Find the best plan for your organization</h1>
|
||||
<p>
|
||||
Have a feature request? Open an issue on{" "}
|
||||
<a href="https://github.com/firezone/firezone/issues">GitHub</a>, or{" "}
|
||||
<a href="/sales">get in touch</a> with our team.
|
||||
</p>
|
||||
</center>
|
||||
|
||||
| | Community | Enterprise |
|
||||
| ---------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
||||
| <strong>Management</strong> | | |
|
||||
| Users | Unlimited | Unlimited |
|
||||
| Devices | Unlimited | Unlimited |
|
||||
| Self-hosted | <span className="badge badge--success">✔</span> | <span className="badge badge--success">✔</span> |
|
||||
| | | |
|
||||
| <strong>Security and compliance</strong> | | |
|
||||
| User-scoped access rules | <span className="badge badge--success">✔</span> | <span className="badge badge--success">✔</span> |
|
||||
| Single sign-on | <span className="badge badge--success">✔</span> | <span className="badge badge--success">✔</span> |
|
||||
| Debug logs | <span className="badge badge--success">✔</span> | <span className="badge badge--success">✔</span> |
|
||||
| | | |
|
||||
| <strong>Support</strong> | | |
|
||||
| Community support | <span className="badge badge--success">✔</span> | <span className="badge badge--success">✔</span> |
|
||||
| Priority email support | | <span className="badge badge--success">✔</span> |
|
||||
| Dedicated Slack channel | | <span className="badge badge--success">✔</span> |
|
||||
| White-glove onboarding | | <span className="badge badge--success">✔</span> |
|
||||
| SLAs | | <span className="badge badge--success">✔</span> |
|
||||
| Assisted upgrades | | <span className="badge badge--success">✔</span> |
|
||||
| | | |
|
||||
| <strong>Custom development</strong> | | |
|
||||
| Custom integrations | | <span className="badge badge--success">✔</span> |
|
||||
| Roadmap acceleration | | <span className="badge badge--success">✔</span> |
|
||||
| | <a href="https://github.com/firezone/firezone">Visit GitHub ></a> | <a className="button button--primary" href="/sales">Get in touch</a> |
|
||||
49
www/src/pages/sales.mdx
Normal file
49
www/src/pages/sales.mdx
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: Firezone • Open Source Remote Access
|
||||
description: Firezone • Contact us
|
||||
---
|
||||
|
||||
<div className="hero shadow--lw">
|
||||
<div className="container">
|
||||
<h1 className="hero__title">Talk to a Firezone expert</h1>
|
||||
<p>
|
||||
Discover how Firezone can make managing secure access effortless for your
|
||||
organization. We'll help you find the right solution, explain pricing, and
|
||||
answer any questions.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<center>
|
||||
<h2 className="margin-vert--xl">Why Firezone Enterprise?</h2>
|
||||
</center>
|
||||
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<h3>Ensure business continuity</h3>
|
||||
<ul>
|
||||
<li>Technical support with SLAs</li>
|
||||
<li>Private Slack channel</li>
|
||||
<li>White-glove onboarding</li>
|
||||
</ul>
|
||||
<h3>Built for privacy and compliance</h3>
|
||||
<ul>
|
||||
<li>Host on-prem in security sensitive environments</li>
|
||||
<li>Maintain full control of your data and network traffic</li>
|
||||
</ul>
|
||||
<h3>Simplify management for admins</h3>
|
||||
<ul>
|
||||
<li>Automatic de-provisioning with SCIM</li>
|
||||
<li>Deployment advice for complex use cases</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<HubspotForm
|
||||
region="na1"
|
||||
portalId="23723443"
|
||||
formId="76637b95-cef7-4b94-8e7a-411aeec5fbb1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
Try asking on one of our community-powered support channels:
|
||||
|
||||
* [Discussion Forums](https://discourse.firez.one/?utm_source=docs.firezone.dev): Ask questions, report bugs,
|
||||
and suggest features.
|
||||
* [Public Slack Group](https://join.slack.com/t/firezone-users/shared_invite/zt-111043zus-j1lP_jP5ohv52FhAayzT6w):
|
||||
join discussions, meet other users, and meet the contributors
|
||||
- [Discussion Forums](https://discourse.firez.one/?utm_source=docs.firezone.dev): Ask questions, report bugs,
|
||||
and suggest features.
|
||||
- [Public Slack Group](https://join.slack.com/t/firezone-users/shared_invite/zt-111043zus-j1lP_jP5ohv52FhAayzT6w):
|
||||
join discussions, meet other users, and meet the contributors
|
||||
|
||||
**Looking for dedicated support?** [Contact us](https://www.firezone.dev/contact/sales?utm_source=docs.firezone.dev)
|
||||
**Looking for dedicated support?** [Contact us](/sales)
|
||||
about our paid support option if you're using Firezone in a production
|
||||
capacity for your team or organization.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Import the original mapper
|
||||
import MDXComponents from "@theme-original/MDXComponents";
|
||||
import AsciinemaPlayer from '@site/src/components/AsciinemaPlayer';
|
||||
import HubspotForm from '@site/src/components/HubspotForm';
|
||||
import InstallBlock from "@site/src/components/InstallBlock";
|
||||
import AccentBlock from "@site/src/components/AccentBlock";
|
||||
import Feedback from "@site/src/components/Feedback";
|
||||
@@ -12,6 +14,8 @@ export default {
|
||||
...MDXComponents,
|
||||
// Map the "highlight" tag to our <Highlight /> component!
|
||||
// `Highlight` will receive all props that were passed to `highlight` in MDX
|
||||
AsciinemaPlayer: AsciinemaPlayer,
|
||||
HubspotForm: HubspotForm,
|
||||
InstallBlock: InstallBlock,
|
||||
accentblock: AccentBlock,
|
||||
feedback: Feedback,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="512px" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" width="512px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="_x39_4-dislike"><g><path d="M128.543,270.411V68.616c0-7.953,6.442-14.408,14.379-14.408H27.926 c-7.944,0-14.378,6.456-14.378,14.408v201.795c0,7.955,6.434,14.411,14.378,14.413H134.58l-4.139-7.264 C129.176,275.376,128.543,272.922,128.543,270.411z" style="fill:#F54E00;"/><path d="M497.179,192.488l-46.106-104.04c-9.174-20.779-29.813-34.24-52.532-34.24H182.203h-14.375 c-7.937,0-14.379,6.456-14.379,14.408v201.795c0,2.511,0.633,4.965,1.898,7.149l4.139,7.264l51.466,90.317v68.233 c0,7.959,6.442,14.417,14.367,14.417h43.134c31.71,0,57.491-25.864,57.491-57.652v-86.485h115.007 c31.712,0,57.502-25.863,57.501-57.656v-57.656C498.452,196.328,498.021,194.336,497.179,192.488z" style="fill:#F54E00;"/></g></g><g id="Layer_1"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="512px" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" width="512px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="_x31_99-like"><g><path d="M133.815,443.378V241.587c0-2.507,0.632-4.962,1.897-7.148l4.141-7.268H33.193 c-7.938,0-14.378,6.46-14.378,14.416v201.791c0,7.953,6.44,14.412,14.378,14.412h114.994 C140.255,457.79,133.815,451.331,133.815,443.378z" style="fill:#2AC276;"/><path d="M435.682,198.344H320.684v-86.483c0-31.798-25.787-57.651-57.494-57.651h-43.132 c-7.93,0-14.368,6.456-14.368,14.408v68.237l-51.463,90.315l-4.141,7.268c-1.265,2.186-1.897,4.642-1.897,7.148v201.791 c0,7.953,6.44,14.412,14.372,14.412h14.38h216.339c22.715,0,43.355-13.46,52.527-34.245l46.111-104.04 c0.838-1.841,1.27-3.834,1.27-5.849V256C493.186,224.199,467.395,198.344,435.682,198.344z" style="fill:#2AC276;"/></g></g><g id="Layer_1"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
3
www/static/js/hubspot.js
Normal file
3
www/static/js/hubspot.js
Normal file
@@ -0,0 +1,3 @@
|
||||
<!-- Start of HubSpot Embed Code -->
|
||||
<script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/23723443.js"></script>
|
||||
<!-- End of HubSpot Embed Code -->
|
||||
7
www/tsconfig.json
Normal file
7
www/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
// This file is not used in compilation. It is here just for a nice editor experience.
|
||||
"extends": "@tsconfig/docusaurus/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "."
|
||||
}
|
||||
}
|
||||
1888
www/yarn.lock
1888
www/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user