From 4a4f7dfb77144e9ab594ed9a1a26044031c4d7a9 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 17 Mar 2021 15:40:50 +0100 Subject: [PATCH] nixos/privacyidea: use envsubst to avoid leaking secrets to the store --- .../modules/services/security/privacyidea.nix | 27 ++++++++++++++++++- nixos/tests/privacyidea.nix | 12 +++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/nixos/modules/services/security/privacyidea.nix b/nixos/modules/services/security/privacyidea.nix index c2988858e56..f7b40089a93 100644 --- a/nixos/modules/services/security/privacyidea.nix +++ b/nixos/modules/services/security/privacyidea.nix @@ -57,6 +57,26 @@ in services.privacyidea = { enable = mkEnableOption "PrivacyIDEA"; + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/root/privacyidea.env"; + description = '' + File to load as environment file. Environment variables + from this file will be interpolated into the config file + using envsubst which is helpful for specifying + secrets: + + { = "$SECRET"; } + + + The environment-file can now specify the actual secret key: + + SECRET=veryverytopsecret + + ''; + }; + stateDir = mkOption { type = types.str; default = "/var/lib/privacyidea"; @@ -206,7 +226,7 @@ in wantedBy = [ "multi-user.target" ]; after = [ "postgresql.service" ]; path = with pkgs; [ openssl ]; - environment.PRIVACYIDEA_CONFIGFILE = piCfgFile; + environment.PRIVACYIDEA_CONFIGFILE = "${cfg.stateDir}/privacyidea.cfg"; preStart = let pi-manage = "${pkgs.sudo}/bin/sudo -u privacyidea -HE ${penv}/bin/pi-manage"; pgsu = config.services.postgresql.superUser; @@ -214,6 +234,10 @@ in in '' mkdir -p ${cfg.stateDir} /run/privacyidea chown ${cfg.user}:${cfg.group} -R ${cfg.stateDir} /run/privacyidea + umask 077 + ${lib.getBin pkgs.envsubst}/bin/envsubst -o ${cfg.stateDir}/privacyidea.cfg \ + -i "${piCfgFile}" + chown ${cfg.user}:${cfg.group} ${cfg.stateDir}/privacyidea.cfg if ! test -e "${cfg.stateDir}/db-created"; then ${pkgs.sudo}/bin/sudo -u ${pgsu} ${psql}/bin/createuser --no-superuser --no-createdb --no-createrole ${cfg.user} ${pkgs.sudo}/bin/sudo -u ${pgsu} ${psql}/bin/createdb --owner ${cfg.user} privacyidea @@ -231,6 +255,7 @@ in Type = "notify"; ExecStart = "${uwsgi}/bin/uwsgi --json ${piuwsgi}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID"; NotifyAccess = "main"; KillSignal = "SIGQUIT"; diff --git a/nixos/tests/privacyidea.nix b/nixos/tests/privacyidea.nix index b71ff0a1669..4a94f072794 100644 --- a/nixos/tests/privacyidea.nix +++ b/nixos/tests/privacyidea.nix @@ -12,10 +12,16 @@ import ./make-test-python.nix ({ pkgs, ...} : rec { services.privacyidea = { enable = true; - secretKey = "testing"; - pepper = "testing"; + secretKey = "$SECRET_KEY"; + pepper = "$PEPPER"; adminPasswordFile = pkgs.writeText "admin-password" "testing"; adminEmail = "root@localhost"; + + # Don't try this at home! + environmentFile = pkgs.writeText "pi-secrets.env" '' + SECRET_KEY=testing + PEPPER=testing + ''; }; services.nginx = { enable = true; @@ -29,6 +35,8 @@ import ./make-test-python.nix ({ pkgs, ...} : rec { machine.start() machine.wait_for_unit("multi-user.target") machine.succeed("curl --fail http://localhost | grep privacyIDEA") + machine.succeed("grep \"SECRET_KEY = 'testing'\" /var/lib/privacyidea/privacyidea.cfg") + machine.succeed("grep \"PI_PEPPER = 'testing'\" /var/lib/privacyidea/privacyidea.cfg") machine.succeed( "curl --fail http://localhost/auth -F username=admin -F password=testing | grep token" )