exim: select smarthost according to sender address

When sending mails from my systems, I usually want to use different smarthosts according to the sender address. If I use the sender address vwegert@web.de, I want the mail to be delivered via smtp.web.de, if I use one of my @volker-wegert.de addresses, I want to use the smarthost at Manitu and so on. With exim, this is possible with a few configuration adaptions.

First create a file named /etc/exim/smarthosts that will contain the routing information. The contents look like this:

vwegert@web.de:     smarthost=smtp.web.de             auth_name=vwegert auth_pass=secret
*@volker-wegert.de: smarthost=smtp.volker-wegert.de   auth_name=vwegert auth_pass=veeerysecret

The contents are fairly self-explanatory. As you can see, wildcards are possible for the sender address. Since this file contains sensitive information, a restrictive permission setting (-rw-------) sould be used. Now head on to exim.conf. In the router configuration, disable domain_literal if it's not already disabled and replace it with the following entry:

smarthost_auto:
   condition = ${extract{smarthost}{${lookup{$sender_address}wildlsearch{/etc/exim/smarthosts}{$value}fail}}}
   driver = manualroute
   domains = ! +local_domains
   route_list = "* ${extract{smarthost}{${lookup{$sender_address}wildlsearch{/etc/exim/smarthosts}{$value}fail}}}"
   transport = remote_smtp

Caution: The order in which the routers are defined matters!

This router definition can be read as "If I find a line in /etc/exim/smarthosts whose key as wildcard matches the sender adress and where a smarthost is set, then use this smarthost as next MTA and transfer the message using SMTP." This is not quite enough because I want to authenticate using the password when sending mail. This requires an additional line in the transport remote_smtp:

  hosts_try_auth = smtp.volker-wegert.de:smtp.web.de

as well as the following configuration in the authenticators section:

cram_md5:
     driver = cram_md5
     public_name = CRAM-MD5
     client_name = "${extract{auth_name}{${lookup{$sender_address}wildlsearch{/etc/exim/smarthosts}{$value}fail}}}"
     client_secret = "${extract{auth_pass}{${lookup{$sender_address}wildlsearch{/etc/exim/smarthosts}{$value}fail}}}"

That's it - have fun.

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer