diff --git a/clanModules/flake-module.nix b/clanModules/flake-module.nix index 819b6f26..f68bc27b 100644 --- a/clanModules/flake-module.nix +++ b/clanModules/flake-module.nix @@ -19,6 +19,7 @@ thelounge = ./thelounge; user-password = ./user-password; xfce = ./xfce; + zerotier-static-peers = ./zerotier-static-peers; zt-tcp-relay = ./zt-tcp-relay; }; } diff --git a/clanModules/zerotier-static-peers/README.md b/clanModules/zerotier-static-peers/README.md new file mode 100644 index 00000000..cf480f41 --- /dev/null +++ b/clanModules/zerotier-static-peers/README.md @@ -0,0 +1,5 @@ +Statically configure the `zerotier` peers of a clan network. +--- +Statically configure the `zerotier` peers of a clan network. + +Requires a machine, that is the zerotier controller configured in the network. diff --git a/clanModules/zerotier-static-peers/default.nix b/clanModules/zerotier-static-peers/default.nix new file mode 100644 index 00000000..31fe7d99 --- /dev/null +++ b/clanModules/zerotier-static-peers/default.nix @@ -0,0 +1,71 @@ +{ + lib, + config, + pkgs, + inputs, + ... +}: +let + clanDir = config.clanCore.clanDir; + machineDir = clanDir + "/machines/"; + machinesFileSet = builtins.readDir machineDir; + machines = lib.mapAttrsToList (name: _: name) machinesFileSet; + + zerotierNetworkIdPath = machines: machineDir + machines + "/facts/zerotier-network-id"; + networkIdsUnchecked = builtins.map ( + machine: + let + fullPath = zerotierNetworkIdPath machine; + in + if builtins.pathExists fullPath then builtins.readFile fullPath else null + ) machines; + networkIds = lib.filter (machine: machine != null) networkIdsUnchecked; + networkId = builtins.elemAt networkIds 0; +in +#TODO:trace on multiple found network-ids +#TODO:trace on no single found networkId +{ + options.clan.zerotier-static-peers = { + excludeHosts = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ config.clanCore.machineName ]; + description = "Hosts that should be excluded"; + }; + }; + + config.systemd.services.zerotier-static-peers-autoaccept = + let + machines = builtins.readDir machineDir; + zerotierIpMachinePath = machines: machineDir + machines + "/facts/zerotier-ip"; + filteredMachines = lib.filterAttrs ( + name: _: !(lib.elem name config.clan.static-hosts.excludeHosts) + ) machines; + hosts = lib.mapAttrsToList (host: _: host) ( + lib.mapAttrs' ( + machine: _: + let + fullPath = zerotierIpMachinePath machine; + in + if builtins.pathExists fullPath then + lib.nameValuePair (builtins.readFile fullPath) [ machine ] + else + null + ) filteredMachines + ); + in + lib.mkIf (config.clan.networking.zerotier.controller.enable) { + wantedBy = [ "multi-user.target" ]; + after = [ "zerotierone.service" ]; + path = [ pkgs.zerotierone ]; + serviceConfig.ExecStart = pkgs.writeScript "static-zerotier-peers-autoaccept" '' + #!/bin/sh + ${lib.concatMapStringsSep "\n" (host: '' + ${ + inputs.clan-core.packages.${pkgs.system}.zerotier-members + }/bin/zerotier-members allow --member-ip ${host} + '') hosts} + ''; + }; + + config.clan.networking.zerotier.networkId = lib.mkDefault networkId; +} diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index afd4587b..58de8222 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -66,6 +66,7 @@ nav: - reference/clanModules/thelounge.md - reference/clanModules/user-password.md - reference/clanModules/xfce.md + - reference/clanModules/zerotier-static-peers.md - reference/clanModules/zt-tcp-relay.md - CLI: - reference/cli/index.md