Add support for DKIM key management

After bumping the generation of new DKIM keys to RSA 2048 in NixOS 25.11
key rotation for existing users could not be done safely.

To resolve this situation we now support multiple generations of
selectors per domain to enable proper DKIM key transitions as described
in RFC6376 3.1. The added documentation introduces and motivates DKIM
and guides the user through a DKIM key rotation.

Additionally, DKIM key material can now also be treated as a managed
secrets when autogenerated state on the mail server host is undesirable.

This change is fully backwards compatible in behavior and will continue
to use the previously generated DKIM key without any additional
configuration up until the point when DKIM selectors are configured
explicitly.
This commit is contained in:
Martin Weinelt
2026-03-06 02:36:42 +01:00
parent ea775773d9
commit 6ff4a50f02
11 changed files with 512 additions and 86 deletions
+23 -4
View File
@@ -49,7 +49,21 @@
"example2.com"
];
rewriteMessageId = true;
dkimKeyBits = 1535;
dkim = {
defaults.keyLength = 1535;
domains."example2.com".selectors = {
"dkim-rsa" = {
# rsa 1535 bits via defaults
};
"dkim-ed25519" = {
keyType = "ed25519";
keyLength = null;
};
"dkim-file" = {
keyFile = "/run/rspamd/dkim-test.key";
};
};
};
dmarcReporting.enable = true;
loginAccounts = {
@@ -369,6 +383,9 @@
"set +e; timeout 1 nc -U /run/rspamd/rspamd-milter.sock < /dev/null; [ $? -eq 124 ]"
)
server.succeed("rspamadm dkim_keygen > /run/rspamd/dkim-test.key")
server.succeed("chown rspamd: /run/rspamd/dkim-test.key")
client.execute("cp -p /etc/root/.* ~/")
client.succeed("mkdir -p ~/mail")
client.succeed("ls -la ~/ >&2")
@@ -404,10 +421,10 @@
with subtest("dkim has user-specified size"):
server.succeed(
"openssl rsa -in /var/dkim/example.com.mail.key -text -noout | grep 'Private-Key: (1535 bit'"
"openssl rsa -in /var/dkim/example2.com.dkim-rsa.key -text -noout | grep 'Private-Key: (1535 bit'"
)
with subtest("dkim singing, multiple domains"):
with subtest("dkim signing, multiple domains"):
client.execute("rm ~/mail/*")
# send email from user2 to user1
client.succeed(
@@ -418,7 +435,9 @@
client.succeed("fetchmail --nosslcertck -v")
client.succeed("cat ~/mail/* >&2")
# make sure it is dkim signed
client.succeed("grep DKIM-Signature: ~/mail/*")
client.succeed("grep 's=dkim-rsa' ~/mail/*")
client.succeed("grep 's=dkim-ed25519' ~/mail/*")
client.succeed("grep 's=dkim-file' ~/mail/*")
with subtest("aliases"):
client.execute("rm ~/mail/*")