My previous ACL postings are not as one complete item, the following list of ACL's are recommended for shared hosting environments where users authenticate locally to send mail from dynamic address space.

Use of PBL's and suchlike would be much better but aren't entirely practical unless you have only business customers that ALL have static IP's (Which in reality will never happen) or seperate recieving SMTP servers from the ones your customers relay out through.

There is one part of this that I often get asked about so I will explain myself and let you know the implications of doing so before you do it.

I run my RBL checks at the HELO/EHLO stage of SMTP transactions, some will agree with me on this, others will beg to differ.

HELO/EHLO RBL checks - why and why not

I deliberatly reject SMTP transactions if the connecting address is in an RBL because:

  1. If the sending address is in an RBL, there is a fair chance that they are in there because they have spammed/are a zombie machine - and who wants those on their network - I don't!
  2. Exim likes to fill the logs with - Unexpected disconnection messages if you do it at rcpt stage.
  3. Although negligable, why create more load processing the rcpt stage when you won't accept mail from that address anyway?
  4. Most of my shared hosting clients are businesses with Business DSL & IT companies that can be contacted to remedy the situation fairly quickly.
  5. If the worst comes to the worst, you can temporarily remove the checks of the nuisance RBL quickly & easily.
  6. If the offending client IP is dynamic, getting the client to turn their router/modem off and back on again tends to pick up another IP.

The downside with the above is the distinct inability to whitelist IP's, even SMTP auth clients will fail at this stage.

My personal experience of this, is that it hasn't been too much of a problem for me - but then the company I work for doesn't have hundreds of servers to keep an eye on.

I will admit, it might not be entirely practical to implement with larger hosts but I haven't personally had any trouble.

The ACLs

Ok so now I've explained myself - on to the ACL's - I will be happy to answer any questions anyone may have

HELO/EHLO stage ACL's

Near the very top of your exim.conf you need to add:

acl_smtp_helo = check_helo

Now for the helo acls

check_helo:
# RBL checks (List formulated by trial and error with shared hosting in mind
# Drop connection if client IP address listed in any of the RBLs.
deny message = Your message was rejected because $sender_fullhost \
is blacklisted at $dnslist_domain see $dnslist_text for an explanation
dnslists = bl.spamcop.net : \
sbl.spamhaus.org : \
xbl.spamhaus.org : \
list.dsbl.org : \
zombie.dnsbl.sorbs.net : \
blackholes.mail-abuse.org : \
smtp.dnsbl.sorbs.net : \
web.dnsbl.sorbs.net : \
escalations.dnsbl.sorbs.net : \
nomail.rhsbl.sorbs.net : \
badconf.rhsbl.sorbs.net : \
http.dnsbl.sorbs.net : \
socks.dnsbl.sorbs.net : \
misc.dnsbl.sorbs.net
#Check sender actually sent a HELO string
deny message = Im afraid I need your name before I can let you in.
log_message = no HELO/EHLO specified
condition = ${if match {$sender_helo_name}{none} {yes}{no}}
# Check sender isnt announcing itself with local IP, replace 00.00.00.00 with your main interface IP
deny message = HELO/EHLO with my ip address. You are not me.
log_message = HELO/EHLO local IP
condition = ${if eq {$sender_helo_name}{00.00.00.00} {yes}{no}}
# Check sender isnt announcing itself with your hostname, replace server.company.com with your servers hostname
deny message = HELO/EHLO with my hostname. You are not me.
log_message = HELO/EHLO Local Hostname
condition = ${if match {$sender_helo_name}{server.company.com} {yes}{no}}
# Check sender hasnt said that they are localhost
deny message = You are NOT localhost.
log_message = HELO/EHLO localhost
condition = ${if match {$sender_helo_name}{localhost} {yes}{no}}

By the time it gets to here, its passed the checks, so let it go on to the next stage.

accept:

RCPT stage ACL's

Most exim servers already come with a RCPT stage ACL list of some nature, so in this instance we just need to add a few things to it.

Spammers like to forge some big names when they send you email. We can't easily check all of them, not until Sender Permitted From (SPF) is widely used. At least we can check for some of the most commonly abused domains, Yahoo, Hotmail, MSN, and AOL. These four filters will reject email with forged From: addresses containing the "big four" domains.

#Fake Yahoo
deny message = Suspected Faked Yahoo Account, E-mail Rejected.
     log_message = Fake Yahoo
     senders = *@yahoo.com
condition = ${if match{$sender_host_name}{\Nyahoo.com$\N}{no}{yes}}
#Fake Hotmail
deny message = Suspected Faked Hotmail Account, E-mail Rejected.
     log_message = Fake hotmail
     senders = *@hotmail.com
     condition = ${if match {$sender_host_name}{\Nhotmail.com$\N}{no}{yes}}
#Fake MSN
deny message = Suspected Faked MSN Account, E-mail Rejected.
     log_message = Fake MSN
     senders = *@msn.com
     condition = ${if match {$sender_host_name}{\N(hotmail|msn).com$\N}{no}{yes}}
# Fake AOL
deny message = Suspected Faked AOL Account, E-mail Rejected.
     log_message = Fake AOL
     senders = *@aol.com
     condition = ${if match {$sender_host_name}{\Nmx.aol.com$\N}{no}{yes}}

DATA stage ACL's

You should be running some form of spam filtering daemon on ANY public mail server - yes they are load heavy but until someone comes up with a way to remove spam at source (not likely) you should be filtering your mail.

I could go in to detail with SpamAssassin ACL checks here but I would imagine most people reading this have cPanel servers, as cPanel already installs and configures SA I'm going to skip it for now.

I have used varying levels of filtering and header checks with ACL's at data stage in the past, but they tend to be the most problematic when you have customers relaying out via your server.

A prime example of this is the common: Check Message ID acl (see rossz's list) - if a message hasn't been relayed through an SMTP server already, then it won't have a message ID header.

All we need to do now is add one final part to the exim config - within the RCPT acl which again commonly already exists on most servers.

Email should have a proper date header (E-mail client software tends to set this, so its normally ok to check it and reject if not found).

deny condition = ${if !def:h_Date: {1}}
message = Message SHOULD have Date: but does not