diff --git a/nixos/modules/services/misc/geoipupdate.nix b/nixos/modules/services/misc/geoipupdate.nix
index 6a0b616473fb..db643c3d8479 100644
--- a/nixos/modules/services/misc/geoipupdate.nix
+++ b/nixos/modules/services/misc/geoipupdate.nix
@@ -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 = ''
geoipupdate configuration
options. See
for a full list of available options.
+
+ Settings containing secret data should be set to an
+ attribute set containing the attribute
+ _secret - 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
+ GeoIP.conf file, the
+ ProxyUserPassword key will be set to the
+ contents of the
+ /run/keys/proxy_pass 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 MaxMind
- license key.
+ A file containing the
+ MaxMind license key.
+
+ Always handled as a secret whether the value is
+ wrapped in a { _secret = ...; }
+ attrset or not (refer to 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}";