From 95a2affcf30b46bad60b91ea3b65b798e129bc4f Mon Sep 17 00:00:00 2001 From: Matthew Saunders Brown Date: Mon, 22 Nov 2021 14:18:18 -0800 Subject: [PATCH] checks for domain & mbox status, moved spam detectin and filtering up in the routers --- etc/exim4/exim4.conf | 96 +++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/etc/exim4/exim4.conf b/etc/exim4/exim4.conf index c457952..1b0f749 100644 --- a/etc/exim4/exim4.conf +++ b/etc/exim4/exim4.conf @@ -656,18 +656,13 @@ acl_data: # Warn unless there is a verifiable sender address in at least # one of the "Sender:", "Reply-To:", or "From:" header lines. - # - # - accept - message = X-Sender-Verify-Failed: No valid sender in message header - log_message = No valid sender in message header + warn !verify = header_sender + log_message = No valid sender in message header add_header = X-Sender-Verify-Failed: No valid sender in message header - add_header = X-Junk-Flag: YES # Deny if the message contains a virus. Before enabling this check, you # must install a virus scanner and set the av_scanner option above. - ## accept ## condition = ${if ! def:header_X-Junk-Flag: } ## malware = */defer_ok @@ -719,15 +714,45 @@ dnslookup: # The remaining routers handle addresses in the local domain(s). +virtual_alias: + driver = redirect + domains = +local_domains + local_part_suffix = +* + local_part_suffix_optional = true + condition = ${if !eq {$received_protocol}{spam-scanned}} + data = ${lookup mysql{SELECT CONCAT(vm_mboxes.mbox,'@${domain}') FROM vm_aliases, vm_mboxes, vm_domains WHERE vm_aliases.alias='${local_part}' AND vm_aliases.mbox_id = vm_mboxes.id AND vm_mboxes.domain_id = vm_domains.id AND vm_domains.domain='${domain}' AND vm_domains.status = '1' AND vm_mboxes.status = '1'}} + junk_filter: driver = accept domains = +local_domains local_part_suffix = +* local_part_suffix_optional = true - condition = ${if eq {$header_X-Junk-Flag:}{YES}} + condition = ${if and { \ + { !eq {$received_protocol}{spam-scanned}} \ + { eq {$header_X-Junk-Flag:}{YES}} \ + { !eq {$header_X-Whitelist-Flag:}{YES}} \ + } {yes}{no}} condition = ${lookup mysql{SELECT vm_mboxes.id FROM vm_domains, vm_mboxes WHERE vm_domains.domain='${domain}' AND vm_mboxes.mbox='${local_part}' AND vm_domains.id = vm_mboxes.domain_id AND vm_domains.status = '1' AND vm_mboxes.status = '1' AND vm_mboxes.filter > '0'}} transport = junk_delivery +spamcheck_router: + driver = accept + domains = +local_domains + local_part_suffix = +* + local_part_suffix_optional = true + condition = ${if and { \ + { !eq {$received_protocol}{spam-scanned}} \ + { !eq {$sender_address_domain}{$domain}} \ + { < {$message_size}{512k}} \ + { !eq {$header_X-Junk-Flag:}{YES}} \ + { !eq {$header_X-Whitelist-Flag:}{YES}} \ + { eq {${lookup mysql{SELECT vm_mboxes.status FROM vm_domains, vm_mboxes WHERE vm_domains.domain='${domain}' AND vm_mboxes.mbox='${local_part}' AND vm_domains.id = vm_mboxes.domain_id AND vm_domains.status = '1'}{$value}fail}}{1} } \ + } {yes} {no}} + # check domain & mbox 'status'? + # Check for other headers too? Blacklist, SPF, DKIM failers go directly to Spam folder without spam scan??? - actually they should go to spam folder before this router is hit? + headers_remove = X-Spam-Checker-Version:X-Spam-Flag:X-Spam-Level:X-Spam-Status:X-Spam-Score:X-Spam-Report + transport = spamcheck + spam_filter: driver = accept domains = +local_domains @@ -736,6 +761,7 @@ spam_filter: condition = ${if and { \ { eq {$received_protocol}{spam-scanned}} \ { eq {$header_X-Spam-Flag:}{YES}} \ + { !eq {$header_X-Whitelist-Flag:}{YES}} \ } {yes}{no}} condition = ${lookup mysql{SELECT vm_mboxes.id FROM vm_domains, vm_mboxes WHERE vm_domains.domain='${domain}' AND vm_mboxes.mbox='${local_part}' AND vm_domains.id = vm_mboxes.domain_id AND vm_domains.status = '1' AND vm_mboxes.status = '1' AND vm_mboxes.filter = '2'}} transport = junk_delivery @@ -745,7 +771,6 @@ virtual_vacation: domains = +local_domains # do not reply to errors or lists or spam-scanned messages, require vacation message in db condition = ${if and { \ - { !eq {$received_protocol}{spam-scanned}} \ {!match {$h_precedence:} {(?i)junk|bulk|list}} \ {!eq {$sender_address} {}} \ { eq {${lookup mysql{SELECT vm_autoresponders.mode FROM vm_domains, vm_mboxes, vm_autoresponders WHERE vm_domains.domain='${domain}' AND vm_mboxes.mbox='${local_part}' AND vm_domains.id = vm_mboxes.domain_id AND vm_autoresponders.mbox_id = vm_mboxes.id AND vm_domains.status = '1' AND vm_mboxes.status = '1' AND vm_autoresponders.status = '1'}{$value}fail}}{Vacation}} \ @@ -771,7 +796,6 @@ virtual_autoresponder: #local_part_suffix_optional = true # do not reply to errors or lists or spam-scanned messages, require autoresponder message in db condition = ${if and { \ - { !eq {$received_protocol}{spam-scanned}} \ {!match {$h_precedence:} {(?i)junk|bulk|list}} \ {!eq {$sender_address} {}} \ { eq {${lookup mysql{SELECT vm_autoresponders.mode FROM vm_domains, vm_mboxes, vm_autoresponders WHERE vm_domains.domain='${domain}' AND vm_mboxes.mbox='${local_part}' AND vm_domains.id = vm_mboxes.domain_id AND vm_autoresponders.mbox_id = vm_mboxes.id AND vm_domains.status = '1' AND vm_mboxes.status = '1' AND vm_autoresponders.status = '1'}{$value}fail}}{Autoresponder} } \ @@ -794,36 +818,9 @@ virtual_forward: domains = +local_domains local_part_suffix = +* local_part_suffix_optional = true - condition = ${if !eq {$received_protocol}{spam-scanned}} data = ${lookup mysql{SELECT vm_forwards.forward_to FROM vm_domains, vm_mboxes, vm_forwards WHERE vm_domains.domain='${domain}' AND vm_domains.id = vm_mboxes.domain_id AND vm_mboxes.mbox='${local_part}' AND vm_mboxes.id=vm_forwards.mbox_id AND vm_domains.status = '1' AND vm_mboxes.status = '1' }} unseen = ${lookup mysql{SELECT vm_forwards.id FROM vm_domains, vm_mboxes, vm_forwards WHERE vm_domains.domain='${domain}' AND vm_domains.id = vm_mboxes.domain_id AND vm_mboxes.mbox='${local_part}' AND vm_mboxes.id=vm_forwards.mbox_id AND vm_domains.status = '1' AND vm_mboxes.status = '1' AND vm_forwards.save_local='1'}{true}{false}} -virtual_alias: - driver = redirect - domains = +local_domains - local_part_suffix = +* - local_part_suffix_optional = true - condition = ${if !eq {$received_protocol}{spam-scanned}} - data = ${lookup mysql{SELECT CONCAT(vm_mboxes.mbox,'@${domain}') FROM vm_aliases, vm_mboxes, vm_domains WHERE vm_aliases.alias='${local_part}' AND vm_aliases.mbox_id = vm_mboxes.id AND vm_mboxes.domain_id = vm_domains.id AND vm_domains.domain='${domain}' AND vm_domains.status = '1' AND vm_mboxes.status = '1'}} - -spamcheck_router: - driver = accept - domains = +local_domains - local_part_suffix = +* - local_part_suffix_optional = true - condition = ${if and { \ - { !eq {$received_protocol}{spam-scanned}} \ - { !eq {$sender_address_domain}{$domain}} \ - { < {$message_size}{512k}} \ - { !eq {$header_X-Junk-Flag:}{YES}} \ - { !eq {$header_X-Whitelist-Flag:}{YES}} \ - { eq {${lookup mysql{SELECT vm_mboxes.status FROM vm_domains, vm_mboxes WHERE vm_domains.domain='${domain}' AND vm_mboxes.mbox='${local_part}' AND vm_domains.id = vm_mboxes.domain_id AND vm_domains.status = '1'}{$value}fail}}{1} } \ - } {yes} {no}} - # check domain & mbox 'status'? - # Check for other headers too? Blacklist, SPF, DKIM failers go directly to Spam folder without spam scan??? - actually they should go to spam folder before this router is hit? - headers_remove = X-Spam-Checker-Version:X-Spam-Flag:X-Spam-Level:X-Spam-Status:X-Spam-Score:X-Spam-Report - transport = spamcheck - user_filter: driver = redirect domains = +local_domains @@ -851,6 +848,13 @@ lmtp_localuser: transport = dovecot_lmtp cannot_route_message = Unknown user +# Support for catchall aliases. It is *not* recommended to use this. +virtual_alias_catchall: + driver = redirect + domains = +local_domains + condition = ${if !eq {$received_protocol}{spam-scanned}} + data = ${lookup mysql{SELECT CONCAT(vm_mboxes.mbox,'@${domain}') FROM vm_aliases, vm_mboxes, vm_domains WHERE vm_aliases.alias='catchall' AND vm_aliases.mbox_id = vm_mboxes.id AND vm_mboxes.domain_id = vm_domains.id AND vm_domains.domain='${domain}' AND vm_domains.status='1' AND vm_mboxes.status='1'}} + # This router handles aliasing using a linearly searched alias file with the # name SYSTEM_ALIASES_FILE. When this configuration is installed automatically, # the name gets inserted into this file from whatever is set in Exim's @@ -877,9 +881,9 @@ system_aliases: allow_fail allow_defer data = ${lookup{$local_part}lsearch{/etc/aliases}} -# user = exim - file_transport = address_file - pipe_transport = address_pipe +# user = exim +# file_transport = address_file +# pipe_transport = address_pipe # This router handles forwarding using traditional .forward files in users' @@ -1120,16 +1124,16 @@ begin rewrite begin authenticators -dovecot_login: - driver = dovecot - public_name = LOGIN - server_socket = /run/dovecot/auth-client - server_set_id = $auth1 - dovecot_plain: driver = dovecot public_name = PLAIN server_socket = /run/dovecot/auth-client server_set_id = $auth1 +dovecot_login: + driver = dovecot + public_name = LOGIN + server_socket = /run/dovecot/auth-client + server_set_id = $auth1 + # End of Exim configuration file