Merge pull request #24366 from rvl/longview-password-file

longview service: don't write passwords to nix store
This commit is contained in:
Michael Raskin 2017-05-01 09:39:35 +02:00 committed by GitHub
commit 7e19fcddcc
2 changed files with 82 additions and 35 deletions

View File

@ -5,22 +5,10 @@ with lib;
let let
cfg = config.services.longview; cfg = config.services.longview;
pidFile = "/run/longview.pid"; runDir = "/run/longview";
configsDir = "${runDir}/longview.d";
apacheConf = optionalString (cfg.apacheStatusUrl != "") '' in {
location ${cfg.apacheStatusUrl}?auto
'';
mysqlConf = optionalString (cfg.mysqlUser != "") ''
username ${cfg.mysqlUser}
password ${cfg.mysqlPassword}
'';
nginxConf = optionalString (cfg.nginxStatusUrl != "") ''
location ${cfg.nginxStatusUrl}
'';
in
{
options = { options = {
services.longview = { services.longview = {
@ -35,10 +23,27 @@ in
apiKey = mkOption { apiKey = mkOption {
type = types.str; type = types.str;
default = "";
example = "01234567-89AB-CDEF-0123456789ABCDEF"; example = "01234567-89AB-CDEF-0123456789ABCDEF";
description = '' description = ''
Longview API key. To get this, look in Longview settings which Longview API key. To get this, look in Longview settings which
are found at https://manager.linode.com/longview/. are found at https://manager.linode.com/longview/.
Warning: this secret is stored in the world-readable Nix store!
Use <option>apiKeyFile</option> instead.
'';
};
apiKeyFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/longview-api-key";
description = ''
A file containing the Longview API key.
To get this, look in Longview settings which
are found at https://manager.linode.com/longview/.
<option>apiKeyFile</option> takes precedence over <option>apiKey</option>.
''; '';
}; };
@ -77,11 +82,23 @@ in
mysqlPassword = mkOption { mysqlPassword = mkOption {
type = types.str; type = types.str;
default = "";
description = '' description = ''
The password corresponding to mysqlUser. Warning: this is The password corresponding to <option>mysqlUser</option>.
stored in cleartext in the Nix store! Warning: this is stored in cleartext in the Nix store!
Use <option>mysqlPasswordFile</option> instead.
''; '';
}; };
mysqlPasswordFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/dbpassword";
description = ''
A file containing the password corresponding to <option>mysqlUser</option>.
'';
};
}; };
}; };
@ -94,25 +111,50 @@ in
serviceConfig.Type = "forking"; serviceConfig.Type = "forking";
serviceConfig.ExecStop = "-${pkgs.coreutils}/bin/kill -TERM $MAINPID"; serviceConfig.ExecStop = "-${pkgs.coreutils}/bin/kill -TERM $MAINPID";
serviceConfig.ExecReload = "-${pkgs.coreutils}/bin/kill -HUP $MAINPID"; serviceConfig.ExecReload = "-${pkgs.coreutils}/bin/kill -HUP $MAINPID";
serviceConfig.PIDFile = pidFile; serviceConfig.PIDFile = "${runDir}/longview.pid";
serviceConfig.ExecStart = "${pkgs.longview}/bin/longview"; serviceConfig.ExecStart = "${pkgs.longview}/bin/longview";
preStart = ''
umask 077
mkdir -p ${configsDir}
'' + (optionalString (cfg.apiKeyFile != null) ''
cp --no-preserve=all "${cfg.apiKeyFile}" ${runDir}/longview.key
'') + (optionalString (cfg.apacheStatusUrl != "") ''
cat > ${configsDir}/Apache.conf <<EOF
location ${cfg.apacheStatusUrl}?auto
EOF
'') + (optionalString (cfg.mysqlUser != "" && cfg.mysqlPasswordFile != null) ''
cat > ${configsDir}/MySQL.conf <<EOF
username ${cfg.mysqlUser}
password `head -n1 "${cfg.mysqlPasswordFile}"`
EOF
'') + (optionalString (cfg.nginxStatusUrl != "") ''
cat > ${configsDir}/Nginx.conf <<EOF
location ${cfg.nginxStatusUrl}
EOF
'');
}; };
environment.etc."linode/longview.key" = { warnings = let warn = k: optional (cfg.${k} != "")
mode = "0400"; "config.services.longview.${k} is insecure. Use ${k}File instead.";
text = cfg.apiKey; in concatMap warn [ "apiKey" "mysqlPassword" ];
};
environment.etc."linode/longview.d/Apache.conf" = { assertions = [
mode = "0400"; { assertion = cfg.apiKeyFile != null;
text = apacheConf; message = "Longview needs an API key configured";
}; }
environment.etc."linode/longview.d/MySQL.conf" = { ];
mode = "0400";
text = mysqlConf; # Create API key file if not configured.
}; services.longview.apiKeyFile = mkIf (cfg.apiKey != "")
environment.etc."linode/longview.d/Nginx.conf" = { (mkDefault (toString (pkgs.writeTextFile {
mode = "0400"; name = "longview.key";
text = nginxConf; text = cfg.apiKey;
}; })));
# Create MySQL password file if not configured.
services.longview.mysqlPasswordFile = mkDefault (toString (pkgs.writeTextFile {
name = "mysql-password-file";
text = cfg.mysqlPassword;
}));
}; };
} }

View File

@ -16,8 +16,13 @@ stdenv.mkDerivation rec {
./log-stdout.patch ./log-stdout.patch
]; ];
# Read all configuration from /run/longview
postPatch = '' postPatch = ''
substituteInPlace Linode/Longview/Util.pm --replace /var/run/longview.pid /run/longview.pid substituteInPlace Linode/Longview/Util.pm \
--replace /var/run/longview.pid /run/longview/longview.pid \
--replace /etc/linode /run/longview
substituteInPlace Linode/Longview.pl \
--replace /etc/linode /run/longview
''; '';
buildInputs = [ perl makeWrapper glibc ] buildInputs = [ perl makeWrapper glibc ]