[Exim] problems setting up exim+spamassassin+cyrus imap

Top Page
Delete this message
Reply to this message
Author: Derek Stevenson
Date:  
To: exim-users
Subject: [Exim] problems setting up exim+spamassassin+cyrus imap
I'm trying to configure exim to work properly with spamassassin and cyrus
imap. I first set up exim and cyrus, and made the necessary changes to get
exim to deliver mail using the cyrus deliver command. That worked just fine.

After that, I tried following the instructions at

http://dman.ddts.net/~dman/config_docs/exim4_spamassassin.html

to get SA to run in the exim router chain, before it gets passed to cyrus
for final delivery to the user's mailbox. I added the router
(spamcheck_router) and transport (spamcheck) to exim.conf (I've attached
the relevant parts of my exim.conf below). However, now it looks like
inbound email to my main domain name gets stuck in some sort of infinite
routing loop (I killed the mailserver, restarted exim without the SA
router, and got an email that had about 40 'Received-by' headers), drives
load on the server way up, and never delivers to the cyrus email box
properly. Strangely enough, email addressed to aliases on the server is
properly processed by SA, which writes in the X-Spam-Flag and X-Spam-Status
etc headers, and is delivered to the user's inbox.

I've only been working on this for a week, so I'm pretty new to it and feel
like I'm in over my head. My questions are: 1) What am I doing wrong with
the SA router/transport that keeps the email in some sort of routing loop
-- I just want to see that the headers are written and then passed on to
cyrus for inbox delivery; and 2) once that's functional, how do I configure
which mailbox to deliver the email to based on the headers written by SA
(e.g. a spam subfolder)?

Config:
exim4.12-4
cyrus 2.1.12-7
spamassassin 2.52-1

Thanks in advance, apparently this config isn't very common as I've been
scouring the web for example configs but haven't had much luck.

-- Derek

=================================================================
######################################################################
#                      ROUTERS CONFIGURATION                         #
#               Specifies how addresses are handled                  #
######################################################################
#     THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT!       #
# An address is passed to each router in turn until it is accepted.  #
######################################################################


begin routers

# This router routes to remote hosts over SMTP by explicit IP address,
# when an email address is given in "domain literal" form, for example,
# <user@???>. The RFCs require this facility. However, it is
# little-known these days, and has been exploited by evil people seeking
# to abuse SMTP relays. Consequently it is commented out in the default
# configuration. If you uncomment this router, you also need to uncomment
# allow_domain_literals above, so that Exim can recognize the syntax of
# domain literal addresses.

# domain_literal:
# driver = ipliteral
# domains = ! +local_domains
# transport = remote_smtp


# This router routes addresses that are not in local domains by doing a DNS
# lookup on the domain name. Any domain that resolves to 0.0.0.0 or to a
# loopback interface address (127.0.0.0/8) is treated as if it had no DNS
# entry. Note that 0.0.0.0 is the same as 0.0.0.0/32, which is commonly treated
# as the local host inside the network stack. It is not 0.0.0.0/0, the default
# route. If the DNS lookup fails, no further routers are tried because of
# the no_more setting, and consequently the address is unrouteable.

dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more


# The remaining routers handle addresses in the local domain(s).


# This router handles aliasing using a linearly searched alias file with the
# name SYSTEM_ALIASES_FILE. When this configuration is installed automatically,
# the name gets inserted into this file from whatever is set in Exim's
# build-time configuration. The default path is the traditional /etc/aliases.
# If you install this configuration by hand, you need to specify the correct
# path in the "data" setting below.
#
##### NB You must ensure that the alias file exists. It used to be the case
##### NB that every Unix had that file, because it was the Sendmail default.
##### NB These days, there are systems that don't have it. Your aliases
##### NB file should at least contain an alias for "postmaster".
#
# If any of your aliases expand to pipes or files, you will need to set
# up a user and a group for these deliveries to run under. You can do
# this by uncommenting the "user" option below (changing the user name
# as appropriate) and adding a "group" option if necessary. Alternatively, you
# can specify "user" on the transports that are used. Note that the transports
# listed below are the same as are used for .forward files; you might want
# to set up different ones for pipe and file deliveries from aliases.

system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
# user = exim
file_transport = address_file
pipe_transport = address_pipe

# This router handles forwarding using traditional .forward files in users'
# home directories. If you want it also to allow mail filtering when a forward
# file starts with the string "# Exim filter", uncomment the "allow_filter"
# option.

# The no_verify setting means that this router is skipped when Exim is
# verifying addresses. Similarly, no_expn means that this router is skipped if
# Exim is processing an EXPN command.

# The check_ancestor option means that if the forward file generates an
# address that is an ancestor of the current one, the current one gets
# passed on instead. This covers the case where A is aliased to B and B
# has a .forward file pointing to A.

# The three transports specified at the end are those that are used when
# forwarding generates a direct delivery to a file, or to a pipe, or sets
# up an auto-reply, respectively.

userforward:
driver = redirect
check_local_user
file = $home/.forward
no_verify
no_expn
check_ancestor
allow_filter
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply

# Spam Assassin
spamcheck_router:
no_verify
check_local_user
# When to scan a message :
# - it isn't already flagged as spam
# - it isn't already scanned
condition = "${if and { {!def:h_X-Spam-Flag:} {!eq
{$received_protocol}{spam\
-scanned}}} {1}{0}}"
driver = accept
transport = spamcheck

# This router matches local user mailboxes.

localuser:
driver = accept
check_local_user
transport = local_delivery

######################################################################
#                      TRANSPORTS CONFIGURATION                      #
######################################################################
#                       ORDER DOES NOT MATTER                        #
#     Only one appropriate transport is called for each delivery.    #
######################################################################


# A transport is used only when referenced from a router that successfully
# handles an address.

begin transports


# This transport is used for delivering messages over SMTP connections.

remote_smtp:
driver = smtp


# For use with Cyrus
# note the 'current_directory = /' option was the critical piece to
# get cyrus to play well with exim

local_delivery:
   driver = pipe
   command = /usr/libexec/cyrus/deliver \
             -m ${substr_1:$local_part_suffix} -- $local_part
   user = cyrus
   group = mail
   return_output
   log_output = true
   message_prefix =
   message_suffix =
   current_directory = /


# This transport is used for handling pipe deliveries generated by alias or
# .forward files. If the pipe generates any standard output, it is returned
# to the sender of the message as a delivery error. Set return_fail_output
# instead of return_output if you want this to happen only when the pipe fails
# to complete normally. You can set different transports for aliases and
# forwards if you want to - see the references to address_pipe in the routers
# section above.

address_pipe:
driver = pipe
return_output


# This transport is used for handling deliveries directly to files that are
# generated by aliasing or forwarding.

address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add


# This transport is used for handling autoreplies generated by the filtering
# option of the userforward router.

address_reply:
driver = autoreply

# Spam Assassin
spamcheck:
driver = pipe
command = /usr/sbin/exim -oMr spam-scanned -bS
use_bsmtp = true
transport_filter = /usr/bin/spamc
home_directory = "/tmp"
current_directory = "/tmp"
# must use a privileged user to set $received_protocol on the way back in!
user = cyrus
group = mail
log_output = true
return_fail_output = true
return_path_add = false
message_prefix =
message_suffix =