After messing with my email setup for virtual domain support, I decided I should really move from the old mbox format to Maildir.
Debian
This requires changes to exim, dovecot and the maildrop
~/.mailfilter
file.
Exim
To turn on Maildir delivery, add a macro definition to
/etc/exim4/exim4.conf.localmacros
:
LOCAL_DELIVERY=maildir_home
Update the configuration and restart Exim4:
sudo update-exim4.conf.template -r && sudo update-exim4.conf sudo systemctl restart exim4
Exim4 will now deliver mail to ~/Maildir
for local users.
To enable Maildir delivery for virtual domains, the virtual_domains router was changed to this:
# Router for virtual domains # Use of domain_data to avoid using tainted data # Data is considered tainted if if comes from the mail virtual_domains: debug_print = "R: virtual_domains for $local_part@$domain" driver = accept domains = dsearch;/home/vmail local_parts = wildlsearch;/home/vmail/${domain_data}/aliases user = vmail group = vmail router_home_directory = /home/vmail/${domain_data}/${local_part_data} transport = maildir_home # Fail mail to non-existent users for virtual domains virtual_domains_fail: driver = redirect allow_fail = yes domains = dsearch;/home/vmail data = :fail:
The virtual_mailboxes transport is no longer required as the virtual_domains router can directly invoke the maildir_home transport, after setting up the environment correctly.
I’d got the priority of the virtual_domains router wrong in the
original setup. By putting the virtual_domains router before before
the smarthost router (defined in
/etc/exim4/conf.d/router/200_exim4-config_primary
, the supported
virtual domains do not need to be added to the list of local
domains. The fact that a directory exists in /home/vmail
is
sufficient.
Dovecot
Change the setting of mail_location
in the file
/etc/dovecot/conf.d/10-mail.conf
:
mail_location = maildir:~/Maildir:INDEX=~/Maildir/index:CONTROL=~/Maildir/control
Maildrop
The ~/.mailfilter
file needed a small change to enable Maildir
delivery. If the target of to
is a directory, maildrop assumes a
Maildir format. This is an example of what the filter looks like now:
MAILDIR="$HOME/Maildir" if ( /freebsd-stable/:h || /freebsd-security/:h ) to ${MAILDIR}/.Archive.${MATCH}
Migration
In order to convert from the current mbox-with-added-Maildir setup, I
first made the Maildir configuration changes on opal (the backup
server), used imapsync to copy the
existing mail setup from ash to opal, then made the configuration
changes on ash and performed a reverse sync. Once all looked good on
ash, I could delete the old ~/mail
content.
OpenSMTPD
For systems running OpenSMTPD (OpenBSD and Oracle Linux), the dovecot
changes are the same. However, the action for mail delivery (as
defined in smptd.conf.local
) is now:
action "local" maildir alias <aliases> # virtual domain email delivery action "vmail" \ maildir "/home/vmail/%{dest.domain}/%{dest.user:lowercase|strip}/Maildir" \ virtual <virtual_users>
Caveats
A small downside of this approach is reading incoming mail using command-line mail. GNU mail handles Maildir format, as can s-nail on Oracle Linux, but OpenBSD mail does not. So, on OpenBSD, I’ve installed s-nail from ports to enable command-line mail.
I use maildrop for filtering on hydrus mail, but should I want to allow filtering for virtual domains, I’d probably need to use Dovecot’s LMTP for local delivery so that I can use the Pigeonhole sieve capability.