Contents
CREATING A NEW DIRECTOR
To integrate DSPAM with exim 4, you'll need to create a new director in the exim configuration. First, add the following code to the directors:
spamscan: no_verify condition = "${if and {{!eq {$received_protocol}{spam-scanned}} {!eq {$received_protocol}{local}} } {1}{0}}" driver = accept transport = spamcheck require_files = /usr/local/var/dspam:\ +/usr/local/bin
This code tells exim to run spamcheck unless the message was marked by the agent with the spam-scanned protocol, or if it is local mail (to prevent loops). If you're using an alternative prefix, adjust the pathnames to match.
Then add the following code to the transports section. This code defines how dspam is called by exim for scanning email:
spamcheck: driver = pipe command = /usr/local/bin/dspam --deliver=innocent --user $local_part -- %u user = mail group = mail return_path_add = false log_output = true return_fail_output = true
If you're using virtual users on the system, you may wish to include the domain as part of the username:
command = /usr/local/bin/dspam --deliver=innocent --user "$local_part@$domain" -- %u
Finally, you will need to configure and compile DSPAM. DSPAM will most likely end up calling exim again for delivery, using the spam-scanned protocol to identify scanned messages. The most common example is:
./configure --with-delivery-agent="/usr/sbin/exim -oMr spam-scanned"
RUNNING WITHOUT PRIVILEGED EXIM USERS
The problem with setting the $received_protocol in the transport is that only privileged Exim users are allowed to do so. With the setup below, DSPAM can run as a nonprivileged user. The problem, however, is that this header could be easily spoofed:
condition = "${if and {\ {!def:h_X-DSPAM-Check:}\ }{1}{0}}" headers_add = "X-DSPAM-Check: by $primary_hostname on $tod_full"
DIRECTORY SETTINGS
When changing the user/group it is highly advisable to set "home_directory" and "current_directory" to match the DSPAM home:
home_directory = "/usr/local/var/dspam" # or /tmp current_directory = "/usr/local/var/dspam" # or /tmp
Otherwise, the transport might try to run DSPAM in something like /home/bob under certain circumstances. This will most likely fail if DSPAM runs as "mail".
PASS-THROUGH
For a pass-through setup where DSPAM feeds all processed messages back to Exim it is also a good idea to set "prefix" and "suffix" to an empty string:
prefix = "" suffix = ""
ALIASES
There is no need to create aliases for every user on the system in order to handle spam reports and false positives. They can be handled by directors and transports, using the following directors:
dspam_addspam: prefix = spam- driver = localuser transport = addspam dspam_falsepositive: prefix = falsepos- driver = localuser transport = falsepositive
For every $user on the system, these directors will handle messages addressed to "spam-$user@localhost" and "falsepos-$user@localhost", strip the prefix from the address, and pass the message to the respective transport. This requires two additional transports:
addspam: driver = pipe command = "/path/to/dspam --user $local_part --class=spam --source=error" return_path_add = false return_fail_output = true log_output = true home_directory = "/path/to/dspam/dspam-home" # or "/tmp" current_directory = "/path/to/dspam/dspam-home" # or "/tmp" user = mail group = mail prefix = "" suffix = "" falsepositive: driver = pipe command = "/path/to/dspam --user $local_part --class=innocent --source=error --deliver=innocent %u" return_path_add = false return_fail_output = true log_output = true home_directory = "/path/to/dspam-home" # or "/tmp" current_directory = "/path/to/dspam-home" # or "/tmp" user = mail group = mail prefix = "" suffix = ""
This way, all users are handled transparently. No fiddling with aliases is required as you add or remove users.