feat: add support for DKIM private key files

This gives people an option to declaratively manage these secrets,
rather than having them generated.
This commit is contained in:
Jeremy Fleischman 2024-10-31 15:07:47 -05:00
parent b4fbffe79c
commit 909681c13a
No known key found for this signature in database
2 changed files with 38 additions and 5 deletions

View File

@ -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";

View File

@ -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;