at 15.09-beta 12 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.postfix; 8 user = cfg.user; 9 group = cfg.group; 10 setgidGroup = cfg.setgidGroup; 11 12 mainCf = 13 '' 14 queue_directory = /var/postfix/queue 15 command_directory = ${pkgs.postfix}/sbin 16 daemon_directory = ${pkgs.postfix}/libexec/postfix 17 18 mail_owner = ${user} 19 default_privs = nobody 20 21 '' 22 + optionalString config.networking.enableIPv6 '' 23 inet_protocols = all 24 '' 25 + (if cfg.networks != null then 26 '' 27 mynetworks = ${concatStringsSep ", " cfg.networks} 28 '' 29 else if cfg.networksStyle != "" then 30 '' 31 mynetworks_style = ${cfg.networksStyle} 32 '' 33 else 34 # Postfix default is subnet, but let's play safe 35 '' 36 mynetworks_style = host 37 '') 38 + optionalString (cfg.hostname != "") '' 39 myhostname = ${cfg.hostname} 40 '' 41 + optionalString (cfg.domain != "") '' 42 mydomain = ${cfg.domain} 43 '' 44 + optionalString (cfg.origin != "") '' 45 myorigin = ${cfg.origin} 46 '' 47 + optionalString (cfg.destination != null) '' 48 mydestination = ${concatStringsSep ", " cfg.destination} 49 '' 50 + optionalString (cfg.relayDomains != null) '' 51 relay_domains = ${concatStringsSep ", " cfg.relayDomains} 52 '' 53 + '' 54 local_recipient_maps = 55 56 relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then 57 cfg.relayHost 58 else 59 "[" + cfg.relayHost + "]"} 60 61 alias_maps = hash:/var/postfix/conf/aliases 62 63 mail_spool_directory = /var/spool/mail/ 64 65 setgid_group = ${setgidGroup} 66 '' 67 + optionalString (cfg.sslCert != "") '' 68 69 smtp_tls_CAfile = ${cfg.sslCACert} 70 smtp_tls_cert_file = ${cfg.sslCert} 71 smtp_tls_key_file = ${cfg.sslKey} 72 73 smtp_use_tls = yes 74 75 smtpd_tls_CAfile = ${cfg.sslCACert} 76 smtpd_tls_cert_file = ${cfg.sslCert} 77 smtpd_tls_key_file = ${cfg.sslKey} 78 79 smtpd_use_tls = yes 80 81 recipient_delimiter = ${cfg.recipientDelimiter} 82 '' 83 + optionalString (cfg.virtual != "") '' 84 virtual_alias_maps = hash:/etc/postfix/virtual 85 '' 86 + cfg.extraConfig; 87 88 masterCf = '' 89 # ========================================================================== 90 # service type private unpriv chroot wakeup maxproc command + args 91 # (yes) (yes) (yes) (never) (100) 92 # ========================================================================== 93 smtp inet n - n - - smtpd 94 #submission inet n - n - - smtpd 95 # -o smtpd_tls_security_level=encrypt 96 # -o smtpd_sasl_auth_enable=yes 97 # -o smtpd_client_restrictions=permit_sasl_authenticated,reject 98 # -o milter_macro_daemon_name=ORIGINATING 99 pickup unix n - n 60 1 pickup 100 cleanup unix n - n - 0 cleanup 101 qmgr unix n - n 300 1 qmgr 102 tlsmgr unix - - n 1000? 1 tlsmgr 103 rewrite unix - - n - - trivial-rewrite 104 bounce unix - - n - 0 bounce 105 defer unix - - n - 0 bounce 106 trace unix - - n - 0 bounce 107 verify unix - - n - 1 verify 108 flush unix n - n 1000? 0 flush 109 proxymap unix - - n - - proxymap 110 proxywrite unix - - n - 1 proxymap 111 smtp unix - - n - - smtp 112 relay unix - - n - - smtp 113 -o smtp_fallback_relay= 114 # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 115 showq unix n - n - - showq 116 error unix - - n - - error 117 retry unix - - n - - error 118 discard unix - - n - - discard 119 local unix - n n - - local 120 virtual unix - n n - - virtual 121 lmtp unix - - n - - lmtp 122 anvil unix - - n - 1 anvil 123 scache unix - - n - 1 scache 124 ${cfg.extraMasterConf} 125 ''; 126 127 aliases = 128 optionalString (cfg.postmasterAlias != "") '' 129 postmaster: ${cfg.postmasterAlias} 130 '' 131 + optionalString (cfg.rootAlias != "") '' 132 root: ${cfg.rootAlias} 133 '' 134 + cfg.extraAliases 135 ; 136 137 aliasesFile = pkgs.writeText "postfix-aliases" aliases; 138 virtualFile = pkgs.writeText "postfix-virtual" cfg.virtual; 139 mainCfFile = pkgs.writeText "postfix-main.cf" mainCf; 140 masterCfFile = pkgs.writeText "postfix-master.cf" masterCf; 141 142in 143 144{ 145 146 ###### interface 147 148 options = { 149 150 services.postfix = { 151 152 enable = mkOption { 153 default = false; 154 description = "Whether to run the Postfix mail server."; 155 }; 156 157 setSendmail = mkOption { 158 default = true; 159 description = "Whether to set the system sendmail to postfix's."; 160 }; 161 162 user = mkOption { 163 default = "postfix"; 164 description = "What to call the Postfix user (must be used only for postfix)."; 165 }; 166 167 group = mkOption { 168 default = "postfix"; 169 description = "What to call the Postfix group (must be used only for postfix)."; 170 }; 171 172 setgidGroup = mkOption { 173 default = "postdrop"; 174 description = " 175 How to call postfix setgid group (for postdrop). Should 176 be uniquely used group. 177 "; 178 }; 179 180 networks = mkOption { 181 default = null; 182 example = ["192.168.0.1/24"]; 183 description = " 184 Net masks for trusted - allowed to relay mail to third parties - 185 hosts. Leave empty to use mynetworks_style configuration or use 186 default (localhost-only). 187 "; 188 }; 189 190 networksStyle = mkOption { 191 default = ""; 192 description = " 193 Name of standard way of trusted network specification to use, 194 leave blank if you specify it explicitly or if you want to use 195 default (localhost-only). 196 "; 197 }; 198 199 hostname = mkOption { 200 default = ""; 201 description =" 202 Hostname to use. Leave blank to use just the hostname of machine. 203 It should be FQDN. 204 "; 205 }; 206 207 domain = mkOption { 208 default = ""; 209 description =" 210 Domain to use. Leave blank to use hostname minus first component. 211 "; 212 }; 213 214 origin = mkOption { 215 default = ""; 216 description =" 217 Origin to use in outgoing e-mail. Leave blank to use hostname. 218 "; 219 }; 220 221 destination = mkOption { 222 default = null; 223 example = ["localhost"]; 224 description = " 225 Full (!) list of domains we deliver locally. Leave blank for 226 acceptable Postfix default. 227 "; 228 }; 229 230 relayDomains = mkOption { 231 default = null; 232 example = ["localdomain"]; 233 description = " 234 List of domains we agree to relay to. Default is the same as 235 destination. 236 "; 237 }; 238 239 relayHost = mkOption { 240 default = ""; 241 description = " 242 Mail relay for outbound mail. 243 "; 244 }; 245 246 lookupMX = mkOption { 247 default = false; 248 description = " 249 Whether relay specified is just domain whose MX must be used. 250 "; 251 }; 252 253 postmasterAlias = mkOption { 254 default = "root"; 255 description = "Who should receive postmaster e-mail."; 256 }; 257 258 rootAlias = mkOption { 259 default = ""; 260 description = " 261 Who should receive root e-mail. Blank for no redirection. 262 "; 263 }; 264 265 extraAliases = mkOption { 266 default = ""; 267 description = " 268 Additional entries to put verbatim into aliases file, cf. man-page aliases(8). 269 "; 270 }; 271 272 extraConfig = mkOption { 273 default = ""; 274 description = " 275 Extra lines to be added verbatim to the main.cf configuration file. 276 "; 277 }; 278 279 sslCert = mkOption { 280 default = ""; 281 description = "SSL certificate to use."; 282 }; 283 284 sslCACert = mkOption { 285 default = ""; 286 description = "SSL certificate of CA."; 287 }; 288 289 sslKey = mkOption { 290 default = ""; 291 description = "SSL key to use."; 292 }; 293 294 recipientDelimiter = mkOption { 295 default = ""; 296 example = "+"; 297 description = " 298 Delimiter for address extension: so mail to user+test can be handled by ~user/.forward+test 299 "; 300 }; 301 302 virtual = mkOption { 303 default = ""; 304 description = " 305 Entries for the virtual alias map, cf. man-page virtual(8). 306 "; 307 }; 308 309 extraMasterConf = mkOption { 310 default = ""; 311 example = "submission inet n - n - - smtpd"; 312 description = "Extra lines to append to the generated master.cf file."; 313 }; 314 315 }; 316 317 }; 318 319 320 ###### implementation 321 322 config = mkIf config.services.postfix.enable { 323 324 environment = { 325 etc = singleton 326 { source = "/var/postfix/conf"; 327 target = "postfix"; 328 }; 329 330 # This makes comfortable for root to run 'postqueue' for example. 331 systemPackages = [ pkgs.postfix ]; 332 }; 333 334 services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail { 335 program = "sendmail"; 336 source = "${pkgs.postfix}/bin/sendmail"; 337 owner = "nobody"; 338 group = "postdrop"; 339 setuid = false; 340 setgid = true; 341 }; 342 343 users.extraUsers = singleton 344 { name = user; 345 description = "Postfix mail server user"; 346 uid = config.ids.uids.postfix; 347 group = group; 348 }; 349 350 users.extraGroups = 351 [ { name = group; 352 gid = config.ids.gids.postfix; 353 } 354 { name = setgidGroup; 355 gid = config.ids.gids.postdrop; 356 } 357 ]; 358 359 jobs.postfix = 360 # I copy _lots_ of shipped configuration filed 361 # that can be left as is. I am afraid the exact 362 # will list slightly change in next Postfix 363 # release, so listing them all one-by-one in an 364 # accurate way is unlikely to be better. 365 { description = "Postfix mail server"; 366 367 wantedBy = [ "multi-user.target" ]; 368 after = [ "network.target" ]; 369 370 daemonType = "fork"; 371 372 preStart = '' 373 if ! [ -d /var/spool/postfix ]; then 374 ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue 375 fi 376 377 ${pkgs.coreutils}/bin/chown -R ${user}:${group} /var/postfix 378 ${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue 379 ${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue 380 ${pkgs.coreutils}/bin/chown root:root /var/spool/mail 381 ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail 382 ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/mail 383 384 ln -sf "${pkgs.postfix}/etc/postfix/"* /var/postfix/conf 385 386 ln -sf ${aliasesFile} /var/postfix/conf/aliases 387 ln -sf ${virtualFile} /var/postfix/conf/virtual 388 ln -sf ${mainCfFile} /var/postfix/conf/main.cf 389 ln -sf ${masterCfFile} /var/postfix/conf/master.cf 390 391 ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases 392 ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual 393 394 ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start 395 ''; 396 397 preStop = '' 398 ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop 399 ''; 400 401 }; 402 403 }; 404 405}