mailsystem: Add configuration options for dkim signatures

This commit is contained in:
Thomas Preisner 2024-12-29 01:27:00 +01:00
parent 88d2b387c7
commit de330a87a4
2 changed files with 92 additions and 6 deletions

View file

@ -168,6 +168,45 @@ in {
default = {}; default = {};
}; };
dkimSettings = lib.mkOption {
type = with lib.types;
attrsOf (listOf (submodule {
options = {
selector = lib.mkOption {
type = lib.types.str;
example = "mail";
description = "DKIM Selector";
};
keyFile = lib.mkOption {
type = lib.types.path;
example = "/run/secrets/dkim/example.com.mail.key";
description = ''
Path to DKIM private-key-file. A public-private-pair can be generated as follows:
```
nix-shell -p rspamd --run 'rspamadm dkim_keygen -s "selector" -t ed25519 -d example.com
nix-shell -p rspamd --run 'rspamadm dkim_keygen -s "selector" -b 2048 -d example.com
```
'';
};
};
}));
example = {
"example.com" = [
{
selector = "mail";
keyFile = "/run/secrets/dkim/example.com.mail.key";
}
];
};
description = ''
Per-domain DKIM configuration.
This option allows to optionally set one or more DKIM private keys
and their respective selectors for each domain individually.
'';
default = {};
};
certificateScheme = lib.mkOption { certificateScheme = lib.mkOption {
type = lib.types.enum ["acme" "selfsigned"]; type = lib.types.enum ["acme" "selfsigned"];
default = "acme"; default = "acme";

View file

@ -39,12 +39,27 @@ in {
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
assertions = [ assertions =
[
{ {
assertion = !cfg.rspamd.webUi.enable || cfg.rspamd.webUi.basicAuthFile != null; assertion = !cfg.rspamd.webUi.enable || cfg.rspamd.webUi.basicAuthFile != null;
message = "Setting basicAuthFile is required if rspamd's web interface is enabled"; message = "Setting basicAuthFile is required if rspamd's web interface is enabled";
} }
]; ]
++ lib.mapAttrsToList (
domain: dkimList: {
assertion = builtins.elem domain cfg.domains;
message = "Domain ${domain} as per `config.mailsystem.dkimSettings` needs to be managed by the mailserver.";
}
)
cfg.dkimSettings
++ lib.mapAttrsToList (
domain: dkimList: {
assertion = dkimList != [];
message = "Entry ${domain} as per `config.mailsystem.dkimSettings` must not be an empty list.";
}
)
cfg.dkimSettings;
services.rspamd = { services.rspamd = {
enable = true; enable = true;
@ -57,6 +72,38 @@ in {
} }
''; '';
}; };
"dkim_signing.conf" = let
genDkimSelectorList = entry: ''
{
path: "${entry.keyFile}";
selector: "${entry.selector}";
}
'';
genDkimDomainCfg = domain: domainSettings: ''
${domain} {
selectors [
${lib.concatStringsSep "\n" (map genDkimSelectorList domainSettings)}
]
}
'';
in {
text =
''
sign_authenticated = true;
use_esld = true;
use_domain = "header";
check_pubkey = true;
allow_username_mismatch = true;
allow_hdrfrom_mismatch = true;
allow_hdrfrom_mismatch_sign_networks = true;
''
+ lib.optionalString (cfg.dkimSettings != {}) ''
domain {
${lib.concatStringsSep "\n" (lib.mapAttrsToList genDkimDomainCfg cfg.dkimSettings)}
}
'';
};
"milter_headers.conf" = { "milter_headers.conf" = {
text = '' text = ''
# Add headers related to spam-detection # Add headers related to spam-detection