Sender Verify Fails on "Recipient"
This isn't 100% foolproof but the sending server has to be badly misconfigured to get a false positive with this ACL. This is a sender verification test that fails if the server specifically says the sending email address does not exist. If the server fails to respond or rejects the verification before the RCPT TO: then this ACL won't block it.
drop message = REJECTED - Sender Verify Failed - error code \"$sender_verify_failure\"\n\n\
The return address you are using for this email message <$sender_address>\
does not seem to be a working account.
log_message = REJECTED - Sender Verify Failed - error code \"$sender_verify_failure\"
!hosts = +no_verify
!verify = sender/callout=2m,defer_ok
condition = ${if eq{recipient}{$sender_verify_failure}}The no_verify list is your white list in case there are domains that are really badly configured and won't fix their configuration.
Sender Verify Failed and Blacklisted
Combination of sender verify fails and in a minor blacklist. Either one of these is forgivable but if combined they get dropped.
drop message = REJECTED - Sender Verify Failed and Host $sender_host_address is Blacklisted in $dnslist_domain=$dnslist_value - $dnslist_text
log_message = REJECTED - Sender Verify Failed and Host $sender_host_address is Blacklisted in $dnslist_domain=$dnslist_value - $dnslist_text
dnslists = dnsbl.sorbs.net : dnsbl.njabl.org : relays.ordb.org : bl.spamcop.net : opm.blitzed.org
!verify = sender/callout=2m,defer_ok
!condition = ${if eq{$sender_verify_failure}{}}
Sender Verify Failed and no Reverse DNS
This one bounces email if the sender verify fails and reverse DNS fails. The idea being that the combination of two sins is enough to get you excluded.
drop message = REJECTED - Sender Verify Failed and no RDNS
log_message = REJECTED - Sender Verify Failed and no RDNS
!verify = reverse_host_lookup
!verify = sender/callout=2m,defer_ok
!condition = ${if eq{$sender_verify_failure}{}}
Recipient Verification
Drop at connect time if the Recipient doesn't exist.
deny message = REJECTED - Recipient Verify Failed - User Not Found
domains = +all_mail_handled_locally
!verify = recipient/callout=2m,defer_ok,use_sender
Too many Failed Recipients
With multiple recipients the sender shouldn't get that many wrong. If more than 3 are wrong it's probably a dictionary attack.
drop message = REJECTED - Too many failed recipients - count = $rcpt_fail_count
log_message = REJECTED - Too many failed recipients - count = $rcpt_fail_count
condition = ${if > {${eval:$rcpt_fail_count}}{3}{yes}{no}}
!verify = recipient/callout=2m,defer_ok,use_senderbut RSET resets $rcpt_fail_count, thus making any delays after a certain number of failed recipients useless. So let's do it with an acl variable, set the variable in a warn condition:
warn domains = +local_domains
!verify = recipient
set acl_c0 = ${eval: $acl_c0+1}
delay = ${eval: ($acl_c0 - 1) * 60}s