I am transferring our organisations email from sendmail
to exim. I have what I think is a fairly complicated
setup here, and have been scouring the Exim book and
manuals for ideas on how to proceed. Having arrived at
what I think is a reasonable strategy for for handling
everything, I thought I would bounce it off the list
in the hope that if I have gone wildly off the rails
someone would set me straight.
This is the situation:
- The organisation has several offices around the
country. Each office has a server that holds the
mail boxes for its local people.
- Apart from that little detail, all servers are
nearly identical. They all have the same /etc/passwd,
for example, and the same directories under /home.
(If they weren't I would go mad trying to maintain them
all).
- All servers are connected by a VPN. VPN addresses
are rfc 1918 addresses. Each office has its own
subnet. All the intranet addresses have DNS records
of the format machine-name.office-name.lube.
- Not all servers are equal. Some are firewall machines
that have direct connections to the internet. Firewall
machine do not forward port 25. Non firewall machines
must use them as a smarthost. The smarthost for the
office has a DNS alias of smtp.office-name.lube. Every
office has at least one firewall machine, obviously.
- One of the offices has the primary MX record pointing
at it. Other offices have secondary MX records pointing
to them. This implies external email can arrive at any
office.
- All users have email addresses of the format
USER@???. Ie, the domain name does not
include the office name. Routing between the offices
must depend on the user name.
- All email that passes through the servers must be virus
checked.
- We act as a primary or secondary MX for some external
organisations. We also have a couple of aliases (eg
email sent to USER@??? should be routed
to USER@???).
- It seems the law now requires us to keep a copy of all
emails that may contain contractually binding information.
We should not keep copies of email we handle for external
organisations, of course. And employees are allowed to
have private email, which we shouldn't keep a copy of.
And there must be only one copy taken, of course.
- People like email sent to Joe across the hallway to happen
fast, even if the office's internet connection is down.
Ergo intra-office email (ie email that is between two people
in the same office) should NOT be sent via the internet.
The whole thing seems to revolve around the last two requirements.
Since scanning an email for "contractually binding" stuff is
impossible, I am going to have to copy everything. To handle
private email, I will allocate private email addresses to every
user of the form USER@???. If the
from/to/cc headers contain an address of that form the email
is deemed private and will not be copied.
It wouldn't be hard if we had a hub-and-spoke system - the
copy required by the lawyers could be done at the hub. Since
there is only one hub it should be simple to ensure that one
one copy is made as it passes through it. But the last
requirement means I can't implement it that way (I think).
The best alternative I could think of was to regard all the
servers as a cluster. Then these two operations should be
performed only once, when an email enters the cluster:
1. Virus checking.
2. Creating an copy of the lawyers, if requires.
When email passes between servers in the cluster, these two
operations should be skipped.
The easiest I could think of to implement a "cluster" concept
was would be to have secure channel. This could be on a
different port, or possibly AUTH'ed. An email arriving by
any of the normal means wouldn't be on the secure channel,
so it would be copied and virus checked. The virus checker
would hand it back by the secure channel. Thereafter it
would be forwarded over the secure channel between servers.
The email copies have to be on a single server, which I can
physically get to so I can ensure it is backed up. The easiest
was to get the copies there is via the email system. So I
thought a few routers would do the trick:
#
# Check if we should copy the email because we sent it.
#
enter_sender_copy:
driver = redirect
PRECONDITION = ..! secure.. # some magic precondition here.
sender_address_domain = lubemobile.com.au
condition ${if match ${header_from} {.*@private\.lubemobile\.com.*} {no} {yes}}
condition ${if match ${header_to} {.*@private\.lubemobile\.com.*} {no} {yes}}
condition ${if match ${header_cc} {.*@private\.lubemobile\.com.*} {no} {yes}}
condition ${if match ${header_reply-to} {.*@private\.lubemobile\.com.*} {no} {yes}}
data = archive@???, ${quote:$local_part}@$domain
#
# Check if we could copy the email because we are receiving it.
#
enter_rcpt_copy:
driver = redirect
PRECONDITION = ..! secure..
domain = local_domain
condition ${if match ${header_from} {.*@private\.lubemobile\.com.*} {no} {yes}}
condition ${if match ${header_to} {.*@private\.lubemobile\.com.*} {no} {yes}}
condition ${if match ${header_cc} {.*@private\.lubemobile\.com.*} {no} {yes}}
condition ${if match ${header_reply-to} {.*@private\.lubemobile\.com.*} {no} {yes}}
data = archive@???, ${quote:$local_part}@$domain
#
# Send it to the virus scanner. It will come back with
# PRECONDITION = secure
# true.
#
virus_scanner:
driver = accept
PRECONDITION = ..! secure ..
transport = virus_scanner_transport
no_more
I am presuming that the duplicate redirects to
archive@??? will be eliminated, and
the redirect router won't mind how I am abusing it
by re-directing an address to itself.
The remainder of the routers will only see email's on the
secure channel. Assuming they always use a transport that
sends over a secure channel the stuff above should be
by-passed, although I wonder about what will happen with
.forward files. With a bit of effort I could get rid of
Handling the user@??? virtual domain seems simple.
I just plan to redirect user@??? using a database
lookup. The other massaging seems equally simple.
I would like to keep all exim.conf's the same. Do to this and
handle machines behind the firewall, it seems easier to put
the a "smarthost" in an included file. At the top of the
routers I can then have something like:
smart_host:
driver = manualroute
condition ${if =={$smart_host}{""} {no} {yes}}
domains = !+local_domains
transport = remote_smtp
route_list = * ${smart_host}
Does this all sound reasonable, or is there some really simple
was to do this?