nixos/postfix: fold main and master config into settings attribute

This commit is contained in:
Martin Weinelt 2025-07-17 00:40:08 +02:00
parent 791dcff3a9
commit 7f52135a59
No known key found for this signature in database
GPG Key ID: 87C1E9888F856759
26 changed files with 341 additions and 322 deletions

View File

@ -118,8 +118,8 @@
- The Postfix module has been updated and likely requires configuration changes:
- The `services.postfix.sslCert` and `sslKey` options were removed and you now need to configure
- [services.postfix.config.smtpd_tls_chain_files](#opt-services.postfix.config.smtpd_tls_chain_files) for server certificates,
- [services.postfix.config.smtp_tls_chain_files](#opt-services.postfix.config) for client certificates.
- [services.postfix.settings.main.smtpd_tls_chain_files](#opt-services.postfix.settings.main.smtpd_tls_chain_files) for server certificates,
- [services.postfix.settings.main.smtp_tls_chain_files](#opt-services.postfix.settings.main) for client certificates.
- `vmalert` now supports multiple instances with the option `services.vmalert.instances."".enable`

View File

@ -14,7 +14,7 @@ For a basic configuration with Postfix as the MTA, the following settings are su
{
services.postfix = {
enable = true;
config = {
settings.main = {
transport_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ];
local_recipient_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ];
relay_domains = [ "hash:/var/lib/mailman/data/postfix_domains" ];

View File

@ -554,7 +554,7 @@ in
];
services.postfix = lib.mkIf cfg.enablePostfix {
config = {
settings.main = {
owner_request_special = "no"; # Mailman handles -owner addresses on its own
recipient_delimiter = "+"; # bake recipient addresses in mail envelopes via VERP
};

View File

@ -120,11 +120,11 @@ in
services.postfix = {
enable = true;
config = {
settings.main = {
recipient_delimiter = "+";
propagate_unmatched_extensions = "virtual";
};
masterConfig.mlmmj = {
settings.master.mlmmj = {
type = "unix";
private = true;
privileged = true;

View File

@ -51,7 +51,7 @@ in
config = lib.mkMerge [
(lib.mkIf (cfg.enable && cfg.configurePostfix && config.services.postfix.enable) {
services.postfix.config = {
services.postfix.settings.main = {
sender_canonical_maps = [ "tcp:127.0.0.1:10001" ];
sender_canonical_classes = [ "envelope_sender" ];
recipient_canonical_maps = [ "tcp:127.0.0.1:10002" ];

View File

@ -135,7 +135,7 @@ in
config = mkMerge [
(mkIf (cfg.enable && config.services.postfix.enable && cfg.configurePostfix) {
# https://github.com/Zuplu/postfix-tlspol#postfix-configuration
services.postfix.config = {
services.postfix.settings.main = {
smtp_dns_support_level = "dnssec";
smtp_tls_security_level = "dane";
smtp_tls_policy_maps =

View File

@ -53,7 +53,7 @@ let
mkEntry = name: value: "${escape name} =${mkVal value}";
in
lib.concatStringsSep "\n" (
lib.mapAttrsToList mkEntry (lib.filterAttrsRecursive (_: value: value != null) cfg.config)
lib.mapAttrsToList mkEntry (lib.filterAttrsRecursive (_: value: value != null) cfg.settings.main)
);
masterCfOptions =
@ -235,7 +235,7 @@ let
""
];
masterCf = lib.mapAttrsToList (lib.const (lib.getAttr "rawEntry")) cfg.masterConfig;
masterCf = lib.mapAttrsToList (lib.const (lib.getAttr "rawEntry")) cfg.settings.master;
# A list of the maximum width of the columns across all lines and labels
maxWidths =
@ -511,7 +511,8 @@ in
description = "The format the alias map should have. Use regexp if you want to use regular expressions.";
};
config = lib.mkOption {
settings = {
main = lib.mkOption {
type = lib.types.submodule {
freeformType =
with types;
@ -707,9 +708,10 @@ in
"may"
"encrypt"
];
default = if config.services.postfix.config.smtpd_tls_chain_files != [ ] then "may" else "none";
default =
if config.services.postfix.settings.main.smtpd_tls_chain_files != [ ] then "may" else "none";
defaultText = lib.literalExpression ''
if config.services.postfix.config.smtpd_tls_chain_files != [ ] then "may" else "none"
if config.services.postfix.settings.main.smtpd_tls_chain_files != [ ] then "may" else "none"
'';
example = "may";
description = ''
@ -736,6 +738,30 @@ in
};
};
master = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule masterCfOptions);
default = { };
example = {
submission = {
type = "inet";
args = [
"-o"
"smtpd_tls_security_level=encrypt"
];
};
};
description = ''
The {file}`master.cf` configuration file as an attribute set of service
defitions
::: {.tip}
Check <https://www.postfix.org/master.5.html> for possible settings.
:::
'';
};
};
canonical = lib.mkOption {
type = lib.types.lines;
default = "";
@ -797,25 +823,6 @@ in
description = "contents of check_client_access for overriding dnsBlacklists";
};
masterConfig = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule masterCfOptions);
default = { };
example = {
submission = {
type = "inet";
args = [
"-o"
"smtpd_tls_security_level=encrypt"
];
};
};
description = ''
An attribute set of service options, which correspond to the service
definitions usually done within the Postfix
{file}`master.cf` file.
'';
};
extraMasterConf = lib.mkOption {
type = lib.types.lines;
default = "";
@ -1016,7 +1023,7 @@ in
};
};
services.postfix.config =
services.postfix.settings.main =
(lib.mapAttrs (_: v: lib.mkDefault v) {
compatibility_level = pkgs.postfix.version;
mail_owner = cfg.user;
@ -1057,7 +1064,7 @@ in
header_checks = [ "regexp:/etc/postfix/header_checks" ];
};
services.postfix.masterConfig = {
services.postfix.settings.master = {
pickup = {
private = false;
wakeup = 60;
@ -1216,66 +1223,74 @@ in
imports = [
(lib.mkRemovedOptionModule [ "services" "postfix" "sslCACert" ]
"services.postfix.sslCACert was replaced by services.postfix.tlsTrustedAuthorities. In case you intend that your server should validate requested client certificates use services.postfix.config.smtp_tls_CAfile."
"services.postfix.sslCACert was replaced by services.postfix.tlsTrustedAuthorities. In case you intend that your server should validate requested client certificates use services.postfix.settings.main.smtp_tls_CAfile."
)
(lib.mkRemovedOptionModule [ "services" "postfix" "sslCert" ]
"services.postfix.sslCert was removed. Use services.postfix.config.smtpd_tls_chain_files for the server certificate, or services.postfix.config.smtp_tls_chain_files for the client certificate."
"services.postfix.sslCert was removed. Use services.postfix.settings.main.smtpd_tls_chain_files for the server certificate, or services.postfix.settings.main.smtp_tls_chain_files for the client certificate."
)
(lib.mkRemovedOptionModule [ "services" "postfix" "sslKey" ]
"services.postfix.sslKey was removed. Use services.postfix.config.smtpd_tls_chain_files for server private key, or services.postfix.config.smtp_tls_chain_files for the client private key."
"services.postfix.sslKey was removed. Use services.postfix.settings.main.smtpd_tls_chain_files for server private key, or services.postfix.settings.main.smtp_tls_chain_files for the client private key."
)
(lib.mkRemovedOptionModule [ "services" "postfix" "lookupMX" ]
"services.postfix.lookupMX was removed. Use services.postfix.config.relayhost and put the hostname in angled brackets, if you need to turn off MX and SRV lookups."
"services.postfix.lookupMX was removed. Use services.postfix.settings.main.relayhost and put the hostname in angled brackets, if you need to turn off MX and SRV lookups."
)
(lib.mkRemovedOptionModule [ "services" "postfix" "relayHost" ]
"services.postfix.relayHost was removed in favor of services.postfix.config.relayhost, which now takes a list of host/port."
"services.postfix.relayHost was removed in favor of services.postfix.settings.main.relayhost, which now takes a list of host/port."
)
(lib.mkRemovedOptionModule [ "services" "postfix" "relayPort" ]
"services.postfix.relayHost was removed in favor of services.postfix.config.relayhost, which now takes a list of host/port."
"services.postfix.relayHost was removed in favor of services.postfix.settings.main.relayhost, which now takes a list of host/port."
)
(lib.mkRemovedOptionModule [ "services" "postfix" "extraConfig" ]
"services.postfix.extraConfig was replaced by the structured freeform service.postfix.config option."
"services.postfix.extraConfig was replaced by the structured freeform service.postfix.settings.main option."
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "networks" ]
[ "services" "postfix" "config" "mynetworks" ]
[ "services" "postfix" "settings" "main" "mynetworks" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "networkStyle" ]
[ "services" "postfix" "config" "mynetworks_style" ]
[ "services" "postfix" "settings" "main" "mynetworks_style" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "hostname" ]
[ "services" "postfix" "config" "myhostname" ]
[ "services" "postfix" "settings" "main" "myhostname" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "domain" ]
[ "services" "postfix" "config" "mydomain" ]
[ "services" "postfix" "settings" "main" "mydomain" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "origin" ]
[ "services" "postfix" "config" "myorigin" ]
[ "services" "postfix" "settings" "main" "myorigin" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "destination" ]
[ "services" "postfix" "config" "mydestination" ]
[ "services" "postfix" "settings" "main" "mydestination" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "relayDomains" ]
[ "services" "postfix" "config" "relay_domains" ]
[ "services" "postfix" "settings" "main" "relay_domains" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "recipientDelimiter" ]
[ "services" "postfix" "config" "recipient_delimiter" ]
[ "services" "postfix" "settings" "main" "recipient_delimiter" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "tlsTrustedAuthoriies" ]
[ "services" "postfix" "config" "smtp_tls_CAfile" ]
[ "services" "postfix" "settings" "main" "smtp_tls_CAfile" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "config" ]
[ "services" "postfix" "settings" "main" ]
)
(lib.mkRenamedOptionModule
[ "services" "postfix" "masterConfig" ]
[ "services" "postfix" "settings" "master" ]
)
(lib.mkChangedOptionModule
[ "services" "postfix" "useDane" ]
[ "services" "postfix" "config" "smtp_tls_security_level" ]
[ "services" "postfix" "settings" "main" "smtp_tls_security_level" ]
(config: lib.mkIf config.services.postfix.useDane "dane")
)
(lib.mkRenamedOptionModule [ "services" "postfix" "useSrs" ] [ "services" "pfix-srsd" "enable" ])

View File

@ -235,7 +235,7 @@ in
config = lib.mkMerge [
(lib.mkIf (cfg.enable && cfg.configurePostfix && config.services.postfix.enable) {
services.postfix.config = {
services.postfix.settings.main = {
# https://github.com/roehling/postsrsd#configuration
sender_canonical_maps = "socketmap:${cfg.settings.socketmap}:forward";
sender_canonical_classes = "envelope_sender";

View File

@ -426,7 +426,7 @@ in
};
services.postfix = mkIf (cfg.postfix.enable && cfg.mda.enable) {
# Not sure limiting to 1 is necessary, but better safe than sorry.
config.public-inbox_destination_recipient_limit = "1";
settings.main.public-inbox_destination_recipient_limit = "1";
# Register the addresses as existing
virtual = concatStringsSep "\n" (
@ -443,7 +443,7 @@ in
);
# The public-inbox transport
masterConfig.public-inbox = {
settings.master.public-inbox = {
type = "unix";
privileged = true; # Required for user=
command = "pipe";

View File

@ -451,7 +451,7 @@ in
'';
};
};
services.postfix.config = mkIf cfg.postfix.enable cfg.postfix.config;
services.postfix.settings.main = mkIf cfg.postfix.enable cfg.postfix.config;
systemd.services.postfix = mkIf cfg.postfix.enable {
serviceConfig.SupplementaryGroups = [ postfixCfg.group ];

View File

@ -115,7 +115,7 @@ in
flags=DRhu user=schleuder argv=/${pkgs.schleuder}/bin/schleuder work ''${recipient}
'';
transport = lib.mkIf (cfg.lists != [ ]) (postfixMap (lib.genAttrs cfg.lists (_: "schleuder:")));
config.schleuder_destination_recipient_limit = 1;
settings.main.schleuder_destination_recipient_limit = 1;
# review: does this make sense?
localRecipients = lib.mkIf (cfg.lists != [ ]) cfg.lists;
};

View File

@ -585,7 +585,8 @@ in
services.postfix = lib.mkIf (cfg.mta.type == "postfix") {
enable = true;
config = {
settings = {
main = {
recipient_delimiter = "+";
virtual_alias_maps = [ "hash:${dataDir}/virtual.sympa" ];
virtual_mailbox_maps = [
@ -599,7 +600,7 @@ in
"hash:${dataDir}/sympa_transport"
];
};
masterConfig = {
master = {
"sympa" = {
type = "unix";
privileged = true;
@ -626,6 +627,7 @@ in
};
};
};
};
services.mysql = lib.optionalAttrs mysqlLocal {
enable = true;

View File

@ -128,6 +128,6 @@ in
-o smtpd_authorized_xforward_hosts=127.0.0.0/8,[::1]/128
'';
services.postfix.config.content_filter = "zeyple";
services.postfix.settings.main.content_filter = "zeyple";
};
}

View File

@ -427,7 +427,7 @@ in
services.postfix = lib.mkIf cfg.provision.localMail.enable {
enable = true;
config = {
settings.main = {
myhostname = cfg.provision.localMail.hostname;
myorigin = cfg.provision.localMail.hostname;
mydestination = cfg.provision.localMail.hostname;

View File

@ -1077,7 +1077,7 @@ in
services.postfix = lib.mkIf cfg.mail.incoming.enable {
enable = true;
config = {
settings.main = {
smtpd_recipient_restrictions = "check_policy_service unix:private/discourse-policy";
append_dot_mydomain = lib.mkDefault false;
compatibility_level = "2";
@ -1097,7 +1097,7 @@ in
transport = ''
${cfg.hostname} discourse-mail-receiver:
'';
masterConfig = {
settings.master = {
"discourse-mail-receiver" = {
type = "unix";
privileged = true;

View File

@ -1100,7 +1100,7 @@ in
services.postfix = lib.mkIf (cfg.smtp.createLocally && cfg.smtp.host == "127.0.0.1") {
enable = true;
config.myhostname = lib.mkDefault "${cfg.localDomain}";
settings.main.myhostname = lib.mkDefault "${cfg.localDomain}";
};
services.redis.servers.mastodon = lib.mkIf redisActuallyCreateLocally (

View File

@ -959,7 +959,7 @@ in
services.postfix = lib.mkIf cfg.smtp.createLocally {
enable = true;
config.myhostname = lib.mkDefault "${cfg.localDomain}";
settings.main.myhostname = lib.mkDefault "${cfg.localDomain}";
};
users.users = lib.mkMerge [

View File

@ -28,7 +28,7 @@ in
enableSubmission = true;
enableSubmissions = true;
config = {
settings.main = {
smtp_tls_CAfile = "${certs.ca.cert}";
smtpd_tls_chain_files = [
"${certs.${domain}.key}"

View File

@ -107,7 +107,7 @@ in
services.postfix = {
enable = true;
config = {
settings.main = {
compatibility_level = "2";
mydestination = [ clientDomain ];
myhostname = clientDomain;

View File

@ -13,16 +13,18 @@
services.mailman.webHosts = [ "example.com" ];
services.postfix.enable = true;
services.postfix.config.mydestination = [
services.postfix.settings.main = {
mydestination = [
"example.com"
"example.net"
];
services.postfix.config.relay_domains = [ "hash:/var/lib/mailman/data/postfix_domains" ];
services.postfix.config.local_recipient_maps = [
relay_domains = [ "hash:/var/lib/mailman/data/postfix_domains" ];
local_recipient_maps = [
"hash:/var/lib/mailman/data/postfix_lmtp"
"proxy:unix:passwd.byname"
];
services.postfix.config.transport_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ];
transport_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ];
};
users.users.user = {
isNormalUser = true;

View File

@ -187,7 +187,7 @@ in
# blackhole transport
transport = "example.com discard:silently";
config = {
settings.main = {
myhostname = "${mailerDomain}";
# open relay for subnet
mynetworks_style = "subnet";

View File

@ -184,7 +184,7 @@ in
services.postfix = {
enable = true;
origin = mailDomain;
config = {
settings.main = {
myhostname = mailDomain;
mydestination = mailDomain;
};

View File

@ -13,7 +13,7 @@ import ./make-test-python.nix {
enable = true;
enableSubmission = true;
enableSubmissions = true;
config = {
settings.main = {
smtp_tls_CAfile = "${certs.ca.cert}";
smtpd_tls_chain_files = [
certs.${domain}.key

View File

@ -166,7 +166,7 @@ in
setSendmail = true;
#sslCert = "${tls-cert}/cert.pem";
#sslKey = "${tls-cert}/key.pem";
config.recipient_delimiter = "+";
settings.main.recipient_delimiter = "+";
};
environment.systemPackages = [

View File

@ -293,7 +293,7 @@ in
};
services.postfix = {
enable = true;
config.mydestination = [ "example.com" ];
settings.main.mydestination = [ "example.com" ];
};
services.rspamd = {
enable = true;

View File

@ -11,7 +11,7 @@ in
services.postfix = {
enable = true;
enableSubmission = true;
config = {
settings.main = {
mydomain = domain;
destination = domain;
smtp_tls_CAfile = "${certs.ca.cert}";