From 8b5c57b6742aa16fdb7337715e32cb35018ae95b Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Thu, 7 Aug 2025 10:02:38 +0200 Subject: [PATCH] nixos/netbird: add `useRoutingFeatures` option Similar to what the NixOS Tailscale service has. Hope this will help a bunch of users struggling to make the "exit node" feature working. --- nixos/modules/services/networking/netbird.md | 5 ++ nixos/modules/services/networking/netbird.nix | 53 ++++++++++++++----- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/nixos/modules/services/networking/netbird.md b/nixos/modules/services/networking/netbird.md index 37e104795237..a1aab94473a3 100644 --- a/nixos/modules/services/networking/netbird.md +++ b/nixos/modules/services/networking/netbird.md @@ -76,6 +76,11 @@ Each Netbird client service by default: peer-to-peer communication, - can be additionally configured with environment variables, - automatically determines whether `netbird-ui-` should be available, +- does not enable [routing features](#opt-services.netbird.useRoutingFeatures) by default + If you plan to use routing features, you must explicitly enable them. By enabling them, the service will + configure the firewall and enable IP forwarding on the system. + When set to `client` or `both`, reverse path filtering will be set to loose instead of strict. + When set to `server` or `both`, IP forwarding will be enabled. [autoStart](#opt-services.netbird.clients._name_.autoStart) allows you to start the client (an actual systemd service) on demand, for example to connect to work-related or otherwise conflicting network only when required. diff --git a/nixos/modules/services/networking/netbird.nix b/nixos/modules/services/networking/netbird.nix index 2d0f363e13ee..a5a89296621d 100644 --- a/nixos/modules/services/networking/netbird.nix +++ b/nixos/modules/services/networking/netbird.nix @@ -24,6 +24,7 @@ let mkMerge mkOption mkOptionDefault + mkOverride mkPackageOption nameValuePair optional @@ -112,6 +113,23 @@ in }; ui.package = mkPackageOption pkgs "netbird-ui" { }; + useRoutingFeatures = mkOption { + type = enum [ + "none" + "client" + "server" + "both" + ]; + default = "none"; + example = "server"; + description = '' + Enables settings required for Netbird's routing features like subnet routers and exit nodes. + + When set to `client` or `both`, reverse path filtering will be set to loose instead of strict. + When set to `server` or `both`, IP forwarding will be enabled. + ''; + }; + clients = mkOption { type = attrsOf ( submodule ( @@ -467,19 +485,30 @@ in networking.dhcpcd.denyInterfaces = toClientList (client: client.interface); networking.networkmanager.unmanaged = toClientList (client: "interface-name:${client.interface}"); - networking.firewall.allowedUDPPorts = concatLists ( - toClientList (client: optional client.openFirewall client.port) - ); + # Required for the routing ("Exit node") feature(s) to work + boot.kernel.sysctl = mkIf (cfg.useRoutingFeatures == "server" || cfg.useRoutingFeatures == "both") { + "net.ipv4.conf.all.forwarding" = mkOverride 97 true; + "net.ipv6.conf.all.forwarding" = mkOverride 97 true; + }; - # Ports opened on a specific - networking.firewall.interfaces = listToAttrs ( - toClientList (client: { - name = client.interface; - value.allowedUDPPorts = optionals client.openFirewall [ - 5353 # required for the DNS forwarding/routing to work - ]; - }) - ); + networking.firewall = { + allowedUDPPorts = concatLists (toClientList (client: optional client.openFirewall client.port)); + + # Required for the routing ("Exit node") feature(s) to work + checkReversePath = mkIf ( + cfg.useRoutingFeatures == "client" || cfg.useRoutingFeatures == "both" + ) "loose"; + + # Ports opened on a specific + interfaces = listToAttrs ( + toClientList (client: { + name = client.interface; + value.allowedUDPPorts = optionals client.openFirewall [ + 5353 # required for the DNS forwarding/routing to work + ]; + }) + ); + }; systemd.network.networks = mkIf config.networking.useNetworkd ( toClientAttrs (