[Pkg-exim4-users] Exim4 with local network as well as smarthost (longish post)

ael law_ence.dev at ntlworld.com
Sun Mar 8 18:04:19 UTC 2009


The standard debian exim configurations do not seem to cater
for a small local network behind a NAT router.

Most mail needs to go to an (isp) smarthost with FROM headers
rewritten. But local mail within the network needs to be delivered
directly with headers unchanged.

This already presents a problem to exim4 because, as I understand it,
envelope rewriting can only be done globally.

My local network is small and no single machine is necessarily
running at all times. Thus a dedicated local network mail machine
is not an option. Instead each machine runs its own copy of exim4
and accepts email directly from its local peers.

The local hosts each have the local network hostnames in /etc/hosts:
these are not registered dns names and are aliases as usual for
reserved 10.0.0.*, 192.168.*.* or 172.16.*.* IP4 addresses.

As a total novice at exim4, I have cobbled together a solution which
appears to work, except that I have found no way to rewrite the envelope
headers when sending to the smarthost. As I understand it, bounce 
messages are sent to the envelope address rather than to the FROM or 
REPLY-TO headers of the message itself. Thus a smarthost trying to 
bounce will encounter an invalid address,or just conceivably will bounce 
to the wrong place.

I describe my configuration below for two reasons:

1) to ask for a better solution from more experienced people;
2) in case it might be useful to others, despite the minor (?) problem.


If the global rewrite limitation on envelope headers really is
the problem that it seems to be, perhaps upstream might consider
a modification in some future version.

-------------------------------------------------------------------------

The description here is using a monolithic configuration.

First I define a new macro LOCAL_NETWORK in exim4.conf.localmacros.

LOCAL_NETWORK is a regular expression used to recognise the local network
names (held in /etc/hosts). I tried to get exim4 to examine /etc/hosts
directly, but eventually resorted to writing the regular expression
manually:

--------------- exim4.conf.localmacros -------------------------

# Define macros for local network here

LOCAL_NETWORKS = 
\N^(?:mouse\d[^.]?|cw\d|w?(?:cat|tiger|lion))(?:\.rodent)?$\N

# Since LOCAL_NETWORKS appears in string lists with default separator :,
# those lists need default changed (or ::/: above)

#Since main rewriting rules are global we must turn them off:
NO_EAA_REWRITE_REWRITE = true
#To compensate, must add them to right transport

REMOTE_NETS_REWRITE1 = \
*@+local_domains "${lookup{${local_part}}lsearch{/etc/email-addresses}\
                    {$value}fail}" frs
REMOTE_NETS_REWRITE2 = \
*@ETC_MAILNAME "${lookup{${local_part}}lsearch{/etc/email-addresses}\
                    {$value}fail}" frs

REMOTE_NETS_REWRITES = REMOTE_NETS_REWRITE1 : REMOTE_NETS_REWRITE2

-----------------------------------------------------------------------

I had to edit update-exim4.conf.conf manually:

----------------- update-exim4.conf.conf ----------------
#...

dc_eximconfig_configtype='smarthost'
dc_other_hostnames='mousebag.rodent'
dc_local_interfaces=''
dc_readhost='mouse1.rodent'
dc_relay_domains=''
dc_minimaldns='true'
dc_relay_nets=''
dc_smarthost='smtp.isp.com'
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname='false'
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'
---------------------------------------------------

dpkg-reconfigure exim4 would not let me have smarthost and
dc_hide_mailname='false' together. This last was to turn off that
troublesome global envelope rewriting.

local_host_blacklist had
!192.168.0.0/17
to allow the incoming mail from local peers.
{ The local network has a wifi subnet. }

I had to edit exim4.conf.template:

First I added a new initial router to catch the local network mail:

----------------------------------------------------------------
  begin routers

#### LOCAL_NETWORKS is an RE from exim4.conf.localmacros ###

.ifdef LOCAL_NETWORKS
local_net:
   debug_print = "R: local_net for $domain"
   driver  = manualroute
   domains = <; LOCAL_NETWORKS
   route_list = * $domain byname
   condition = ${if match_domain{$domain}{+local_domains}{no}{yes}}
   transport = smtp_lnet
.endif

------------------------------------------------------------------
"byname" above ensures that the local network names can be translated
from /etc/hosts. The condition makes sure that the local names on the
host machine pass through.

It uses a dedicated transport smtp_lnet defined below:

--------------------------------------------------

  begin transports

# transport to avoid from rewrite

.ifdef LOCAL_NETWORKS
smtp_lnet:
   debug_print= "T: smtp_lnet for $local_part@$domain"
   driver = smtp
.endif

----------------------------------------------------------

But since the global header rewrite has been turned off, I had
to hack the next best thing

----------------------------------------------------------------
# local nets hack
.ifdef LOCAL_NETWORKS
REMOTE_SMTP_HEADERS_REWRITE=REMOTE_NETS_REWRITES
.elifdef HIDE_MAILNAME
REMOTE_SMTP_HEADERS_REWRITE=*@+local_domains $1 at DCreadhost frs : 
*@ETC_MAILNAME $1 at DCreadhost frs
.endif

.ifdef HIDE_MAILNAME
REMOTE_SMTP_RETURN_PATH=${if 
match_domain{$sender_address_domain}{+local_domains}{${sender_address_local_part}@DCreadhost}{${if 
match_domain{$sender_address_domain}{ETC_MAILNAME}{${sender_address_local_part}@DCreadhost}fail}}}

.endif
# end of local nets hack

-------------------------------------------------------------------

That gets picked up in the remote_smtp_smarthost transport where
it causes the appropriate non-envelope headers to be re-written.

=====================================================================

Warning. I have not considered TLS or other configuration options
which may well be broken as the above stands.

ael



More information about the Pkg-exim4-users mailing list