David Woodhouse wrote:
> Personally I like to greylist _after_ SA. Mail with zero SA points
> doesn't get greylisted (unless it commits other offences).
>
> You don't need magic support in SA-Exim for this; it's all perfectly
> achievable in normal ACLs -- and you can play with whatever tuples you
> want for the greylist database. Personally I don't like to use the
> sending host, since retries may come from another machine. I use
> {sender,recipients,message-id} but I do _store_ the host, because the
> original host needs to be whitelisted so that we never greylist mail
> from it again -- even if it does send its retries via another route.
I second all of the above. I've been doing this for more than a year in
production with good results.
As a message hash I use MD5 over $sender_address, $rheader_from,
$rheader_to, $rheader_subject.
I also whitelist the "original" host and the "retry" host".
Here are the relevant snippets (Uses Mysql as a backend). Sorry for the
long lines, but I don't feel like reformatting this now.
# -- Macros -------------------------------------------------------
GREYLIST_RETRY_HOST_INSERT = ${lookup mysql{DELETE FROM
greylist_retry_hosts \
WHERE
host='${quote_mysql:$sender_host_address}'}{}{}}\
${lookup mysql{INSERT INTO
greylist_retry_hosts VALUES \
('${quote_mysql:$sender_host_address}',UNIX_TIMESTAMP())}{}{}}\
${lookup mysql{DELETE FROM
greylist_retry_hosts \
WHERE host='${quote_mysql:$acl_m1}'}{}{}}\
${lookup mysql{INSERT INTO
greylist_retry_hosts VALUES \
('${quote_mysql:$acl_m1}',UNIX_TIMESTAMP())}{1}{1}}
GREYLIST_RETRY_HOST_CLEANUP = ${lookup mysql{DELETE FROM
greylist_retry_hosts \
WHERE ((UNIX_TIMESTAMP() - stamp) >
(60*60*24*30))}{1}{1}}
GREYLIST_RETRY_HOST_CHECK = ${lookup mysql{SELECT host FROM
greylist_retry_hosts \
WHERE
host='${quote_mysql:$sender_host_address}'}{1}{0}}
GREYLIST_MESSAGE_CLEANUP = ${lookup mysql{DELETE FROM greylist_msg_hashes \
WHERE ((UNIX_TIMESTAMP() - stamp) >
(60*60*24*4))}{1}{1}}
GREYLIST_MESSAGE_DIGEST =
${md5:$sender_address$rheader_from:$rheader_to:$rheader_subject:}
GREYLIST_MESSAGE_INSERT = ${lookup mysql{INSERT INTO greylist_msg_hashes
VALUES \
('${quote_mysql:$sender_host_address}',UNIX_TIMESTAMP(),\
'GREYLIST_MESSAGE_DIGEST')}{1}{1}}
GREYLIST_MESSAGE_CHECK = ${lookup mysql{SELECT host FROM
greylist_msg_hashes WHERE \
((UNIX_TIMESTAMP() - stamp) > (60*4)) AND \
md5='GREYLIST_MESSAGE_DIGEST'}{$value}{}}
GREYLIST_MESSAGE_REMOVE = ${lookup mysql{DELETE FROM greylist_msg_hashes
WHERE \
md5='GREYLIST_MESSAGE_DIGEST'}{1}{1}}
IPT_TEMP_BLACKHOLE = ${run {/usr/local/bin/timeban add
$sender_host_address}{1}{1}}
# -- end of DATA ACL (after SA run) -------------------------------
# (1 < spam_score < 5) starting here
warn message = X-Spam-Report: $spam_report
accept condition = GREYLIST_RETRY_HOST_CLEANUP
condition = GREYLIST_RETRY_HOST_CHECK
logwrite = Greylisting: $sender_host_address is a known retry host
accept condition = GREYLIST_MESSAGE_CLEANUP
set acl_m1 = GREYLIST_MESSAGE_CHECK
condition = ${if eq{$acl_m1}{}{0}{1}}
condition = GREYLIST_MESSAGE_REMOVE
condition = GREYLIST_RETRY_HOST_INSERT
logwrite = Greylisting: Successful greylist retry from
$sender_host_address (original host was $acl_m1)
defer message = Temporary local problem, please try again!
log_message = Greylisted as suspected spam ($spam_score)
condition = GREYLIST_MESSAGE_REMOVE
condition = GREYLIST_MESSAGE_INSERT
condition = IPT_TEMP_BLACKHOLE
logwrite = Greylisting: Greylisted $sender_host_address