Build/fix no prefix (#1089)

* fix: use caddy in host network_mode and make sure urls have a scheme

* fix: remove unnecesary exposed ports

* fix: remove support for hostnames begining with // since caddy doesn't support it

* Fix schemeless external URLs; error on invalid ones (#1090)

* Fix schemeless external URLs; error on invalid ones

* use different dockerfile for linux vs non-linux

* Use conditional EXTERNAL_URL defaults

* suppress empty warning

* postgres volume location

* Use inline Caddyfile

Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
This commit is contained in:
Gabi
2022-11-03 23:36:37 -03:00
committed by GitHub
parent 85494de270
commit 029891c69e
11 changed files with 252 additions and 69 deletions

View File

@@ -65,4 +65,16 @@ defmodule FzCommon.FzNet do
def valid_hostname?(hostname) when is_binary(hostname) do
String.match?(hostname, @host_regex)
end
def to_complete_url(str) when is_binary(str) do
case URI.new(str) do
{:ok, %{host: nil, scheme: nil}} ->
{:ok, "https://" <> str}
{:ok, _} ->
{:ok, str}
err -> err
end
end
end

View File

@@ -110,4 +110,32 @@ defmodule FzCommon.FzNetTest do
assert "fd00:3::1" == FzNet.standardized_inet("fd00:3:0000::1")
end
end
describe "to_complete_url/1" do
@tag cases: [
{"foobar", "https://foobar"},
{"google.com", "https://google.com"},
{"127.0.0.1", "https://127.0.0.1"},
{"8.8.8.8", "https://8.8.8.8"},
{"https://[fd00::1]", "https://[fd00::1]"},
{"http://foobar", "http://foobar"},
{"https://foobar", "https://foobar"}
]
test "parses valid string URIs", %{cases: cases} do
for {subject, expected} <- cases do
assert {:ok, ^expected} = FzNet.to_complete_url(subject)
end
end
@tag cases: [
"<",
"{",
"["
]
test "returns {:error, _} for invalid URIs", %{cases: cases} do
for subject <- cases do
assert {:error, _} = FzNet.to_complete_url(subject)
end
end
end
end

View File

@@ -5,10 +5,18 @@
import Config
alias FzCommon.{CLI, FzInteger, FzString, FzKernelVersion}
alias FzCommon.{CLI, FzInteger, FzString, FzKernelVersion, FzNet}
# external_url is important, so fail fast here if we can't parse
{:ok, external_url} =
if config_env() == :prod do
System.fetch_env!("EXTERNAL_URL")
|> FzNet.to_complete_url()
else
System.get_env("EXTERNAL_URL", "https://localhost")
|> FzNet.to_complete_url()
end
# external_url is important
external_url = System.get_env("EXTERNAL_URL", "https://localhost")
config :fz_http, :external_url, external_url
%{host: host, path: path, port: port, scheme: scheme} = URI.parse(external_url)

View File

@@ -0,0 +1,90 @@
# Example compose file for a running a local Firezone instance on
# macOS or Windows.
#
# Note: This file is meant to serve as a template. Please modify it
# according to your needs. Read more about Docker Compose:
#
# https://docs.docker.com/compose/compose-file/
#
#
x-deploy: &default-deploy
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
update_config:
order: start-first
version: '3.7'
services:
caddy:
image: caddy:2
volumes:
- ${FZ_INSTALL_DIR:-.}/caddy:/data/caddy
ports:
- 80:80
- 443:443
# See Caddy's documentation for customizing the Caddyfile
# https://caddyserver.com/docs/quick-starts/reverse-proxy
command:
- /bin/sh
- -c
- |
cat <<EOF > /etc/caddy/Caddyfile && caddy run --config /etc/caddy/Caddyfile
https:// {
log
reverse_proxy * firezone:13000
tls internal {
on_demand
}
}
EOF
deploy:
<<: *default-deploy
firezone:
image: firezone/firezone
ports:
- 51820:51820/udp
env_file:
# This should contain a list of env vars for configuring Firezone.
# See https://docs.firezone.dev/reference/env-vars for more info.
- ${FZ_INSTALL_DIR:-.}/.env
volumes:
# IMPORTANT: Persists WireGuard private key and other data. If
# /var/firezone/private_key exists when Firezone starts, it is
# used as the WireGuard private. Otherwise, one is generated.
- ${FZ_INSTALL_DIR:-.}/firezone:/var/firezone
cap_add:
# Needed for WireGuard and firewall support.
- NET_ADMIN
- SYS_MODULE
sysctls:
# Needed for masquerading and NAT.
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
depends_on:
- postgres
deploy:
<<: *default-deploy
postgres:
image: postgres:15
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${DATABASE_NAME:-firezone}
POSTGRES_USER: ${DATABASE_USER:-postgres}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD:?err}
deploy:
<<: *default-deploy
update_config:
order: stop-first
# Postgres needs a named volume to prevent perms issues on non-linux platforms
volumes:
postgres-data:

View File

@@ -1,4 +1,4 @@
# Example compose file for production deployment.
# Example compose file for production deployment on Linux.
#
# Note: This file is meant to serve as a template. Please modify it
# according to your needs. Read more about Docker Compose:
@@ -22,12 +22,10 @@ services:
image: caddy:2
volumes:
- ${FZ_INSTALL_DIR:-.}/caddy:/data/caddy
ports:
- 80:80
- 443:443
# See Caddy's documentation for customizing this line
# https://caddyserver.com/docs/quick-starts/reverse-proxy
command: caddy reverse-proxy ${CADDY_OPTS} --to firezone:13000 --from ${EXTERNAL_URL:?err}
# See Caddy's documentation for customizing this line
# https://caddyserver.com/docs/quick-starts/reverse-proxy
command: caddy reverse-proxy ${CADDY_OPTS:-} --to 172.25.0.100:13000 --from ${EXTERNAL_URL:?err}
network_mode: "host"
deploy:
<<: *default-deploy
@@ -55,6 +53,9 @@ services:
- net.ipv6.conf.all.forwarding=1
depends_on:
- postgres
networks:
firezone-network:
ipv4_address: 172.25.0.100
deploy:
<<: *default-deploy
@@ -66,6 +67,8 @@ services:
POSTGRES_DB: ${DATABASE_NAME:-firezone}
POSTGRES_USER: ${DATABASE_USER:-postgres}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD:?err}
networks:
- firezone-network
deploy:
<<: *default-deploy
update_config:
@@ -74,3 +77,10 @@ services:
# Postgres needs a named volume to prevent perms issues on non-linux platforms
volumes:
postgres-data:
networks:
firezone-network:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16

View File

@@ -62,9 +62,14 @@ installation process, follow the steps below to install manually.
1. Ensure you're on a supported platform and have a recent version of
[docker-compose](https://docs.docker.com/compose/install/) installed.
1. Download the docker compose template to a local working directory:
**For Linux**:
```shell
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.prod.yml -o docker-compose.yml
```
**For macOS, Windows (non-production only)**:
```shell
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.desktop.yml -o docker-compose.yml
```
1. Generate required secrets:
```shell
docker run --rm firezone/firezone bin/gen-env > .env

View File

@@ -6,17 +6,28 @@ sidebar_position: 1
Firezone currently supports the following platforms for Docker-based
deployments.
| OS | Architecture(s) | Runtime | Status | Notes |
| --- | --- | --- | --- | --- |
| Linux | `amd64` `arm64` | Docker Server | Fully-supported | `wireguard` module needed for kernels &lt; `5.6` |
| Linux | `amd64` `arm64` | Docker Desktop | Fully-supported | Not recommended for production deployments. |
| macOS | `amd64` `arm64` | Docker Desktop | Fully-supported | Not recommended for production deployments. |
| Windows | `amd64` `arm64` | Docker Desktop | Fully-supported | Not recommended for production deployments. |
| OS | Architecture(s) | Runtime | Status | Notes |
| --- | --- | --- | --- | --- |
| Linux | `amd64` `arm64` | Docker Server | **Fully-supported** | `wireguard` kernel module needed for kernels &lt; `5.6`. |
| Linux | `amd64` `arm64` | Docker Desktop | Works, but unsupported. | Not recommended for production deployments. See [caveats](#docker-desktop-caveats). |
| macOS | `amd64` `arm64` | Docker Desktop | Works. but unsupported. | Not recommended for production deployments. See [caveats](#non-linux-platform-caveats). |
| Windows | `amd64` `arm64` | Docker Desktop | **Untested** | Not recommended for production deployments. See [caveats](#non-linux-platform-caveats). |
## Docker Desktop Caveats
:::info
Docker Desktop [rewrites the source address
](https://www.docker.com/blog/how-docker-desktop-networking-works-under-the-hood/)
for packets flowing out of container networks under some conditions. This can
cause routing loops and other hard to debug connectivity issues with Firezone.
We recommend **only** using Docker Server for Linux for production deployments.
:::
## Non-Linux Platform Caveats
Only Docker for Linux supports the host networking mode, so macOS and Windows
platforms will be able unable to properly attribute client source address
for HTTP requests. This means any IP-based throttling or logging in your
chosen proxy (`caddy` by default) will be ineffective, since the source
IP will always be the Docker-side host IP (typically `172.X.0.1`).
Egress rules operate on the tunneled client IP address and aren't affected
by this limitation.

View File

@@ -10,7 +10,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.
We recommend setting these in your Docker ENV file (`/data/firezone/firezone/.env` by
We recommend setting these in your Docker ENV file (`$HOME/.firezone/.env` by
default). Required fields in **bold**.
| Name | Description | Format | Default |

View File

@@ -10,18 +10,18 @@ your installation.
<Tabs>
<TabItem label="Docker" value="docker" default>
| path | description |
| --- | --- |
| `<install_dir>/.env` | Firezone secrets used for encryption, cookies, and sessions. **Losing this file will result in irrecoverable data loss**. |
| `<install_dir>/docker-compose.yml` | Docker Compose file used to manage Firezone services. |
| `/data/firezone/firezone` | Top-level directory containing Firezone-related persisted data |
| `/data/firezone/postgres` | Postgres DB files. |
| `/data/firezone/caddy` | Caddy persisted files. |
| 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 |
| `$HOME/.firezone/caddy` | Caddy persisted files. |
| Default Docker volume location. | Postgres DB files. |
</TabItem>
<TabItem label="Omnibus" value="omnibus">
| path | description |
| 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. |

View File

@@ -34,47 +34,14 @@ x-deploy: &default-deploy
order: start-first
networks:
app:
firezone-network:
enable_ipv6: true
ipam:
config:
- subnet: 172.28.0.0/16
- subnet: 172.25.0.0/16
- subnet: 2001:3990:3990::/64
services:
firezone:
image: firezone/firezone
ports:
- 51820:51820/udp
volumes:
# IMPORTANT: Persists WireGuard private key and other data. If
# /var/firezone/private_key exists when Firezone starts, it is
# used as the WireGuard private. Otherwise, one is generated.
- /data/firezone/firezone:/var/firezone
environment:
EXTERNAL_URL: ${EXTERNAL_URL:?err}
ADMIN_EMAIL: ${ADMIN_EMAIL:?err}
DEFAULT_ADMIN_PASSWORD: ${DEFAULT_ADMIN_PASSWORD:?err}
GUARDIAN_SECRET_KEY: ${GUARDIAN_SECRET_KEY:?err}
SECRET_KEY_BASE: ${SECRET_KEY_BASE:?err}
LIVE_VIEW_SIGNING_SALT: ${LIVE_VIEW_SIGNING_SALT:?err}
COOKIE_SIGNING_SALT: ${COOKIE_SIGNING_SALT:?err}
COOKIE_ENCRYPTION_SALT: ${COOKIE_ENCRYPTION_SALT:?err}
DATABASE_ENCRYPTION_KEY: ${DATABASE_ENCRYPTION_KEY:?err}
# Ensure this includes the traefik service IP.
EXTERAL_TRUSTED_PROXIES: ['']
networks:
- app
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
depends_on:
- postgres
traefik:
deploy:
<<: *default-deploy
@@ -98,22 +65,65 @@ services:
- ./rules.yml:/rules.yml
# make the IP of this service deterministic
networks:
app:
ipv4_address: 172.28.0.99
firezone-network:
ipv4_address: 172.25.0.99
ipv6_address: 2001:3990:3990::99
postgres:
image: postgres:13
firezone:
image: firezone/firezone
ports:
- 51820:51820/udp
env_file:
# This should contain a list of env vars for configuring Firezone.
# See https://docs.firezone.dev/reference/env-vars for more info.
- ${FZ_INSTALL_DIR:-.}/.env
volumes:
- /data/firezone/postgres:/var/lib/postgresql/data
# IMPORTANT: Persists WireGuard private key and other data. If
# /var/firezone/private_key exists when Firezone starts, it is
# used as the WireGuard private. Otherwise, one is generated.
- ${FZ_INSTALL_DIR:-.}/firezone:/var/firezone
cap_add:
# Needed for WireGuard and firewall support.
- NET_ADMIN
- SYS_MODULE
sysctls:
# Needed for masquerading and NAT.
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
depends_on:
- postgres
networks:
firezone-network:
ipv4_address: 172.25.0.100
deploy:
<<: *default-deploy
postgres:
image: postgres:15
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
# same value as ## DB section above
POSTGRES_DB: ${DATABASE_NAME:-firezone}
POSTGRES_USER: ${DATABASE_USER:-postgres}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD:?err}
networks:
- firezone-network
deploy:
<<: *default-deploy
update_config:
order: stop-first
# Postgres needs a named volume to prevent perms issues on non-linux platforms
volumes:
postgres-data:
networks:
firezone-network:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
```
### `rules.yml`

View File

@@ -113,7 +113,16 @@ firezoneSetup() {
export FZ_INSTALL_DIR=$installDir
if ! test -f $installDir/docker-compose.yml; then
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.prod.yml -o $installDir/docker-compose.yml
os_type="$(uname -s)"
case "${os_type}" in
Linux*)
file=docker-compose.prod.yml
;;
*)
file=docker-compose.desktop.yml
;;
esac
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/$file -o $installDir/docker-compose.yml
fi
db_pass=$(od -vN "8" -An -tx1 /dev/urandom | tr -d " \n" ; echo)
docker run --rm firezone/firezone bin/gen-env > "$installDir/.env"