diff --git a/default.nix b/default.nix index 60dbceb..c2b353f 100644 --- a/default.nix +++ b/default.nix @@ -794,6 +794,27 @@ in ''; }; + dkimPrivateKeyFiles = mkOption { + type = types.nullOr (types.attrsOf types.path); + default = null; + example = { + "mail.example.com" = "/run/secrets/dkim/mail.example.com.mail.key"; + }; + description = '' + Paths to opendkim private keys generated with `opendkim-genkey`, + indexed by domain name. + If `null`, then the keys are auto generated. + If not `null`, then there must be an entry for every domain in + {option}`config.mailserver.domains`. + + >>> TODO: explain/assert how this interacts with `dkimKeyBits`. would + this be cleaner if we had an explicit "generate dkim keys" option that + defaults to true, and perhaps we move the generation option (just + `dkimKeyBits` right now) under an optional `generateOpts` section? this + is not backward compatible, though <<< + ''; + }; + dkimKeyDirectory = mkOption { type = types.path; default = "/var/dkim"; diff --git a/mail-server/opendkim.nix b/mail-server/opendkim.nix index cdb283c..e81bf6a 100644 --- a/mail-server/opendkim.nix +++ b/mail-server/opendkim.nix @@ -23,14 +23,26 @@ let dkimUser = config.services.opendkim.user; dkimGroup = config.services.opendkim.group; - createDomainDkimCert = dom: + createOrLinkDkimCerts = dom: let dkim_key = "${cfg.dkimKeyDirectory}/${dom}.${cfg.dkimSelector}.key"; dkim_txt = "${cfg.dkimKeyDirectory}/${dom}.${cfg.dkimSelector}.txt"; in + if cfg.dkimPrivateKeyFiles != null then + let + dkimPrivateKeyFile = cfg.dkimPrivateKeyFiles.${dom}; + in '' - if [ ! -f "${dkim_key}" ] - then + if [ ! -f "${dkimPrivateKeyFile}" ]; then + echo "DKIM keyfile does not exist: ${dkimPrivateKeyFile}" + exit 1 + fi + + ln -sf "${dkimPrivateKeyFile}" "${dkim_key}" + '' + else + '' + if [ ! -f "${dkim_key}" ]; then ${pkgs.opendkim}/bin/opendkim-genkey -s "${cfg.dkimSelector}" \ -d "${dom}" \ --bits="${toString cfg.dkimKeyBits}" \ @@ -41,7 +53,7 @@ let echo "Generated key for domain ${dom} selector ${cfg.dkimSelector}" fi ''; - createAllCerts = lib.concatStringsSep "\n" (map createDomainDkimCert cfg.domains); + createOrLinkAllCerts = lib.concatStringsSep "\n" (map createOrLinkDkimCerts cfg.domains); keyTable = pkgs.writeText "opendkim-KeyTable" (lib.concatStringsSep "\n" (lib.flip map cfg.domains @@ -76,7 +88,7 @@ in postfix.extraGroups = [ "${dkimGroup}" ]; }; systemd.services.opendkim = { - preStart = lib.mkForce createAllCerts; + preStart = lib.mkForce createOrLinkAllCerts; serviceConfig = { ExecStart = lib.mkForce "${pkgs.opendkim}/bin/opendkim ${escapeShellArgs args}"; PermissionsStartOnly = lib.mkForce false;