From e918a6d5811dbd574c22e3beed5138511baa8d75 Mon Sep 17 00:00:00 2001 From: oddlama Date: Fri, 7 Feb 2025 03:44:29 +0100 Subject: [PATCH] wip: more firezone clients --- modules/default.nix | 2 + modules/firezone-gateways.nix | 170 +++++++++++ modules/firezone-relay.nix | 177 +++++++++++ modules/firezone-server.nix | 130 ++++---- pkgs/default.nix | 4 + pkgs/firezone-gateway/package.nix | 39 +++ .../0000-add-hyper-tls-dependency.patch | 281 ++++++++++++++++++ pkgs/firezone-gui-client/package.nix | 153 ++++++++++ pkgs/firezone-headless-client/package.nix | 44 +++ pkgs/firezone-relay/package.nix | 39 +++ .../0000-add-healthz-port.patch | 60 ++++ .../0001-postgres-socket.patch | 100 +++++++ .../{a.patch => 0002-add-mua.patch} | 110 ++----- pkgs/firezone-server-domain/generic.nix | 6 +- 14 files changed, 1174 insertions(+), 141 deletions(-) create mode 100644 modules/firezone-gateways.nix create mode 100644 modules/firezone-relay.nix create mode 100644 pkgs/firezone-gateway/package.nix create mode 100644 pkgs/firezone-gui-client/0000-add-hyper-tls-dependency.patch create mode 100644 pkgs/firezone-gui-client/package.nix create mode 100644 pkgs/firezone-headless-client/package.nix create mode 100644 pkgs/firezone-relay/package.nix create mode 100644 pkgs/firezone-server-domain/0000-add-healthz-port.patch create mode 100644 pkgs/firezone-server-domain/0001-postgres-socket.patch rename pkgs/firezone-server-domain/{a.patch => 0002-add-mua.patch} (58%) diff --git a/modules/default.nix b/modules/default.nix index 0d7160e..0db5116 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -8,6 +8,8 @@ ./backups.nix ./deterministic-ids.nix ./distributed-config.nix + ./firezone-relay.nix + ./firezone-gateways.nix ./firezone-server.nix ./globals.nix ./meta.nix diff --git a/modules/firezone-gateways.nix b/modules/firezone-gateways.nix new file mode 100644 index 0000000..c09cca8 --- /dev/null +++ b/modules/firezone-gateways.nix @@ -0,0 +1,170 @@ +{ + lib, + pkgs, + config, + ... +}: +let + inherit (lib) + boolToString + concatMapAttrs + flip + getExe + mkEnableOption + mkOption + mkPackageOption + types + ; +in +{ + options = { + services.firezone.gateways = mkOption { + description = '' + A set of gateway clients to deploy on this machine. Each gateway can + connect to exactly one firezone server. + ''; + default = { }; + type = types.attrsOf ( + types.submodule (gatewaysSubmod: { + options = { + package = mkPackageOption pkgs "firezone-gateway" { }; + + name = mkOption { + type = types.str; + default = gatewaysSubmod.config._module.args.name; + description = "The name of this gateway as shown in firezone"; + }; + + user = mkOption { + type = types.strMatching "^[a-zA-Z0-9_-]{1,32}$"; + default = "firezone-gw-${gatewaysSubmod.config._module.args.name}"; + description = "The DynamicUser name under which the gateway will run. Cannot exceed 32 characters."; + }; + + interface = mkOption { + type = types.strMatching "^[a-zA-Z0-9_-]{1,15}$"; + default = "tun-${gatewaysSubmod.config._module.args.name}"; + description = "The name of the TUN interface which will be created by this gateway"; + }; + + apiUrl = mkOption { + type = types.str; + example = "wss://firezone.example.com/api"; + description = '' + The URL of your firezone server's API. This should be the same + as your server's setting for {option}`services.firezone.server.settings.api.externalUrl`, + but with `wss://` instead of `https://`. + ''; + }; + + tokenFile = mkOption { + type = types.path; + example = "/run/secrets/firezone-gateway-token"; + description = '' + A file containing the firezone gateway token. Do not use a nix-store path here + as it will make the token publicly readable! + + This file will be passed via systemd credentials, it should only be accessible + by the root user. + ''; + }; + + logLevel = mkOption { + type = types.str; + default = "info"; + description = '' + The log level for the firezone application. See + [RUST_LOG](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) + for the format. + ''; + }; + + enableTelemetry = mkEnableOption "telemetry"; + }; + }) + ); + }; + }; + + config = { + systemd.services = flip concatMapAttrs config.services.firezone.gateways ( + gatewayName: gatewayCfg: { + "firezone-gateway-${gatewayName}" = { + description = "Gateway service for the Firezone zero-trust access platform"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + path = [ pkgs.util-linux ]; + script = '' + # If FIREZONE_ID is not given by the user, use a persisted (or newly generated) uuid. + if [[ -z "''${FIREZONE_ID:-}" ]]; then + if [[ ! -e gateway_id ]]; then + uuidgen -r > gateway_id + fi + export FIREZONE_ID=$(< gateway_id) + fi + + export FIREZONE_TOKEN=$(< "$CREDENTIALS_DIRECTORY/firezone-token") + exec ${getExe gatewayCfg.package} + ''; + + environment = { + FIREZONE_API_URL = gatewayCfg.apiUrl; + FIREZONE_NAME = gatewayCfg.name; + FIREZONE_NO_TELEMETRY = boolToString gatewayCfg.enableTelemetry; + FIREZONE_TUN_INTERFACE = gatewayCfg.interface; + RUST_LOG = gatewayCfg.logLevel; + }; + + serviceConfig = { + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = false; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_NETLINK" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + UMask = "077"; + + Type = "exec"; + DynamicUser = true; + User = gatewayCfg.user; + LoadCredential = [ "firezone-token:${gatewayCfg.tokenFile}" ]; + + DeviceAllow = "/dev/net/tun"; + AmbientCapabilities = [ "CAP_NET_ADMIN" ]; + CapabilityBoundingSet = [ "CAP_NET_ADMIN" ]; + + StateDirectory = "firezone-gateways/${gatewayName}"; + WorkingDirectory = "/var/lib/firezone-gateways/${gatewayName}"; + }; + }; + } + ); + }; + + meta.maintainers = with lib.maintainers; [ + oddlama + patrickdag + ]; +} diff --git a/modules/firezone-relay.nix b/modules/firezone-relay.nix new file mode 100644 index 0000000..702a4ab --- /dev/null +++ b/modules/firezone-relay.nix @@ -0,0 +1,177 @@ +{ + lib, + pkgs, + config, + ... +}: +let + inherit (lib) + boolToString + getExe + mkEnableOption + mkIf + mkOption + mkPackageOption + types + ; + + cfg = config.services.firezone.relay; +in +{ + options = { + services.firezone.relay = { + enable = mkEnableOption "the firezone relay server"; + package = mkPackageOption pkgs "firezone-relay" { }; + + publicIpv4 = mkOption { + type = types.str; + description = "The public ipv4 address of this relay"; + }; + + publicIpv6 = mkOption { + type = types.str; + description = "The public ipv6 address of this relay"; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = "Opens up the main STUN port and the TURN allocation range."; + }; + + port = mkOption { + type = types.port; + default = 3478; + description = "The port to listen on for STUN messages"; + }; + + lowestPort = mkOption { + type = types.port; + default = 49152; + description = "The lowest port to use in TURN allocation"; + }; + + highestPort = mkOption { + type = types.port; + default = 65535; + description = "The highest port to use in TURN allocation"; + }; + + apiUrl = mkOption { + type = types.str; + example = "wss://firezone.example.com/api"; + description = '' + The URL of your firezone server's API. This should be the same + as your server's setting for {option}`services.firezone.server.settings.api.externalUrl`, + but with `wss://` instead of `https://`. + ''; + }; + + tokenFile = mkOption { + type = types.path; + example = "/run/secrets/firezone-relay-token"; + description = '' + A file containing the firezone relay token. Do not use a nix-store path here + as it will make the token publicly readable! + + This file will be passed via systemd credentials, it should only be accessible + by the root user. + ''; + }; + + logLevel = mkOption { + type = types.str; + default = "firezone_relay=info,firezone_tunnel=info,connlib_shared=info,tunnel_state=info,phoenix_channel=info,snownet=info,str0m=info,warn"; + description = '' + The log level for the firezone application. See + [RUST_LOG](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) + for the format. + ''; + }; + + enableTelemetry = mkEnableOption "telemetry"; + }; + }; + + config = mkIf cfg.enable { + systemd.services."firezone-relay" = { + description = "relay service for the Firezone zero-trust access platform"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + path = [ pkgs.util-linux ]; + script = '' + # If FIREZONE_ID is not given by the user, use a persisted (or newly generated) uuid. + if [[ -z "''${FIREZONE_ID:-}" ]]; then + if [[ ! -e relay_id ]]; then + uuidgen -r > relay_id + fi + export FIREZONE_ID=$(< relay_id) + fi + + export FIREZONE_TOKEN=$(< "$CREDENTIALS_DIRECTORY/firezone-token") + exec ${getExe cfg.package} + ''; + + environment = { + FIREZONE_API_URL = cfg.apiUrl; + FIREZONE_NAME = cfg.name; + FIREZONE_TELEMETRY = boolToString cfg.enableTelemetry; + + PUBLIC_IPV4_ADDRESS = cfg.publicIpv4; + PUBLIC_IPV6_ADDRESS = cfg.publicIpv6; + + LISTEN_PORT = toString cfg.port; + LOWEST_PORT = toString cfg.lowestPort; + HIGHEST_PORT = toString cfg.highestPort; + + RUST_LOG = cfg.logLevel; + LOG_FORMAT = "human"; + }; + + serviceConfig = { + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = false; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_NETLINK" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + UMask = "077"; + + Type = "exec"; + DynamicUser = true; + User = "firezone-relay"; + LoadCredential = [ "firezone-token:${cfg.tokenFile}" ]; + + StateDirectory = "firezone-relay"; + WorkingDirectory = "/var/lib/firezone-relay"; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ + oddlama + patrickdag + ]; +} diff --git a/modules/firezone-server.nix b/modules/firezone-server.nix index 1f248f2..62ae9d8 100644 --- a/modules/firezone-server.nix +++ b/modules/firezone-server.nix @@ -85,14 +85,15 @@ let ); in concatLines ( - forEach relevantSecrets (secret: '' - export ${secret}=$(< ${ + forEach relevantSecrets ( + secret: + ''export ${secret}=$(< ${ if cfg.settingsSecret.${secret} == null then "secrets/${secret}" else "\"$CREDENTIALS_DIRECTORY/${secret}\"" - }) - '') + })'' + ) ); provisionStateJson = @@ -121,20 +122,20 @@ let commonServiceConfig = { AmbientCapablities = [ ]; CapabilityBoundingSet = [ ]; - LockPersonality = "true"; - MemoryDenyWriteExecute = "true"; - NoNewPrivileges = "true"; - PrivateMounts = "true"; - PrivateTmp = "true"; - PrivateUsers = "false"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = false; ProcSubset = "pid"; - ProtectClock = "true"; - ProtectControlGroups = "true"; - ProtectHome = "true"; - ProtectHostname = "true"; - ProtectKernelLogs = "true"; - ProtectKernelModules = "true"; - ProtectKernelTunables = "true"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; ProtectProc = "invisible"; ProtectSystem = "strict"; RestrictAddressFamilies = [ @@ -143,9 +144,9 @@ let "AF_NETLINK" "AF_UNIX" ]; - RestrictNamespaces = "true"; - RestrictRealtime = "true"; - RestrictSUIDSGID = "true"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; SystemCallArchitectures = "native"; SystemCallFilter = "@system-service"; UMask = "077"; @@ -157,10 +158,12 @@ let StateDirectory = "firezone"; WorkingDirectory = "/var/lib/firezone"; - Type = "exec"; LoadCredential = mapAttrsToList (secretName: secretFile: "${secretName}:${secretFile}") ( filterAttrs (_: v: v != null) cfg.settingsSecret ); + Type = "exec"; + Restart = "on-failure"; + RestartSec = 10; }; componentOptions = component: { @@ -199,20 +202,7 @@ in options.services.firezone.server = { enable = mkEnableOption "all Firezone components"; enableLocalDB = mkEnableOption "a local postgresql database for Firezone"; - - nginx = { - enable = mkEnableOption "nginx virtualhost definition"; - apiDomain = mkOption { - type = types.str; - example = "api.firezone.example.com"; - description = "The virtual host domain under which the api should be exposed"; - }; - webDomain = mkOption { - type = types.str; - example = "firezone.example.com"; - description = "The virtual host domain under which the web interface should be exposed"; - }; - }; + nginx.enable = mkEnableOption "nginx virtualhost definition"; openClusterFirewall = mkOption { type = types.bool; @@ -482,7 +472,7 @@ in api = componentOptions "api" // { externalUrl = mkOption { type = types.strMatching "^https://.+/$"; - example = "https://api.firezone.example.com/"; + example = "https://firezone.example.com/api/"; description = '' The external URL under which you will serve the api. You need to setup a reverse proxy for TLS termination, either with @@ -690,23 +680,45 @@ in }) # Create a local nginx reverse proxy (mkIf cfg.nginx.enable { - services.nginx = { - enable = true; - virtualHosts.${cfg.nginx.webDomain} = { - forceSSL = mkDefault true; - locations."/" = { - proxyPass = "http://${cfg.web.address}:${toString cfg.web.port}"; - proxyWebsockets = true; - }; - }; - virtualHosts.${cfg.nginx.apiDomain} = { - forceSSL = mkDefault true; - locations."/" = { - proxyPass = "http://${cfg.api.address}:${toString cfg.api.port}"; - proxyWebsockets = true; - }; - }; - }; + services.nginx = mkMerge [ + { + enable = true; + } + ( + let + urlComponents = builtins.elemAt (builtins.split "https://([^/]*)(/?.*)" cfg.web.externalUrl) 1; + domain = builtins.elemAt urlComponents 0; + location = builtins.elemAt urlComponents 1; + in + { + virtualHosts.${domain} = { + forceSSL = mkDefault true; + locations.${location} = { + # The trailing slash is important to strip the location prefix from the request + proxyPass = "http://${cfg.web.address}:${toString cfg.web.port}/"; + proxyWebsockets = true; + }; + }; + } + ) + ( + let + urlComponents = builtins.elemAt (builtins.split "https://([^/]*)(/?.*)" cfg.api.externalUrl) 1; + domain = builtins.elemAt urlComponents 0; + location = builtins.elemAt urlComponents 1; + in + { + virtualHosts.${domain} = { + forceSSL = mkDefault true; + locations.${location} = { + # The trailing slash is important to strip the location prefix from the request + proxyPass = "http://${cfg.api.address}:${toString cfg.api.port}/"; + proxyWebsockets = true; + }; + }; + } + ) + ]; }) # Specify sensible defaults { @@ -832,7 +844,7 @@ in }; systemd.services.firezone-initialize = { - description = "Firezone initialization"; + description = "Backend initialization service for the Firezone zero-trust access platform"; after = mkIf cfg.enableLocalDB [ "postgresql.service" ]; requires = mkIf cfg.enableLocalDB [ "postgresql.service" ]; @@ -859,7 +871,7 @@ in }; systemd.services.firezone-server-domain = mkIf cfg.domain.enable { - description = "Firezone domain server"; + description = "Backend domain server for the Firezone zero-trust access platform"; after = [ "firezone-initialize.service" ]; bindsTo = [ "firezone-initialize.service" ]; wantedBy = [ "firezone.target" ]; @@ -870,12 +882,13 @@ in exec ${getExe cfg.domain.package} start; ''; + path = [ pkgs.curl ]; postStart = mkIf cfg.provision.enable '' ${loadSecretEnvironment "domain"} # Wait for the firezone server to come online count=0 - while ! ${getExe cfg.domain.package} pid >/dev/null + while [[ "$(curl -s "http://localhost:${toString cfg.domain.settings.HEALTHZ_PORT}" 2>/dev/null || echo)" != '{"status":"ok"}' ]] do sleep 1 if [[ "$count" -eq 30 ]]; then @@ -885,6 +898,7 @@ in count=$((count++)) done + sleep 1 # Wait for server to fully come up. Not ideal to use sleep, but at least it works. ln -sTf ${provisionStateJson} provision-state.json ${getExe cfg.domain.package} rpc 'Code.eval_file("${./provision.exs}")' ''; @@ -894,7 +908,7 @@ in }; systemd.services.firezone-server-web = mkIf cfg.web.enable { - description = "Firezone web server"; + description = "Backend web server for the Firezone zero-trust access platform"; after = [ "firezone-initialize.service" ]; bindsTo = [ "firezone-initialize.service" ]; wantedBy = [ "firezone.target" ]; @@ -910,7 +924,7 @@ in }; systemd.services.firezone-server-api = mkIf cfg.api.enable { - description = "Firezone api server"; + description = "Backend api server for the Firezone zero-trust access platform"; after = [ "firezone-initialize.service" ]; bindsTo = [ "firezone-initialize.service" ]; wantedBy = [ "firezone.target" ]; diff --git a/pkgs/default.nix b/pkgs/default.nix index f354ade..db1e13b 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -22,6 +22,10 @@ _inputs: [ firezone-server-domain = prev.callPackage ./firezone-server-domain/package.nix { }; firezone-server-web = prev.callPackage ./firezone-server-web/package.nix { }; firezone-server-api = prev.callPackage ./firezone-server-api/package.nix { }; + firezone-gateway = prev.callPackage ./firezone-gateway/package.nix { }; + firezone-relay = prev.callPackage ./firezone-relay/package.nix { }; + firezone-gui-client = prev.callPackage ./firezone-gui-client/package.nix { }; + firezone-headless-client = prev.callPackage ./firezone-headless-client/package.nix { }; mdns-repeater = prev.callPackage ./mdns-repeater.nix { }; diff --git a/pkgs/firezone-gateway/package.nix b/pkgs/firezone-gateway/package.nix new file mode 100644 index 0000000..bac49eb --- /dev/null +++ b/pkgs/firezone-gateway/package.nix @@ -0,0 +1,39 @@ +{ + lib, + rustPlatform, + fetchFromGitHub, + nix-update-script, +}: +rustPlatform.buildRustPackage rec { + pname = "firezone-gateway"; + version = "1.4.2"; + src = fetchFromGitHub { + owner = "oddlama"; + repo = "firezone"; + rev = "feat/configurable-gateway-interface"; + hash = "sha256-dsGQubRs/ZHdAd6MHpa+3K4vGm4OnCdf1yMlGG1AIJk="; + }; + + useFetchCargoVendor = true; + cargoHash = "sha256-odrexu5mBGmvHNF4cUu9PDIEdxZC451lWV7dsLYT/Sg="; + sourceRoot = "${src.name}/rust"; + buildAndTestSubdir = "gateway"; + + # Required to remove profiling arguments which conflict with this builder + postPatch = '' + rm .cargo/config.toml + ''; + + passthru.updateScript = nix-update-script { }; + + meta = { + description = "WireGuard tunnel server for the Firezone zero-trust access platform"; + homepage = "https://github.com/firezone/firezone"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ + oddlama + patrickdag + ]; + mainProgram = "firezone-gateway"; + }; +} diff --git a/pkgs/firezone-gui-client/0000-add-hyper-tls-dependency.patch b/pkgs/firezone-gui-client/0000-add-hyper-tls-dependency.patch new file mode 100644 index 0000000..1d4349c --- /dev/null +++ b/pkgs/firezone-gui-client/0000-add-hyper-tls-dependency.patch @@ -0,0 +1,281 @@ +diff --git a/rust/Cargo.lock b/rust/Cargo.lock +index 9645ee069..558339b1f 100644 +--- a/rust/Cargo.lock ++++ b/rust/Cargo.lock +@@ -951,7 +951,7 @@ dependencies = [ + "cocoa-foundation 0.1.2", + "core-foundation 0.9.4", + "core-graphics 0.23.2", +- "foreign-types", ++ "foreign-types 0.5.0", + "libc", + "objc", + ] +@@ -967,7 +967,7 @@ dependencies = [ + "cocoa-foundation 0.2.0", + "core-foundation 0.10.0", + "core-graphics 0.24.0", +- "foreign-types", ++ "foreign-types 0.5.0", + "libc", + "objc", + ] +@@ -1173,7 +1173,7 @@ dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types 0.1.3", +- "foreign-types", ++ "foreign-types 0.5.0", + "libc", + ] + +@@ -1186,7 +1186,7 @@ dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", + "core-graphics-types 0.2.0", +- "foreign-types", ++ "foreign-types 0.5.0", + "libc", + ] + +@@ -1999,6 +1999,7 @@ dependencies = [ + "firezone-logging", + "firezone-telemetry", + "futures", ++ "hyper-tls", + "native-dialog", + "nix 0.29.0", + "rand 0.8.5", +@@ -2281,6 +2282,15 @@ version = "0.1.3" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + ++[[package]] ++name = "foreign-types" ++version = "0.3.2" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" ++dependencies = [ ++ "foreign-types-shared 0.1.1", ++] ++ + [[package]] + name = "foreign-types" + version = "0.5.0" +@@ -2288,7 +2298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" + dependencies = [ + "foreign-types-macros", +- "foreign-types-shared", ++ "foreign-types-shared 0.3.1", + ] + + [[package]] +@@ -2302,6 +2312,12 @@ dependencies = [ + "syn 2.0.87", + ] + ++[[package]] ++name = "foreign-types-shared" ++version = "0.1.1" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" ++ + [[package]] + name = "foreign-types-shared" + version = "0.3.1" +@@ -3035,6 +3051,22 @@ dependencies = [ + "tower-service", + ] + ++[[package]] ++name = "hyper-tls" ++version = "0.6.0" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" ++dependencies = [ ++ "bytes", ++ "http-body-util", ++ "hyper", ++ "hyper-util", ++ "native-tls", ++ "tokio", ++ "tokio-native-tls", ++ "tower-service", ++] ++ + [[package]] + name = "hyper-util" + version = "0.1.9" +@@ -3723,6 +3755,23 @@ dependencies = [ + "winapi", + ] + ++[[package]] ++name = "native-tls" ++version = "0.2.12" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" ++dependencies = [ ++ "libc", ++ "log", ++ "openssl", ++ "openssl-probe", ++ "openssl-sys", ++ "schannel", ++ "security-framework", ++ "security-framework-sys", ++ "tempfile", ++] ++ + [[package]] + name = "ndk" + version = "0.9.0" +@@ -4286,6 +4335,50 @@ dependencies = [ + "pathdiff", + ] + ++[[package]] ++name = "openssl" ++version = "0.10.68" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" ++dependencies = [ ++ "bitflags 2.6.0", ++ "cfg-if", ++ "foreign-types 0.3.2", ++ "libc", ++ "once_cell", ++ "openssl-macros", ++ "openssl-sys", ++] ++ ++[[package]] ++name = "openssl-macros" ++version = "0.1.1" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" ++dependencies = [ ++ "proc-macro2", ++ "quote", ++ "syn 2.0.87", ++] ++ ++[[package]] ++name = "openssl-probe" ++version = "0.1.5" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" ++ ++[[package]] ++name = "openssl-sys" ++version = "0.9.104" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" ++dependencies = [ ++ "cc", ++ "libc", ++ "pkg-config", ++ "vcpkg", ++] ++ + [[package]] + name = "opentelemetry" + version = "0.26.0" +@@ -5385,6 +5478,15 @@ dependencies = [ + "winapi-util", + ] + ++[[package]] ++name = "schannel" ++version = "0.1.27" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" ++dependencies = [ ++ "windows-sys 0.59.0", ++] ++ + [[package]] + name = "schemars" + version = "0.8.21" +@@ -5474,6 +5576,29 @@ dependencies = [ + "zbus", + ] + ++[[package]] ++name = "security-framework" ++version = "2.11.1" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" ++dependencies = [ ++ "bitflags 2.6.0", ++ "core-foundation 0.9.4", ++ "core-foundation-sys", ++ "libc", ++ "security-framework-sys", ++] ++ ++[[package]] ++name = "security-framework-sys" ++version = "2.14.0" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" ++dependencies = [ ++ "core-foundation-sys", ++ "libc", ++] ++ + [[package]] + name = "selectors" + version = "0.22.0" +@@ -5947,7 +6072,7 @@ dependencies = [ + "bytemuck", + "cfg_aliases", + "core-graphics 0.24.0", +- "foreign-types", ++ "foreign-types 0.5.0", + "js-sys", + "log", + "objc2", +@@ -6786,6 +6911,16 @@ dependencies = [ + "syn 2.0.87", + ] + ++[[package]] ++name = "tokio-native-tls" ++version = "0.3.1" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" ++dependencies = [ ++ "native-tls", ++ "tokio", ++] ++ + [[package]] + name = "tokio-rustls" + version = "0.26.0" +@@ -7395,6 +7530,12 @@ version = "0.1.0" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + ++[[package]] ++name = "vcpkg" ++version = "0.2.15" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" ++ + [[package]] + name = "version-compare" + version = "0.2.0" +diff --git a/rust/gui-client/src-tauri/Cargo.toml b/rust/gui-client/src-tauri/Cargo.toml +index 32ca56197..f0475e6bf 100644 +--- a/rust/gui-client/src-tauri/Cargo.toml ++++ b/rust/gui-client/src-tauri/Cargo.toml +@@ -25,6 +25,7 @@ firezone-headless-client = { workspace = true } + firezone-logging = { workspace = true } + firezone-telemetry = { workspace = true } + futures = { workspace = true } ++hyper-tls = "0.6.0" + native-dialog = { workspace = true } + rand = { workspace = true } + rustls = { workspace = true } diff --git a/pkgs/firezone-gui-client/package.nix b/pkgs/firezone-gui-client/package.nix new file mode 100644 index 0000000..975bbcd --- /dev/null +++ b/pkgs/firezone-gui-client/package.nix @@ -0,0 +1,153 @@ +{ + lib, + rustPlatform, + fetchFromGitHub, + nix-update-script, + pkg-config, + dbus, + openssl, + zenity, + cargo-tauri, + gdk-pixbuf, + glib, + gobject-introspection, + gtk3, + kdialog, + libsoup_3, + libayatana-appindicator, + webkitgtk_4_1, + wrapGAppsHook3, + stdenvNoCC, + git, + pnpm_9, + nodejs, +}: +let + version = "1.4.0"; + src = fetchFromGitHub { + owner = "firezone"; + repo = "firezone"; + tag = "gui-client-${version}"; + hash = "sha256-gwlkHTFVd1gHwOOIar+5+LEP2ovoyEIMmLfPxYb/OCs="; + # FIXME: remove once https://github.com/firezone/firezone/pull/7808 is released + # FIXME: somehow still required... + postFetch = '' + ${lib.getExe git} -C $out apply ${./0000-add-hyper-tls-dependency.patch} + ''; + }; + + frontend = stdenvNoCC.mkDerivation rec { + pname = "firezone-gui-client-frontend"; + inherit version src; + + pnpmDeps = pnpm_9.fetchDeps { + inherit pname version; + src = "${src}/rust/gui-client"; + hash = "sha256-Gc+X4mbpHa8b/Ol6Fee7VFpTPG25LksoAEjFww1WH5I="; + }; + pnpmRoot = "rust/gui-client"; + + nativeBuildInputs = [ + pnpm_9.configHook + nodejs + ]; + + buildPhase = '' + runHook preBuild + + cd $pnpmRoot + cp node_modules/flowbite/dist/flowbite.min.js src/ + pnpm tailwindcss -i src/input.css -o src/output.css + node --max_old_space_size=1024000 ./node_modules/vite/bin/vite.js build + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + cp -r dist $out + + runHook postInstall + ''; + }; +in +rustPlatform.buildRustPackage rec { + pname = "firezone-gui-client"; + inherit version src; + + useFetchCargoVendor = true; + cargoHash = "sha256-eqkYwP14kca7Q/P9wc+CvTBmKETTmbd06EBNx3MKLro="; + sourceRoot = "${src.name}/rust"; + buildAndTestSubdir = "gui-client"; + + nativeBuildInputs = [ + cargo-tauri.hook + + pkg-config + wrapGAppsHook3 + ]; + + buildInputs = [ + openssl + dbus + gdk-pixbuf + glib + gobject-introspection + gtk3 + libsoup_3 + + libayatana-appindicator + webkitgtk_4_1 + ]; + + # Required to remove profiling arguments which conflict with this builder + postPatch = '' + rm .cargo/config.toml + ln -s ${frontend} gui-client/dist + ''; + + # Required to run tests + preCheck = '' + export XDG_RUNTIME_DIR=$(mktemp -d) + ''; + + checkFlags = [ + # Requires network access + "--skip=notifiers" + ]; + + preFixup = '' + gappsWrapperArgs+=( + # Otherwise blank screen, see https://github.com/tauri-apps/tauri/issues/9304 + --set WEBKIT_DISABLE_DMABUF_RENDERER 1 + --prefix PATH ":" ${ + lib.makeBinPath [ + zenity + kdialog + ] + } + --prefix LD_LIBRARY_PATH ":" ${ + lib.makeLibraryPath [ + libayatana-appindicator + ] + } + ) + ''; + + passthru = { + inherit frontend; + updateScript = nix-update-script { }; + }; + + meta = { + description = "GUI client for the Firezone zero-trust access platform"; + homepage = "https://github.com/firezone/firezone"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ + oddlama + patrickdag + ]; + mainProgram = "firezone-gui-client"; + }; +} diff --git a/pkgs/firezone-headless-client/package.nix b/pkgs/firezone-headless-client/package.nix new file mode 100644 index 0000000..0ab970a --- /dev/null +++ b/pkgs/firezone-headless-client/package.nix @@ -0,0 +1,44 @@ +{ + lib, + rustPlatform, + fetchFromGitHub, + nix-update-script, +}: +rustPlatform.buildRustPackage rec { + pname = "firezone-headless-client"; + version = "1.4.0"; + src = fetchFromGitHub { + owner = "oddlama"; + repo = "firezone"; + rev = "feat/configurable-gateway-interface"; + hash = "sha256-dsGQubRs/ZHdAd6MHpa+3K4vGm4OnCdf1yMlGG1AIJk="; + }; + + useFetchCargoVendor = true; + cargoHash = "sha256-odrexu5mBGmvHNF4cUu9PDIEdxZC451lWV7dsLYT/Sg="; + sourceRoot = "${src.name}/rust"; + buildAndTestSubdir = "headless-client"; + + # Required to remove profiling arguments which conflict with this builder + postPatch = '' + rm .cargo/config.toml + ''; + + # Required to run tests + preCheck = '' + export XDG_RUNTIME_DIR=$(mktemp -d) + ''; + + passthru.updateScript = nix-update-script { }; + + meta = { + description = "CLI client for the Firezone zero-trust access platform"; + homepage = "https://github.com/firezone/firezone"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ + oddlama + patrickdag + ]; + mainProgram = "firezone-headless-client"; + }; +} diff --git a/pkgs/firezone-relay/package.nix b/pkgs/firezone-relay/package.nix new file mode 100644 index 0000000..ee341ad --- /dev/null +++ b/pkgs/firezone-relay/package.nix @@ -0,0 +1,39 @@ +{ + lib, + rustPlatform, + fetchFromGitHub, + nix-update-script, +}: +rustPlatform.buildRustPackage rec { + pname = "firezone-relay"; + version = "unstable-2025-01-19"; + src = fetchFromGitHub { + owner = "firezone"; + repo = "firezone"; + rev = "8c9427b7b133e5050be34c2ac0e831c12c08f02c"; + hash = "sha256-yccplADHRJQQiKrmHcJ5rvouswHrbx4K6ysnIAoZJR0="; + }; + + useFetchCargoVendor = true; + cargoHash = "sha256-WpJL5ALFMvyYv3QI5gMazAj6BVr4oyGq+zOo40rxqOE="; + sourceRoot = "${src.name}/rust"; + buildAndTestSubdir = "relay"; + + # Required to remove profiling arguments which conflict with this builder + postPatch = '' + rm .cargo/config.toml + ''; + + passthru.updateScript = nix-update-script { }; + + meta = { + description = "STUN/TURN server for the Firezone zero-trust access platform"; + homepage = "https://github.com/firezone/firezone"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ + oddlama + patrickdag + ]; + mainProgram = "firezone-relay"; + }; +} diff --git a/pkgs/firezone-server-domain/0000-add-healthz-port.patch b/pkgs/firezone-server-domain/0000-add-healthz-port.patch new file mode 100644 index 0000000..dc95561 --- /dev/null +++ b/pkgs/firezone-server-domain/0000-add-healthz-port.patch @@ -0,0 +1,60 @@ +diff --git a/apps/domain/lib/domain/config/definitions.ex b/apps/domain/lib/domain/config/definitions.ex +index 8cd2e8d0f..de55c8e8f 100644 +--- a/apps/domain/lib/domain/config/definitions.ex ++++ b/apps/domain/lib/domain/config/definitions.ex +@@ -120,6 +120,7 @@ defmodule Domain.Config.Definitions do + ]}, + {"Instrumentation", + [ ++ :healthz_port, + :instrumentation_client_logs_enabled, + :instrumentation_client_logs_bucket, + :telemetry_metrics_reporter, +@@ -474,6 +475,19 @@ defmodule Domain.Config.Definitions do + ## Telemetry + ############################################## + ++ @doc """ ++ The port for the internal healthz endpoint. ++ """ ++ defconfig(:healthz_port, :integer, ++ default: 4000, ++ changeset: fn changeset, key -> ++ Ecto.Changeset.validate_number(changeset, key, ++ greater_than: 0, ++ less_than_or_equal_to: 65_535 ++ ) ++ end ++ ) ++ + @doc """ + Enable or disable the Firezone telemetry collection. + +diff --git a/apps/domain/lib/domain/telemetry.ex b/apps/domain/lib/domain/telemetry.ex +index af430358d..d154282b4 100644 +--- a/apps/domain/lib/domain/telemetry.ex ++++ b/apps/domain/lib/domain/telemetry.ex +@@ -13,7 +13,7 @@ defmodule Domain.Telemetry do + + children = [ + # We start a /healthz endpoint that is used for liveness probes +- {Bandit, plug: Telemetry.HealthzPlug, scheme: :http, port: 4000}, ++ {Bandit, plug: Telemetry.HealthzPlug, scheme: :http, port: Keyword.get(config, :healthz_port)}, + + # Telemetry poller will execute the given period measurements + # every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics +diff --git a/config/runtime.exs b/config/runtime.exs +index 7817942fa..c6dfe9c31 100644 +--- a/config/runtime.exs ++++ b/config/runtime.exs +@@ -211,7 +211,9 @@ if config_env() == :prod do + otlp_endpoint: System.get_env("OTLP_ENDPOINT") + end + +- config :domain, Domain.Telemetry, metrics_reporter: compile_config!(:telemetry_metrics_reporter) ++ config :domain, Domain.Telemetry, ++ healthz_port: compile_config!(:healthz_port), ++ metrics_reporter: compile_config!(:telemetry_metrics_reporter) + + if telemetry_metrics_reporter = compile_config!(:telemetry_metrics_reporter) do + config :domain, telemetry_metrics_reporter, compile_config!(:telemetry_metrics_reporter_opts) diff --git a/pkgs/firezone-server-domain/0001-postgres-socket.patch b/pkgs/firezone-server-domain/0001-postgres-socket.patch new file mode 100644 index 0000000..9e8f0f4 --- /dev/null +++ b/pkgs/firezone-server-domain/0001-postgres-socket.patch @@ -0,0 +1,100 @@ +diff --git a/apps/domain/lib/domain/config.ex b/apps/domain/lib/domain/config.ex +index 11fdcc3a1..9254f210d 100644 +--- a/apps/domain/lib/domain/config.ex ++++ b/apps/domain/lib/domain/config.ex +@@ -42,6 +42,24 @@ defmodule Domain.Config do + end + end + ++ @doc """ ++ Similar to `compile_config/2` but returns nil if the configuration is invalid. ++ ++ This function does not resolve values from the database because it's intended use is during ++ compilation and before application boot (in `config/runtime.exs`). ++ ++ If you need to resolve values from the database, use `fetch_config/1` or `fetch_config!/1`. ++ """ ++ def compile_config(module \\ Definitions, key, env_config \\ System.get_env()) do ++ case Fetcher.fetch_source_and_config(module, key, %{}, env_config) do ++ {:ok, _source, value} -> ++ value ++ ++ {:error, reason} -> ++ nil ++ end ++ end ++ + def config_changeset(changeset, schema_key, config_key \\ nil) do + config_key = config_key || schema_key + +diff --git a/apps/domain/lib/domain/config/definitions.ex b/apps/domain/lib/domain/config/definitions.ex +index 8cd2e8d0f..f27d67c69 100644 +--- a/apps/domain/lib/domain/config/definitions.ex ++++ b/apps/domain/lib/domain/config/definitions.ex +@@ -61,6 +61,7 @@ defmodule Domain.Config.Definitions do + {"Database", + [ + :database_host, ++ :database_socket_dir, + :database_port, + :database_name, + :database_user, +@@ -255,6 +256,11 @@ defmodule Domain.Config.Definitions do + """ + defconfig(:database_host, :string, default: "postgres") + ++ @doc """ ++ PostgreSQL socket directory (takes precedence over hostname). ++ """ ++ defconfig(:database_socket_dir, :string, default: nil) ++ + @doc """ + PostgreSQL port. + """ +diff --git a/config/runtime.exs b/config/runtime.exs +index 7817942fa..14cbe182f 100644 +--- a/config/runtime.exs ++++ b/config/runtime.exs +@@ -1,22 +1,31 @@ + import Config + + if config_env() == :prod do +- import Domain.Config, only: [compile_config!: 1] ++ import Domain.Config, only: [compile_config!: 1, compile_config: 1] + + ############################### + ##### Domain ################## + ############################### + +- config :domain, Domain.Repo, +- database: compile_config!(:database_name), +- username: compile_config!(:database_user), +- hostname: compile_config!(:database_host), +- port: compile_config!(:database_port), +- password: compile_config!(:database_password), +- pool_size: compile_config!(:database_pool_size), +- ssl: compile_config!(:database_ssl_enabled), +- ssl_opts: compile_config!(:database_ssl_opts), +- parameters: compile_config!(:database_parameters) ++ config :domain, ++ Domain.Repo, ++ [ ++ {:database, compile_config!(:database_name)}, ++ {:username, compile_config!(:database_user)}, ++ {:port, compile_config!(:database_port)}, ++ {:pool_size, compile_config!(:database_pool_size)}, ++ {:ssl, compile_config!(:database_ssl_enabled)}, ++ {:ssl_opts, compile_config!(:database_ssl_opts)}, ++ {:parameters, compile_config!(:database_parameters)} ++ ] ++ ++ if(compile_config(:database_password), ++ do: [{:password, compile_config!(:database_password)}], ++ else: [] ++ ) ++ ++ if(compile_config(:database_socket_dir), ++ do: [{:socket_dir, compile_config!(:database_socket_dir)}], ++ else: [{:hostname, compile_config!(:database_host)}] ++ ) + + config :domain, Domain.Tokens, + key_base: compile_config!(:tokens_key_base), diff --git a/pkgs/firezone-server-domain/a.patch b/pkgs/firezone-server-domain/0002-add-mua.patch similarity index 58% rename from pkgs/firezone-server-domain/a.patch rename to pkgs/firezone-server-domain/0002-add-mua.patch index 5070baf..458caf9 100644 --- a/pkgs/firezone-server-domain/a.patch +++ b/pkgs/firezone-server-domain/0002-add-mua.patch @@ -1,28 +1,8 @@ diff --git a/apps/domain/lib/domain/config/definitions.ex b/apps/domain/lib/domain/config/definitions.ex -index 8cd2e8d0f..92e18b10b 100644 +index 8cd2e8d0f..2e6ca054b 100644 --- a/apps/domain/lib/domain/config/definitions.ex +++ b/apps/domain/lib/domain/config/definitions.ex -@@ -61,6 +61,7 @@ defmodule Domain.Config.Definitions do - {"Database", - [ - :database_host, -+ :database_socket_dir, - :database_port, - :database_name, - :database_user, -@@ -255,6 +256,11 @@ defmodule Domain.Config.Definitions do - """ - defconfig(:database_host, :string, default: "postgres") - -+ @doc """ -+ PostgreSQL socket directory (takes precedence over hostname). -+ """ -+ defconfig(:database_socket_dir, :string, default: nil) -+ - @doc """ - PostgreSQL port. - """ -@@ -584,6 +590,7 @@ defmodule Domain.Config.Definitions do +@@ -584,6 +584,7 @@ defmodule Domain.Config.Definitions do Swoosh.Adapters.Mailgun, Swoosh.Adapters.Mailjet, Swoosh.Adapters.Mandrill, @@ -30,21 +10,8 @@ index 8cd2e8d0f..92e18b10b 100644 Swoosh.Adapters.Postmark, Swoosh.Adapters.ProtonBridge, Swoosh.Adapters.SMTP, -diff --git a/apps/domain/lib/domain/telemetry.ex b/apps/domain/lib/domain/telemetry.ex -index af430358d..a544e706e 100644 ---- a/apps/domain/lib/domain/telemetry.ex -+++ b/apps/domain/lib/domain/telemetry.ex -@@ -13,7 +13,7 @@ defmodule Domain.Telemetry do - - children = [ - # We start a /healthz endpoint that is used for liveness probes -- {Bandit, plug: Telemetry.HealthzPlug, scheme: :http, port: 4000}, -+ {Bandit, plug: Telemetry.HealthzPlug, scheme: :http, port: System.get_env("HEALTHZ_PORT") |> String.to_integer()}, - - # Telemetry poller will execute the given period measurements - # every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics diff --git a/apps/web/lib/web/live/sign_up.ex b/apps/web/lib/web/live/sign_up.ex -index c4e06bc58..89533fb81 100644 +index dfbc94d9b..638e3b373 100644 --- a/apps/web/lib/web/live/sign_up.ex +++ b/apps/web/lib/web/live/sign_up.ex @@ -1,5 +1,6 @@ @@ -54,65 +21,44 @@ index c4e06bc58..89533fb81 100644 alias Domain.{Auth, Accounts, Actors, Config} alias Web.Registration -@@ -358,7 +359,8 @@ defmodule Web.SignUp do +@@ -358,7 +359,9 @@ defmodule Web.SignUp do {:noreply, assign(socket, form: to_form(changeset))} - {:error, :send_email, _reason, _effects_so_far} -> + {:error, :send_email, reason, _effects_so_far} -> -+ Logger.info("failed to send email", reason: inspect(reason)) ++ Logger.warning("Failed to send sign_up email", reason: inspect(reason)) ++ changeset = Ecto.Changeset.add_error( changeset, diff --git a/config/runtime.exs b/config/runtime.exs -index 15037e0a3..475c4ddfb 100644 +index 7817942fa..8704ccde5 100644 --- a/config/runtime.exs +++ b/config/runtime.exs -@@ -8,15 +8,17 @@ if config_env() == :prod do - ############################### - - config :domain, Domain.Repo, -- database: compile_config!(:database_name), -- username: compile_config!(:database_user), -- hostname: compile_config!(:database_host), -- port: compile_config!(:database_port), -- password: compile_config!(:database_password), -- pool_size: compile_config!(:database_pool_size), -- ssl: compile_config!(:database_ssl_enabled), -- ssl_opts: compile_config!(:database_ssl_opts), -- parameters: compile_config!(:database_parameters) -+ [ -+ {:database, compile_config!(:database_name)}, -+ {:username, compile_config!(:database_user)}, -+ {:port, compile_config!(:database_port)}, -+ {:pool_size, compile_config!(:database_pool_size)}, -+ {:ssl, compile_config!(:database_ssl_enabled)}, -+ {:ssl_opts, compile_config!(:database_ssl_opts)}, -+ {:parameters, compile_config!(:database_parameters)} -+ ] -+ ++ (if System.get_env("DATABASE_PASSWORD"), do: [{:password, compile_config!(:database_password)}], else: []) -+ ++ (if System.get_env("DATABASE_SOCKET_DIR"), do: [{:socket_dir, compile_config!(:database_socket_dir)}], else: [{:hostname, compile_config!(:database_host)}]) - - config :domain, Domain.Tokens, - key_base: compile_config!(:tokens_key_base), -@@ -226,8 +228,15 @@ if config_env() == :prod do - config :domain, - Domain.Mailer, +@@ -228,7 +228,21 @@ if config_env() == :prod do [ -- adapter: compile_config!(:outbound_email_adapter), -- from_email: compile_config!(:outbound_email_from) -+ adapter: compile_config!(:outbound_email_adapter), -+ from_email: compile_config!(:outbound_email_from), -+ protocol: String.to_atom(System.get_env("OUTBOUND_EMAIL_SMTP_PROTOCOL")), -+ relay: System.get_env("OUTBOUND_EMAIL_SMTP_HOST"), -+ port: String.to_integer(System.get_env("OUTBOUND_EMAIL_SMTP_PORT")), -+ auth: [ -+ username: System.get_env("OUTBOUND_EMAIL_SMTP_USERNAME"), -+ password: System.get_env("OUTBOUND_EMAIL_SMTP_PASSWORD") -+ ] - ] ++ compile_config!(:outbound_email_adapter_opts) + adapter: compile_config!(:outbound_email_adapter), + from_email: compile_config!(:outbound_email_from) +- ] ++ compile_config!(:outbound_email_adapter_opts) ++ ] ++ ++ (if System.get_env("OUTBOUND_EMAIL_ADAPTER") == "Elixir.Swoosh.Adapters.Mua" do ++ [ ++ protocol: String.to_atom(System.get_env("OUTBOUND_EMAIL_SMTP_PROTOCOL")), ++ relay: System.get_env("OUTBOUND_EMAIL_SMTP_HOST"), ++ port: String.to_integer(System.get_env("OUTBOUND_EMAIL_SMTP_PORT")), ++ auth: [ ++ username: System.get_env("OUTBOUND_EMAIL_SMTP_USERNAME"), ++ password: System.get_env("OUTBOUND_EMAIL_SMTP_PASSWORD") ++ ] ++ ] ++ else ++ [] ++ end) ++ ++ compile_config!(:outbound_email_adapter_opts) config :workos, WorkOS.Client, + api_key: compile_config!(:workos_api_key), diff --git a/mix.exs b/mix.exs index 12782d631..dee1245d2 100644 --- a/mix.exs @@ -129,7 +75,7 @@ index 12782d631..dee1245d2 100644 end diff --git a/mix.lock b/mix.lock -index 8c4b65959..3d2f9faca 100644 +index 757829003..47775677d 100644 --- a/mix.lock +++ b/mix.lock @@ -50,11 +50,13 @@ diff --git a/pkgs/firezone-server-domain/generic.nix b/pkgs/firezone-server-domain/generic.nix index 15c81d5..7987334 100644 --- a/pkgs/firezone-server-domain/generic.nix +++ b/pkgs/firezone-server-domain/generic.nix @@ -24,7 +24,11 @@ beamPackages.mixRelease rec { hash = "sha256-yccplADHRJQQiKrmHcJ5rvouswHrbx4K6ysnIAoZJR0="; } }/elixir"; - patches = [ ./a.patch ]; + patches = [ + ./0000-add-healthz-port.patch + ./0001-postgres-socket.patch + ./0002-add-mua.patch + ]; pnpmDeps = pnpm_9.fetchDeps { inherit pname version;