nixos-config/lib/fudo/mail/dkim.nix

115 lines
3.8 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.fudo.mail-server;
createDomainDkimCert = dom:
let
dkim_key = "${cfg.dkim.key-directory}/${dom}.${cfg.dkim.selector}.key";
dkim_txt = "${cfg.dkim.key-directory}/${dom}.${cfg.dkim.selector}.txt";
in
''
if [ ! -f "${dkim_key}" ] || [ ! -f "${dkim_txt}" ]
then
${cfg.dkim.package}/bin/opendkim-genkey -s "${cfg.dkim.selector}" \
-d "${dom}" \
--bits="${toString cfg.dkim.key-bits}" \
--directory="${cfg.dkim.key-directory}"
mv "${cfg.dkim.key-directory}/${cfg.dkim.selector}.private" "${dkim_key}"
mv "${cfg.dkim.key-directory}/${cfg.dkim.selector}.txt" "${dkim_txt}"
echo "Generated key for domain ${dom} selector ${cfg.dkim.selector}"
fi
'';
createAllCerts = lib.concatStringsSep "\n" (map createDomainDkimCert cfg.local-domains);
keyTable = pkgs.writeText "opendkim-KeyTable"
(lib.concatStringsSep "\n" (lib.flip map cfg.local-domains
(dom: "${dom} ${dom}:${cfg.dkim.selector}:${cfg.dkim.key-directory}/${dom}.${cfg.dkim.selector}.key")));
signingTable = pkgs.writeText "opendkim-SigningTable"
(lib.concatStringsSep "\n" (lib.flip map cfg.local-domains (dom: "${dom} ${dom}")));
dkim = config.services.opendkim;
args = [ "-f" "-l" ] ++ lib.optionals (dkim.configFile != null) [ "-x" dkim.configFile ];
in
{
options.fudo.mail-server.dkim = {
signing = mkOption {
type = types.bool;
default = true;
description = "Enable dkim signatures for mail.";
};
key-directory = mkOption {
type = types.str;
default = "/var/dkim";
description = "Path to use to store DKIM keys.";
};
selector = mkOption {
type = types.str;
default = "mail";
description = "Name to use for mail-signing keys.";
};
key-bits = mkOption {
type = types.int;
default = 2048;
description = ''
How many bits in generated DKIM keys. RFC6376 advises minimum 1024-bit keys.
If you have already deployed a key with a different number of bits than specified
here, then you should use a different selector (dkimSelector). In order to get
this package to generate a key with the new number of bits, you will either have to
change the selector or delete the old key file.
'';
};
package = mkOption {
type = types.package;
default = pkgs.opendkim;
description = "OpenDKIM package to use.";
};
};
config = mkIf (cfg.dkim.signing && cfg.enable) {
services.opendkim = {
enable = true;
selector = cfg.dkim.selector;
domains = "csl:${builtins.concatStringsSep "," cfg.local-domains}";
configFile = pkgs.writeText "opendkim.conf" (''
Canonicalization relaxed/simple
UMask 0002
Socket ${dkim.socket}
KeyTable file:${keyTable}
SigningTable file:${signingTable}
'' + (lib.optionalString cfg.debug ''
Syslog yes
SyslogSuccess yes
LogWhy yes
''));
};
users.users = {
"${config.services.postfix.user}" = {
extraGroups = [ "${config.services.opendkim.group}" ];
};
};
systemd.services.opendkim = {
preStart = lib.mkForce createAllCerts;
serviceConfig = {
ExecStart = lib.mkForce "${cfg.dkim.package}/bin/opendkim ${escapeShellArgs args}";
PermissionsStartOnly = lib.mkForce false;
};
};
systemd.tmpfiles.rules = [
"d '${cfg.dkim.key-directory}' - ${config.services.opendkim.user} ${config.services.opendkim.group} - -"
];
};
}