diff options
author | Maximilian Bosch <maximilian@mbosch.me> | 2022-10-06 11:26:13 +0200 |
---|---|---|
committer | Maximilian Bosch <maximilian@mbosch.me> | 2022-10-06 11:43:20 +0200 |
commit | ecaf6aed02da7cc72721567fe85387e4bdd9948d (patch) | |
tree | ab48031dbad7fd4fb5229c7b81b0e6142ec4cdfb /nixos | |
parent | a2d443c7e84c9ea74958bb884f0a17eaebfec920 (diff) |
nixos/privacyidea: add proper support for `privacyidea-token-janitor`
`privacyidea-token-janitor`[1] is a tool which helps to automate
maintenance of tokens. This is helpful to identify e.g. orphaned tokens,
i.e. tokens of users that were removed or tokens that were unused for a
longer period of time and apply actions to them (e.g. `disable` or
`delete`).
This patch adds two new things:
* A wrapper for `privacyidea-token-janitor` to make sure it's executable
from CLI. To achieve this, it does a `sudo(8)` into the
`privacyidea`-user and sets up the environment to make sure the
configuration file can be found. With that, administrators can
directly invoke it from the CLI without additional steps.
* An optional service is added which performs automatic cleanups of
orphaned and/or unassigned tokens. Yes, the tool can do way more
stuff, but I figured it's reasonable to have an automatic way to clean
up tokens of users who were removed from the PI instance. Additional
automation steps should probably be implemented in additional
services (and are perhaps too custom to add them to this module).
[1] https://privacyidea.readthedocs.io/en/v3.7/workflows_and_tools/tools/index.html
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/services/security/privacyidea.nix | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/nixos/modules/services/security/privacyidea.nix b/nixos/modules/services/security/privacyidea.nix index 5cd338ebf7fe..f8f97a88d2fc 100644 --- a/nixos/modules/services/security/privacyidea.nix +++ b/nixos/modules/services/security/privacyidea.nix @@ -61,6 +61,12 @@ let (flip mapAttrs cfg.ldap-proxy.settings (const (mapAttrs (const renderValue))))); + privacyidea-token-janitor = pkgs.writeShellScriptBin "privacyidea-token-janitor" '' + exec -a privacyidea-token-janitor \ + /run/wrappers/bin/sudo -u ${cfg.user} \ + env PRIVACYIDEA_CONFIGFILE=${cfg.stateDir}/privacyidea.cfg \ + ${penv}/bin/privacyidea-token-janitor $@ + ''; in { @@ -178,6 +184,42 @@ in description = lib.mdDoc "Group account under which PrivacyIDEA runs."; }; + tokenjanitor = { + enable = mkEnableOption "automatic runs of the token janitor"; + interval = mkOption { + default = "quarterly"; + type = types.str; + description = lib.mdDoc '' + Interval in which the cleanup program is supposed to run. + See {manpage}`systemd.time(7)` for further information. + ''; + }; + action = mkOption { + type = types.enum [ "delete" "mark" "disable" "unassign" ]; + description = lib.mdDoc '' + Which action to take for matching tokens. + ''; + }; + unassigned = mkOption { + default = false; + type = types.bool; + description = lib.mdDoc '' + Whether to search for **unassigned** tokens + and apply [](#opt-services.privacyidea.tokenjanitor.action) + onto them. + ''; + }; + orphaned = mkOption { + default = true; + type = types.bool; + description = lib.mdDoc '' + Whether to search for **orphaned** tokens + and apply [](#opt-services.privacyidea.tokenjanitor.action) + onto them. + ''; + }; + }; + ldap-proxy = { enable = mkEnableOption (lib.mdDoc "PrivacyIDEA LDAP Proxy"); @@ -228,10 +270,60 @@ in (mkIf cfg.enable { - environment.systemPackages = [ pkgs.privacyidea ]; + assertions = [ + { + assertion = cfg.tokenjanitor.enable -> (cfg.tokenjanitor.orphaned || cfg.tokenjanitor.unassigned); + message = '' + privacyidea-token-janitor has no effect if neither orphaned nor unassigned tokens + are to be searched. + ''; + } + ]; + + environment.systemPackages = [ pkgs.privacyidea (hiPrio privacyidea-token-janitor) ]; services.postgresql.enable = mkDefault true; + systemd.services.privacyidea-tokenjanitor = mkIf cfg.tokenjanitor.enable { + environment.PRIVACYIDEA_CONFIGFILE = "${cfg.stateDir}/privacyidea.cfg"; + path = [ penv ]; + serviceConfig = { + CapabilityBoundingSet = [ "" ]; + ExecStart = "${pkgs.writeShellScript "pi-token-janitor" '' + ${optionalString cfg.tokenjanitor.orphaned '' + echo >&2 "Removing orphaned tokens..." + privacyidea-token-janitor find \ + --orphaned true \ + --action ${cfg.tokenjanitor.action} + ''} + ${optionalString cfg.tokenjanitor.unassigned '' + echo >&2 "Removing unassigned tokens..." + privacyidea-token-janitor find \ + --assigned false \ + --action ${cfg.tokenjanitor.action} + ''} + ''}"; + Group = cfg.group; + LockPersonality = true; + MemoryDenyWriteExecute = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + ReadWritePaths = cfg.stateDir; + Type = "oneshot"; + User = cfg.user; + WorkingDirectory = cfg.stateDir; + }; + }; + systemd.timers.privacyidea-tokenjanitor = mkIf cfg.tokenjanitor.enable { + wantedBy = [ "timers.target" ]; + timerConfig.OnCalendar = cfg.tokenjanitor.interval; + timerConfig.Persistent = true; + }; + systemd.services.privacyidea = let piuwsgi = pkgs.writeText "uwsgi.json" (builtins.toJSON { uwsgi = { |