diff --git a/nixos/doc/manual/release-notes/rl-2511.section.md b/nixos/doc/manual/release-notes/rl-2511.section.md index 02f752cef0fe..8e5afa62e829 100644 --- a/nixos/doc/manual/release-notes/rl-2511.section.md +++ b/nixos/doc/manual/release-notes/rl-2511.section.md @@ -46,6 +46,11 @@ - `renovate` was updated to v40. See the [upstream release notes](https://github.com/renovatebot/renovate/releases/tag/40.0.0) for breaking changes. +- 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. + ## Other Notable Changes {#sec-release-25.11-notable-changes} diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix index 34c236dcd2a6..85e04b992259 100644 --- a/nixos/modules/services/mail/postfix.nix +++ b/nixos/modules/services/mail/postfix.nix @@ -5,6 +5,10 @@ ... }: let + inherit (lib) + mkOption + types + ; cfg = config.services.postfix; user = cfg.user; @@ -47,7 +51,11 @@ let ); mkEntry = name: value: "${escape name} =${mkVal value}"; in - lib.concatStringsSep "\n" (lib.mapAttrsToList mkEntry cfg.config) + "\n" + cfg.extraConfig; + lib.concatStringsSep "\n" ( + lib.mapAttrsToList mkEntry (lib.filterAttrsRecursive (_: value: value != null) cfg.config) + ) + + "\n" + + cfg.extraConfig; masterCfOptions = { @@ -564,16 +572,60 @@ in }; config = lib.mkOption { - type = - with lib.types; - attrsOf (oneOf [ - bool - int - str - (listOf str) - ]); + type = lib.types.submodule { + freeformType = + with types; + attrsOf ( + nullOr (oneOf [ + bool + int + str + (listOf str) + ]) + ); + options = { + smtpd_tls_chain_files = mkOption { + type = with types; listOf path; + default = [ ]; + example = [ + "/var/lib/acme/mail.example.com/privkey.pem" + "/var/lib/acme/mail.example.com/fullchain.pem" + ]; + description = '' + List of paths to the server private keys and certificates. + + ::: {.caution} + The order of items matters and a private key must always be followed by the corresponding certificate. + ::: + + + ''; + }; + + smtpd_tls_security_level = mkOption { + type = types.enum [ + "none" + "may" + "encrypt" + ]; + default = if config.services.postfix.config.smtpd_tls_chain_files != [ ] then "may" else "none"; + defaultText = lib.literalExpression '' + if config.services.postfix.config.smtpd_tls_chain_files != [ ] then "may" else "none" + ''; + example = "may"; + description = '' + The server TLS security level. Enable TLS by configuring at least `may`. + + + ''; + }; + }; + }; + description = '' The main.cf configuration file as key value set. + + Null values will not be rendered. ''; example = { mail_owner = "postfix"; @@ -599,18 +651,6 @@ in ''; }; - sslCert = lib.mkOption { - type = lib.types.str; - default = ""; - description = "SSL certificate to use."; - }; - - sslKey = lib.mkOption { - type = lib.types.str; - default = ""; - description = "SSL key to use."; - }; - recipientDelimiter = lib.mkOption { type = lib.types.str; default = ""; @@ -974,18 +1014,6 @@ in // lib.optionalAttrs (cfg.tlsTrustedAuthorities != "") { smtp_tls_CAfile = cfg.tlsTrustedAuthorities; smtp_tls_security_level = lib.mkDefault "may"; - } - // lib.optionalAttrs (cfg.sslCert != "") { - smtp_tls_cert_file = cfg.sslCert; - smtp_tls_key_file = cfg.sslKey; - - smtp_tls_security_level = lib.mkDefault "may"; - - smtpd_tls_cert_file = cfg.sslCert; - smtpd_tls_key_file = cfg.sslKey; - - smtpd_tls_security_level = lib.mkDefault "may"; - }; services.postfix.masterConfig = @@ -1150,6 +1178,12 @@ in (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.extraConfig." ) + (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." + ) + (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." + ) (lib.mkChangedOptionModule [ "services" "postfix" "useDane" ] diff --git a/nixos/tests/postfix.nix b/nixos/tests/postfix.nix index 674a7656079f..36a2b03469d6 100644 --- a/nixos/tests/postfix.nix +++ b/nixos/tests/postfix.nix @@ -14,8 +14,10 @@ import ./make-test-python.nix { enableSubmission = true; enableSubmissions = true; tlsTrustedAuthorities = "${certs.ca.cert}"; - sslCert = "${certs.${domain}.cert}"; - sslKey = "${certs.${domain}.key}"; + config.smtpd_tls_chain_files = [ + certs.${domain}.key + certs.${domain}.cert + ]; submissionsOptions = { smtpd_sasl_auth_enable = "yes"; smtpd_client_restrictions = "permit";