Once your new e-mail server has Courier-IMAP set up and running and you have a MySQL database to authenticate users, then you are well on your way to being finished with the project. But there are still a number of items you need to complete before your e-mail server is ready for prime time. For example, you’ll still need to configure Postfix to deliver mail to the correct mailbox, add the actual user accounts, and set up DNS entries to point to the new server. By the end of this article, your e-mail server should be fully functional.

Read the previous installments in this series

Catch up on the creation of this e-mail setup by checking out these articles:

Local delivery agents
Postfix comes with two local delivery agents (LDAs): local and virtual. The local LDA is used to deliver mail to UNIX user accounts. The virtual LDA doesn’t care about UNIX users—it delivers to a mailbox in a designated location using any designated user ID (UID) and group ID (GID). You can configure Postfix to use different LDAs for different domains and even specify an LDA for specific e-mail accounts. You can use Procmail as an LDA, allowing you to apply all kinds of custom rules. But for now, I’m going to show you how to configure Postfix’s virtual LDA to use MySQL to get its account information.

Configure Postfix to use MySQL virtual accounts
To get Postfix to use the same MySQL database to deliver to virtual accounts, you need to create three configuration files that map e-mail addresses to values. Each of these files contains the connection information for your MySQL server, the column that represents the e-mail address, and the column containing the result. I need one for the Delivery location, one for the UID, and one for the GID. The three code samples in these three sidebar links are examples of these connection files—create them with appropriate values for your installation. You can name them whatever you wish, but they must be owned by root and in a location where Postfix can read them.

The next task is to edit /etc/postfix/main.cf so the virtual delivery agent can use the values in the MySQL database to deliver mail. Table A lists the settings that should be changed.
Table A

Setting What it does Setting change
local_recipient_maps Designates which user accounts and domains are valid recipients for this server. Since you’re going to have virtual users (users that don’t have a real UNIX user account), set this to nothing. Otherwise, all of the mail for virtual users will bounce:
local_recipient_maps =
mydestination Designates which domains are handled by the local delivery agent. Since you are going to use the virtual delivery agent for all mail, you need to disable this setting or mail will bounce before reaching the virtual delivery agent:
mydestination =
virtual_mailbox_domains Lists the domains that are handled by the virtual delivery agent. Set this to the list of domains handled by this server:
virtual_mailbox_domains =
virtual_mailbox_base Base path containing all virtual mailboxes. Set this to the same value as the default “home” column in the database:
virtual_mailbox_base = /var/mail/virtual
virtual_mailbox_maps Maps e-mail addresses to directories. This is one of your MySQL maps:
virtual_mailbox_maps =
virtual_uid_maps Maps e-mail addresses to a UNIX user ID. virtual_uid_maps =
virtual_gid_maps Maps e-mail addresses to a UNIX group ID. virtual_gid_maps =

Here are the /etc/postfix/main.cf settings for virtual delivery.

After making these configuration file changes, reload Postfix by typing:
       # postfix reload

Next, check the mail log for errors. If you don’t see any errors, Postfix should be using MySQL correctly to recognize incoming mail. Now you need to configure the operating system to support these user accounts.

Set up a virtual UNIX account and directory
If you look back at my “Extend the reach of users’ e-mail with IMAP” article, you can see that the Create Table script had some specific default values. I defined a default user ID of 5000, a default group ID of 5000, and a Home column of /var/mail/virtual. Now you need to make sure these exist, with the proper ownership by typing:
       # adduser -M -u 5000 virtual
       # mkdir /var/mail/virtual
       # chown virtual /var/mail/virtual

All mail will be delivered to a Maildir-style mailbox in /var/mail/virtual, creating the appropriate directories and files on delivery, as UNIX user Virtual. The other default value is an encrypted password string: sdtrusfX0Jj66. MySQL uses a different algorithm for its “crypt” function than the operating system. Courier-IMAP uses the system crypt library to test whether the password matches what’s stored in the database. The string I provided as a default works for a password of “ChangeMe.” At some point you can change the password, but for now “ChangeMe” is the password for your new accounts.

Add user accounts
Now you can add actual user accounts to MySQL. For each account, you need to specify the full e-mail address for the user in the ID column and the Maildir directory (as in /var/mail/virtual) to store the messages.


For the Maildir column, be sure to include a trailing slash (“/”). This tells Postfix to deliver to a Maildir-style of mailbox, instead of a traditional UNIX mailbox.

To satisfy the RFCs for e-mail servers, you need to provide valid addresses for postmaster and abuse accounts. These can deliver mail to your user account:
       mysql> INSERT INTO users (id, maildir) VALUES
          -> (‘abuse@localhost.localdomain’,’user/’),
          -> (‘user@localhost.localdomain’, ‘user/’);

Set up DNS
You should now have a working e-mail server that is capable of sending and receiving e-mail to and from the Internet. However, until you set up the proper Domain Name Service (DNS) entries, nothing will find your new server. Your e-mail server can host e-mail for many domains or for specific hosts. To get the e-mail to route to your server, add an MX (Mail Exchange) record to the name servers for each domain you want the server to handle.

It can take up to 48 hours for DNS changes to propagate throughout the Internet. I’ve found that many large sites (such as Hotmail) cache DNS entries for much longer than that—even weeks or months. To force these sites to deliver to the correct e-mail server, you may need to set the old mail server to bounce mail for the domains your new server is handling. When the e-mail bounces, the caching servers will now look up the correct destination, which is your new server.

While you’re testing, it’s wise to only use a new server to receive mail for one particular host. Set up the DNS entry only for the particular host: host.localdomain.domain. Then use that entire host as the domain for the e-mail address: user@host.localhost.domain. Once you have all the bugs worked out, you can set the new server to handle mail for your entire domain.

Use your new e-mail server
You can now set up as many e-mail addresses as you want. In any mail client, set up a new IMAP account using the full e-mail address as the username and ChangeMe as the password. You should be able to send outgoing mail through the new server as long as you’re connecting from the same subnet.

Subscribe to the Developer Insider Newsletter

From the hottest programming languages to commentary on the Linux OS, get the developer and open source news and tips you need to know. Delivered Tuesdays and Thursdays

Subscribe to the Developer Insider Newsletter

From the hottest programming languages to commentary on the Linux OS, get the developer and open source news and tips you need to know. Delivered Tuesdays and Thursdays