at 18.09-beta 7.9 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5{ 6 7 options = { 8 9 services.nullmailer = { 10 enable = mkOption { 11 type = types.bool; 12 default = false; 13 description = "Whether to enable nullmailer daemon."; 14 }; 15 16 user = mkOption { 17 type = types.string; 18 default = "nullmailer"; 19 description = '' 20 User to use to run nullmailer-send. 21 ''; 22 }; 23 24 group = mkOption { 25 type = types.string; 26 default = "nullmailer"; 27 description = '' 28 Group to use to run nullmailer-send. 29 ''; 30 }; 31 32 setSendmail = mkOption { 33 type = types.bool; 34 default = true; 35 description = "Whether to set the system sendmail to nullmailer's."; 36 }; 37 38 remotesFile = mkOption { 39 type = types.nullOr types.str; 40 default = null; 41 description = '' 42 Path to the <code>remotes</code> control file. This file contains a 43 list of remote servers to which to send each message. 44 45 See <code>man 8 nullmailer-send</code> for syntax and available 46 options. 47 ''; 48 }; 49 50 config = { 51 adminaddr = mkOption { 52 type = types.nullOr types.str; 53 default = null; 54 description = '' 55 If set, all recipients to users at either "localhost" (the literal string) 56 or the canonical host name (from the me control attribute) are remapped to this address. 57 This is provided to allow local daemons to be able to send email to 58 "somebody@localhost" and have it go somewhere sensible instead of being bounced 59 by your relay host. To send to multiple addresses, 60 put them all on one line separated by a comma. 61 ''; 62 }; 63 64 allmailfrom = mkOption { 65 type = types.nullOr types.str; 66 default = null; 67 description = '' 68 If set, content will override the envelope sender on all messages. 69 ''; 70 }; 71 72 defaultdomain = mkOption { 73 type = types.nullOr types.str; 74 default = null; 75 description = '' 76 The content of this attribute is appended to any host name that 77 does not contain a period (except localhost), including defaulthost 78 and idhost. Defaults to the value of the me attribute, if it exists, 79 otherwise the literal name defauldomain. 80 ''; 81 }; 82 83 defaulthost = mkOption { 84 type = types.nullOr types.str; 85 default = null; 86 description = '' 87 The content of this attribute is appended to any address that 88 is missing a host name. Defaults to the value of the me control 89 attribute, if it exists, otherwise the literal name defaulthost. 90 ''; 91 }; 92 93 doublebounceto = mkOption { 94 type = types.nullOr types.str; 95 default = null; 96 description = '' 97 If the original sender was empty (the original message was a 98 delivery status or disposition notification), the double bounce 99 is sent to the address in this attribute. 100 ''; 101 }; 102 103 helohost = mkOption { 104 type = types.nullOr types.str; 105 default = null; 106 description = '' 107 Sets the environment variable $HELOHOST which is used by the 108 SMTP protocol module to set the parameter given to the HELO command. 109 Defaults to the value of the me configuration attribute. 110 ''; 111 }; 112 113 idhost = mkOption { 114 type = types.nullOr types.str; 115 default = null; 116 description = '' 117 The content of this attribute is used when building the message-id 118 string for the message. Defaults to the canonicalized value of defaulthost. 119 ''; 120 }; 121 122 maxpause = mkOption { 123 type = types.nullOr types.str; 124 default = null; 125 description = '' 126 The maximum time to pause between successive queue runs, in seconds. 127 Defaults to 24 hours (86400). 128 ''; 129 }; 130 131 me = mkOption { 132 type = types.nullOr types.str; 133 default = null; 134 description = '' 135 The fully-qualifiled host name of the computer running nullmailer. 136 Defaults to the literal name me. 137 ''; 138 }; 139 140 pausetime = mkOption { 141 type = types.nullOr types.str; 142 default = null; 143 description = '' 144 The minimum time to pause between successive queue runs when there 145 are messages in the queue, in seconds. Defaults to 1 minute (60). 146 Each time this timeout is reached, the timeout is doubled to a 147 maximum of maxpause. After new messages are injected, the timeout 148 is reset. If this is set to 0, nullmailer-send will exit 149 immediately after going through the queue once (one-shot mode). 150 ''; 151 }; 152 153 remotes = mkOption { 154 type = types.nullOr types.str; 155 default = null; 156 description = '' 157 A list of remote servers to which to send each message. Each line 158 contains a remote host name or address followed by an optional 159 protocol string, separated by white space. 160 161 See <code>man 8 nullmailer-send</code> for syntax and available 162 options. 163 164 WARNING: This is stored world-readable in the nix store. If you need 165 to specify any secret credentials here, consider using the 166 <code>remotesFile</code> option instead. 167 ''; 168 }; 169 170 sendtimeout = mkOption { 171 type = types.nullOr types.str; 172 default = null; 173 description = '' 174 The time to wait for a remote module listed above to complete sending 175 a message before killing it and trying again, in seconds. 176 Defaults to 1 hour (3600). If this is set to 0, nullmailer-send 177 will wait forever for messages to complete sending. 178 ''; 179 }; 180 }; 181 }; 182 }; 183 184 config = let 185 cfg = config.services.nullmailer; 186 in mkIf cfg.enable { 187 188 assertions = [ 189 { assertion = cfg.config.remotes == null || cfg.remotesFile == null; 190 message = "Only one of `remotesFile` or `config.remotes` may be used at a time."; 191 } 192 ]; 193 194 environment = { 195 systemPackages = [ pkgs.nullmailer ]; 196 etc = let 197 validAttrs = filterAttrs (name: value: value != null) cfg.config; 198 in 199 (foldl' (as: name: as // { "nullmailer/${name}".text = validAttrs.${name}; }) {} (attrNames validAttrs)) 200 // optionalAttrs (cfg.remotesFile != null) { "nullmailer/remotes".source = cfg.remotesFile; }; 201 }; 202 203 users = { 204 users = singleton { 205 name = cfg.user; 206 description = "Nullmailer relay-only mta user"; 207 group = cfg.group; 208 }; 209 210 groups = singleton { 211 name = cfg.group; 212 }; 213 }; 214 215 systemd.services.nullmailer = { 216 description = "nullmailer"; 217 wantedBy = [ "multi-user.target" ]; 218 after = [ "network.target" ]; 219 220 preStart = '' 221 mkdir -p /var/spool/nullmailer/{queue,tmp} 222 rm -f /var/spool/nullmailer/trigger && mkfifo -m 660 /var/spool/nullmailer/trigger 223 chown ${cfg.user} /var/spool/nullmailer/* 224 ''; 225 226 serviceConfig = { 227 User = cfg.user; 228 Group = cfg.group; 229 PermissionsStartOnly=true; 230 ExecStart = "${pkgs.nullmailer}/bin/nullmailer-send"; 231 Restart = "always"; 232 }; 233 }; 234 235 services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail { 236 program = "sendmail"; 237 source = "${pkgs.nullmailer}/bin/sendmail"; 238 owner = cfg.user; 239 group = cfg.group; 240 setuid = true; 241 setgid = true; 242 }; 243 }; 244}