On 2007-05-05 at 15:56 +0000, Mordur Ingolfsson wrote:
> Is there any way to route mail from localhost differently than mail from
> other hosts?
Sure. Lots of ways.
Match on $sender_host_address in a condition.
Use an ACL variable, so that you can set the variable under several
different conditions and then have the router state policy by using the
variable instead of hard-coding the address down there.
Eg, you might want to set acl_m_fromlocal based upon acl_smtp_connect
checking "hosts" and also, separately, in acl_not_smtp. Well, actually
in your case, using a macro ACL_M_FROMLOCAL=acl_m0 (or whatever value)
since named ACL variables were introduced in 4.64.
> This creates a problem. If a member of a mailing list has an address in
> one of the local_domains, Exim considers the domain to be a local one
> and tries to deliver it locally.
>
> I therefore need "outgoing" mail (from localhost) to be sent by a router
> to a remote_smtp transport, even if the address is in a domain that Exim
> considers to be a local domain.
>
> How can I do this?
Exim 4 doesn't really have a distinction between ye olde Directors and
Routers. It's all just routers, based upon the restrictions you specify.
You probably have something like the example in the default configure
file:
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more
and then the local stuff beneath. There's no reason that you can't have
a second Router which uses rempte_smtp even when domains =
+local_domains, put beneath the list-handling stuff. There is, however,
very good reason to be very careful when doing so: mail loops.
Eg, if the list-machine is not in the MX records for your domain
"example.tld", but all the relevant hosts which can send to it are,
except 192.0.2.1 which is an internal hub, then you might have one final
Router (untested):
# in first section:
hostlist no_remotelocal_if_from = <; 192.0.2.1 ; \
${lookup dnsdb{>; a=${lookup dnsdb{>: mxh=example.tld}}}}
# at end of "begin routers" section, before next begin:
remote_despite_local:
driver = dnslookup
domains = +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
condition = ${if and{\
{def:sender_host_address}\
{match_ip{$sender_host_address}{+no_remotelocal_if_from}}\
} {no}{yes}}
Note the {no}{yes} to invert the sense of the earlier lookups; if
and{..all these...} then no, otherwise yes. So the remote_despite_local
router will *not* run *if*: the variable sender_host_address is defined
and the value $sender_host_address exists in the hostlist
no_remotelocal_if_from, which contains one IP address which is
explicitly specified and a bunch of IP addresses extracted from the MX
records.
For high volume servers, maintaining the list of IP addresses statically
may be a win, or having a local name service cache. And I'm fairly sure
that I'm currently forgetting a much easier way to do an IP address
comparison against the hosts in the MX records. It was easier to write
the dnsdb queries from scratch than to remember the option syntax, which
is more a commentary on how little I deal with SMTP servers these days.
-Phil