diff --git a/nix/module.nix b/nix/module.nix index 43c2924..8a21960 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -33,7 +33,17 @@ in { uid:1001 ''' ''; - description = "Path to the ignore list for users that should be hidden from rwhod."; + description = '' + List of users/UIDs to ignore from the local machine both when + broadcasting packets and when responding to local rwho/ruptime requests. + + If set to `null`, rwhod will not ignore any users, and will serve all users on the system. + + ::: {.note} + This option is also available as `services.roowho2.settings.rwhod.ignoreUsers`, + which is a more convenient way to specify the ignore list from within a NixOS module. + ::: + ''; }; interfaces = lib.mkOption { @@ -51,6 +61,18 @@ in { ''; }; + ignoreUsers = lib.mkOption { + type = with lib.types; listOf (either str ints.unsigned); + default = [ ]; + example = [ "user1" 1002 ]; + description = '' + List of users/UIDs to ignore from the local machine both when + broadcasting packets and when responding to local rwho/ruptime requests. + + If left empty, rwhod will not ignore any users, and will serve all users on the system. + ''; + }; + socketConfig = lib.mkOption { type = utils.systemdUtils.unitOptions.unitOption; default = { }; @@ -84,7 +106,29 @@ in { uid:1001 ''' ''; - description = "Path to the ignore list for users that should be hidden from fingerd."; + description = '' + List of users/UIDs to ignore from the local machine when responding to + local or remote finger requests. + + If set to `null`, fingerd will not ignore any users, and will serve all users on the system. + + ::: {.note} + This option is also available as `services.roowho2.settings.fingerd.ignoreUsers`, + which is a more convenient way to specify the ignore list from within a NixOS module. + ::: + ''; + }; + + ignoreUsers = lib.mkOption { + type = with lib.types; listOf (either str ints.unsigned); + default = [ ]; + example = [ "user1" 1002 ]; + description = '' + List of users/UIDs to ignore from the local machine when responding to + local or remote finger requests. + + If left empty, fingerd will not ignore any users, and will serve all users on the system. + ''; }; # enable_remote_finger = lib.mkOption { @@ -126,6 +170,73 @@ in { }; config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = cfg.settings.rwhod.enable || cfg.settings.fingerd.enable; + message = "At least one of `services.roowho2.settings.rwhod.enable` or `services.roowho2.settings.fingerd.enable` must be true."; + } + { + assertion = + cfg.settings.rwhod.ignoreUsers == [ ] + || cfg.settings.rwhod.ignore_list_path == "/etc/roowho2/rwhod-ignore-list"; + message = "Cannot set both `services.roowho2.settings.rwhod.ignoreUsers` and `services.roowho2.settings.rwhod.ignore_list_path`."; + } + { + assertion = + cfg.settings.fingerd.ignoreUsers == [ ] + || cfg.settings.fingerd.ignore_list_path == "/etc/roowho2/fingerd-ignore-list"; + message = "Cannot set both `services.roowho2.settings.fingerd.ignoreUsers` and `services.roowho2.settings.fingerd.ignore_list_path`."; + } + ]; + + services.roowho2.settings = { + rwhod.ignore_list_path = + lib.mkIf + (cfg.settings.rwhod.enable && cfg.settings.rwhod.ignoreUsers != [ ]) + "/etc/roowho2/rwhod-ignore-list"; + fingerd.ignore_list_path = + lib.mkIf + (cfg.settings.fingerd.enable && cfg.settings.fingerd.ignoreUsers != [ ]) + "/etc/roowho2/fingerd-ignore-list"; + }; + + environment.etc = let + generateIgnoreList = let + nameToUidMapping = lib.pipe config.users.users [ + (lib.filterAttrs (_: user: user.uid != null)) + (lib.mapAttrsToList (name: user: { name = name; value = user.uid; })) + lib.listToAttrs + ]; + + uidToNameMapping = lib.pipe config.users.users [ + (lib.filterAttrs (_: user: user.uid != null)) + (lib.mapAttrsToList (name: user: { name = toString user.uid; value = name; })) + lib.listToAttrs + ]; + in users: lib.pipe users [ + # Prefer UIDs for users we know the UID + (map (user: if builtins.isString user + then (nameToUidMapping.${user} or user) + else user)) + + # Then render back to strings + (map (user: + if builtins.isString user + then "user:${user}" + else "uid:${toString user} # ${uidToNameMapping.${toString user} or "unknown"}")) + + (lib.concatStringsSep "\n") + ]; + in { + "roowho2/rwhod-ignore-list" = lib.mkIf (cfg.settings.rwhod.enable && cfg.settings.rwhod.ignoreUsers != [ ]) { + text = generateIgnoreList cfg.settings.rwhod.ignoreUsers; + }; + + "roowho2/fingerd-ignore-list" = lib.mkIf (cfg.settings.fingerd.enable && cfg.settings.fingerd.ignoreUsers != [ ]) { + text = generateIgnoreList cfg.settings.fingerd.ignoreUsers; + }; + }; + systemd.sockets.roowho2-client = { wantedBy = [ "sockets.target" ]; description = "Roowho2 Client Communication Socket"; @@ -163,9 +274,9 @@ in { ExecStart = let configFile = lib.pipe cfg.settings [ (lib.filterAttrsRecursive (n: v: v != null)) - (settings: lib.recursiveUpdate settings { - rwhod = lib.removeAttrs settings.rwhod [ "socketConfig" ]; - fingerd = lib.removeAttrs settings.fingerd [ "socketConfig" ]; + (settings: settings // { + rwhod = lib.removeAttrs settings.rwhod [ "socketConfig" "ignoreUsers" ]; + fingerd = lib.removeAttrs settings.fingerd [ "socketConfig" "ignoreUsers" ]; }) (format.generate "roowho2-config.toml") ]; @@ -173,6 +284,8 @@ in { Restart = "on-failure"; DynamicUser = true; + ConfigurationDirectory = [ "roowho2" ]; + # NOTE: roowho2 might at some point need to read from home directories # to get user settings, so let's keep these disabled for now. # PrivateUsers = true; diff --git a/nix/vm.nix b/nix/vm.nix index aecf309..67d86f7 100644 --- a/nix/vm.nix +++ b/nix/vm.nix @@ -21,9 +21,9 @@ nixpkgs.lib.nixosSystem { virtualisation.graphics = false; virtualisation.memorySize = 256; - virtualisation.vlans = [ 1 ]; users.users.alice.extraGroups = [ "wheel" ]; + users.users.bob.uid = 1001; services.getty.autologinUser = "alice"; @@ -49,6 +49,9 @@ nixpkgs.lib.nixosSystem { services.roowho2 = { enable = true; settings.log_level = "trace"; + settings.fingerd.ignoreUsers = [ + "bob" + ]; }; programs.vim = {