forked from mirrors/nixpkgs
nixos/geoipupdate: Improve secret handling
Make secret replacement more robust and futureproof: - Allow any attribute in `services.geoipupdate.settings` to be a secret if set to `{ _secret = "/path/to/secret"; }`. - Hash the license key path before using it as a placeholder in the config file to minimize the risk of conflicting file paths being replaced instead.
This commit is contained in:
parent
23c15323ce
commit
4dddca8240
|
@ -2,6 +2,7 @@
|
|||
|
||||
let
|
||||
cfg = config.services.geoipupdate;
|
||||
inherit (builtins) isAttrs isString isInt isList typeOf hashString;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
@ -27,11 +28,30 @@ in
|
|||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
AccountID = 200001;
|
||||
DatabaseDirectory = "/var/lib/GeoIP";
|
||||
LicenseKey = { _secret = "/run/keys/maxmind_license_key"; };
|
||||
Proxy = "10.0.0.10:8888";
|
||||
ProxyUserPassword = { _secret = "/run/keys/proxy_pass"; };
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
<productname>geoipupdate</productname> configuration
|
||||
options. See
|
||||
<link xlink:href="https://github.com/maxmind/geoipupdate/blob/main/doc/GeoIP.conf.md" />
|
||||
for a full list of available options.
|
||||
|
||||
Settings containing secret data should be set to an
|
||||
attribute set containing the attribute
|
||||
<literal>_secret</literal> - a string pointing to a file
|
||||
containing the value the option should be set to. See the
|
||||
example to get a better picture of this: in the resulting
|
||||
<filename>GeoIP.conf</filename> file, the
|
||||
<literal>ProxyUserPassword</literal> key will be set to the
|
||||
contents of the
|
||||
<filename>/run/keys/proxy_pass</filename> file.
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
freeformType =
|
||||
|
@ -65,11 +85,18 @@ in
|
|||
};
|
||||
|
||||
LicenseKey = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
type = with lib.types; either path (attrsOf path);
|
||||
description = ''
|
||||
A file containing the <productname>MaxMind</productname>
|
||||
license key.
|
||||
A file containing the
|
||||
<productname>MaxMind</productname> license key.
|
||||
|
||||
Always handled as a secret whether the value is
|
||||
wrapped in a <literal>{ _secret = ...; }</literal>
|
||||
attrset or not (refer to <xref
|
||||
linkend="opt-services.geoipupdate.settings" /> for
|
||||
details).
|
||||
'';
|
||||
apply = x: if isAttrs x then x else { _secret = x; };
|
||||
};
|
||||
|
||||
DatabaseDirectory = lib.mkOption {
|
||||
|
@ -118,22 +145,30 @@ in
|
|||
"network-online.target"
|
||||
"nss-lookup.target"
|
||||
];
|
||||
path = [ pkgs.replace-secret ];
|
||||
wants = [ "network-online.target" ];
|
||||
startAt = cfg.interval;
|
||||
serviceConfig = {
|
||||
ExecStartPre =
|
||||
let
|
||||
isSecret = v: isAttrs v && v ? _secret && isString v._secret;
|
||||
geoipupdateKeyValue = lib.generators.toKeyValue {
|
||||
mkKeyValue = lib.flip lib.generators.mkKeyValueDefault " " rec {
|
||||
mkValueString = v: with builtins;
|
||||
mkValueString = v:
|
||||
if isInt v then toString v
|
||||
else if isString v then v
|
||||
else if true == v then "1"
|
||||
else if false == v then "0"
|
||||
else if isList v then lib.concatMapStringsSep " " mkValueString v
|
||||
else if isSecret v then hashString "sha256" v._secret
|
||||
else throw "unsupported type ${typeOf v}: ${(lib.generators.toPretty {}) v}";
|
||||
};
|
||||
};
|
||||
secretPaths = lib.catAttrs "_secret" (lib.collect isSecret cfg.settings);
|
||||
mkSecretReplacement = file: ''
|
||||
replace-secret ${lib.escapeShellArgs [ (hashString "sha256" file) file "/run/geoipupdate/GeoIP.conf" ]}
|
||||
'';
|
||||
secretReplacements = lib.concatMapStrings mkSecretReplacement secretPaths;
|
||||
|
||||
geoipupdateConf = pkgs.writeText "geoipupdate.conf" (geoipupdateKeyValue cfg.settings);
|
||||
|
||||
|
@ -144,9 +179,7 @@ in
|
|||
chown geoip "${cfg.settings.DatabaseDirectory}"
|
||||
|
||||
cp ${geoipupdateConf} /run/geoipupdate/GeoIP.conf
|
||||
${pkgs.replace-secret}/bin/replace-secret '${cfg.settings.LicenseKey}' \
|
||||
'${cfg.settings.LicenseKey}' \
|
||||
/run/geoipupdate/GeoIP.conf
|
||||
${secretReplacements}
|
||||
'';
|
||||
in
|
||||
"+${pkgs.writeShellScript "start-pre-full-privileges" script}";
|
||||
|
|
Loading…
Reference in a new issue