diff --git a/README.md b/README.md index 519e342..e8367d4 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ SNM branch corresponding to your NixOS version. * [x] Via ClamAV * DKIM Signing * [x] Via Rspamd + * [x] Automatic key generation + * [x] Multiple selectors per Domain * User Management * [x] Declarative user management * [x] Declarative password management @@ -66,9 +68,6 @@ SNM branch corresponding to your NixOS version. * [ ] [Autoconfig](https://web.archive.org/web/20210624004729/https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration) * [ ] [Autodiscovery](https://learn.microsoft.com/en-us/exchange/architecture/client-access/autodiscover?view=exchserver-2019) * [ ] [Mobileconfig](https://support.apple.com/guide/profile-manager/distribute-profiles-manually-pmdbd71ebc9/mac) -* DKIM Signing - * [ ] Allow per domain selectors - * [ ] Allow passing DKIM signing keys * Improve the Forwarding Experience * [ ] Support [ARC](https://en.wikipedia.org/wiki/Authenticated_Received_Chain) signing with [Rspamd](https://rspamd.com/doc/modules/arc.html) * User management diff --git a/default.nix b/default.nix index f1f50bb..a56cf84 100644 --- a/default.nix +++ b/default.nix @@ -917,63 +917,170 @@ in ''; }; - dkimSigning = mkOption { - type = types.bool; - default = true; - description = '' - Whether to activate dkim signing. - ''; - }; + dkim = { + enable = mkEnableOption "DKIM signing" // { + default = true; + }; - dkimSelector = mkOption { - type = types.str; - default = "mail"; - description = '' - The DKIM selector. - ''; - }; + keyDirectory = mkOption { + type = types.path; + default = "/var/dkim"; + description = '' + The path where DKIM siging keys are stored. + ''; + }; - dkimKeyDirectory = mkOption { - type = types.path; - default = "/var/dkim"; - description = '' - The DKIM directory. - ''; - }; + defaults = { + selector = mkOption { + type = types.str; + default = "mail"; + description = '' + The default selector used to reference and lookup DKIM keys. - dkimKeyType = mkOption { - type = types.enum [ - "rsa" - "ed25519" - ]; - default = "rsa"; - description = '' - The key type used for generating DKIM keys. Ed25519 support was - introduced in RFC6376 (2018). + This value should most likely not be changed. Instead manage + {option}`mailserver.dkim.domains..selectors` to sign with one + or multiple DKIM key pairs and manage migrations. + ''; + }; - :::{warning} - Ed25519 DKIM keys are currently not recommended for primary use, as - various DKIM validators out there lack support and consider the keypair invalid. - ::: + keyType = mkOption { + type = types.enum [ + "rsa" + "ed25519" + ]; + default = "rsa"; + description = '' + The key type used for generating DKIM keys. Ed25519 support was + introduced in RFC6376 (2018). - If you have already deployed a key with a different type than specified - here, then you should use a different selector ({option}`mailserver.dkimSelector`). In order to get - this package to generate a key with the new type, you will either have to - change the selector or delete the old key file. - ''; - }; + :::{warning} + Ed25519 DKIM keys are currently not recommended for sole use, as + various DKIM validators out there lack support and consider the + keypair invalid. + ::: - dkimKeyBits = mkOption { - type = types.int; - default = 2048; - description = '' - How many bits in generated DKIM keys. RFC8301 suggests a minimum RSA key length of 2048 bit. + This value should most likely not be changed. Once DKIM keys for + domain and selector are generated changing this value will not + regenerate the keypair. Instead create a new selector and configure + {option}`mailserver.dkim.domains..selectors..keyType`. + ''; + }; - If you have already deployed a key with a different number of bits than specified - here, then you should use a different selector ({option}`mailserver.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. - ''; + keyLength = mkOption { + type = types.int; + default = 2048; + description = '' + The default key length used for generating new DKIM keys. + + Only applies for RSA keys, Ed25519 keys use a fixed key length. + + Per [RFC8301 3.2] the minimum RSA key length should be at least + 2048 bit. + + This value should most likely not be changed. Once DKIM keys for + domain and selector are generated changing this value will not + regenerate the keypair. Instead create a new selector and configure + {option}`mailserver.dkim.domains..selectors..keyLength`. + + [RFC8301 3.2]: https://datatracker.ietf.org/doc/html/rfc8301#section-3.2 + ''; + }; + }; + + domains = mkOption { + description = "DKIM configuration per domain."; + type = types.attrsOf ( + types.submodule ({ + options = { + selectors = mkOption { + description = '' + DKIM selectors used for signing outgoing mail for this domain. + + When no selector is configured a default selector will be + created with settings inherited from {option}`mailserver.defaults.dkim `. + ''; + type = types.attrsOf ( + types.submodule ({ + options = { + keyType = mkOption { + type = + with types; + nullOr (enum [ + "rsa" + "ed25519" + ]); + default = null; + example = "rsa"; + description = '' + The key type used for generating this DKIM keypair. + + :::{warning} + Ed25519 DKIM keys are currently not recommended for sole use, as + various DKIM validators out there lack support and consider the + keypair invalid. + ::: + + This option is mutually exclusive with `keyFile`. + ''; + }; + + keyLength = mkOption { + type = with types; nullOr int; + default = null; + example = 2048; + description = '' + The key length used for generating this DKIM key. + + Only applies for RSA keys, Ed25519 keys use a fixed key size. + + This option is mutually exclusive with `keyFile`. + ''; + }; + + keyFile = mkOption { + type = + with types; + nullOr (pathWith { + inStore = false; + }); + default = null; + example = "/run/keys/example.com-dkim-rsa-2026-03.key"; + description = '' + Path to an existing DKIM private key file. + + DKIM keys can be generated using `rspamadm dkim_keygen`. + + This option is mutually exclusive with `keyType` and `keyLength`. + ''; + }; + }; + }) + ); + default = { }; + example = lib.literalExpression '' + { + "mail" = { + # inherit defaults from mailserver.dkim.defaults + }; + "rsa-2026-03".keyFile = "/run/keys/example.com-dkim-rsa-2026-03.key"; + }; + ''; + }; + }; + }) + ); + default = { }; + example = lib.literalExpression '' + { + "example.com".selectors = { + "mail" = { + # inherit defaults from mailserver.dkim.defaults + }; + "rsa-2026-03".keyFile = "/run/keys/example.com-dkim-rsa-2026-03.key"; + }; + }; + ''; + }; }; dmarcReporting = { @@ -1468,6 +1575,13 @@ in (mkRemovedOptionModule [ "mailserver" "smtpdForbidBareNewline" ] '' The workaround for the SMTP Smuggling attack is default enabled in Postfix >3.9. Use `services.postfix.config.smtpd_forbid_bare_newline` if you need to deviate from its default. '') + (mkRenamedOptionModule [ "mailserver" "dkimSigning" ] [ "mailserver" "dkim" "enable" ]) + (mkRenamedOptionModule [ "mailserver" "dkimKeyDirectory" ] [ "mailserver" "dkim" "keyDirectory" ]) + (mkRenamedOptionModule + [ "mailserver" "dkimSelector" ] + [ "mailserver" "dkim" "defaults" "selector" ] + ) + (mkRenamedOptionModule [ "mailserver" "dkimKeyType" ] [ "mailserver" "dkim" "defaults" "keyType" ]) (mkRenamedOptionModule [ "mailserver" "dmarcReporting" "domain" ] [ "mailserver" "systemDomain" ]) (mkRenamedOptionModule [ "mailserver" "dmarcReporting" "organizationName" ] diff --git a/docs/backup-guide.rst b/docs/backup-guide.rst index 71b6ff4..caff6bf 100644 --- a/docs/backup-guide.rst +++ b/docs/backup-guide.rst @@ -21,7 +21,7 @@ Maildir. To backup spam and ham training data, backup ``/var/lib/redis-rspamd``. -Finally you can (optionally) make a backup of ``/var/dkim`` (or whatever -you specified as ``dkimKeyDirectory``). If you should lose those don’t -worry, new ones will be created on the fly. But you will need to repeat -step ``B)5`` and correct all the ``dkim`` keys. +Finally you can (optionally) make a backup of ``/var/dkim`` (or whatever you +specified as :option:`mailserver.dkim.keyDirectory`). If you should lose those +don’t worry, new ones will be created on the fly. But you will need to update +the DKIM TXT records to reflect the new key material. diff --git a/docs/dkim.rst b/docs/dkim.rst new file mode 100644 index 0000000..f5c38a1 --- /dev/null +++ b/docs/dkim.rst @@ -0,0 +1,201 @@ +DKIM Signing +============ + +DKIM (DomainKeys Identified Mail) is an email authentication mechanism that +allows a mailserver to digitally sign outgoing emails for a domain. Receiving +mail servers can verify this signature using a public key published in DNS to +confirm the message was authorized by the domain and was not modified during +transit. + +How DKIM works in practice +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. ``bob@bar.example`` sends an email to ``alice@foo.example``. The sending +mail server for ``bar.example`` selects one or multiple DKIM keys using a +**selector** (e.g., ``mail``) and creates one or multiple cryptographic +signature for selected headers and the message body, adding a ``DKIM-Signature`` +header that references the selector. + +2. The message arrives at ``foo.example``. The receiving mail server reads the +``DKIM-Signature`` headers, looks up the public keys for ``bar.example`` for +each of the specified selectors (e.g., ``mail._domainkey.bar.example``), and +verifies that at least one signature matches the message content. + +3. With a valid signature, the receiver knows the message was authorized by +``bar.example`` and that the signed headers and body were not modified in +transit. If the content or signed headers were changed, the DKIM verification +fails. The use of selectors allows ``bar.example`` to rotate or migrate keys +without disrupting verification for previously sent messages. + +Enabling DKIM Signing +~~~~~~~~~~~~~~~~~~~~~ + +Because DKIM signing is crucial for reliable mail delivery it is enabled by +default and without further configuration a DKIM keypair will be generated for +each :option:`mailserver.domains` (including :option:`mailserver.srs.domain`, +if set) based on :option:`mailserver.dkim.defaults +`. + +.. code:: nix + + { + mailserver = { + domains = [ "example.com" ]; + dkim.enable = true; # enabled by default + }; + } + + +.. note:: + If you set up NixOS Mailserver before the `25.11 release`_ your DKIM keys were + generated with 1024 bit RSA and we recommend replacing them with 2048 bit + RSA key material per `RFC8301 3.2`_. + + .. _25.11 release: release-notes.html#nixos-25-11 + .. _RFC8301 3.2: https://www.rfc-editor.org/rfc/rfc8301#section-3.2 + +DKIM Key Rotation +~~~~~~~~~~~~~~~~~ + +DKIM key rotation replaces a domain's signing keys to maintain +strong email authentication and support algorithm upgrades. Rotation is +essential for migrating away from weaker or deprecated algorithms. + +Selectors allow multiple keys to coexist during the transition: a new key can +be deployed under a different selector while the old key remains valid for a +limited period to verify messages still in transit. Once all messages signed +with the old key have been delivered, the key can be safely retired, ensuring a +reliable migration without breaking verification. + + +1. Make the automatically generated key explicit +************************************************ + +First we need to make sure we keep the current DKIM key configured. If you were +relying on automatically generated keys before, you now need to start explicitly +defining that key, because explicit selector configuration takes precedence. + +.. code:: nix + + { + mailserver = { + domains = [ "example.com" ]; + dkim.domains = { + "example.com".selectors = { + "${config.mailserver.dkim.defaults.selector}" = { }; + }; + }; + }; + } + + +2. Create the new DKIM keypair +****************************** + +Next we need to create a new DKIM key with a unique selector, you can +for example choose the current date. Without any settings passed a new +key will be generated from the current :option:`mailserver.dkim.defaults +`, which should be sufficient. + +.. code:: nix + + { + mailserver = { + domains = [ "example.com" ]; + dkim = { + enable = true; + domains."example.com".selectors = { + "${config.mailserver.dkim.defaults.selector}" = { }; + "rsa-2026-03" = { + keyType = "rsa"; + keyLength = 2048; + }; + }; + }; + }; + } + +.. warning:: + While DKIM does support Ed25519 keys (`RFC8463`_), many validators still lack + proper support and may treat Ed25519 key material as invalid. As a result, + mail signed only with Ed25519 DKIM keys may fail verification at some + receivers. + + .. _RFC8463: https://datatracker.ietf.org/doc/html/rfc8463 + +Once this configuration is applied the new keypair will be generated below +:option:`mailserver.dkim.keyDirectory`, which defaults to ``/var/dkim``. The +mailserver then begins signing outgoing mail with this key, so that it is now +signing with two DKIM keys simultaneously. + +To allow receiving servers to verify the new DKIM signature its +public key needs to be published into DNS. Look up the public key from +``/var/dkim/example.com.rsa-2026-03.txt`` and create the following DNS record by +substituting selector and public key. + +.. csv-table:: + :header: "Name", "TTL", "Type", "Value" + :widths: 30, 10, 10, 50 + + rsa-2026-03._domainkey.example.com., 86400, TXT, v=DKIM1; k=rsa; p= + +.. note:: + If you created an Ed25519 key, make sure to set the correct key type: ``k=ed25519`` + +Now wait for a few minutes and then check DNS propagation to show the value specified. + +.. code-block:: console + + $ nix-shell -p dig --command "dig @ns1.example.org TXT rsa-2026-03._domainkey.example.com" + +You can use https://www.mail-tester.com to test the new DKIM signature passes +validation. They allow you to view the message source where you can check that +the correct number of ``DKIM-Signature`` keys are present in the mail header. + + +3. Stop signing with the old DKIM keypair +***************************************** + +Once validation passes we need to stop signing with the old DKIM keypair, so +mail in transit eventually stops depending on the key material we want to rotate +out. Removing the selector will not remove the key material from disk, but it +will stop using it to sign outgoing mail. + +.. code:: nix + + { + mailserver = { + domains = [ "example.com" ]; + dkim = { + enable = true; + domains."example.com".selectors = { + "rsa-2026-03" = { + keyType = "rsa"; + keyLength = 2048; + }; + }; + } + } + } + +Apply the configuration. + + +4. Remove the old DKIM selector from DNS +**************************************** + +.. warning:: + Do not remove the DNS records for the old selector immediately. Keeping them + in place is essential to ensure that messages still in transit can be verified + and delivered successfully. + +Mail delivery is not always instantaneous. In the worst case, multiple retries +over several days may be required. According to `RFC5321 4.5.4.1`_ delivery +should be retried for at least 4-5 days. + +This means messages signed only with the old DKIM key could still be in transit +and rely on the old selector to verify their signatures. To ensure reliable +delivery, we recommend waiting **at least five days** before removing the old +DKIM selector from DNS. + +.. _RFC5321 4.5.4.1: https://www.rfc-editor.org/rfc/rfc5321#section-4.5.4.1 diff --git a/docs/index.rst b/docs/index.rst index 4d5cb3c..5f2c53f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,6 +25,7 @@ Welcome to NixOS Mailserver's documentation! :maxdepth: 1 :caption: Features + dkim fts ldap srs diff --git a/docs/release-notes.rst b/docs/release-notes.rst index b7b988b..7aa2237 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -11,6 +11,12 @@ NixOS 26.05 :option:`mailserver.x509.privateKeyFile` instead. Support for automatic creation of self-signed certificates has been removed. Check the updated `setup guide`_ for a basic ACME HTTP-01 example. +- `DKIM key management`_ is now available with multiple concurrent selectors per + domain enabling proper DKIM key rotation. While we still generate a default + key for backwards compatibility we now also support passing pre-created + key material. If your DKIM keys were automatically created before the 25.11 + release they are 1024 bit RSA keys and should be rotated out. + See :option:`mailserver.dkim.domains` for further relevant options. - Cleartext password files can now be configured for login accounts. This is an alternative to hashed passwords that integrates well with workflows established by `agenix`_/`sops-nix`_ that instead rely on encryption. This @@ -18,6 +24,7 @@ NixOS 26.05 See :option:`mailserver.loginAccounts..passwordFile`. .. _setup guide: setup-guide.html#setup-the-server +.. _DKIM key management: dkim.html .. _agenix: https://github.com/ryantm/agenix .. _sops-nix: https://github.com/Mic92/sops-nix diff --git a/mail-server/assertions.nix b/mail-server/assertions.nix index 7f9c001..3961d6d 100644 --- a/mail-server/assertions.nix +++ b/mail-server/assertions.nix @@ -53,6 +53,20 @@ in message = "Configure either an ACME certificate (`mailserver.x509.useACMEHost`) or pass an existing certificate (`mailserver.x509.certificateFile`, `mailserver.x509.privateKeyFile`)."; } ] + ++ lib.optionals config.mailserver.dkim.enable ( + lib.flatten ( + lib.mapAttrsToList ( + domain: domainAttrs: + lib.mapAttrsToList (selector: selectorAttrs: [ + { + assertion = + selectorAttrs.keyFile != null -> (selectorAttrs.keyType == null && selectorAttrs.keyLength == null); + message = "${domain} DKIM selector ${selector} can only use either `keyType`, `keyLength` OR `keyFile` not both."; + } + ]) domainAttrs.selectors + ) config.mailserver.dkim.domains + ) + ) ++ lib.optionals config.mailserver.ldap.enable [ { assertion = config.mailserver.loginAccounts == { }; diff --git a/mail-server/postfix.nix b/mail-server/postfix.nix index d6827ae..3a21894 100644 --- a/mail-server/postfix.nix +++ b/mail-server/postfix.nix @@ -450,7 +450,7 @@ in smtpd_tls_loglevel = "1"; smtpd_milters = smtpdMilters; - non_smtpd_milters = lib.mkIf cfg.dkimSigning [ "unix:/run/rspamd/rspamd-milter.sock" ]; + non_smtpd_milters = lib.mkIf cfg.dkim.enable [ "unix:/run/rspamd/rspamd-milter.sock" ]; milter_protocol = "6"; milter_mail_macros = "i {mail_addr} {client_addr} {client_name} {auth_authen}"; }; diff --git a/mail-server/rspamd.nix b/mail-server/rspamd.nix index f6c08b5..bf2caa3 100644 --- a/mail-server/rspamd.nix +++ b/mail-server/rspamd.nix @@ -31,27 +31,80 @@ let rspamdGroup = config.services.rspamd.group; createDkimKeypair = - domain: + { + domain, + selector, + type, + bits, + ... + }: let - privateKey = "${cfg.dkimKeyDirectory}/${domain}.${cfg.dkimSelector}.key"; - publicKey = "${cfg.dkimKeyDirectory}/${domain}.${cfg.dkimSelector}.txt"; + privkey = "${cfg.dkim.keyDirectory}/${domain}.${selector}.key"; + pubkey = "${cfg.dkim.keyDirectory}/${domain}.${selector}.txt"; in - pkgs.writeShellScript "dkim-keygen-${domain}" '' - if [ ! -f "${privateKey}" ] + pkgs.writeShellScript "dkim-keygen-${domain}-${selector}" '' + if [ ! -f "${privkey}" ] then - export PATH=${lib.makeBinPath [ pkgs.openssl ]} - ${lib.getExe' pkgs.rspamd "rspamadm"} dkim_keygen \ - --domain "${domain}" \ - --selector "${cfg.dkimSelector}" \ - --type "${cfg.dkimKeyType}" \ - --bits ${toString cfg.dkimKeyBits} \ - --privkey "${privateKey}" > "${publicKey}" - chmod 0644 "${publicKey}" - echo "Generated key for domain ${domain} and selector ${cfg.dkimSelector}" + ${lib.getExe' pkgs.rspamd "rspamadm"} dkim_keygen ${ + lib.cli.toCommandLineShellGNU { } { + inherit + domain + selector + type + bits + privkey + ; + } + } > "${pubkey}" + chmod 0644 "${pubkey}" + echo "Generated key for domain ${domain} and selector ${selector}" fi ''; - dkimDomains = lib.unique (cfg.domains ++ (lib.optionals cfg.srs.enable [ cfg.srs.domain ])); + mailDomains = lib.unique ( + # primary mailserver domains + config.mailserver.domains + # all dkim domains, even extra domains specified + ++ lib.attrNames cfg.dkim.domains + # and the srs domain, if one is configured + ++ lib.optionals (cfg.srs.domain != null) [ cfg.srs.domain ] + ); + + dkimKeys = lib.concatMap ( + domain: + let + configuredSelectors = config.mailserver.dkim.domains.${domain}.selectors or { }; + + finalSelectors = + if configuredSelectors == { } then + # synthesize default dkim key, if none configured + { + "${config.mailserver.dkim.defaults.selector}" = { + keyType = null; + keyLength = null; + keyFile = null; + }; + } + else + configuredSelectors; + in + lib.mapAttrsToList (selector: settings: rec { + inherit domain selector; + keyFile = settings.keyFile; + keyPath = if keyFile != null then keyFile else "${cfg.dkim.keyDirectory}/${domain}.${selector}.key"; + bits = + if settings.keyLength != null then + settings.keyLength + else + config.mailserver.dkim.defaults.keyLength; + type = + if settings.keyType != null then settings.keyType else config.mailserver.dkim.defaults.keyType; + }) finalSelectors + ) mailDomains; + + dkimKeysToGenerate = lib.filter (key: key.keyFile == null) dkimKeys; + + dkimKeysByDomain = lib.groupBy (item: item.domain) dkimKeys; in { config = lib.mkIf cfg.enable { @@ -110,13 +163,31 @@ in }; "dkim_signing.conf" = { text = '' - enabled = ${lib.boolToString cfg.dkimSigning}; - path = "${cfg.dkimKeyDirectory}/$domain.$selector.key"; - selector = "${cfg.dkimSelector}"; + enabled = ${lib.boolToString cfg.dkim.enable}; + # Only sign explicitly configured domains + try_fallback = false; # Allow for usernames w/o domain part allow_username_mismatch = true; # Don't normalize DKIM key selection for subdomains use_esld = false; + + domain { + ${lib.concatStringsSep "\n\n" ( + map (domain: '' + ${domain} { + selectors [ + ${lib.concatStringsSep ",\n" ( + map (selector: '' + { + path: "${selector.keyPath}"; + selector: "${selector.selector}"; + }'') dkimKeysByDomain.${domain} + )} + ] + } + '') (lib.attrNames dkimKeysByDomain) + )} + } ''; }; "dmarc.conf" = { @@ -183,7 +254,7 @@ in services.redis.servers.rspamd.enable = lib.mkDefault cfg.redis.configureLocally; systemd.tmpfiles.settings."10-rspamd.conf" = { - "${cfg.dkimKeyDirectory}" = { + "${cfg.dkim.keyDirectory}" = { d = { # Create /var/dkim owned by rspamd user/group user = rspamdUser; @@ -204,9 +275,9 @@ in { SupplementaryGroups = [ config.services.redis.servers.rspamd.group ]; } - (lib.optionalAttrs cfg.dkimSigning { - ExecStartPre = map createDkimKeypair dkimDomains; - ReadWritePaths = [ cfg.dkimKeyDirectory ]; + (lib.optionalAttrs cfg.dkim.enable { + ExecStartPre = map createDkimKeypair dkimKeysToGenerate; + ReadWritePaths = [ cfg.dkim.keyDirectory ]; }) ]; }; diff --git a/mail-server/systemd.nix b/mail-server/systemd.nix index 208b8de..b401d6b 100644 --- a/mail-server/systemd.nix +++ b/mail-server/systemd.nix @@ -66,9 +66,9 @@ in after = [ "dovecot.service" ] - ++ lib.optional cfg.dkimSigning "rspamd.service" + ++ lib.optional cfg.dkim.enable "rspamd.service" ++ certificateDeps; - requires = [ "dovecot.service" ] ++ lib.optional cfg.dkimSigning "rspamd.service"; + requires = [ "dovecot.service" ] ++ lib.optional cfg.dkim.enable "rspamd.service"; }; }; } diff --git a/tests/external.nix b/tests/external.nix index 21503ba..e4ff571 100644 --- a/tests/external.nix +++ b/tests/external.nix @@ -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/*")