| 1 | ### -*-m4-*- |
| 2 | ### |
| 3 | ### Basic settings for distorted.org.uk Exim configuration |
| 4 | ### |
| 5 | ### (c) 2012 Mark Wooding |
| 6 | ### |
| 7 | |
| 8 | ###----- Licensing notice --------------------------------------------------- |
| 9 | ### |
| 10 | ### This program is free software; you can redistribute it and/or modify |
| 11 | ### it under the terms of the GNU General Public License as published by |
| 12 | ### the Free Software Foundation; either version 2 of the License, or |
| 13 | ### (at your option) any later version. |
| 14 | ### |
| 15 | ### This program is distributed in the hope that it will be useful, |
| 16 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | ### GNU General Public License for more details. |
| 19 | ### |
| 20 | ### You should have received a copy of the GNU General Public License |
| 21 | ### along with this program; if not, write to the Free Software Foundation, |
| 22 | ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 23 | |
| 24 | ###-------------------------------------------------------------------------- |
| 25 | ### Global settings. |
| 26 | |
| 27 | SECTION(global, priv)m4_dnl |
| 28 | admin_groups = CONF_admin_groups |
| 29 | trusted_groups = CONF_trusted_groups |
| 30 | prod_requires_admin = false |
| 31 | |
| 32 | SECTION(global, logging)m4_dnl |
| 33 | log_file_path = : syslog |
| 34 | log_selector = \ |
| 35 | +smtp_confirmation \ |
| 36 | +tls_peerdn |
| 37 | log_timezone = true |
| 38 | syslog_duplication = false |
| 39 | syslog_timestamp = false |
| 40 | |
| 41 | SECTION(global, daemon)m4_dnl |
| 42 | local_interfaces = <; CONF_interfaces |
| 43 | extra_local_interfaces = <; 0.0.0.0 ; ::0 |
| 44 | |
| 45 | SECTION(global, resource)m4_dnl |
| 46 | deliver_queue_load_max = 8 |
| 47 | message_size_limit = 500M |
| 48 | queue_only_load = 12 |
| 49 | smtp_accept_max = 16 |
| 50 | smtp_accept_queue = 32 |
| 51 | smtp_accept_reserve = 4 |
| 52 | smtp_load_reserve = 10 |
| 53 | smtp_reserve_hosts = +trusted |
| 54 | |
| 55 | SECTION(global, policy)m4_dnl |
| 56 | host_lookup = * |
| 57 | |
| 58 | SECTION(global, users)m4_dnl |
| 59 | gecos_name = $1 |
| 60 | gecos_pattern = ([^,:]*) |
| 61 | |
| 62 | SECTION(global, incoming)m4_dnl |
| 63 | rfc1413_hosts = * |
| 64 | rfc1413_query_timeout = 10s |
| 65 | received_header_text = Received: \ |
| 66 | ${if def:sender_rcvhost \ |
| 67 | {from $sender_rcvhost\n\t} \ |
| 68 | {${if def:sender_ident \ |
| 69 | {from ${quote_local_part:$sender_ident} }}}}\ |
| 70 | by $primary_hostname \ |
| 71 | (Exim $version_number)\ |
| 72 | ${if def:tls_cipher {\n\t} { }}\ |
| 73 | ${if def:received_protocol \ |
| 74 | {with $received_protocol \ |
| 75 | ${if def:tls_cipher {(cipher=$tls_cipher)}}}}\n\t\ |
| 76 | ${if def:sender_address \ |
| 77 | {(envelope-from $sender_address\ |
| 78 | ${if def:authenticated_id \ |
| 79 | {; auth=${quote_local_part:$authenticated_id}} \ |
| 80 | {${if and {{def:authenticated_sender} \ |
| 81 | {match_address{$authenticated_sender} \ |
| 82 | {*@CONF_master_domain}}} \ |
| 83 | {; auth=${quote_local_part:\ |
| 84 | ${local_part:\ |
| 85 | $authenticated_sender}}}}}})\n\t}}\ |
| 86 | id $message_exim_id\ |
| 87 | ${if def:received_for {\n\tfor $received_for}} |
| 88 | |
| 89 | SECTION(global, smtp)m4_dnl |
| 90 | smtp_return_error_details = true |
| 91 | accept_8bitmime = true |
| 92 | chunking_advertise_hosts = |
| 93 | |
| 94 | SECTION(global, env)m4_dnl |
| 95 | keep_environment = |
| 96 | |
| 97 | SECTION(global, process)m4_dnl |
| 98 | extract_addresses_remove_arguments = false |
| 99 | headers_charset = utf-8 |
| 100 | qualify_domain = CONF_master_domain |
| 101 | untrusted_set_sender = * |
| 102 | local_from_check = false |
| 103 | local_sender_retain = true |
| 104 | |
| 105 | SECTION(global, bounce)m4_dnl |
| 106 | delay_warning = 1h : 24h : 2d |
| 107 | |
| 108 | SECTION(global, tls)m4_dnl |
| 109 | tls_certificate = CONF_certlist |
| 110 | tls_privatekey = CONF_sysconf_dir/server.key |
| 111 | tls_advertise_hosts = ${if exists {CONF_sysconf_dir/server.key} {*}{}} |
| 112 | tls_dhparam = CONF_ca_dir/dh-param-2048.pem |
| 113 | tls_require_ciphers = ${if or {{={$received_port}{CONF_submission_port}} \ |
| 114 | {match_ip {$sender_host_address}{+trusted}}} \ |
| 115 | {CONF_good_ciphers} \ |
| 116 | {CONF_acceptable_ciphers}} |
| 117 | tls_verify_certificates = CONF_ca_dir/ca.cert |
| 118 | tls_verify_hosts = ${if eq{$acl_c_mode}{submission} {} {+allnets}} |
| 119 | |
| 120 | DIVERT(null) |
| 121 | ###-------------------------------------------------------------------------- |
| 122 | ### Access control lists. |
| 123 | |
| 124 | SECTION(global, acl-after) |
| 125 | SECTION(global, acl)m4_dnl |
| 126 | acl_smtp_helo = helo |
| 127 | SECTION(acl, misc)m4_dnl |
| 128 | helo: |
| 129 | ## Don't worry if this is local submission. MUAs won't necessarily |
| 130 | ## have a clear idea of their hostnames. (For some reason.) |
| 131 | accept condition = ${if !eq{$acl_c_mode}{submission}} |
| 132 | |
| 133 | ## Check that the caller's claimed identity is actually plausible. |
| 134 | ## This seems like it's a fairly effective filter on spamminess, but |
| 135 | ## it's too blunt a tool. Rather than reject, add a warning header. |
| 136 | ## Only we can't do this the easy way, so save it up for use in MAIL. |
| 137 | ## Also, we're liable to get a subsequent HELO (e.g., after STARTTLS) |
| 138 | ## and we should only care about the most recent one. |
| 139 | warn set acl_c_helo_warning = false |
| 140 | !condition = \ |
| 141 | ${if and {{match_ip {$sender_host_address} \ |
| 142 | {<; 127.0.0.0/8 ; ::1}} \ |
| 143 | {match_domain {$sender_helo_name} \ |
| 144 | {localhost : +thishost}}}} |
| 145 | !condition = \ |
| 146 | ${if exists {CONF_sysconf_dir/helo.conf} \ |
| 147 | {${lookup {$sender_helo_name} \ |
| 148 | partial0-lsearch \ |
| 149 | {CONF_sysconf_dir/helo.conf} \ |
| 150 | {${if match_ip \ |
| 151 | {$sender_host_address} \ |
| 152 | {<; $value}}}}}} |
| 153 | !verify = helo |
| 154 | set acl_c_helo_warning = true |
| 155 | |
| 156 | accept |
| 157 | |
| 158 | SECTION(global, acl)m4_dnl |
| 159 | acl_not_smtp_start = not_smtp_start |
| 160 | SECTION(acl, misc)m4_dnl |
| 161 | not_smtp_start: |
| 162 | ## Record the user's name. |
| 163 | warn set acl_c_user = $sender_ident |
| 164 | set acl_m_user = $sender_ident |
| 165 | |
| 166 | ## Done. |
| 167 | accept |
| 168 | |
| 169 | SECTION(global, acl)m4_dnl |
| 170 | acl_smtp_mail = mail |
| 171 | SECTION(acl, mail)m4_dnl |
| 172 | mail: |
| 173 | |
| 174 | ## If we stashed a warning header about HELO from earlier, we should |
| 175 | ## add it now. Only don't bother if the client has authenticated |
| 176 | ## successfully for submission (because we can't expect mobile |
| 177 | ## clients to be properly set up knowing their names), or it's one of |
| 178 | ## our own satellites (because they're either properly set up anyway, |
| 179 | ## or satellites using us as a smarthost). |
| 180 | warn condition = $acl_c_helo_warning |
| 181 | !condition = ${if eq{$acl_c_mode}{submission}} |
| 182 | !hosts = +allnets |
| 183 | WARNING_HEADER(BADHELO, |
| 184 | <:Client's HELO doesn't match its IP address.\n\t\ |
| 185 | helo-name=$sender_helo_name \ |
| 186 | address=$sender_host_address:>) |
| 187 | |
| 188 | ## Always allow the empty sender, so that we can receive bounces. |
| 189 | accept senders = : |
| 190 | |
| 191 | ## Ensure that the sender looks valid. |
| 192 | require acl = mail_check_sender |
| 193 | |
| 194 | ## If this is directly from a client then hack on it for a while. |
| 195 | warn condition = ${if eq{$acl_c_mode}{submission}} |
| 196 | control = submission/sender_retain |
| 197 | |
| 198 | ## Insist that a local client connect through TLS. |
| 199 | deny message = Hosts within CONF_master_domain must use TLS |
| 200 | !condition = ${if eq{$acl_c_mode}{submission}} |
| 201 | hosts = +allnets |
| 202 | !encrypted = * |
| 203 | |
| 204 | ## Check that a submitted message's sender address is allowable. |
| 205 | require acl = mail_check_auth |
| 206 | |
| 207 | SECTION(acl, mail-tail)m4_dnl |
| 208 | ## And we're done. |
| 209 | accept |
| 210 | |
| 211 | SECTION(acl, misc)m4_dnl |
| 212 | mail_check_sender: |
| 213 | |
| 214 | ## See whether there's a special exception for this sender domain. |
| 215 | accept senders = ${LOOKUP_DOMAIN($sender_address_domain, |
| 216 | {KV(senders)})} |
| 217 | |
| 218 | ## Ensure that the sender is routable. This is important to prevent |
| 219 | ## undeliverable bounces. |
| 220 | require message = Invalid sender; \ |
| 221 | ($sender_verify_failure; $acl_verify_message) |
| 222 | verify = sender |
| 223 | |
| 224 | ## We're good, then. |
| 225 | accept |
| 226 | |
| 227 | SECTION(global, acl)m4_dnl |
| 228 | acl_smtp_connect = connect |
| 229 | SECTION(acl, connect)m4_dnl |
| 230 | connect: |
| 231 | SECTION(acl, connect-tail)m4_dnl |
| 232 | ## Configure variables according to the submission mode. |
| 233 | warn acl = check_submission |
| 234 | |
| 235 | ## Done. |
| 236 | accept |
| 237 | |
| 238 | check_submission: |
| 239 | ## See whether this message needs hacking on. |
| 240 | accept !hosts = +thishost |
| 241 | !condition = ${if ={$received_port}{CONF_submission_port}} |
| 242 | set acl_c_mode = relay |
| 243 | |
| 244 | ## Remember to apply submission controls. |
| 245 | warn set acl_c_mode = submission |
| 246 | control = no_enforce_sync |
| 247 | |
| 248 | ## Done. |
| 249 | accept |
| 250 | |
| 251 | SECTION(global, acl)m4_dnl |
| 252 | acl_smtp_rcpt = rcpt |
| 253 | SECTION(acl, rcpt)m4_dnl |
| 254 | rcpt: |
| 255 | |
| 256 | ## Reject if the client isn't allowed to relay and the recipient |
| 257 | ## isn't in one of our known domains. |
| 258 | require message = Relaying not permitted |
| 259 | acl = check_relay |
| 260 | |
| 261 | ## Ensure that the recipient is routable. |
| 262 | require message = Invalid recipient \ |
| 263 | ($recipient_verify_failure; $acl_verify_message) |
| 264 | verify = recipient |
| 265 | |
| 266 | SECTION(acl, misc)m4_dnl |
| 267 | check_relay: |
| 268 | ## Accept either if the client is allowed to relay through us, or if |
| 269 | ## we're the correct place to send this mail. |
| 270 | |
| 271 | ## Known clients and authenticated users are OK. |
| 272 | accept hosts = CONF_relay_clients |
| 273 | accept authenticated = * |
| 274 | |
| 275 | ## Known domains are OK. |
| 276 | accept domains = +public |
| 277 | |
| 278 | ## Finally, domains in our table are OK, unless they say they aren't. |
| 279 | accept domains = \ |
| 280 | ${if exists{CONF_sysconf_dir/domains.conf} \ |
| 281 | {partial0-lsearch; CONF_sysconf_dir/domains.conf}} |
| 282 | condition = DOMKV(service, {$value}{true}) |
| 283 | |
| 284 | ## Nope, that's not allowed. |
| 285 | deny |
| 286 | |
| 287 | SECTION(acl, rcpt-tail)m4_dnl |
| 288 | ## Everything checks out OK: let this one go through. |
| 289 | accept |
| 290 | |
| 291 | SECTION(global, acl)m4_dnl |
| 292 | acl_smtp_data = data |
| 293 | SECTION(acl, data)m4_dnl |
| 294 | data: |
| 295 | ## Don't accept messages with overly-long lines. |
| 296 | deny message = line length exceeds SMTP permitted maximum: \ |
| 297 | $max_received_linelength > 998 |
| 298 | condition = ${if >{$max_received_linelength}{998}} |
| 299 | |
| 300 | SECTION(acl, data-tail)m4_dnl |
| 301 | accept |
| 302 | |
| 303 | SECTION(global, acl)m4_dnl |
| 304 | acl_smtp_expn = expn_vrfy |
| 305 | acl_smtp_vrfy = expn_vrfy |
| 306 | SECTION(acl, misc)m4_dnl |
| 307 | expn_vrfy: |
| 308 | accept hosts = +trusted |
| 309 | deny message = Suck it and see |
| 310 | |
| 311 | DIVERT(null) |
| 312 | ###-------------------------------------------------------------------------- |
| 313 | ### Verification of sender address. |
| 314 | |
| 315 | SECTION(acl, misc)m4_dnl |
| 316 | mail_check_auth: |
| 317 | |
| 318 | ## If this isn't a submission then it doesn't need checking. |
| 319 | accept condition = ${if !eq{$acl_c_mode}{submission}} |
| 320 | |
| 321 | ## If the caller hasn't formally authenticated, but this is a |
| 322 | ## loopback connection, then we can trust identd to tell us the right |
| 323 | ## answer. So we should stash the right name somewhere consistent. |
| 324 | warn set acl_c_user = $authenticated_id |
| 325 | hosts = +thishost |
| 326 | !authenticated = * |
| 327 | condition = ${if def:sender_ident} |
| 328 | set acl_c_user = $sender_ident |
| 329 | |
| 330 | ## User must be authenticated by now. |
| 331 | deny message = Sender not authenticated |
| 332 | condition = ${if !def:acl_c_user} |
| 333 | |
| 334 | ## Set the per-message authentication flag, since we now know that |
| 335 | ## there's a sensible value. |
| 336 | warn set acl_m_user = $acl_c_user |
| 337 | |
| 338 | ## All done. |
| 339 | accept |
| 340 | |
| 341 | DIVERT(null) |
| 342 | ###-------------------------------------------------------------------------- |
| 343 | ### Common options for forwarding routers. |
| 344 | |
| 345 | ## We're pretty permissive here. |
| 346 | m4_define(<:FILTER_BASE:>, |
| 347 | <:driver = redirect |
| 348 | modemask = 002 |
| 349 | check_owner = false |
| 350 | check_group = false |
| 351 | allow_filter = true |
| 352 | allow_defer = true |
| 353 | allow_fail = true |
| 354 | forbid_blackhole = false |
| 355 | check_ancestor = true:>) |
| 356 | |
| 357 | ## Common options for forwarding routers at verification time. |
| 358 | m4_define(<:FILTER_VERIFY:>, |
| 359 | <:verify_only = true |
| 360 | user = CONF_filter_user |
| 361 | forbid_filter_dlfunc = true |
| 362 | forbid_filter_logwrite = true |
| 363 | forbid_filter_perl = true |
| 364 | forbid_filter_readsocket = true |
| 365 | forbid_filter_run = true |
| 366 | file_transport = dummy |
| 367 | directory_transport = dummy |
| 368 | pipe_transport = dummy |
| 369 | reply_transport = dummy:>) |
| 370 | |
| 371 | ## Transports for redirection filters. |
| 372 | m4_define(<:FILTER_TRANSPORTS:>, |
| 373 | <:file_transport = mailbox |
| 374 | directory_transport = maildir |
| 375 | pipe_transport = pipe |
| 376 | reply_transport = reply:>) |
| 377 | |
| 378 | m4_define(<:FILTER_ROUTER:>, |
| 379 | <:$1_vrf: |
| 380 | $2 |
| 381 | FILTER_VERIFY<::>$3 |
| 382 | $1: |
| 383 | $2 |
| 384 | verify = no |
| 385 | FILTER_TRANSPORTS<::>$4:>) |
| 386 | |
| 387 | DIVERT(null) |
| 388 | ###-------------------------------------------------------------------------- |
| 389 | ### Common routers. |
| 390 | |
| 391 | SECTION(routers, alias)m4_dnl |
| 392 | ## Look up the local part in the address map. |
| 393 | alias: |
| 394 | driver = redirect |
| 395 | allow_fail = true |
| 396 | allow_defer = true |
| 397 | user = CONF_filter_user |
| 398 | FILTER_TRANSPORTS |
| 399 | local_parts = nwildlsearch; CONF_alias_file |
| 400 | data = ${expand:$local_part_data} |
| 401 | SECTION(routers, alias-opts)m4_dnl |
| 402 | |
| 403 | DIVERT(null) |
| 404 | ###-------------------------------------------------------------------------- |
| 405 | ### Some standard transports. |
| 406 | |
| 407 | m4_define(<:USER_DELIVERY:>, |
| 408 | <:delivery_date_add = true |
| 409 | envelope_to_add = true |
| 410 | return_path_add = true:>) |
| 411 | |
| 412 | m4_define(<:APPLY_HEADER_CHANGES:>, |
| 413 | <:headers_add = m4_ifelse(<:$1:>, <::>, |
| 414 | <:$acl_m_hdradd:>, |
| 415 | <:${if def:acl_m_hdradd{$acl_m_hdradd\n}}\ |
| 416 | $1:>) |
| 417 | headers_remove = m4_ifelse(<:$2:>, <::>, |
| 418 | <:$acl_m_hdrrm:>, |
| 419 | <:${if def:acl_m_hdrrm{$acl_m_hdrrm:}}\ |
| 420 | $2:>):>) |
| 421 | |
| 422 | m4_define(<:DKIM_SIGN_P:>, |
| 423 | <:and {{exists{CONF_sysconf_dir/dkim-sign.conf}} \ |
| 424 | {!def:h_DKIM-Signature:} \ |
| 425 | {!def:h_List-ID:} \ |
| 426 | {or {{def:authenticated_id} \ |
| 427 | {def:authenticated_sender}}}}:>) |
| 428 | |
| 429 | m4_define(<:DKIM_KEYS_INSTANCE:>, |
| 430 | <:${lookup {${domain:$h_From:}} partial0-lsearch \ |
| 431 | {CONF_sysconf_dir/dkim-sign.conf} \ |
| 432 | _LOOKUP_ARGS(<:$1:>, <:$2:>)}:>) |
| 433 | m4_define(<:DKIM_KEYS_STATE:>, <:${lookup {$1} lsearch \ |
| 434 | {DKIM_KEYS_INSTANCE(<:{CONF_dkim_keys_dir/$value/active/dkim-keys.state}:>)} \ |
| 435 | _LOOKUP_ARGS(<:$2:>, <:$3:>, <:fail:>)}:>) |
| 436 | m4_define(<:DKIM_KEYS_INFO:>, <:DKIM_KEYS_STATE(<:params:>, |
| 437 | <:{${if and {{>={$tod_epoch}{KV(t0)}} \ |
| 438 | {<{$tod_epoch}{${eval:KV(t0) + KV(n)*KV(step)}}}} \ |
| 439 | {DKIM_KEYS_STATE(<:info.${eval:($tod_epoch - KV(t0))/KV(step)}:>, |
| 440 | <:$1:>, <:$2:>)} \ |
| 441 | m4_ifelse(<:$2:>, <::>, <:fail:>, <:$2:>)}}:>, |
| 442 | m4_ifelse(<:$2:>, <::>, <:fail:>, <:$2:>)):>) |
| 443 | |
| 444 | m4_define(<:DKIM_SIGN:>, |
| 445 | <:dkim_domain = \ |
| 446 | ${if DKIM_SIGN_P \ |
| 447 | {DKIM_KEYS_INSTANCE({${domain:$h_From:}})}} |
| 448 | dkim_selector = DKIM_KEYS_INFO(<:{KV(k)}:>) |
| 449 | dkim_private_key = \ |
| 450 | DKIM_KEYS_INSTANCE(<:m4_dnl |
| 451 | {CONF_dkim_keys_dir/$value/active/$dkim_selector.priv}:>) |
| 452 | dkim_canon = relaxed |
| 453 | dkim_strict = true |
| 454 | dkim_sign_headers = CONF_dkim_headers : \ |
| 455 | X-CONF_header_token-DKIM-Key-Publication |
| 456 | headers_add = \ |
| 457 | ${if DKIM_SIGN_P \ |
| 458 | {DKIM_KEYS_INFO(<:m4_dnl |
| 459 | {X-CONF_header_token-DKIM-Key-Publication: \ |
| 460 | DKIM signature not suitable for \ |
| 461 | as evidence after delivery; \ |
| 462 | DKIM private key KV(k) will be \ |
| 463 | published at KV(u) on or before \ |
| 464 | KV(tpub)}:>)}}:>) |
| 465 | |
| 466 | m4_define(<:SMTP_DELIVERY:>, |
| 467 | <:## Prevent sending messages with overly long lines. The use of |
| 468 | ## `message_size_limit' here is somewhat misleading. |
| 469 | message_size_limit = ${if >{$max_received_linelength}{998}{1}{0}}:>) |
| 470 | |
| 471 | SECTION(transports)m4_dnl |
| 472 | ## A standard transport for remote delivery. By default, try to do TLS, and |
| 473 | ## don't worry too much if it's not very secure: the alternative is sending |
| 474 | ## in plaintext anyway. But all of this can be overridden from the |
| 475 | ## `domains.conf' file. Annoyingly, the `tls_dh_min_bits' setting isn't |
| 476 | ## expanded before use, so we can't set it the obvious way. Instead, encode |
| 477 | ## it into the transport name. This is very unpleasant, of course. |
| 478 | smtp: |
| 479 | driver = smtp |
| 480 | SMTP_DELIVERY |
| 481 | APPLY_HEADER_CHANGES |
| 482 | DKIM_SIGN |
| 483 | tls_require_ciphers = CONF_acceptable_ciphers |
| 484 | tls_dh_min_bits = 508 |
| 485 | tls_tempfail_tryclear = true |
| 486 | |
| 487 | m4_define(<:SMTP_TRANS_DHBITS:>, |
| 488 | <:driver = smtp |
| 489 | SMTP_DELIVERY |
| 490 | APPLY_HEADER_CHANGES |
| 491 | DKIM_SIGN |
| 492 | hosts_try_auth = * |
| 493 | hosts_require_tls = DOMKV(tls-peer-ca, {*}{}) |
| 494 | hosts_require_auth = \ |
| 495 | ${if bool {DOMKV(require-auth, {$value}{false})} {*}{}} |
| 496 | tls_certificate = DOMKV(tls-certificate, {${expand:$value}}fail) |
| 497 | tls_privatekey = DOMKV(tls-private-key, {${expand:$value}}fail) |
| 498 | tls_verify_certificates = DOMKV(tls-peer-ca, {${expand:$value}}fail) |
| 499 | tls_require_ciphers = \ |
| 500 | DOMKV(tls-ciphers, |
| 501 | {${extract {${expand:$value}} \ |
| 502 | { good = CONF_good_ciphers \ |
| 503 | any = CONF_acceptable_ciphers } \ |
| 504 | {$value} \ |
| 505 | {${expand:$value}}}} \ |
| 506 | {CONF_acceptable_ciphers}) |
| 507 | tls_dh_min_bits = $1 |
| 508 | tls_tempfail_tryclear = true:>)m4_dnl |
| 509 | smtp_dhbits_512: |
| 510 | SMTP_TRANS_DHBITS(508) |
| 511 | smtp_dhbits_768: |
| 512 | SMTP_TRANS_DHBITS(764) |
| 513 | smtp_dhbits_1024: |
| 514 | SMTP_TRANS_DHBITS(1020) |
| 515 | smtp_dhbits_2048: |
| 516 | SMTP_TRANS_DHBITS(2044) |
| 517 | |
| 518 | ## Transport to a local SMTP server; use TLS and perform client |
| 519 | ## authentication. |
| 520 | smtp_local: |
| 521 | driver = smtp |
| 522 | SMTP_DELIVERY |
| 523 | APPLY_HEADER_CHANGES |
| 524 | hosts_require_tls = * |
| 525 | tls_certificate = CONF_sysconf_dir/client.certlist |
| 526 | tls_privatekey = CONF_sysconf_dir/client.key |
| 527 | tls_verify_certificates = CONF_ca_dir/ca.cert |
| 528 | tls_require_ciphers = CONF_good_ciphers |
| 529 | tls_dh_min_bits = 2046 |
| 530 | tls_tempfail_tryclear = false |
| 531 | authenticated_sender_force = true |
| 532 | authenticated_sender = \ |
| 533 | ${if def:acl_m_user {$acl_m_user@CONF_master_domain} \ |
| 534 | {${if def:authenticated_sender {$authenticated_sender} \ |
| 535 | fail}}} |
| 536 | |
| 537 | ## A standard transport for local delivery. |
| 538 | deliver: |
| 539 | driver = appendfile |
| 540 | APPLY_HEADER_CHANGES |
| 541 | file = /var/mail/$local_part |
| 542 | group = mail |
| 543 | mode = 0600 |
| 544 | mode_fail_narrower = false |
| 545 | USER_DELIVERY |
| 546 | |
| 547 | ## Transports for user filters. |
| 548 | mailbox: |
| 549 | driver = appendfile |
| 550 | APPLY_HEADER_CHANGES |
| 551 | initgroups = true |
| 552 | USER_DELIVERY |
| 553 | |
| 554 | maildir: |
| 555 | driver = appendfile |
| 556 | APPLY_HEADER_CHANGES |
| 557 | maildir_format = true |
| 558 | initgroups = true |
| 559 | USER_DELIVERY |
| 560 | |
| 561 | pipe: |
| 562 | driver = pipe |
| 563 | APPLY_HEADER_CHANGES |
| 564 | path = ${if and {{def:home} {exists{$home/bin}}} {$home/bin:} {}}\ |
| 565 | /usr/local/bin:/usr/local/sbin:\ |
| 566 | /usr/bin:/usr/sbin:/bin:/sbin |
| 567 | initgroups = true |
| 568 | umask = 002 |
| 569 | return_fail_output = true |
| 570 | log_output = true |
| 571 | |
| 572 | ## A special dummy transport for use during address verification. |
| 573 | dummy: |
| 574 | driver = appendfile |
| 575 | file = /dev/null |
| 576 | |
| 577 | DIVERT(null) |
| 578 | ###-------------------------------------------------------------------------- |
| 579 | ### Retry configuration. |
| 580 | |
| 581 | SECTION(retry, default)m4_dnl |
| 582 | ## Be persistent when sending to the site relay. It ought to work, but |
| 583 | ## particularly satellites such as laptops often encounter annoying temporary |
| 584 | ## failures due to network unavailability, and the usual gradual policy can |
| 585 | ## leave mail building up for no good reason. |
| 586 | CONF_smarthost * \ |
| 587 | F,4d,15m |
| 588 | |
| 589 | ## Default. |
| 590 | * * \ |
| 591 | F,2h,15m; G,16h,2h,1.5; F,4d,6h |
| 592 | |
| 593 | DIVERT(null) |
| 594 | ###----- That's all, folks -------------------------------------------------- |