X-Git-Url: https://git.distorted.org.uk/~mdw/exim-config/blobdiff_plain/e12c95862063d5cba833a8db2852916eb5e4e87f..9384ef4f973dc22ca7e65b1710f1c486c4efad0c:/base.m4 diff --git a/base.m4 b/base.m4 index fee3626..62b46ab 100644 --- a/base.m4 +++ b/base.m4 @@ -25,6 +25,7 @@ ### Global settings. SECTION(global, priv)m4_dnl +admin_groups = CONF_admin_groups prod_requires_admin = false SECTION(global, logging)m4_dnl @@ -58,18 +59,18 @@ gecos_pattern = ([^,:]*) SECTION(global, incoming)m4_dnl received_header_text = Received: \ - ${if def:sender_rcvhost {from $sender_rcvhost\n\t} \ + ${if def:sender_rcvhost \ + {from $sender_rcvhost\n\t} \ {${if def:sender_ident \ - {from ${quote_local_part:$sender_ident} }}\ - ${if def:sender_helo_name \ - {(helo=$sender_helo_name)\n\t}}}}\ + {from ${quote_local_part:$sender_ident} }}}}\ by $primary_hostname \ + (Exim $version_number)\ + ${if def:tls_cipher {\n\t} { }}\ ${if def:received_protocol \ {with $received_protocol \ - ${if def:tls_cipher {(cipher=$tls_cipher)\n\t}}}}\ - (Exim $version_number)\n\t\ + ${if def:tls_cipher {(cipher=$tls_cipher)}}}}\n\t\ ${if def:sender_address \ - {(envelope-from <$sender_address>\ + {(envelope-from $sender_address\ ${if def:authenticated_id \ {; auth=$authenticated_id}})\n\t}}\ id $message_exim_id\ @@ -96,16 +97,50 @@ SECTION(global, acl)m4_dnl acl_smtp_helo = helo SECTION(acl, misc)m4_dnl helo: - require message = The other one has bells on - verify = helo + ## Check that the caller's claimed identity is actually plausible. + ## This seems like it's a fairly effective filter on spamminess, but + ## it's too blunt a tool. Rather than reject, add a warning header. + ## Only we can't do this the easy way, so save it up for use in MAIL. + ## Also, we're liable to get a subsequent HELO (e.g., after STARTTLS) + ## and we should only care about the most recent one. + warn set acl_c_helo_warning = false + !condition = \ + ${if exists {CONF_sysconf_dir/helo.conf} \ + {${lookup {$sender_helo_name} \ + partial0-lsearch \ + {CONF_sysconf_dir/helo.conf} \ + {${if match_ip \ + {$sender_host_address} \ + {$value}}}}}} + !verify = helo + set acl_c_helo_warning = true accept SECTION(global, acl)m4_dnl +acl_not_smtp_start = not_smtp_start +SECTION(acl, misc)m4_dnl +not_smtp_start: + ## Record the user's name. + warn set acl_c_user = $sender_ident + + ## Done. + accept + +SECTION(global, acl)m4_dnl acl_smtp_mail = mail SECTION(acl, mail)m4_dnl mail: + ## If we stashed a warning header about HELO from earlier, we should + ## add it now. + warn condition = $acl_c_helo_warning + add_header = :after_received:X-Distorted-Warning: \ + BADHELO \ + Client's HELO doesn't match its IP address.\n\t\ + HELO name=$sender_helo_name, \ + address=$sender_host_address + ## Always allow the empty sender, so that we can receive bounces. accept senders = : @@ -119,6 +154,15 @@ mail: warn condition = ${if eq{$acl_c_mode}{submission}} control = submission + ## Insist that a local client connect through TLS. + deny message = Hosts within CONF_master_domain must use TLS + !condition = ${if eq{$acl_c_mode}{submission}} + hosts = +allnets + !encrypted = * + + ## Check that a submitted message's sender address is allowable. + require acl = mail_check_auth + SECTION(acl, mail-tail)m4_dnl ## And we're done. accept @@ -185,6 +229,51 @@ expn_vrfy: DIVERT(null) ###-------------------------------------------------------------------------- +### Verification of sender address. + +SECTION(acl, misc)m4_dnl +mail_check_auth: + + ## If this isn't a submission then it doesn't need checking. + accept condition = ${if !eq{$acl_c_mode}{submission}} + + ## If the caller hasn't formally authenticated, but this is a + ## loopback connection, then we can trust identd to tell us the right + ## answer. So we should stash the right name somewhere consistent. + warn set acl_c_user = $authenticated_id + hosts = +localnet + !authenticated = * + set acl_c_user = $sender_ident + + ## User must be authenticated. + deny message = Sender not authenticated + !hosts = +localnet + !authenticated = * + + ## Make sure that the local part is one that the authenticated sender + ## is allowed to claim. + deny message = Sender address forbidden to calling user + !condition = ${LOOKUP_DOMAIN($sender_address_domain, + {${if and {{match_local_part \ + {$acl_c_user} \ + {+dom_users}} \ + {match_local_part \ + {$sender_address_local_part} \ + {+dom_locals}}}}}, + {${if and {{match_local_part \ + {$sender_address_local_part} \ + {+user_extaddr}} \ + {or {{eq {$sender_address_domain} \ + {}} \ + {match_domain \ + {$sender_address_domain} \ + {+public}}}}}}})} + + ## All done. + accept + +DIVERT(null) +###-------------------------------------------------------------------------- ### Common options for forwarding routers. ## We're pretty permissive here. @@ -220,6 +309,15 @@ m4_define(<:FILTER_TRANSPORTS:>, pipe_transport = pipe reply_transport = reply:>) +m4_define(<:FILTER_ROUTER:>, +<:$1_vrf: + $2 + FILTER_VERIFY<::>$3 +$1: + $2 + verify = no + FILTER_TRANSPORTS<::>$4:>) + DIVERT(null) ###-------------------------------------------------------------------------- ### Some standard transports. @@ -248,31 +346,42 @@ smtp_local: tls_privatekey = CONF_sysconf_dir/client.key tls_verify_certificates = CONF_ca_dir/ca.cert tls_require_ciphers = CONF_good_ciphers - tls_dh_min_bits = 3070 + tls_dh_min_bits = 2046 tls_tempfail_tryclear = false authenticated_sender = ${if def:authenticated_id \ - ${authenticated_id@CONF_master_domain} \ + {$authenticated_id@CONF_master_domain} \ fail} ## A standard transport for local delivery. deliver: driver = appendfile file = /var/mail/$local_part + group = mail + mode = 0600 + mode_fail_narrower = false USER_DELIVERY ## Transports for user filters. mailbox: driver = appendfile + initgroups = true USER_DELIVERY maildir: driver = appendfile maildir_format = true + initgroups = true USER_DELIVERY pipe: driver = pipe - return_output = true + path = ${if and {{def:home} {exists{$home/bin}}} {$home/bin:} {}}\ + /usr/local/bin:/usr/local/sbin:\ + /usr/bin:/usr/sbin:/bin:/sbin + initgroups = true + umask = 002 + return_fail_output = true + log_output = true ## A special dummy transport for use during address verification. dummy: