diff --git a/lib/fudo/mail/postfix.nix b/lib/fudo/mail/postfix.nix index c66fc5e..ec72abd 100644 --- a/lib/fudo/mail/postfix.nix +++ b/lib/fudo/mail/postfix.nix @@ -8,48 +8,40 @@ let # The final newline is important write-entries = filename: entries: - let - entries-string = (concatStringsSep "\n" entries); + let entries-string = (concatStringsSep "\n" entries); in builtins.toFile filename '' ${entries-string} ''; make-user-aliases = entries: - concatStringsSep "\n" - (mapAttrsToList (user: aliases: - concatStringsSep "\n" - (map (alias: "${alias} ${user}") aliases)) - entries); + concatStringsSep "\n" (mapAttrsToList (user: aliases: + concatStringsSep "\n" + (map (alias: "${alias} ${user}@${cfg.domain}") aliases)) entries); make-alias-users = domains: entries: - concatStringsSep "\n" - (flatten - (mapAttrsToList (alias: users: - (map (domain: - "${alias}@${domain} ${concatStringsSep "," users}") - domains)) - entries)); + concatStringsSep "\n" (flatten (mapAttrsToList (alias: users: + (map (domain: "${alias}@${domain} ${concatStringsSep "," users}") + domains)) entries)); - policyd-spf = pkgs.writeText "policyd-spf.conf" ( - cfg.postfix.policy-spf-extra-config - + (lib.optionalString cfg.debug '' - debugLevel = 4 - '')); + policyd-spf = pkgs.writeText "policyd-spf.conf" + (cfg.postfix.policy-spf-extra-config + (lib.optionalString cfg.debug '' + debugLevel = 4 + '')); - submission-header-cleanup-rules = pkgs.writeText "submission_header_cleanup_rules" ('' - # Removes sensitive headers from mails handed in via the submission port. - # See https://thomas-leister.de/mailserver-debian-stretch/ - # Uses "pcre" style regex. + submission-header-cleanup-rules = + pkgs.writeText "submission_header_cleanup_rules" ('' + # Removes sensitive headers from mails handed in via the submission port. + # See https://thomas-leister.de/mailserver-debian-stretch/ + # Uses "pcre" style regex. - /^Received:/ IGNORE - /^X-Originating-IP:/ IGNORE - /^X-Mailer:/ IGNORE - /^User-Agent:/ IGNORE - /^X-Enigmail:/ IGNORE - ''); + /^Received:/ IGNORE + /^X-Originating-IP:/ IGNORE + /^X-Mailer:/ IGNORE + /^User-Agent:/ IGNORE + /^X-Enigmail:/ IGNORE + ''); blacklist-postfix-entry = sender: "${sender} REJECT"; - blacklist-postfix-file = filename: entries: - write-entries filename entries; + blacklist-postfix-file = filename: entries: write-entries filename entries; sender-blacklist-file = blacklist-postfix-file "reject_senders" (map blacklist-postfix-entry cfg.sender-blacklist); recipient-blacklist-file = blacklist-postfix-file "reject_recipients" @@ -57,12 +49,13 @@ let # A list of domains for which we accept mail virtual-mailbox-map-file = write-entries "virtual_mailbox_map" - (map (domain: "@${domain} OK") (cfg.local-domains ++ [cfg.domain])); + (map (domain: "@${domain} OK") (cfg.local-domains ++ [ cfg.domain ])); - sender-login-map-file = let - escapeDot = (str: replaceStrings ["."] ["\\."] str); - in write-entries "sender_login_maps" - (map (domain: "/^(.*)@${escapeDot domain}$/ \${1}") (cfg.local-domains ++ [cfg.domain])); + sender-login-map-file = + let escapeDot = (str: replaceStrings [ "." ] [ "\\." ] str); + in write-entries "sender_login_maps" + (map (domain: "/^(.*)@${escapeDot domain}$/ \${1}") + (cfg.local-domains ++ [ cfg.domain ])); mapped-file = name: "hash:/var/lib/postfix/conf/${name}"; @@ -112,7 +105,7 @@ in { domain = cfg.domain; origin = cfg.domain; hostname = cfg.mail-hostname; - destination = ["localhost" "localhost.localdomain"]; + destination = [ "localhost" "localhost.localdomain" ]; # destination = ["localhost" "localhost.localdomain" cfg.hostname] ++ # cfg.local-domains;; @@ -132,25 +125,27 @@ in { virtual = '' ${make-user-aliases cfg.user-aliases} - ${make-alias-users ([cfg.domain] ++ cfg.local-domains) cfg.alias-users} + ${make-alias-users ([ cfg.domain ] ++ cfg.local-domains) + cfg.alias-users} ''; sslCert = cfg.postfix.ssl-certificate; sslKey = cfg.postfix.ssl-private-key; config = { - virtual_mailbox_domains = cfg.local-domains ++ [cfg.domain]; + virtual_mailbox_domains = cfg.local-domains ++ [ cfg.domain ]; # virtual_mailbox_base = "${cfg.mail-directory}/"; virtual_mailbox_maps = mapped-file "virtual_mailbox_map"; virtual_uid_maps = "static:${toString cfg.mail-user-id}"; - virtual_gid_maps = "static:${toString config.users.groups."${cfg.mail-group}".gid}"; + virtual_gid_maps = + "static:${toString config.users.groups."${cfg.mail-group}".gid}"; virtual_transport = "lmtp:unix:/run/dovecot2/dovecot-lmtp"; # NOTE: it's important that this ends with /, to indicate Maildir format! # mail_spool_directory = "${cfg.mail-directory}/"; - message_size_limit = toString(cfg.message-size-limit * 1024 * 1024); + message_size_limit = toString (cfg.message-size-limit * 1024 * 1024); smtpd_banner = "${cfg.mail-hostname} ESMTP NO UCE"; @@ -176,7 +171,8 @@ in { recipient_delimiter = "+"; milter_protocol = "6"; - milter_mail_macros = "i {mail_addr} {client_addr} {client_name} {auth_type} {auth_authen} {auth_author} {mail_addr} {mail_host} {mail_mailer}"; + milter_mail_macros = + "i {mail_addr} {client_addr} {client_name} {auth_type} {auth_authen} {auth_author} {mail_addr} {mail_host} {mail_mailer}"; smtpd_milters = [ "unix:/run/rspamd/rspamd-milter.sock" @@ -218,11 +214,8 @@ in { "reject_non_fqdn_recipient" ]; - smtpd_helo_restrictions = [ - "permit_mynetworks" - "reject_invalid_hostname" - "permit" - ]; + smtpd_helo_restrictions = + [ "permit_mynetworks" "reject_invalid_hostname" "permit" ]; # Handled by submission smtpd_tls_security_level = "may"; @@ -230,44 +223,27 @@ in { smtpd_tls_eecdh_grade = "ultra"; # Disable obselete protocols - smtpd_tls_protocols = [ - "TLSv1.2" - "TLSv1.1" - "!TLSv1" - "!SSLv2" - "!SSLv3" - ]; - smtp_tls_protocols = [ - "TLSv1.2" - "TLSv1.1" - "!TLSv1" - "!SSLv2" - "!SSLv3" - ]; - smtpd_tls_mandatory_protocols = [ - "TLSv1.2" - "TLSv1.1" - "!TLSv1" - "!SSLv2" - "!SSLv3" - ]; - smtp_tls_mandatory_protocols = [ - "TLSv1.2" - "TLSv1.1" - "!TLSv1" - "!SSLv2" - "!SSLv3" - ]; + smtpd_tls_protocols = + [ "TLSv1.2" "TLSv1.1" "!TLSv1" "!SSLv2" "!SSLv3" ]; + smtp_tls_protocols = [ "TLSv1.2" "TLSv1.1" "!TLSv1" "!SSLv2" "!SSLv3" ]; + smtpd_tls_mandatory_protocols = + [ "TLSv1.2" "TLSv1.1" "!TLSv1" "!SSLv2" "!SSLv3" ]; + smtp_tls_mandatory_protocols = + [ "TLSv1.2" "TLSv1.1" "!TLSv1" "!SSLv2" "!SSLv3" ]; smtp_tls_ciphers = "high"; smtpd_tls_ciphers = "high"; smtp_tls_mandatory_ciphers = "high"; smtpd_tls_mandatory_ciphers = "high"; - smtpd_tls_mandatory_exclude_ciphers = ["MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL"]; - smtpd_tls_exclude_ciphers = ["MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL"]; - smtp_tls_mandatory_exclude_ciphers = ["MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL"]; - smtp_tls_exclude_ciphers = ["MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL"]; + smtpd_tls_mandatory_exclude_ciphers = + [ "MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL" ]; + smtpd_tls_exclude_ciphers = + [ "MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL" ]; + smtp_tls_mandatory_exclude_ciphers = + [ "MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL" ]; + smtp_tls_exclude_ciphers = + [ "MD5" "DES" "ADH" "RC4" "PSD" "SRP" "3DES" "eNULL" "aNULL" ]; tls_preempt_cipherlist = "yes"; @@ -286,8 +262,10 @@ in { smtpd_sasl_security_options = "noanonymous"; smtpd_sasl_local_domain = cfg.domain; smtpd_client_restrictions = "permit_sasl_authenticated,reject"; - smtpd_sender_restrictions = "reject_sender_login_mismatch,reject_unknown_sender_domain"; - smtpd_recipient_restrictions = "reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject"; + smtpd_sender_restrictions = + "reject_sender_login_mismatch,reject_unknown_sender_domain"; + smtpd_recipient_restrictions = + "reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject"; cleanup_service_name = "submission-header-cleanup"; }; @@ -297,7 +275,11 @@ in { privileged = true; chroot = false; command = "spawn"; - args = [ "user=nobody" "argv=${pkgs.pypolicyd-spf}/bin/policyd-spf" "${policyd-spf}"]; + args = [ + "user=nobody" + "argv=${pkgs.pypolicyd-spf}/bin/policyd-spf" + "${policyd-spf}" + ]; }; "submission-header-cleanup" = { type = "unix"; @@ -305,7 +287,8 @@ in { chroot = false; maxproc = 0; command = "cleanup"; - args = ["-o" "header_checks=pcre:${submission-header-cleanup-rules}"]; + args = + [ "-o" "header_checks=pcre:${submission-header-cleanup-rules}" ]; }; }; }; @@ -313,9 +296,9 @@ in { # Postfix requires dovecot lmtp socket, dovecot auth socket and certificate to work systemd.services.postfix = { after = [ "dovecot2.service" ] - ++ (lib.optional cfg.dkim.signing "opendkim.service"); + ++ (lib.optional cfg.dkim.signing "opendkim.service"); requires = [ "dovecot2.service" ] - ++ (lib.optional cfg.dkim.signing "opendkim.service"); + ++ (lib.optional cfg.dkim.signing "opendkim.service"); }; }; }