This is an old revision of the document!
You know how it is. Your little mail host has just sat there for a long while, slowly accreting a user here and a user there. They are all full users on the machine, so they have logins and everything, and exim
is configured to deliver their mails to ~/Maildir.
And then some dangerous loon suddenly demands that you add mailboxes for people using a completely different domain. They're not really much to do with you, and certainly shouldn't be full-blown users on your host.
Time, then, to add virtual mailboxes to your poor little mail host.
There all sorts of HOWTOs on doing this, of various ages and usefulness. I'm adding this page to the malestrom just to document the configuration changes I did. Or rather, the configuration changes I ended up with. The details of configuration aren't original, but synthesised from too many of the HOWTOs I read to properly credit each.
I'm illustrating this by setting up a new domain example.mod with user tommy.atkins.
First I created a system user and group vmail
to own all virtual mailboxes.
# adduser -system --home /var/local/vmail --group vmail
and a configuration directory.
# mkdir /etc/vmail
Configuration information for the domain will be under /etc/vmail/<domain>
. If that directory doesn't exist, the domain isn't supported.
# mkdir /etc/vmail/example.mod
The general scheme is that we have mailboxes under /var/local/vmail/<domain>/<user>/Maildir
. Why Maildir
? Because our existing users will continue to get mail in ~/Maildir
and it keeps dovecot
config a little simpler.
# mkdir -p /var/local/vmail/example.mod # chown -R vmail:vmail /var/local/vmail
Now add two configuration files. The first, aliases
, is a conventional aliases file for the domain.
# cat > /etc/vmail/example.mod/aliases postmaster: root webmaster: root security: root admin: root root: guru@example-owner.mod squaddie: tommy.atkins ^D
The second, passwd
contains the account information for the domain. There are two items on a line, username and password hash, separated by a colon. Generate the password has using the dovecotpw
utility. Just to be on the safe side, we'll ensure the password file isn't world readable.
# /usr/sbin/dovecotpw -p password {CRAM-MD5}9186d855e11eba527a7a52ca82b313e180d62234f0acc9051b527243d41e2740 # cat > /etc/vmail/example.mod/passwd tommy.atkins:{CRAM-MD5}9186d855e11eba527a7a52ca82b313e180d62234f0acc9051b527243d41e2740 ^D # chgrp /etc/vmail/example.mod/passwd # chmod 0640 /etc/vmail/example.mod/passwd
The next step is to configure Exim to deliver to virtual mailboxes.
The first thing to do is to add the domain to the list of local domains. How you do this depends on which of Debian's configuration scheme you are using. You need to end up with a configuration file with the domain as part of the domainlist local_domains
. From here on, I'll show what I ended up with in the Exim configuration file, and leave it up to you to work out how to get it there.
Next we need a router to expand virtual domain aliases.
vmail_aliases: driver = redirect data = ${lookup{$local_part}lsearch{/etc/vmail/$domain/aliases}} domains = dsearch;/etc/vmail qualify_domain = $domain retry_use_local_part
That desarch;/etc/vmail
will expand to a list of the files/directories under /etc/vmail. Which will be the domains to be handled. qualify_domain = $domain
ensures the expanded alias, if any, has the same domain as the original, if the domain is not specified in the alias.
Once that's done, we can think about routing to a transport for delivery.
vmail_deliver: driver = accept condition = ${if eq {}{${lookup{$local_part}lsearch{/etc/vmail/$domain/passwd}}}{no}{yes}} domains = dsearch;/etc/vmail no_more retry_use_local_part transport = vmail_delivery
Here we're accepting the mail on condition that the local part of the address appears in the domain's password file. If it does, the message proceeds to the transport.
vmail_delivery: driver = appendfile envelope_to_add directory = /var/local/vmail/$domain/$local_part/Maildir maildir_format create_directory = true user = vmail group = vmail return_path_add
This transport adds the message to the user's Maildir
. It runs as user and group vmail
and will create any directories that don't exist.
By the way, when you add a user, it's an idea to either send them a welcome mail to check things are working properly and create their Maildir
into the bargain. Otherwise, you should create the Maildir
by hand, so that there is something there when they try to read their mail.
When that's done, test your handiwork:
# exim4 -bt tommy.atkins@example.mod tommy.atkins@example.mod router = vmail_deliver, transport = vmail_delivery
Now we need to modify the Dovecot setup to allow our user to read mail.
I'm assuming your dovecot.conf
already has
mail_location = maildir:~/Maildir
in it, telling Dovecot to find your regular users mail in ~/Maildir
.
We need to add the virtual domains to the
auth default { }
section of the configuration. The first stage is to add the virtual users password files.
passdb passwd-file { args = username_format=%n /etc/vmail/%d/passwd }
Here's a tip. My configuration also has a configuration for PAM
passdb pam { }
Put the virtual users passwd-file
entry before the pam
section. If you don't, your virtual usernames will be tried in pam
first. Confusion will abound if they succeed. And if they don't, it will look to programs like denyhosts
or fail2ban
as if a PAM login failed, and you may find access to the host unexpectedly blocked.
Now you need to add a userdb
section telling Dovecot how to find the mailbox. You will have a
userdb passwd { }
section serving your existing users. After that, add a catch-all for the virtual mailbox users.
userdb static { args = uid=vmail gid=vmail home=/var/local/vmail/%d/%n }
This tells Dovecot to use vmail
permissions to access the mailbox, and that the user home is at /var/local/main/<domain>/<user>
. Dovecot will apply it's existing rule that the mail is to be found in directory Maildir
under the user's home, and you are off to the races.
In practice, you'll most probably run into authentication problems. For help sorting them out, add
auth_debug = yes auth_debug_passwords = yes
to your dovecot.conf
while you try and work out what's going wrong.