Previous TOC Next

Technical document: Linux Mail Server Howto
Chapter 8 - Creating virtual users and domains
So far we have discussed accessing email for system users. However if you wish to host hundreds or thousands of email accounts it is not efficient to create a system user for each email account. Additionally you may wish to host mails for multiple domains. In order to do this we can set up virtual users within virtual domains. In fact we recommend "virtualising" mail accounts for bone fida system users too - it's more secure and means all accounts can be administered in the same way.

Setting up virtual users essentially means creating a database of non-system users and an area where their mail can be delivered to. First let's configure postfix to deliver mail for a virtual domain. You must of course ensure that the MX records for the domain are configured correctly.

Creating a system user to host virtual user mailboxes

All virtual users need their mail stored somewehere. First create a single system user, which we are calling vmail. As root:

> adduser vmail
> su vmail

Now create directories for each of the domains we will be hosting. In this example we are to host two domains:

> cd
> mkdir [domain_1]
> mkdir [domain_2]

For each domain we create a sub-directory for each virtual user [vuser] within that domain:

> cd [domain_1]
> mkdir [vuser]

Now create the maildir for user [vuser]:

> cd [vuser]
> /usr/lib/courier-imap/bin/maildirmake Maildir
> exit

We now need to configure postfix to deliver to this mailbox and courier to read from it.

Configuring postfix to deliver to virtual mailboxes

You will need to add the following lines to /etc/postfix/main.cf. You can get the user and group ids for vmail by checking /etc/passwd:

# The virtual domains to host (must NOT be the same as anything in $mydestination)
virtual_mailbox_domains = [domain_1], [domain_2] 

# The home directory of the system user (vmail) handling mail for virtual domains
virtual_mailbox_base = /home/vmail

# The database of virtual users
virtual_mailbox_maps = hash:/etc/postfix/vmailbox

# A lower bound for the user id of vmail
virtual_minimum_uid = 500

# The user id of vmail
virtual_uid_maps = static:[uuu]

# The group id of vmail
virtual_gid_maps = static:[ggg]

# Aliases for virtual users
virtual_alias_maps = hash:/etc/postfix/virtual

After editing main.cf do not forget to reload postfix:

> /usr/sbin/postfix reload

Now create the database of virtual users, to which we will add our one virtual user [vuser] in domain [domain_1]. Open a new file /etc/postfix/vmailbox and add:

[vuser]@[domain_1]   [domain_1]/[vuser]/Maildir/

which just specifies where the mailbox for virtual user [vuser] lives (do not forget the trailing slash). Now compile the database:

> /usr/sbin/postmap vmailbox

And finally set up some aliases. Even if you decide you don't need any, you should still compile an empty database, as postfix will expect one per the configuration changes made to main.cf. It's good practice to include a few basic aliases anyway. Open a file /etc/postfix/virtual and add something similar like:

root@[domain]       [vuser]@[domain]
webmaster@[domain]  [vuser]@[domain]
postmaster@[domain] [vuser]@[domain]

Finally compile the database:

> /usr/sbin/postmap virtual

Don't forget to recompile everytime you make changes to vmailbox or virtual. Now your virtual user should be ready to recieve mail. Send a test email to [vuser]@[domain] and ensure that mail is being delivered to the correct inbox - i.e /home/vmail/[domain]/[vuser]/Maildir/new.

Having set up postfix to deliver mail to virtual mailboxes, we need to configure courier to provide access over IMAP.

Configuring authdaemond to authenticate virtual users

authdaemond and courier-imap now need to be configured to authenticate virtual users and access the appropriate mailboxes. As with postfix, we will be storing this information in a Berkeley database.

TODO: explore whether the same db can be used for both authdaemond authentication and postfix

Simply touch /usr/local/etc/authlib/userdb to create an empty userdb file and give it the correct permissions:

> touch /usr/local/etc/authlib/userdb
> chmod 700 /usr/local/etc/authlib/userdb

Now add our user to the database:

> /usr/local/sbin/userdb "[vuser]@[domain]" set home=/home/vmail mail=/home/vmail/[domain]/[vuser]/Maildir uid=[uuu] gid=[ggg]

where [uuu] and [ggg] are the user and group IDs for the system user vmail. You can find these by checking /etc/passwd:

> tail -10 /etc/passwd

You will now see that the virtual user [vuser] has been added to /etc/userdb, in which you should see an entry like:

[vuser]@[domain]      home=/home/vmail|mail=/home/vmail/[vuser]/Maildir|uid=[uuu]|gid=[ggg]

Now set the password for [vuser]:

> /usr/local/sbin/userdbpw | /usr/local/sbin/userdb "[vuser]@[domain]" set imappw

entering a password when prompted. Then compile the database:

> /usr/local/sbin/makeuserdb

which will generate three new files in /usr/local/etc/authlib:

userdb.dat
userdb.lock
userdbshadow.dat

Testing virtual user authentication

Having set this up we can test authentication. You must (of course) have authdaemond configured to authenticate against userdb. In the authdaemond configuration file:

/usr/local/etc/authlib/authdaemonrc

make sure you have authuserdb included in the list of authentication modules:

authmodulelist="authuserdb authpam"

This configuration specifies authenticating first against userdb, and then against authpam (i.e. system users) if authentication fails against userdb. So lets test:

> /usr/local/sbin/authtest [vuser]@[domain]

If authentication fails, then you will get a response like:

Authentication FAILED: Operation not permitted

You may be tempted to also check authenticating against the password specified for [vuser]. However this will fail as authtest authenticates against a login password loginpw, whereas we set an imap password imappw. You can test password authentication by instead connecting to imapd over telnet or openssl, as described here.

Accessing virtual user mail via courier-imap

You should now be able to access Maildir mailboxes via imapd for virtual users. Configure your mail client to access email over IMAP in the usual manner, or as described here. Make sure however that you specify a fully qualified username however, i.e. [vuser]@[domain_1].

So - that is it! Hopefully now you should have mails being delivered correctly for both system and virtual users, and additionally accessible over IMAP.

Previous: Chapter 7 - Configuring Mozilla Thunderbird TOC Next: Chapter 9 - Tieing it all together