diff options
Diffstat (limited to 'nixos/modules/services/mail/postfix.nix')
-rw-r--r-- | nixos/modules/services/mail/postfix.nix | 233 |
1 files changed, 152 insertions, 81 deletions
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix index 3a9e62a0205..6c5d7e92702 100644 --- a/nixos/modules/services/mail/postfix.nix +++ b/nixos/modules/services/mail/postfix.nix @@ -9,14 +9,14 @@ let group = cfg.group; setgidGroup = cfg.setgidGroup; + haveAliases = cfg.postmasterAlias != "" || cfg.rootAlias != "" || cfg.extraAliases != ""; + haveTransport = cfg.transport != ""; + haveVirtual = cfg.virtual != ""; + mainCf = '' compatibility_level = 2 - queue_directory = /var/postfix/queue - command_directory = ${pkgs.postfix}/sbin - daemon_directory = ${pkgs.postfix}/libexec/postfix - mail_owner = ${user} default_privs = nobody @@ -57,8 +57,6 @@ let else "[" + cfg.relayHost + "]"} - alias_maps = hash:/var/postfix/conf/aliases - mail_spool_directory = /var/spool/mail/ setgid_group = ${setgidGroup} @@ -80,7 +78,13 @@ let + optionalString (cfg.recipientDelimiter != "") '' recipient_delimiter = ${cfg.recipientDelimiter} '' - + optionalString (cfg.virtual != "") '' + + optionalString haveAliases '' + alias_maps = hash:/etc/postfix/aliases + '' + + optionalString haveTransport '' + transport_maps = hash:/etc/postfix/transport + '' + + optionalString haveVirtual '' virtual_alias_maps = hash:/etc/postfix/virtual '' + cfg.extraConfig; @@ -108,10 +112,14 @@ let flush unix n - n 1000? 0 flush proxymap unix - - n - - proxymap proxywrite unix - - n - 1 proxymap + '' + + optionalString cfg.enableSmtp '' smtp unix - - n - - smtp relay unix - - n - - smtp -o smtp_fallback_relay= # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 + '' + + '' showq unix n - n - - showq error unix - - n - - error retry unix - - n - - error @@ -138,6 +146,7 @@ let virtualFile = pkgs.writeText "postfix-virtual" cfg.virtual; mainCfFile = pkgs.writeText "postfix-main.cf" mainCf; masterCfFile = pkgs.writeText "postfix-master.cf" masterCf; + transportFile = pkgs.writeText "postfix-transport" cfg.transport; in @@ -150,26 +159,36 @@ in services.postfix = { enable = mkOption { + type = types.bool; default = false; description = "Whether to run the Postfix mail server."; }; + enableSmtp = mkOption { + default = true; + description = "Whether to enable smtp in master.cf."; + }; + setSendmail = mkOption { + type = types.bool; default = true; description = "Whether to set the system sendmail to postfix's."; }; user = mkOption { + type = types.str; default = "postfix"; description = "What to call the Postfix user (must be used only for postfix)."; }; group = mkOption { + type = types.str; default = "postfix"; description = "What to call the Postfix group (must be used only for postfix)."; }; setgidGroup = mkOption { + type = types.str; default = "postdrop"; description = " How to call postfix setgid group (for postdrop). Should @@ -178,6 +197,7 @@ in }; networks = mkOption { + type = types.nullOr (types.listOf types.str); default = null; example = ["192.168.0.1/24"]; description = " @@ -188,6 +208,7 @@ in }; networksStyle = mkOption { + type = types.str; default = ""; description = " Name of standard way of trusted network specification to use, @@ -197,6 +218,7 @@ in }; hostname = mkOption { + type = types.str; default = ""; description =" Hostname to use. Leave blank to use just the hostname of machine. @@ -205,6 +227,7 @@ in }; domain = mkOption { + type = types.str; default = ""; description =" Domain to use. Leave blank to use hostname minus first component. @@ -212,6 +235,7 @@ in }; origin = mkOption { + type = types.str; default = ""; description =" Origin to use in outgoing e-mail. Leave blank to use hostname. @@ -219,6 +243,7 @@ in }; destination = mkOption { + type = types.nullOr (types.listOf types.str); default = null; example = ["localhost"]; description = " @@ -228,6 +253,7 @@ in }; relayDomains = mkOption { + type = types.nullOr (types.listOf types.str); default = null; example = ["localdomain"]; description = " @@ -236,6 +262,7 @@ in }; relayHost = mkOption { + type = types.str; default = ""; description = " Mail relay for outbound mail. @@ -243,6 +270,7 @@ in }; lookupMX = mkOption { + type = types.bool; default = false; description = " Whether relay specified is just domain whose MX must be used. @@ -250,11 +278,13 @@ in }; postmasterAlias = mkOption { + type = types.str; default = "root"; description = "Who should receive postmaster e-mail."; }; rootAlias = mkOption { + type = types.str; default = ""; description = " Who should receive root e-mail. Blank for no redirection. @@ -262,6 +292,7 @@ in }; extraAliases = mkOption { + type = types.lines; default = ""; description = " Additional entries to put verbatim into aliases file, cf. man-page aliases(8). @@ -269,6 +300,7 @@ in }; extraConfig = mkOption { + type = types.lines; default = ""; description = " Extra lines to be added verbatim to the main.cf configuration file. @@ -276,21 +308,25 @@ in }; sslCert = mkOption { + type = types.str; default = ""; description = "SSL certificate to use."; }; sslCACert = mkOption { + type = types.str; default = ""; description = "SSL certificate of CA."; }; sslKey = mkOption { + type = types.str; default = ""; description = "SSL key to use."; }; recipientDelimiter = mkOption { + type = types.str; default = ""; example = "+"; description = " @@ -299,18 +335,39 @@ in }; virtual = mkOption { + type = types.lines; default = ""; description = " Entries for the virtual alias map, cf. man-page virtual(8). "; }; + transport = mkOption { + default = ""; + description = " + Entries for the transport map, cf. man-page transport(8). + "; + }; + extraMasterConf = mkOption { + type = types.lines; default = ""; example = "submission inet n - n - - smtpd"; description = "Extra lines to append to the generated master.cf file."; }; + aliasFiles = mkOption { + type = types.attrsOf types.path; + default = {}; + description = "Aliases' tables to be compiled and placed into /var/lib/postfix/conf."; + }; + + mapFiles = mkOption { + type = types.attrsOf types.path; + default = {}; + description = "Maps to be compiled and placed into /var/lib/postfix/conf."; + }; + }; }; @@ -318,90 +375,104 @@ in ###### implementation - config = mkIf config.services.postfix.enable { + config = mkIf config.services.postfix.enable (mkMerge [ + { - environment = { - etc = singleton - { source = "/var/postfix/conf"; - target = "postfix"; - }; - - # This makes comfortable for root to run 'postqueue' for example. - systemPackages = [ pkgs.postfix ]; - }; + environment = { + etc = singleton + { source = "/var/lib/postfix/conf"; + target = "postfix"; + }; - services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail { - program = "sendmail"; - source = "${pkgs.postfix}/bin/sendmail"; - owner = "nobody"; - group = "postdrop"; - setuid = false; - setgid = true; - }; + # This makes comfortable for root to run 'postqueue' for example. + systemPackages = [ pkgs.postfix ]; + }; - users.extraUsers = singleton - { name = user; - description = "Postfix mail server user"; - uid = config.ids.uids.postfix; - group = group; + services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail { + program = "sendmail"; + source = "${pkgs.postfix}/bin/sendmail"; + group = setgidGroup; + setuid = false; + setgid = true; }; - users.extraGroups = - [ { name = group; + users.extraUsers = optional (user == "postfix") + { name = "postfix"; + description = "Postfix mail server user"; + uid = config.ids.uids.postfix; + group = group; + }; + + users.extraGroups = + optional (group == "postfix") + { name = group; gid = config.ids.gids.postfix; } + ++ optional (setgidGroup == "postdrop") { name = setgidGroup; gid = config.ids.gids.postdrop; - } - ]; - - systemd.services.postfix = - { description = "Postfix mail server"; - - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - - serviceConfig = { - Type = "forking"; - Restart = "always"; - PIDFile = "/var/postfix/queue/pid/master.pid"; }; - preStart = '' - ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue - - ${pkgs.coreutils}/bin/chown -R ${user}:${group} /var/postfix - ${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue - ${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue - ${pkgs.coreutils}/bin/chown root:root /var/spool/mail - ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail - ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/ - - ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/postfix/conf - - ln -sf ${aliasesFile} /var/postfix/conf/aliases - ln -sf ${virtualFile} /var/postfix/conf/virtual - ln -sf ${mainCfFile} /var/postfix/conf/main.cf - ln -sf ${masterCfFile} /var/postfix/conf/master.cf - - ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases - ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual - ''; - - script = '' - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start - ''; - - reload = '' - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf reload - ''; - - preStop = '' - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop - ''; - - }; - - }; + systemd.services.postfix = + { description = "Postfix mail server"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = [ pkgs.postfix ]; + + serviceConfig = { + Type = "forking"; + Restart = "always"; + PIDFile = "/var/lib/postfix/queue/pid/master.pid"; + ExecStart = "${pkgs.postfix}/bin/postfix start"; + ExecStop = "${pkgs.postfix}/bin/postfix stop"; + ExecReload = "${pkgs.postfix}/bin/postfix reload"; + }; + + preStart = '' + # Backwards compatibility + if [ ! -d /var/lib/postfix ] && [ -d /var/postfix ]; then + mkdir -p /var/lib + mv /var/postfix /var/lib/postfix + fi + mkdir -p /var/lib/postfix/data /var/lib/postfix/queue/{pid,public,maildrop} + + chown -R ${user}:${group} /var/lib/postfix + chown root /var/lib/postfix/queue + chown root /var/lib/postfix/queue/pid + chgrp -R ${setgidGroup} /var/lib/postfix/queue/{public,maildrop} + chmod 770 /var/lib/postfix/queue/{public,maildrop} + + rm -rf /var/lib/postfix/conf + mkdir -p /var/lib/postfix/conf + ln -sf ${mainCfFile} /var/lib/postfix/conf/main.cf + ln -sf ${masterCfFile} /var/lib/postfix/conf/master.cf + ${concatStringsSep "\n" (mapAttrsToList (to: from: '' + ln -sf ${from} /var/lib/postfix/conf/${to} + postalias /var/lib/postfix/conf/${to} + '') cfg.aliasFiles)} + ${concatStringsSep "\n" (mapAttrsToList (to: from: '' + ln -sf ${from} /var/lib/postfix/conf/${to} + postmap /var/lib/postfix/conf/${to} + '') cfg.mapFiles)} + + mkdir -p /var/spool/mail + chown root:root /var/spool/mail + chmod a+rwxt /var/spool/mail + ln -sf /var/spool/mail /var/ + ''; + }; + } + + (mkIf haveAliases { + services.postfix.aliasFiles."aliases" = aliasesFile; + }) + (mkIf haveTransport { + services.postfix.mapFiles."transport" = transportFile; + }) + (mkIf haveVirtual { + services.postfix.mapFiles."virtual" = virtualFile; + }) + ]); } |