Hello,
I am having an Exim configuration running for years without any issues, but
lately I am seeing my server being abused as a relay.
A few things that are boggling my mind:
It is my understanding that the abuse happens after an SPA authentication
but the SPA authentication has failed. Normally I only allow authenticated
external users.
I don't understand this warning: Warning: ACL "warn" statement skipped:
condition test deferred: Could not complete sender verify callout
Would someone be so kind to take a look at my log and config, here below? I
don't understand very well why this abuse is happening.
Thank you!
Jan
This is an example of what I can find in my logfile. Mind the SPA:fail lines
and the ACL "warn" error.
2021-08-04 15:06:57 no host name found for IP address 93.122.252.1
2021-08-04 15:06:58 H=(213.233.88.90) [93.122.252.1] Warning: HELO
(213.233.88.90) is IP only (See RFC2821 4.1.3)
2021-08-04 15:06:58 H=(213.233.88.90) [93.122.252.1] Warning: HELO
(213.233.88.90) is IP only (See RFC2821 4.1.3)
2021-08-04 15:06:58 H=(213.233.88.90) [93.122.252.1] Warning: HELO
(213.233.88.90) is IP only (See RFC2821 4.1.3)
2021-08-04 15:06:58 H=(213.233.88.90) [93.122.252.1] sender verify fail for
<xfinity@???>: all relevant MX records point to non-existent
hosts
2021-08-04 15:06:58 H=(213.233.88.90) [93.122.252.1]
X=TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256 CV=no F=<xfinity@???>
A=SPA:fail rejected RCPT <txbutterfly@???>: Sender verify failed
2021-08-04 15:06:58 unexpected disconnection while reading SMTP command from
(213.233.88.90) [93.122.252.1] D=1s
2021-08-04 15:06:58 no host name found for IP address 93.122.252.1
2021-08-04 15:07:00 H=(213.233.88.90) [93.122.252.1] Warning: HELO
(213.233.88.90) is IP only (See RFC2821 4.1.3)
2021-08-04 15:07:01 [66.96.140.174] SSL verify error (during S-verify for
[93.122.252.1]): depth=1 error=self signed certificate in certificate chain
cert=/C=US/O=Sample, Inc./OU=IT Team
20210129161416/OU=bosimpinc03.eigbox.net.eigbox.net/CN=CA
2021-08-04 15:07:01 [66.96.140.174] SSL verify error (during S-verify for
[93.122.252.1]): certificate name mismatch: DN="/C=US/O=Sample, Inc./OU=IT
Team
20210129161416/OU=bosimpinc03.eigbox.net.eigbox.net/CN=bosimpinc03.eigbox.ne
t.eigbox.net" H="mx.easygreenonions.com"
2021-08-04 15:07:02 H=(213.233.88.90) [93.122.252.1] Warning: Sender
(xfinity@???) could not be verified using callout: Sender
verify failed ()
2021-08-04 15:07:03 [103.141.97.82] SSL verify error (during S-verify for
[93.122.252.1]): certificate name mismatch: DN="/CN=*.xserver.jp"
H="tarochan06.com"
2021-08-04 15:07:03 [66.96.140.175] SSL verify error (during S-verify for
[93.122.252.1]): depth=1 error=self signed certificate in certificate chain
cert=/C=US/O=Sample, Inc./OU=IT Team
20210129161416/OU=bosimpinc03.eigbox.net.eigbox.net/CN=CA
2021-08-04 15:07:03 [66.96.140.175] SSL verify error (during S-verify for
[93.122.252.1]): certificate name mismatch: DN="/C=US/O=Sample, Inc./OU=IT
Team
20210129161416/OU=bosimpinc03.eigbox.net.eigbox.net/CN=bosimpinc03.eigbox.ne
t.eigbox.net" H="mx.easygreenonions.com"
2021-08-04 15:07:04 1mBGbw-000GYn-GT Header Message-ID:
<004e07ac4784aea09cc97fd430143e391254b0@???>
2021-08-04 15:07:04 1mBGbw-000GYn-GT Header From: Xfinity
<xfinity@???>\n
2021-08-04 15:07:04 1mBGbw-000GYn-GT Header Subject: Important Update\n
2021-08-04 15:07:04 1mBGbw-000GYn-GT Header To: jsstro@???
2021-08-04 15:07:04 1mBGbw-000GYn-GT <= xfinity@???
H=(213.233.88.90) [93.122.252.1] P=esmtpsa
X=TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256 CV=no A=SPA:fail S=8666
id=004e07ac4784aea09cc97fd430143e391254b0@??? T="Important
Update" from <xfinity@???> for jsstro@???
2021-08-04 15:07:06 H=(213.233.88.90) [93.122.252.1] Warning: HELO
(213.233.88.90) is IP only (See RFC2821 4.1.3)
2021-08-04 15:07:07 H=(213.233.88.90) [93.122.252.1] Warning: ACL "warn"
statement skipped: condition test deferred: Could not complete sender verify
callout
2021-08-04 15:07:09 [103.141.97.82] SSL verify error (during S-verify for
[93.122.252.1]): certificate name mismatch: DN="/CN=*.xserver.jp"
H="tarochan06.com"
2021-08-04 15:07:10 H=(213.233.88.90) [93.122.252.1] Warning: ACL "warn"
statement skipped: condition test deferred: Could not complete sender verify
callout
2021-08-04 15:07:10 1mBGc2-000GYl-A5 Header Message-ID:
<26f831897db98d0a2986d0848f4b719ab91f403cfc@???>
2021-08-04 15:07:10 1mBGc2-000GYl-A5 Header From: Xfinity
<xfinity@???>\n
2021-08-04 15:07:10 1mBGc2-000GYl-A5 Header Subject: Important Update\n
2021-08-04 15:07:10 1mBGc2-000GYl-A5 Header To: tomnewsom@???
2021-08-04 15:07:10 1mBGc2-000GYl-A5 <= xfinity@???
H=(213.233.88.90) [93.122.252.1] P=esmtpsa
X=TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256 CV=no A=SPA:fail S=8630
id=26f831897db98d0a2986d0848f4b719ab91f403cfc@??? T="Important
Update" from <xfinity@???> for tomnewsom@???
2021-08-04 15:07:10 1mBGbw-000GYn-GT => jsstro@??? R=dnslookup
T=remote_smtp H=mx2.comcast.net [68.87.20.5] TFO
X=TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256 CV=dane
DN="/C=US/postalCode=19103/ST=Pennsylvania/L=Philadelphia/street=1 Comcast
Center/O=Comcast Corporation/OU=Business Center/CN=mx2.comcast.net" C="250
2.0.0 BGbymNa8vcIgCBGc1mwY4F mail accepted for delivery"
2021-08-04 15:07:10 1mBGbw-000GYn-GT Completed
<cut some lines>
2021-08-04 15:07:22 1mBGc2-000GYl-A5 => tomnewsom@??? R=dnslookup
T=remote_smtp H=mx1.comcast.net [96.114.157.80] TFO
X=TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256 CV=dane
DN="/C=US/postalCode=19103/ST=Pennsylvania/L=Philadelphia/street=1 Comcast
Center/O=Comcast Corporation/OU=Business Center/CN=mx1.comcast.net" C="250
2.0.0 BGc3meFVNUMphBGc8mFklE mail accepted for delivery"
2021-08-04 15:07:22 1mBGc2-000GYl-A5 Completed
Config:
primary_hostname = my_local_domain.be
domainlist local_domains = @ : r420.my_local_domain.be : ${tr {${lookup
mysql {\
SELECT `domain` FROM `users` WHERE `domain` != '' &&
`domain` IS NOT NULL \
UNION \
SELECT `domain` FROM `alias` WHERE `domain` != '' &&
`domain` IS NOT NULL \
UNION \
SELECT `domain` FROM `catchall` WHERE `domain` != ''
&& `domain` IS NOT NULL \
}}} {"\n"} {:} }
domainlist relay_to_domains =
domainlist fwd_to_pxm_domains = pxm.fr : pxm.com
hostlist relay_from_hosts = localhost : 192.168.0.0/16
acl_not_smtp = acl_log_message_id
acl_smtp_rcpt = acl_check_rcpt
.ifdef _HAVE_PRDR
acl_smtp_data_prdr = acl_check_prdr
.endif
acl_smtp_data = acl_check_data
acl_smtp_dkim = acl_check_dkim
.ifndef MAIN_ACL_CHECK_MIME
MAIN_ACL_CHECK_MIME = acl_check_mime
.endif
acl_smtp_mime = MAIN_ACL_CHECK_MIME
av_scanner = $acl_m0
spamd_address = /var/run/spamd/spamd.sock
tls_advertise_hosts = *
tls_certificate = /etc/ssl/my_local_domain.be/exim/my_local_domain.be.pem
daemon_smtp_ports = 25 : 465 : 587
tls_on_connect_ports = 465
exim_user = mailnull
exim_group = mail
never_users = root
trusted_users = www : fetchmail : dovecot : spamd
host_lookup = *
dns_dnssec_ok = 1
.ifdef _HAVE_PRDR
prdr_enable = true
.endif
log_selector = +smtp_protocol_error +smtp_syntax_error \
+tls_certificate_verified +address_rewrite +subject \
+all_parents +received_recipients +received_sender
+tls_cipher \
+tls_peerdn
ignore_bounce_errors_after = 2d
timeout_frozen_after = 7d
message_size_limit = 100M
keep_environment = ^LDAP
add_environment =
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
hide srs_secrets = g9H__xxxxxxxxxxxxxxxxxxxx
CHECK_RCPT_SPF = true
dmarc_tld_file = /usr/local/etc/exim/public_suffix_list.dat
dmarc_history_file = /var/spool/exim/opendmarc.dat
dmarc_forensic_sender = do-not-reply@my_local_domain.be
SPAM_FILESIZE_LIMIT = 1M
VIRUS_FILESIZE_LIMIT = 5M
CHECK_RCPT_IP_DNSBLS =
cbl.abuseat.org:zen.spamhaus.org:psbl.surriel.com:b.barracudacentral.org:dns
bl.sorbs.net:spamsources.fabel.dk
begin acl
acl_log_message_id:
accept logwrite = Header Message-ID: $h_message-id:
logwrite = Header From: $rh_from:
logwrite = Header Subject: $rh_subject:
logwrite = Header To: $h_to:
acl_check_dkim:
deny message = DKIM fail?
sender_domains = *
dkim_signers = *
dkim_status = fail
deny message = DKIM fail?
sender_domains = gmail.com
dkim_signers = gmail.com
dkim_status = none:invalid:fail
accept
acl_check_rcpt:
accept hosts = :
control = dkim_disable_verify
control = dmarc_disable_verify
deny message = Sender claims to have a local address, but is
neither authenticated nor relayed (try using SMTP-AUTH!)
log_message = Forged Sender address (claims to be local user
[${sender_address}], but isn't authenticated)
!hosts = +relay_from_hosts
!authenticated = *
condition = ${if
match_domain{$sender_address_domain}{+local_domains}}
warn message = You cannot be localhost.localdomain in the
internet
log_message = HELO is faked as localhost.localdomain
condition = ${if
match{$sender_helo_name}{\Nlocalhost\.localdomain\N}}
warn message = X-Invalid-HELO: HELO is IP only (See RFC2821
4.1.3)
log_message = HELO ($sender_helo_name) is IP only (See RFC2821
4.1.3)
condition = ${if isip{$sender_helo_name}}
warn message = X-Invalid-HELO: HELO is no FQDN (contains no
dot) (See RFC2821 4.1.1.1)
log_message = HELO ($sender_helo_name) is no FQDN (contains no
dot) (See RFC2821 4.1.1.1)
condition = ${if match{$sender_helo_name}{\N^\[\N}{no}{yes}}
condition = ${if match{$sender_helo_name}{\N\.\N}{no}{yes}}
warn message = X-Invalid-HELO: HELO is no FQDN (ends in dot)
(See RFC2821 4.1.1.1)
log_message = HELO ($sender_helo_name) is no FQDN (ends in
dot) (See RFC2821 4.1.1.1)
condition = ${if match{$sender_helo_name}{\N\.$\N}}
warn message = X-Invalid-HELO: HELO is no FQDN (contains double
dot) (See RFC2821 4.1.1.1)
log_message = HELO ($sender_helo_name) is no FQDN (contains
double dot) (See RFC2821 4.1.1.1)
condition = ${if match{$sender_helo_name}{\N\.\.\N}}
warn message = X-Invalid-HELO: Host impersonating
[$primary_hostname]
log_message = HELO ($sender_helo_name) impersonating
[$primary_hostname]
!hosts = 127.0.0.1
condition = ${if
match{$sender_helo_name}{$primary_hostname}{yes}{no}}
warn message = X-Invalid-HELO: $interface_address is _my_
address
log_message = HELO ($sender_helo_name) uses _my_ address
($interface_address)
condition = ${if or{{\
eq{[$interface_address]}{$sender_helo_name}\
}{\
eq{$interface_address}{$sender_helo_name}\
}}}
warn message = X-Invalid-HELO: no HELO
log_message = no HELO ($sender_helo_name)
condition = ${if !def:sender_helo_name}
deny message = Restricted characters in address
domains = +local_domains
local_parts = ^[.] : ^.*[@%!/|]
deny message = Restricted characters in address
domains = !+local_domains
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
accept local_parts = postmaster
domains = +local_domains
accept condition = ${lookup mysql{ \
SELECT CONCAT(`username`,'@',`domain`) AS
`email` \
FROM `alias` \
WHERE `username` =
'${quote_mysql:$local_part}' \
AND `domain` = '${quote_mysql:$domain}' \
AND `sendto` LIKE '|%' \
}{true}{false}}
control = dkim_disable_verify
control = dmarc_disable_verify
deny message = [SPF] $sender_host_address is not allowed to
send mail from $sender_address_domain
log_message = SPF check failed.
!authenticated = *
hosts = !+relay_from_hosts
spf = fail
warn message = $spf_received
require verify = sender
warn message = X-Sender-Verify: FAILED ($sender_verify_failure)
log_message = Sender ($sender_address) could not be verified
using callout: $acl_verify_message ($sender_verify_failure)
!verify = sender/callout=30s,random
warn message = X-Sender-Verify: SUCCEEDED (sender exists &
accepts mail)
verify = sender/callout=30s,random
accept authenticated = *
control = submission/sender_retain/domain=
control = dkim_disable_verify
control = dmarc_disable_verify
accept hosts = +relay_from_hosts
control = submission
control = dkim_disable_verify
control = dmarc_disable_verify
require message = nice hosts say HELO first
condition = ${if def:sender_helo_name}
require message = relay not permitted
domains = +local_domains : +relay_to_domains
require verify = recipient
deny message = ${sender_host_address} is listed at
${dnslist_domain}; See ${dnslist_text}
!hosts = +relay_from_hosts
!authenticated = *
dnslists = CHECK_RCPT_IP_DNSBLS
accept
.ifdef _HAVE_PRDR
acl_check_prdr:
warn set acl_m_did_prdr = y
.endif
accept
acl_check_mime:
deny
decode = default
condition = ${if > {$mime_anomaly_level}{2} \
{true}{false}}
message = This message contains a MIME error
($mime_anomaly_text)
log_message = DENY: MIME Error ($mime_anomaly_text)
deny
condition = ${if >{$mime_part_count}{1024}{yes}{no}}
message = MIME error: Too many parts (max 1024)
log_message = DENY: MIME Error (Too many MIME parts:
$mime_part_count)
deny
regex = ^.{8000}
message = MIME error: Line length in message or single header
exceeds 8000.
log_message = DENY: MIME Error (Maximum line length exceeded)
deny
condition = ${if eq
{$mime_content_type}{message/partial}{yes}{no}}
message = MIME error: MIME type message/partial not allowed here
log_message = DENY: MIME Error (MIME type message/partial found)
deny
condition = ${if >{${strlen:$mime_filename}}{255}{yes}{no}}
message = MIME error: Proposed filename exceeds 255 characters
log_message = DENY: MIME Error (Proposed filename too long)
deny
condition = ${if >{${strlen:$mime_boundary}}{1024}{yes}{no}}
message = MIME error: MIME boundary length exceed 1024
characters
log_message = DENY: MIME Error (Boundary length too long)
deny
condition = ${if match \
{${lc:$mime_filename}} \
{\N(\.bat|\.btm|\.cmd|\.com|\.cpl|\.dll|\.exe|\.lnk|\.msi|\.pif|\.prf|\.reg|
\.scr|\.vbs|\.url)$\N} \
{1}{0}}
message = Blacklisted file extension detected in
"$mime_filename". If you legitimately need to send these files please zip
them first.
log_message = DENY: Blacklisted extension ("$mime_filename")
accept
acl_check_data:
deny message = maximum allowed line length is 998 octets,
\
got $max_received_linelength
condition = ${if > {$max_received_linelength}{998}}
deny !verify = header_syntax
message = header syntax
log_message = header syntax ($acl_verify_message)
warn dmarc_status = accept : none : off
!authenticated = *
log_message = DMARC DEBUG: $dmarc_status for
$dmarc_used_domain
add_header = :at_start:${authresults
{$primary_hostname}}
warn dmarc_status = !accept
!authenticated = *
log_message = DMARC DEBUG: $dmarc_status for
$dmarc_used_domain
add_header = :at_start:${authresults
{$primary_hostname}}
warn dmarc_status = quarantine
!authenticated = *
log_message = DMARC DEBUG: $dmarc_status for
$dmarc_used_domain
add_header = :at_start:${authresults
{$primary_hostname}}
set acl_m_quarantine = 1
deny dmarc_status = reject
!authenticated = *
!hosts = +relay_from_hosts
message = Message from $dmarc_used_domain failed
sender's DMARC policy, REJECT
warn set acl_m0 = clamd:/var/run/clamav/clamd.sock
malware = *
message = This message contains a VIRUS
($malware_name) from $sender_address to $recipients (ClamAV)
log_message = warned about VIRUS ($malware_name) from
$sender_address to $recipients (ClamAV)
remove_header = Subject
add_header = Subject: ***VIRUS***$rh_subject:
set acl_m0 = clamd:/var/run/clamav/clamd.sock
condition = ${if <
{$message_size}{VIRUS_FILESIZE_LIMIT}}
warn message = X-Spam-Score: $spam_score\n\
X-Spam-Score-Int: $spam_score_int\n\
X-Spam-Bar: $spam_bar\n\
X-Spam-Report: $spam_report
log_message = spam scanned: $spam_score (Spamassassin)
!authenticated = *
condition = ${if <
{$message_size}{SPAM_FILESIZE_LIMIT}}
spam = spamd:true
warn add_header = X-Exim-Version: $version_number (build at
$compile_date)\n\
X-Date: $tod_log\n\
X-Connected-IP:
$sender_host_address:$sender_host_port
warn add_header = X-Message-Linecount: $message_linecount\n\
X-Body-Linecount: $body_linecount\n\
X-Message-Size: $message_size\n\
X-Body-Size: $message_body_size\n\
X-Received-Count: $received_count\n\
X-Recipient-Count: $recipients_count\n\
X-Local-Recipient-Count: $rcpt_count\n\
X-Local-Recipient-Defer-Count:
$rcpt_defer_count\n\
X-Local-Recipient-Fail-Count:
$rcpt_fail_count
accept logwrite = Header Message-ID: $h_message-id:
logwrite = Header From: $rh_from:
logwrite = Header Subject: $rh_subject:
logwrite = Header To: $h_to:
begin routers
fwd_to_pxm:
driver = manualroute
domains = +fwd_to_pxm_domains
transport = remote_smtp
route_list = * smtp.xxxxxxx.com
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
dnssec_request_domains = *
no_more
mysql_all_domain_alias:
driver = redirect
domains = +local_domains
local_parts = alle
data = ${lookup mysql{ \
SELECT CONCAT(`username`,'@',`domain`) AS `sendto` \
FROM `users` \
WHERE `domain` = '${quote_mysql:$domain}' \
AND `SMTP_allowed` = 'YES' \
}}
condition = ${if or {{\
def:authenticated_id\
}{\
eq {$sender_host_address}{127.0.0.1}\
}}\
}
file_transport = address_file
pipe_transport = address_pipe
mysql_alias:
driver = redirect
domains = +local_domains
file_transport = address_file
pipe_transport = address_pipe
data = ${if or {{\
def:authenticated_id\
}{\
eq {$sender_host_address}{127.0.0.1}\
}}{\
${lookup mysql{ \
SELECT `sendto` \
FROM `alias` \
WHERE ( `username` =
'${quote_mysql:$local_part}' \
AND (`domain` =
'${quote_mysql:$domain}' OR `domain` = '') )}}\
} {\
${lookup mysql{ \
SELECT `sendto` \
FROM `alias` \
WHERE ( ( `username` =
'${quote_mysql:$local_part}' AND (`domain` = '${quote_mysql:$domain}' OR
`domain` = '') ) \
AND internal='NO' )}}\
}}
local_part_suffix = +*
local_part_suffix_optional
srs = forward
srs_dbinsert = ${lookup mysql{INSERT INTO `SRS` (`Key`, `Address`, `Time`)
VALUES ('${srs_db_key}', '${srs_db_address}', NOW())}}
headers_add = "X-SRS: Sender address rewritten from <$sender_address> by
$primary_hostname."
debug_print = "R: srs_forward for $local_part@$domain"
mysql_user_condition:
driver = accept
domains = +local_domains
caseful_local_part = true
condition = ${if and {{\
eq {${lookup mysql{ \
SELECT
CONCAT(`username`,'@',`domain`) AS `email` \
FROM `users` \
WHERE `username` =
'${quote_mysql:$local_part}' \
AND `domain` =
'${quote_mysql:$domain}' \
AND `SMTP_allowed` = 'YES' \
}{true}{false}}}{true}\
}{\
or {{\
and {{\
eq
{${sg{$local_part_suffix}{^#([^#]+)#[0-9]\{8\}\$}{\$1}}}{before}\
}{\
lt
{$tod_logfile}{${sg{$local_part_suffix}{^#[^#]+#([0-9]\{8\})\$}{\$1}}}\
}\
}\
}{\
and {{\
eq
{${sg{$local_part_suffix}{^#([^#]+)#.*\$}{\$1}}}{fromdomain}\
}{\
eq
{$sender_address_domain}{${sg{$local_part_suffix}{^#[^#]+#(.*)\$}{\$1}}}\
}\
}\
}{\
and {{\
eq
{${sg{$local_part_suffix}{^#([^#]+)#.*\$}{\$1}}}{b64from}\
}{\
eq
{${str2b64:$sender_address}}{${sg{$local_part_suffix}{^#[^#]+#(.*)\$}{\$1}}}
\
}\
}\
}\
}\
}\
}\
}
local_part_suffix = #*
transport = local_mysql_delivery
mysql_user:
driver = accept
domains = +local_domains
condition = ${lookup mysql{ \
SELECT CONCAT(`username`,'@',`domain`) AS
`email` \
FROM `users` \
WHERE `username` =
'${quote_mysql:$local_part}' \
AND `domain` = '${quote_mysql:$domain}' \
AND `SMTP_allowed` = 'YES' \
}{true}{false}}
local_part_suffix = +*
local_part_suffix_optional
transport = local_mysql_delivery
no_more
mysql_catchall:
driver = redirect
domains = +local_domains
file_transport = address_file
pipe_transport = address_pipe
data = ${lookup mysql{ \
SELECT `sendto` \
FROM `catchall` \
WHERE `domain` = '${quote_mysql:$domain}' \
}}
srs = forward
srs_dbinsert = ${lookup mysql{INSERT INTO `SRS` (`Key`, `Address`, `Time`)
VALUES ('${srs_db_key}', '${srs_db_address}', NOW())}}
headers_add = "X-SRS: Sender address rewritten from <$sender_address> by
$primary_hostname."
debug_print = "R: srs_forward for $local_part@$domain"
system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
user = mailnull
group = mail
file_transport = address_file
pipe_transport = address_pipe
srs = forward
srs_dbinsert = ${lookup mysql{INSERT INTO `SRS` (`Key`, `Address`, `Time`)
VALUES ('${srs_db_key}', '${srs_db_address}', NOW())}}
headers_add = "X-SRS: Sender address rewritten from <$sender_address> by
$primary_hostname."
debug_print = "R: srs_forward for $local_part@$domain"
userforward:
driver = redirect
check_local_user
file = $home/.forward
no_verify
no_expn
check_ancestor
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
condition = ${if exists{$home/.forward} {yes} {no}}
srs = forward
srs_dbinsert = ${lookup mysql{INSERT INTO `SRS` (`Key`, `Address`, `Time`)
VALUES ('${srs_db_key}', '${srs_db_address}', NOW())}}
headers_add = "X-SRS: Sender address rewritten from <$sender_address> by
$primary_hostname."
debug_print = "R: srs_forward for $local_part@$domain"
localuser:
driver = accept
check_local_user
transport = local_delivery
cannot_route_message = Unknown user
srs_router:
driver = redirect
srs = reverseandforward
srs_dbinsert = ${lookup mysql{INSERT INTO `SRS` (`Key`, `Address`, `Time`)
VALUES ('${srs_db_key}', '${srs_db_address}', NOW())}}
srs_dbselect = ${lookup mysql{SELECT `Address` FROM `SRS` WHERE `Key` =
'${srs_db_key}' AND `Time` > SUBDATE(NOW(), INTERVAL 1 month) LIMIT 1}}
data = ${srs_recipient}
begin transports
remote_smtp:
driver = smtp
message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
headers_remove = X-Spam-Flag : X-Spam-Score-Int : X-Spam-Score :
X-Spam-Bar : X-Spam-Report : X-Sender-Verify : X-Warning :
X-Message-Linecount : X-Body-Linecount : X-Message-Size : X-Body-Size :
X-Received-Count : X-Recipient-Count : X-Local-Recipient-Count :
X-Local-Recipient-Defer-Count : X-Local-Recipient-Fail-Count
dkim_domain =
${lookup{$sender_address_domain.private.pem}dsearch{/usr/local/etc/exim/dkim
_keys}{$sender_address_domain}{}}
dkim_private_key =
/usr/local/etc/exim/dkim_keys/${lookup{$sender_address_domain.private.pem}ds
earch{/usr/local/etc/exim/dkim_keys}}
dkim_selector = exim
dkim_canon = relaxed
dkim_strict = false
.ifdef _HAVE_DANE
dnssec_request_domains = *
hosts_try_dane = *
.endif
.ifdef _HAVE_PRDR
hosts_try_prdr = *
.endif
smarthost_smtp:
driver = smtp
message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
multi_domain
.ifdef _HAVE_TLS
hosts_require_tls = *
tls_verify_hosts = *
tls_try_verify_hosts = *
tls_sni = ROUTER_SMARTHOST
.ifdef _HAVE_OPENSSL
tls_require_ciphers = HIGH:!aNULL:@STRENGTH
.endif
.ifdef _HAVE_GNUTLS
tls_require_ciphers = SECURE192:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1
.endif
.endif
.ifdef _HAVE_PRDR
hosts_try_prdr = *
.endif
local_delivery:
driver = appendfile
file = /var/mail/$local_part
delivery_date_add
envelope_to_add
return_path_add
group = mail
user = $local_part
mode = 0660
no_mode_fail_narrower
address_pipe:
driver = pipe
return_output
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
address_reply:
driver = autoreply
local_mysql_delivery:
debug_print = "T: dovecot LMTP for $local_part@$domain"
driver = lmtp
socket = /var/run/dovecot/lmtp
batch_max = 200
headers_remove = Subject : X-Spam-Flag : X-Spam-Score-Int : X-Spam-Score :
X-Spam-Bar : X-Spam-Report
headers_add = "X-Spam-Threshold: ${lookup mysql{ \
SELECT spam_threshold \
FROM users \
WHERE username='${quote_mysql:$local_part}' \
AND domain='${quote_mysql:$domain}' \
AND SMTP_allowed='YES' \
}{$value}{ERROR}}\n\
X-Spam-Score: $header_X-Spam-Score:\n\
X-Spam-Score-Int: $header_X-Spam-Score-Int:\n\
X-Spam-Bar: $header_X-Spam-Bar:\n\
X-Spam-Report: $header_X-Spam-Report:\n\
X-Spam-Flag: ${if def:header_X-Spam-Score-Int:{\
${if >={$header_X-Spam-Score-Int:}\
{${lookup mysql{ \
SELECT spam_threshold*10 \
FROM users \
WHERE username='${quote_mysql:$local_part}' \
AND domain='${quote_mysql:$domain}' \
AND SMTP_allowed='YES' \
}{$value}{ERROR}}}{YES}{NO}}\
}{\
UNKNOWN\
}}\n\
Subject: ${if def:header_X-Spam-Score-Int:{\
${if >={$header_X-Spam-Score-Int:}\
{${lookup mysql{ \
SELECT spam_threshold*10 \
FROM users \
WHERE username='${quote_mysql:$local_part}' \
AND domain='${quote_mysql:$domain}' \
AND SMTP_allowed='YES' \
}{$value}{ERROR}}}{${lookup mysql{ \
SELECT spam_tag \
FROM users \
WHERE
username='${quote_mysql:$local_part}' \
AND domain='${quote_mysql:$domain}' \
AND SMTP_allowed='YES' \
}{$value}{ERROR}}$rh_subject:}{$rh_subject:}}\
}{$rh_subject:}}\n\
X-Delivered-To: $original_local_part@$original_domain
($local_part@$domain)\n\
X-Message-Age: $message_age"
begin retry
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
begin rewrite
begin authenticators
PLAIN:
driver = plaintext
public_name = PLAIN
server_prompts = :
server_advertise_condition = ${if def:tls_cipher}
server_condition = ${if eq {$auth3}{${lookup mysql{ SELECT
`password` FROM `users` WHERE CONCAT_WS('@', `username`, `domain`) =
'${quote_mysql:$auth2}' AND `SMTPAUTH_allowed` = 'YES'}}}{yes}{no}}
server_set_id = $auth2
server_debug_print = "Running PLAIN auth: $auth2 | $auth3"
LOGIN:
driver = plaintext
public_name = LOGIN
server_prompts = <| Username: | Password:
server_advertise_condition = ${if def:tls_cipher}
server_condition = ${if eq {$auth2}{${lookup mysql{SELECT
`password` FROM `users` WHERE CONCAT_WS('@', `username`, `domain`) =
'${quote_mysql:$auth1}' AND `SMTPAUTH_allowed` = 'YES'}}}{yes}{no}}
server_set_id = $auth1
server_debug_print = "Running LOGIN auth: $auth1 | $auth2"
CRAM:
driver = cram_md5
public_name = CRAM-MD5
server_secret = ${lookup mysql{SELECT `password` FROM `users` WHERE
CONCAT_WS('@', `username`, `domain`) = '${quote_mysql:$auth1}' AND
`SMTPAUTH_allowed` = 'YES';}{$value}{fail}}
server_set_id = $auth1
server_debug_print = "Running CRAM-MD5 auth: $auth1"
SPA:
driver = spa
public_name = NTLM
server_password = ${lookup mysql{SELECT `password` FROM `users` WHERE
CONCAT_WS('@', `username`, `domain`) = '${quote_mysql:$auth1}' AND
`SMTPAUTH_allowed` = 'YES' AND '${quote_mysql:$auth1}' !=
'';}{$value}{fail}}
server_set_id = $auth1
server_debug_print = "Running SPA auth: $auth1"