Introduce system name and domain options

Bring them up from the DMARC reporting section to the mailserver toplevel
so they become reusable for the upcoming TLSRPT integration.

We default to the first domain in the domains option, if not set
explicitly, so that `systemDomain` doesn't become a blocker for existing
setups. We still encourage picking out the intended one, which is likely
the one used for the MX hostname.

This also simplifies the DMARC reporting configuration, which doesn't
need to be so fine-grained.

Co-Authored-By: Emily <git@emilylange.de>
This commit is contained in:
Martin Weinelt 2025-07-08 02:44:23 +02:00
parent 0aeb2849ad
commit 2b240501e0
No known key found for this signature in database
GPG key ID: 87C1E9888F856759
5 changed files with 58 additions and 59 deletions

View file

@ -69,6 +69,35 @@ in
description = "The fully qualified domain name of the mail server.";
};
systemName = mkOption {
type = types.str;
default = "${cfg.systemDomain} mail system";
defaultText = literalExpression "\${config.mailserver.systemDomain} mail system";
example = "ACME Corp.";
description = ''
The sender name given in automated reports.
'';
};
systemDomain = mkOption {
type = types.str;
default =
if (config.networking.domain != null && lib.elem config.networking.domain cfg.domains) then
config.networking.domain
else
lib.head cfg.domains;
defaultText = literalExpression ''
if config.networking.domain != null && lib.elem config.networking.domain cfg.domains then
config.networking.domain
else
lib.head cfg.domains
'';
example = literalExpression "config.networking.domain";
description = ''
The primary domain used for sending automated reports.
'';
};
domains = mkOption {
type = types.listOf types.str;
example = [ "example.com" ];
@ -972,51 +1001,6 @@ in
'';
};
localpart = mkOption {
type = types.str;
default = "dmarc-noreply";
example = "dmarc-report";
description = ''
The local part of the email address used for outgoing DMARC reports.
'';
};
domain = mkOption {
type = types.enum cfg.domains;
example = "example.com";
description = ''
The domain from which outgoing DMARC reports are served.
'';
};
email = mkOption {
type = types.str;
default = with cfg.dmarcReporting; "${localpart}@${domain}";
defaultText = literalExpression ''"''${localpart}@''${domain}"'';
readOnly = true;
description = ''
The email address used for outgoing DMARC reports. Read-only.
'';
};
organizationName = mkOption {
type = types.str;
example = "ACME Corp.";
description = ''
The name of your organization used in the `org_name` attribute in
DMARC reports.
'';
};
fromName = mkOption {
type = types.str;
default = cfg.dmarcReporting.organizationName;
defaultText = literalMD "{option}`mailserver.dmarcReporting.organizationName`";
description = ''
The sender name for DMARC reports. Defaults to the organization name.
'';
};
excludeDomains = mkOption {
type = types.listOf types.str;
default = [ ];
@ -1471,5 +1455,19 @@ 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" "dmarcReporting" "domain" ] [ "mailserver" "systemDomain" ])
(mkRenamedOptionModule
[ "mailserver" "dmarcReporting" "organizationName" ]
[ "mailserver" "systemName" ]
)
(mkRemovedOptionModule [ "mailserver" "dmarcReporting" "localpart" ] ''
The localpart is now fixed at `noreply-dmarc` to simplify the configuration.
'')
(mkRemovedOptionModule [ "mailserver" "dmarcReporting" "email" ] ''
The address is now fixed at `noreply-dmarc@''${config.mailserver.systemDomain}` to simplify the configuration.
'')
(mkRemovedOptionModule [ "mailserver" "dmarcReporting" "fromName" ] ''
The name in the `FROM` field for DMARC report now uses the `mailserver.systemName`.
'')
];
}

View file

@ -1,6 +1,15 @@
Release Notes
=============
NixOS 25.11
-----------
- The ``systemName`` and ``systemDomain`` options have been introduced to have
reusable configurations for automated reports (DMARC, TLSRPT). They come with
reasonable defaults, but it is suggested to check and change them as needed.
- DMARC reports are now sent with the ``noreply-dmarc`` localpart from the
system domain.
NixOS 25.05
-----------

View file

@ -94,10 +94,6 @@
domains = [
"example.com"
];
dmarcReporting = {
organizationName = "Example Corp";
domain = "example.com";
};
};
}
];

View file

@ -121,11 +121,11 @@ in
${lib.optionalString cfg.dmarcReporting.enable ''
reporting {
enabled = true;
email = "${cfg.dmarcReporting.email}";
domain = "${cfg.dmarcReporting.domain}";
org_name = "${cfg.dmarcReporting.organizationName}";
from_name = "${cfg.dmarcReporting.fromName}";
msgid_from = "${cfg.dmarcReporting.domain}";
email = "noreply-dmarc@${cfg.systemDomain}";
domain = "${cfg.systemDomain}";
org_name = "${cfg.systemName}";
from_name = "${cfg.systemName}";
msgid_from = "${cfg.systemDomain}";
${lib.optionalString (cfg.dmarcReporting.excludeDomains != [ ]) ''
exclude_domains = ${builtins.toJSON cfg.dmarcReporting.excludeDomains};
''}

View file

@ -47,11 +47,7 @@
];
rewriteMessageId = true;
dkimKeyBits = 1535;
dmarcReporting = {
enable = true;
domain = "example.com";
organizationName = "ACME Corp";
};
dmarcReporting.enable = true;
loginAccounts = {
"user1@example.com" = {