gull
|
|
Exim spam filter configuration
|
Mar 3 21:55 UTC 2005 |
I was asked to share the Exim configuration I have at work with Grex.
I've placed the complete configuration file in ~gull/exim4.conf, for
reference, but keep in mind large chunks of that file are either
specific to my setup (which is primarily a mail relay) or from the
default Debian configuration. The interesting parts are the ACLs below.
The rest of the item can be used to discuss these; in particular, if
something isn't clear from the comments, just ask. I've added a few
extra comments for clarity.
acl_check_connect is run for each connection, acl_check_rcpt for each
RCPT TO: line, and acl_check_data is run after the DATA segment of the
SMTP transaction, but before the message is acknowledged.
The spam= and malware= conditions in the DATA ACL require Exiscan to
work; they cause Exim to directly interface with clamd and spamd.
######################################################################
# ACL CONFIGURATION #
# Specifies access control lists for incoming SMTP mail #
######################################################################
begin acl
acl_check_connect:
# Immediately accept connections from our own hosts and from
# whitelisted hosts.
accept hosts = +relay_from_hosts
accept hosts = +whitelist_hosts
# Penalize hosts in DNS blacklists with a 15 second delay before
# the 220 greeting. The goal is to make spamware time out
# or commit a synchronization error, which will cause Exim to
# drop the connection. RFC-compliant mailers should be
# unaffected. These blacklists are too aggressive (IMHO)
# for outright rejection but work nicely for this, especially
# sorbs.net, which lists dynamic IPs.
accept
dnslists = bl.spamcop.net : relays.visi.com : dnsbl.sorbs.net
set acl_c0 = X-RBL-Warning: $sender_host_address is listed \
in $dnslist_domain \
${if def:dnslist_text {(dnslist_text)}{}}
set acl_c1 = true
logwrite = acl_check_connect: $sender_host_address is in
$dnslist_domain; delaying 15 seconds.
delay = 15s
# Everyone else just passes on through.
accept
# This access control list is used for every RCPT command in an incoming
# SMTP message. The tests are run in order until the address is either
# accepted or denied.
#
acl_check_rcpt:
# "Rumplestiltskin attack" rejection -- after the fifth bad recipient,
# the connection is dropped.
drop condition = ${if >{$rcpt_fail_count}{5}{1}{0}}
message = Too many bad recipients.
# Add any warnings generated in acl_check_connect to the headers:
warn message = $acl_c0
condition = $acl_c1
# Accept if the source is local SMTP (i.e. not over TCP/IP). We do
# this by testing for an empty sending host field.
accept hosts = :
# The following section of the ACL is concerned with local parts
# that contain @ or % or ! or / or | or dots in unusual places.
#
# The characters other than dots are rarely found in genuine local
# parts, but are often tried by people looking to circumvent
# relaying restrictions.
# Therefore, although they are valid in local parts, these rules
# lock them out, as a precaution.
#
# Empty components (two dots in a row) are not valid in RFC 2822,
# but Exim allows them because they have been encountered.
# (Consider local parts constructed as
# "firstinitial.secondinitial.familyname" when applied to
# someone who has no second initial.) However, a local part starting
# with a dot or containing /../ can cause trouble if it is used
# as part of a file name (e.g. for a mailing list). This is also
# true for local parts that contain slashes. A pipe symbol can also
# be troublesome if the local part is incorporated unthinkingly into
# a shell command line.
#
# Two different rules are used. The first one is stricter, and is
# applied to messages that are addressed to one of the local
# domains handled by this host. It blocks local parts that begin
# with a dot or contain @ % ! / or |. If you have local accounts
# that include these characters, you will have to modify this rule.
deny domains = +local_domains
local_parts = ^[.] : ^.*[@%!/|]
message = restricted characters in address
# The second rule applies to all other domains, and is less strict.
# This allows your own users to send outgoing messages to sites
# that use slashes and vertical bars in their local parts. It
# blocks local parts that begin with a dot, slash, or vertical
# bar, but allows these characters within the local part. However,
# the sequence /../ is barred. The use of @ % and ! is blocked, as
# before. The motivation here is to prevent your users (or your
# users' viruses) from mounting certain kinds of attack on
# remote sites.
deny domains = !+local_domains
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
message = restricted characters in address
# Don't allow outside access to a few special addresses.
deny local_parts = spam : notspam : ^fax-.*
hosts = !+relay_from_hosts
message = This address is reserved for internal use.
# Don't spam filter a few special addresses.
# This sets a variable that is used later, in the data ACL.
accept local_parts = postmaster : abuse : spam : notspam
domains = +local_domains : +relay_to_domains
set acl_c2 = true
# Reject blacklisted senders.
deny senders = +blacklisted_senders
message = Mail is not accepted from this address.
# Accept if the message comes from one of the hosts for which we
# are an outgoing relay. Recipient verification is omitted here,
# because in many cases the clients are dumb MUAs that don't cope
# well with SMTP error responses. If you are actually relaying out
# from MTAs, you should probably add recipient verification here.
#
accept hosts = +relay_from_hosts
# Check against the Spamhaus SBL. This list is conservative enough
# that we can just reject this mail outright.
deny message = Rejected because $sender_host_address is in a \
blacklist at $dnslist_domain. Email \
postmaster@interclean.com for further assistance.\n\
$dnslist_domain says:\n\
$dnslist_text
dnslists = sbl-xbl.spamhaus.org
# Accept if the address is in a local domain, but only if the
# recipient can be verified. Otherwise deny. The "endpass" line is
# the border between passing on to the next ACL statement (if tests
# above it fail) or denying access (if tests below it fail).
#
accept domains = +local_domains
endpass
message = unknown user
verify = recipient
# Accept if the address is in a domain for which we are relaying,
# but again, only if the recipient can be verified.
#
accept domains = +relay_to_domains
endpass
message = unrouteable address
verify = recipient/defer_ok
# If control reaches this point, the domain is neither in
# +local_domains nor in +relay_to_domains.
# Accept if the message arrived over an authenticated connection, from
# any host. Again, these messages are usually from MUAs, so recipient
# verification is omitted.
#
accept authenticated = *
# Reaching the end of the ACL causes a "deny", but we might as well
# give an explicit message.
#
deny message = relay not permitted
acl_check_data:
# Add Message-ID if missing
warn condition = ${if !def:h_Message-ID: {1}}
hosts = +relay_from_hosts
message = Message-ID: <E$message_id@$primary_hostname>
# Don't filter if we determined earlier that the mail was for
# postmaster
accept condition = $acl_c2
# Virus check, both for incoming and outgoing mail.
deny message = Clam Antivirus indicates this message contains a \
virus: $malware_name
malware = *
# Don't spam filter mail from our relay hosts or whitelist hosts.
accept hosts = +relay_from_hosts
accept hosts = +whitelist_hosts
# Skip SpamAssassin checks for big messages.
accept condition = ${if >{$message_size}{1M}{1}{0}}
logwrite = Large message; skipping spam check.
# Add SpamAssassin scores to the headers.
warn message = X-Spam-Score: $spam_score
spam = nobody:true
warn message = X-Spam-Report: $spam_report
spam = nobody:true
# If the SpamAssassin score is greater than 7.0, reject the mail.
deny message = Rejected this message because it looks like spam.\n\
Email postmaster@interclean.com for assistance.
log_message = Rejected message as spam. Score was $spam_score.
spam = nobody:true
condition = ${if >{$spam_score_int}{70}{1}{0}}
# accept otherwise
accept
|
gull
|
|
response 3 of 4:
|
Mar 25 15:43 UTC 2005 |
I recently started having problems with spam that was CC'd to postmaster
*and* to another user leaking past the filters. So I'm implementing the
suggestions here:
http://www.exim.org/pipermail/exim-users/Week-of-Mon-20031006/061151.html
If the first recipient is postmaster, it's accepted, spam filtering is
bypassed, and all non-postmaster recipients are temporarily deferred
with a 451 response. If the first recipient isn't postmaster, spam
filtering is left enabled, and any postmaster recipients are temporarily
deferred.
The benefit here is the postmaster address is still unfiltered, but spam
can't bypass the filters to other recipients. The downside is messages
that are addressed to postmaster *and* to other recipients will always
take two attempts to fully deliver.
|
gull
|
|
response 4 of 4:
|
Mar 26 05:15 UTC 2005 |
I just had a quick look at /usr/local/etc/exim.conf. A few minor
critiques:
In the clause of the RCPT ACL that rejects based on the sbl-xbl list,
I'd suggest either eliminating the reference to
postmaster@interclean.com or changing it to postmaster@cyberspace.org.
If someone emails me about Grex rejecting their mail, there won't be
much I can do about it. ;)
Also, you're defining an addresslist called blacklisted_senders, then
listing hostnames with no local parts in it. I'm not sure if that
works, since I've always used those to blacklist specific senders
(e.g., "luser@badsite.com"); you might want to try faking an SMTP
session with one of those addresses as the envelope sender to see what
happens. It's late, or I'd pull up the Exim spec and look for myself
if that's a workable configuration. There may be some kind of
wildcard matching you need to do if you really want to reject all
addresses with those domain names.
|