I was recently asked to configure Exim to archive all mail sent and received by certain customers. Users authenticate to send mail using their email address so I used a domainlist to specify which domains' users should have their mail archived.
domainlist archive_domains = example.com
I created two routers
and a transport for handling the mail sent by authenticated users. The first
is a redirect
router which rewrites the recipient address to a special address containing
the sender's address, e.g. _!%#archive#%!_-user@example.com. This router has
the unseen
option set so the message is routed to the original
recipient as usual. This doubles the number of recipients, but Exim discards
duplicates so the final recipients are the original recipients plus the
sender's archive copy. The second router strips the _!%#archive#%!_- prefix
and delivers to the message to the sender's archive mailbox using a special
transport.
These routers should probably be the first two since you don't want another router to accept delivery of the message first.
archive_by_sender_rewrite: driver = redirect condition = ${if and { {def:authenticated_id}{match_domain{${domain:$authenticated_id}}{+archive_domains}} }{yes}{no}} data = _!%#archive#%!_-$authenticated_id unseen no_repeat_use no_verify archive_by_sender: local_part_prefix = _!%#archive#%!_- driver = accept no_verify transport=archive_by_sender
Because $authenticated_id
is used to get the sender's address, you
should have server_set_id = $1
in your authenticators
so the variable gets set.
The router to archive recieved mail is pretty simple. It uses the
unseen
option again to create a copy of the message, and like
archive_by_sender
uses a separate transport to archive the
message. This router should be placed before any routers that accept mail for
the +archive_domains
. If you use routers to discard or quarantine
spam, this one should be before those if you want to archive the spam received.
archive_by_recipient: driver = accept domains = +archive_domains unseen no_verify transport=archive_by_recipient
Here are the transports. The messages are written to maildir directories. Any missing directories will be created if Exim has permission to create them.
archive_by_sender: driver = appendfile maildir_format mode = 0600 mode_fail_narrower = false envelope_to_add = true return_path_add = true create_directory directory = /path/to/archive/$domain/$local_part/sent archive_by_recipient: driver = appendfile maildir_format mode = 0600 mode_fail_narrower = false envelope_to_add = true return_path_add = true create_directory directory = /path/to/archive/$domain/$local_part/received
If you don't have the default rule in your rcpt acl to reject local parts
contains %, !, etc., you should make sure you don't accept mail for the special
archive user address. Safeguarding against malicious users with shell access
is left as an exercise for the reader. (Hint: I would probably look at
$received_protocol
.)
tech » mail | Permanent Link
The state is that great fiction by which everyone tries to live at the expense of everyone else. - Frederic Bastiat