about summary refs log tree commit diff
path: root/nixos/modules/services/networking/netbird.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/networking/netbird.nix')
-rw-r--r--nixos/modules/services/networking/netbird.nix203
1 files changed, 157 insertions, 46 deletions
diff --git a/nixos/modules/services/networking/netbird.nix b/nixos/modules/services/networking/netbird.nix
index 4b0bd63e9dbc..6a1511d4d084 100644
--- a/nixos/modules/services/networking/netbird.nix
+++ b/nixos/modules/services/networking/netbird.nix
@@ -1,60 +1,171 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
 
 let
-  cfg = config.services.netbird;
+  inherit (lib)
+    attrNames
+    getExe
+    literalExpression
+    maintainers
+    mapAttrs'
+    mkDefault
+    mkEnableOption
+    mkIf
+    mkMerge
+    mkOption
+    mkPackageOption
+    nameValuePair
+    optional
+    versionOlder
+    ;
+
+  inherit (lib.types)
+    attrsOf
+    port
+    str
+    submodule
+    ;
+
   kernel = config.boot.kernelPackages;
-  interfaceName = "wt0";
-in {
-  meta.maintainers = with maintainers; [ misuzu ];
+
+  cfg = config.services.netbird;
+in
+{
+  meta.maintainers = with maintainers; [
+    misuzu
+    thubrecht
+  ];
+  meta.doc = ./netbird.md;
 
   options.services.netbird = {
     enable = mkEnableOption (lib.mdDoc "Netbird daemon");
     package = mkPackageOption pkgs "netbird" { };
-  };
-
-  config = mkIf cfg.enable {
-    boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
 
-    environment.systemPackages = [ cfg.package ];
+    tunnels = mkOption {
+      type = attrsOf (
+        submodule (
+          { name, config, ... }:
+          {
+            options = {
+              port = mkOption {
+                type = port;
+                default = 51820;
+                description = ''
+                  Port for the ${name} netbird interface.
+                '';
+              };
 
-    networking.dhcpcd.denyInterfaces = [ interfaceName ];
+              environment = mkOption {
+                type = attrsOf str;
+                defaultText = literalExpression ''
+                  {
+                    NB_CONFIG = "/var/lib/''${stateDir}/config.json";
+                    NB_LOG_FILE = "console";
+                    NB_WIREGUARD_PORT = builtins.toString port;
+                    NB_INTERFACE_NAME = name;
+                    NB_DAMEON_ADDR = "/var/run/''${stateDir}"
+                  }
+                '';
+                description = ''
+                  Environment for the netbird service, used to pass configuration options.
+                '';
+              };
 
-    systemd.network.networks."50-netbird" = mkIf config.networking.useNetworkd {
-      matchConfig = {
-        Name = interfaceName;
-      };
-      linkConfig = {
-        Unmanaged = true;
-        ActivationPolicy = "manual";
-      };
-    };
+              stateDir = mkOption {
+                type = str;
+                default = "netbird-${name}";
+                description = ''
+                  Directory storing the netbird configuration.
+                '';
+              };
+            };
 
-    systemd.services.netbird = {
-      description = "A WireGuard-based mesh network that connects your devices into a single private network";
-      documentation = [ "https://netbird.io/docs/" ];
-      after = [ "network.target" ];
-      wantedBy = [ "multi-user.target" ];
-      path = with pkgs; [
-        openresolv
-      ];
-      serviceConfig = {
-        Environment = [
-          "NB_CONFIG=/var/lib/netbird/config.json"
-          "NB_LOG_FILE=console"
-        ];
-        ExecStart = "${cfg.package}/bin/netbird service run";
-        Restart = "always";
-        RuntimeDirectory = "netbird";
-        StateDirectory = "netbird";
-        WorkingDirectory = "/var/lib/netbird";
-      };
-      unitConfig = {
-        StartLimitInterval = 5;
-        StartLimitBurst = 10;
-      };
-      stopIfChanged = false;
+            config.environment = builtins.mapAttrs (_: mkDefault) {
+              NB_CONFIG = "/var/lib/${config.stateDir}/config.json";
+              NB_LOG_FILE = "console";
+              NB_WIREGUARD_PORT = builtins.toString config.port;
+              NB_INTERFACE_NAME = name;
+              NB_DAEMON_ADDR = "unix:///var/run/${config.stateDir}/sock";
+            };
+          }
+        )
+      );
+      default = { };
+      description = ''
+        Attribute set of Netbird tunnels, each one will spawn a daemon listening on ...
+      '';
     };
   };
+
+  config = mkMerge [
+    (mkIf cfg.enable {
+      # For backwards compatibility
+      services.netbird.tunnels.wt0.stateDir = "netbird";
+    })
+
+    (mkIf (cfg.tunnels != { }) {
+      boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
+
+      environment.systemPackages = [ cfg.package ];
+
+      networking.dhcpcd.denyInterfaces = attrNames cfg.tunnels;
+
+      systemd.network.networks = mkIf config.networking.useNetworkd (
+        mapAttrs'
+          (
+            name: _:
+            nameValuePair "50-netbird-${name}" {
+              matchConfig = {
+                Name = name;
+              };
+              linkConfig = {
+                Unmanaged = true;
+                ActivationPolicy = "manual";
+              };
+            }
+          )
+          cfg.tunnels
+      );
+
+      systemd.services =
+        mapAttrs'
+          (
+            name:
+            { environment, stateDir, ... }:
+            nameValuePair "netbird-${name}" {
+              description = "A WireGuard-based mesh network that connects your devices into a single private network";
+
+              documentation = [ "https://netbird.io/docs/" ];
+
+              after = [ "network.target" ];
+              wantedBy = [ "multi-user.target" ];
+
+              path = with pkgs; [ openresolv ];
+
+              inherit environment;
+
+              serviceConfig = {
+                ExecStart = "${getExe cfg.package} service run";
+                Restart = "always";
+                RuntimeDirectory = stateDir;
+                StateDirectory = stateDir;
+                StateDirectoryMode = "0700";
+                WorkingDirectory = "/var/lib/${stateDir}";
+              };
+
+              unitConfig = {
+                StartLimitInterval = 5;
+                StartLimitBurst = 10;
+              };
+
+              stopIfChanged = false;
+            }
+          )
+          cfg.tunnels;
+    })
+  ];
 }