8.3 Using Routers and Transports

‚  < ‚  Day Day Up ‚  > ‚  

You can configure Exim to pass all incoming mail through SpamAssassin by writing a transport that pipes messages to SpamAssassin and then reinjects them into Exim, and a router that directs messages to the transport. To prevent the reinjected messages from being spam-checked again, you can set their $received_protocol to indicate they've been checked when you reinject them, and use the $received_protocol value as a condition to determine whether or not the router will send them for checking.

8.3.1 Configuring the Transport

Example 8-2 shows the configuration of the transport in /usr/exim/configure .

Example 8-2. A transport for spam-checking
 spamassassin:   driver = pipe   use_bsmtp = true   command = /usr/exim/bin/exim -bS -oMr sa-checked   transport_filter = /usr/bin/spamc -f   home_directory = "/tmp"   current_directory = "/tmp"   user = exim   group = exim   log_output = true   return_fail_output = true   return_path_add = false 

The spamassassin transport in Example 8-2 uses Exim's pipe driver to deliver a message to a command. The example specifies that Exim should use the batched SMTP (BSMTP) format to transmit the message. The command is another invocation of exim itself, with the -bS option to accept BSMTP input and the -oMr sa-checked option to set the $received_protocol variable to sa-checked . Before Exim pipes the message to the command, it filters the message through the program specified by transport_filter ‚ in this case, spamc ‚ and uses the output of the filter as the message to deliver. The other transport options provide home and working directories for running the command, specify that the command should be run as user and group exim , cause command output to be logged and any failure messages to be included in a bounce message, and indicate that a Return- Path header should not be added (because this transport is not performing final delivery).

You must specify that the exim command used in the transport will be run as one of Exim's trusted users in order for the -oMr sa-checked option to work. The Exim user (specified during Exim's installation) is always trusted. You can add other trusted users in the configuration file with the trusted_users or trusted_groups directives.

8.3.2 Configuring the Router

The transport provides a mechanism for Exim to filter messages through SpamAssassin and reinject them. You must also define a router that will invoke this transport during delivery. Example 8-3 displays a definition for such a router in /usr/exim/configure .

Example 8-3. A spam-checking router in Exim
 spamassassin_router:   driver = accept   transport = spamassassin   condition = "${if {!eq {$received_protocol}{sa-checked}} {1} {0}}"   no_verify   no_expn 

The spamassassin_router in Example 8-3 uses the accept driver, which simply delivers a message to a transport. The transport directive specifies our spamassassin transport. The condition directive prevents a spam-checking loop when messages are reinjected by insuring that the value of $received_protocol is not sa-checked . The no_verify and no_expn directives instruct Exim to skip this router when performing address verification or expansion.

Add the router definition from Example 8-3 to the section of /usr/exim/configure that lists routers. The order of the router definitions is significant. Where you add the spamassassin_router router in the list determines which messages will be checked, as shown in Table 8-1. Most sites will probably want to add the router between system_aliases and userforward (or possibly between userforward and a procmail router), but spam-checking gateways are likely to need the router before dnslookup as nearly all of their mail will be destined for remote sites.

Table 8-1. Effect of the position of spamassassin_router in the Exim router list

Position

Effect

First in the list (before dnslookup )

SpamAssassin invoked on all messages, including local deliveries, outgoing messages, and messages relayed to remote hosts .

Between dnslookup and system_aliases

SpamAssassin invoked on messages with addresses in locally hosted domains. System aliases and user .forward files will receive messages already spam-checked (and can act on tagging).

Between system_aliases and userforward

SpamAssassin invoked on messages with addresses in locally hosted domains, unless system alias file redirected them to a remote host. User .forward files will receive messages already spam-checked (and can act on tagging).

Between userforward and localuser

SpamAssassin invoked only on messages that will be delivered locally. User .forward files will receive messages without spam-checking. Spam-checked messages will be delivered to local mailbox.

After localuser

Too late! Messages will already have been delivered.


8.3.3 Using Per-User Spam-Checking Preferences

Because Exim routes each delivery address separately, you can configure it to behave differently for messages that will be delivered locally and messages that will be relayed to remote hosts. You can take advantage of this flexibility to direct SpamAssassin to use per-user preferences when checking a message that is destined for a local user and to use sitewide preferences when checking a message that is destined for a remote user. This approach requires a second transport and a second router. Add another transport such as that shown in Example 8-4 to your Exim configuration file.

Example 8-4. Transport for local spam-checking in Exim
 spamassassin_local:   driver = pipe   use_bsmtp = true   command = /usr/exim/bin/exim -bS -oMr sa-checked  transport_filter = /usr/bin/spamc -f -u $local_part  home_directory = "/tmp"   current_directory = "/tmp"   user = exim   group = exim   log_output = true   return_fail_output = true   return_path_add = false 

The key addition in the spamassassin_local transport is the use of spamc 's -u user command-line option to specify the user on whose behalf spamc is running. spamc will convey the username to spamd , which will examine the user's .spamassassin/user_prefs file for preferences.

For this transport to work, spamd must be able to read users' preference files. Because you should run spamd under a dedicated user and group, this user or group must be able to search the .spamassassin subdirectory of each user's home directory and read the user_prefs file. (You may instead run spamd as root , but using a dedicated user is a better security practice.)

You must not invoke spamd with the --nouser-config or --auth-ident options when using this transport. If you use --nouser-config , spamd will ignore spamc 's -u argument, and user preferences will not be examined. If you use --auth-ident , spamd will attempt to confirm that spamc is being run by the user given in its -u argument. Because Exim runs as its own user, the authentication will fail and spamd will refuse to look up user preferences.


Next, add a router that uses the spamassassin_local transport, as shown in Example 8-5.

Example 8-5. A spam-checking router with user preferences in Exim
 spamassassin_local_router:   driver = accept  transport = spamassassin_local  condition = "${if {!eq {$received_protocol}{sa-checked}} {1} {0}}"   no_verify   no_expn 

You should also modify spamassassin_router to limit its use to non-local domains. This modification is shown in Example 8-6.

Example 8-6. A spam-checking router for non-local domains in Exim
 spamassassin_router:   driver = accept   transport = spamassassin  domains = ! +local_domains  condition = "${if {!eq {$received_protocol}{sa-checked}} {1} {0}}"   no_verify   no_expn 

Arrange the routers in the following order:

  1. spamassassin_router , to perform spam-checking for messages addressed to remote domains

  2. dnslookup , to route messages addressed to remote domains via SMTP

  3. system_aliases , to redirect messages with addresses in /etc/aliases

  4. spamassassin_local_router , to perform spam-checking for messages addressed to local users with the per-user preferences of the local user (who may, however, choose to forward the tagged message elsewhere)

  5. userforward , to redirect messages with addresses in user .forward files

  6. localuser , to route messages via the local delivery agent

To illustrate how this approach functions, consider an Exim system running on mail.example.com and configured to relay messages for example.com to an internal mail server. On mail.example.com , postmaster is an alias for the local user chris . When a spammer sends a message addressed to sam@example.com and postmaster@mail.example.com , Exim passes each address through its list of routers. sam@example.com is routed by spamassassin_router , so a copy of the message is tagged by SpamAssassin using its sitewide configuration and then reinjected. The reinjected message bypasses spamassassin_router and is routed by dnslookup , which queues it for remote delivery. Meanwhile, postmaster@mail.example.com is destined for a local domain and bypasses both spamassassin_router and dnslookup . The system_aliases router rewrites the address to chris@mail.example.com , which Exim then begins routing. This address bypasses spamassassin_router , dnslookup , and system_alias and is routed by spamassassin_local_router , which tags a copy of the message using chris 's SpamAssassin preferences and reinjects it. The reinjected message bypasses spamassassin_router , dnslookup , system_alias , and spamassassin_local_router , and assuming chris does not have a .forward file, Exim delivers it to chris 's local mailbox. Figure 8-4 illustrates this process.

Figure 8-4. Exim router lookups during delivery

‚  < ‚  Day Day Up ‚  > ‚  


SpamAssassin
SpamAssassin
ISBN: 0596007078
EAN: 2147483647
Year: 2004
Pages: 88

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net