Mail server using Postfix and Dovecot
From Gentoo Linux Wiki
Contents |
[edit] Introduction
This article will guide you through the process of setting up a basic virtual mail server using Postfix (SMTP), PostfixAdmin (web administration) and Dovecot (POP3 and IMAP) with quotas.
This article does not cover setting up sieve, secure connections (SSL/TLS), mailing lists, anti-virus or spam filtering (including the anti-spam measures built in to Postfix).
[edit] Versions Used
This article was written for both Dovecot 1.0 and 1.1 (differences are noted where applicable), Postfix 2.5.1 and PostfixAdmin 2.1.0. If you are using higher versions than these, please consult the software documentation for a list of changes.
[edit] Prerequisities
This article assumes that you already have Apache 2 installed and set up for virtual hosting, PHP installed and set up under Apache2 with the mysqli module and MySQL installed. This article assumes everything will be housed on a single server.
[edit] Mail Storage
This article will set up the mail storage to be under /var/mail/<domain>/<username>/Maildir/ using the Maildir (Qmail style) format. The /var/mail/<domain>/<username>/ directory is considered to be the virtual users home directory. This home directory is used for storing things like indexes that are not normally part of the Maildir structure.
[edit] Users
The following users are used by this setup:
- root (0) - Most services are started as root (this is a requirement for services that use a port < 1024)
- mail (8) - Used for mail storage
- dovecot (97) - Unprivilidged, used by Dovecot for internal purposes. Not used for mail processing
- postfix (207) - Used for mail storage by Postfix
- nobody (65534) - This setup uses the nobody user for database access since it only needs access to MySQL
The following groups are used by this setup:
- mail (12) - Used for mail storage
[edit] Installation
Add the following lines to /etc/portage/package.use (create it if it doesn't exist) to set the USE flags to get the required features:
| File: /etc/portage/package.use |
mail-mta/postfix dovecot-sasl mysql -pam sasl net-mail/dovecot mysql -pam pop3d www-apps/postfixadmin mysql vhosts |
This article will use webapp-admin to install PostfixAdmin. If you don't want to do this, remove the vhosts USE flag from the "postfixadmin" line above. In this case PostfixAdmin will be installed under /var/www/localhost/htdocs/.
Add the following lines to /etc/portage/package.keywords (create it if it doesn't exist) to unmask the relevent software versions:
| File: /etc/portage/package.keywords |
~mail-mta/postfix-2.5.1 ~www-apps/postfixadmin-2.1.0 |
Install all of the software packages with: emerge -av postfix postfixadmin dovecot
Finally, start and then stop Postfix. This causes it to create the files it uses. If you don't do this, the cron jobs it sets up will chew up file handles unnecessarily: /etc/init.d/postfix start; /etc/init.d/postfix stop
[edit] PostfixAdmin
This section will show you how to set up PostfixAdmin. This is done first because it doesn't depend on anything else and sets up the databases that will be used by Postfix and Dovecot.
[edit] Virtual Host Setup
This section will install PostfixAdmin and configure the Apache virtual host. This section does not deal with configuring SSL, although it is highly recommended that you only access PostfixAdmin over SSL.
Using webapp-config, install PostfixAdmin using the following command: webapp-config --install --host=mailadmin.example.org postfixadmin 2.1.0
Pay attention to any messages that webapp-config displays and follow any instructions you're given.
PostfixAdmin will now be installed to /var/www/mailadmin.example.org/htdocs
Now you need to tell Apache about the virtual host. To do so, put the following into a new file, /etc/apache2/vhosts.d/mailadmin.example.org (based on the Gentoo default virtual host):
| File: /etc/apache2/vhosts.d/mailadmin.example.org |
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/var/www/mailadmin.example.org/htdocs"
<Directory "/var/www/localhost/htdocs">
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
Options Indexes FollowSymLinks
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
AllowOverride All
# Controls who can get stuff from this server.
Order allow,deny
Allow from all
</Directory>
<IfModule alias_module>
# Alias: Maps web paths into filesystem paths and is used to
# access content that does not live under the DocumentRoot.
# Example:
# Alias /webpath /full/filesystem/path
#
# If you include a trailing / on /webpath then the server will
# require it to be present in the URL. You will also likely
# need to provide a <Directory> section to allow access to
# the filesystem path.
# ScriptAlias: This controls which directories contain server scripts.
# ScriptAliases are essentially the same as Aliases, except that
# documents in the target directory are treated as applications and
# run by the server when requested rather than as documents sent to the
# client. The same rules about trailing "/" apply to ScriptAlias
# directives as to Alias.
ScriptAlias /cgi-bin/ "/var/www/mailadmin.example.org/cgi-bin/"
</IfModule>
<Directory "/var/www/mailadmin.example.org/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
<IfModule mpm_peruser_module>
ServerEnvironment apache apache
</IfModule>
</VirtualHost>
# vim: ts=4 filetype=apache
|
Finally, to apply the changes, restart Apache with: /etc/init.d/apache2 restart
[edit] MySQL Setup
This article will not go into the exact methods for creating users. There is plenty of documentation already available and many people use one of a number of tools to help them.
First create a database which will be used to store the mail account details. This article will use "postfixadmin" as the database name.
There are 2 MySQL users you need to create.
The first is the "postfixadmin" user who requires the following permissions: SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX on the "postfixadmin" database. This is the user PostfixAdmin will use to administrate the mail accounts.
The second is the "mailauth" user who requires only SELECT permissions on the "postfixadmin" database. This user is used by Postfix and Dovecot for looking up information.
[edit] Configuration
Open up the config.inc.php file in the postfixadmin directory. The following settings are listed in the order that they appear.
First comment out the configured setting by placing a # in front of it to tell PostfixAdmin that we've configured it. Until you do this, PostfixAdmin will not run:
#$CONF['configured'] = false;
Tell PostfixAdmin what web address it will be accessed with:
$CONF['postfix_admin_url'] = 'http://mailadmin.example.org/';
If your native language isn't English, you'll want to change the default_language setting. A list of language files in the languages/language.php file. For example, if you want PostfixAdmin in German:
$CONF['default_language'] = 'de';
Next set up the MySQL connection. This uses the MySQL database and user set up above. The password should be the same password you entered when creating the postfixadmin MySQL user.
$CONF['database_type'] = 'mysqli'; $CONF['database_host'] = 'localhost'; $CONF['database_user'] = 'postfixadmin'; $CONF['database_password'] = 'password'; $CONF['database_name'] = 'postfixadmin'; $CONF['database_prefix'] = '';
You'll want to change the admin email address that PostfixAdmin uses. This is used as the From address when sending messages to new accounts.
$CONF['admin_email'] = 'postmaster@example.org';
This setup will use mailboxes stored in the format <domain>/<username>, so change the domain_path and domain_in_mailbox settings to match those below.
$CONF['domain_path'] = 'YES'; $CONF['domain_in_mailbox'] = 'NO';
This setup will use quotas, so tell PostfixAdmin to turn them on.
$CONF['quota'] = 'YES';
PostfixAdmin displays a couple of customizable links. You'll probably want to change these to link to your website.
$CONF['user_footer_link'] = "http://example.org/"; $CONF['show_footer_text'] = 'YES'; $CONF['footer_text'] = 'Example Webhosting'; $CONF['footer_link'] = 'http://example.org/';
Finally, you can change the content of the email that is sent to new users.
$CONF['welcome_text'] = <<<EOM Hi, Welcome to your new account. EOM;
[edit] Setup
You can now complete the setup of PostfixAdmin, creating the database, by visiting the setup page. For example: http://mailadmin.example.org/setup.php
At this point you'll be asked to set up a global admin user. Follow the instructions to do so. Remember the details as you'll need them to log in later.
Finally remove the setup.php file to stop others from being able to reset / change your database unexpectedly: rm /var/www/mailadmin.example.org/htdocs/setup.php
You can now visit your PostfixAdmin install at the location you set it up. For example: http://mailadmin.example.org/
However, you should not set any domains or mailboxes up yet because Postfix and Dovecot have not been set up yet.
[edit] Dovecot
This section deals with configuring the Dovecot mail server.
[edit] SQL Configuration
The following configuration is done in /etc/dovecot/dovecot-sql.conf. You can find detailed information on MySQL's SELECT queries in the MySQL manual.
First set the database connection details. The password should be the same password you set when creating the mailauth SQL user above.
driver = mysql connect = host=/var/run/mysql.sock user=mailauth password=password dbname=postfixadmin
Set the default password scheme. This tells Dovecot what format the passwords in the database are stored in.
default_pass_scheme = MD5
There are 2 different ways to configure Dovecot SQL. In this article you'll configure Dovecot to use a single SQL query instead of 2. However, this article will show you the query needed for 2-query authentication.
The following are in the same order as they are presented in the default configuration file.
First set the password_query use for 2-query authentication. Note that it's commented out by starting the line with a #
#password_query = SELECT username as user, password FROM mailbox WHERE username = '%u' AND active = 1
Next configure the user_query. You may want to double check these (user id's are listed in /etc/passwd and groups are listed in /etc/groups).
The quota parameter passes the PostfixAdmin configured quota to Dovecot.
The home value tells Dovecot where the users home directory is. This will be explained more in depth later.
In Dovecot 1.1, the quota specification has changed and uid/guid are now specified in the configuration file.
user_query = SELECT CONCAT('/var/mail/', maildir) AS home, 8 AS uid, 12 AS gid, CONCAT('maildir:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = 1
# For Dovecot 1.1 use:
#user_query = SELECT CONCAT('/var/mail/', maildir) AS home, CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = 1
Finally configure the query used for single query authentication. This combines the results passed by the above two queries into a single result. Note that in this query you must return userdb fields prefixed with "userdb_".
password_query = SELECT CONCAT('/var/mail/', maildir) AS userdb_home, 8 as userdb_uid, 12 as userdb_gid, username as user, password, CONCAT('maildir:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = 1
# For Dovecot 1.1 use:
#password_query = SELECT CONCAT('/var/mail/', maildir) AS userdb_home, username as user, password, CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = 1
[edit] General Configuration
The following configuration is all done in the /etc/dovecot/dovecot.conf file.
The Dovecot configuration file has a number of headers to help seperate the sections. Each of the subheadings here relates to a heading and are in the order they appear in the file.
All settings not mentioned here are left at their default values.
[edit] Basic settings
(This heading doesn't exist. All these settings appear before the first heading).
First configure the protocols that you want Dovecot to respond to. This article will simply use the default ports. If you want to use other ports, please consult Dovecot's documentation.
protocols = pop3 imap
By default Dovecot only listens on IPv6 interfaces. Many people are still using IPv4, so you probably want to listen on IPv4 interfaces too. To do so, change the listen line to:
listen = *, [::]
By default Dovecot disables plain text authentication on unencrypted (non-SSL/TLS) connections. It is highly recommended that you investigate setting up SSL/TLS connections, but for the purposes of this setup you can enable plain text authentication by setting:
disable_plaintext_auth = no
[edit] Mailbox locations and namespaces
The mail_location parameter tells Dovecot where mailboxes are stored and in what format. Thi article uses the Maildir (Qmail style) format. The location of indexes is also set.
mail_location = maildir:/var/mail/%d/%n/Maildir/:INDEX=/var/mail/%d/%n/indexes
For Dovecot 1.1 users, the mail_uid and mail_gid parameters specify the user and group that are used for mail storage.
mail_uid = mail mail_gid = mail
[edit] Mail processes
The following settings set the user id and group id's that Dovecot is allowed to use for mail processes. This setup only allows the mail user and the mail group to be used. You should double check the id's are correct for your system.
first_valid_uid = 8 last_valid_uid = 8 first_valid_gid = 12 last_valid_gid = 12
[edit] IMAP specific settings
Enable the quota and imap_quota plugins by setting the following. This enables the use of quotas and the imap quota support so that clients can report quota usage.
protocol imap {
mail_plugins = quota imap_quota
}
[edit] POP3 specific settings
Enable quota support for POP3 by setting the following.
protocol pop3 {
mail_plugins = quota
}
[edit] LDA specific settings
Set the email address used as the From address for error message emails.
protocol lda {
postmaster_address = postmaster@example.org
Enable the quota plugin.
mail_plugins quota }
[edit] Authentication settings
Set the list of allowed authentication mechanisms. For this setup you want the plain and login mechanisms. The plain mechanism allows clients to send passwords in plain text. While insecure, this method is supported by all clients. The login mechanism provides support for Outlook clients.
auth default {
mechanisms = plain login
There are 2 "databases" you'll need to set. The database used for password queries (passdb) and the database used for user queries (userdb).
Note that all "userdb" and "passdb" sections other than those mentioned below must be commented out.
passdb sql {
args = /etc/dovecot/dovecot-sql.conf
}
Dovecot can use 2 queries to get the information it needs. If you wanted to do this, you would need to set up the userdb as follows and uncomment it (remove the # at the beginning of each line).
# userdb sql {
# args = /etc/dovecot/dovecot-sql.conf
# }
Instead of using sql, this article will use the prefetch method to avoid an extra query to the database. This method requires no values to be set (because all the information comes from passdb).
userdb prefetch {
}
Now set the authentication user to the one created earlier. This allows us to ensure we have a user that does not have access to anything else.
user = nobody
Specify the sockets you want to allow for authentication mechanisms to use. For this setup you want a master socket for the Dovecot LDA and a client socket for Postfix.
socket listen {
master {
path = /var/run/dovecot/auth-master
mode = 0600
user = mail
group = mail
}
client {
# If you change the postfix queue_directory, you must also change this.
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
[edit] Postfix
A small note about Postfix configuration: Postfix specifies (on man 5 postconf that only the last value specified in the /etc/postfix/main.cf is used, so editing it's configuration is as easy as appending the values to the end of the file.
[edit] Local Aliases
Postfix needs to know where you want mail sent to local users (eg. mail sent by cron jobs is usually just sent to "root" - Postfix needs to be able to translate this to a "real" address).
Open up /etc/mail/aliases and uncomment and fill out the root and operator lines as in the example below:
| File: /etc/mail/aliases |
# Basic system aliases -- these MUST be present. MAILER-DAEMON: postmaster postmaster: root # General redirections for pseudo accounts. adm: root bin: root daemon: root exim: root lp: root mail: root named: root nobody: root postfix: root # Well-known aliases -- these should be filled in! root: root@example.org operator: operator@example.org # Standard RFC2142 aliases abuse: postmaster ftp: root hostmaster: root news: usenet noc: root security: root usenet: root uucp: root webmaster: root www: webmaster # trap decode to catch security attacks # decode: /dev/null |
Now run newaliases to generate the actual database. You may also want to symlink these files into the Postfix configuration directory to make them easier to find: ln -s /etc/mail/aliases /etc/postfix/; ln -s /etc/mail/aliases.db /etc/postfix/
[edit] Dovecot Integration - LDA
This setup uses Dovecot's deliver LDA (Local Delivery Agent).
First we need to tell Postfix about deliver. To do this, add the following line to /etc/postfix/master.cf:
dovecot unix - n n - - pipe
flags=DRhu user=mail:mail argv=/usr/local/libexec/dovecot/deliver -f ${sender} -d ${recipient}
To tell Postfix to actually use deliver, add the following to /etc/postfix/main.cf:
dovecot_destination_recipient_limit = 1 virtual_transport = dovecot
Tip: You won't find dovecot_distination_recipient_limit in the Postfix documentation, instead see the documentation for transport_destination_recipient_limit
[edit] Dovecot Integration - Authentication
This setup uses Dovecot's SASL capability for Postfix authentication. Add the following settings to /etc/postfix/main.cf to enable SASL and set it to the dovecot interface we configured earlier:
smtpd_sasl_auth_enable = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth
[edit] MySQL Maps
The following files contain details that postfix will use to look up various details using the PostfixAdmin MySQL database.
Create each of the following files with the contents below in the /etc/postfix directory.
Most of the details here should be self explanatory. We use the same MySQL user as we did for dovecot since Postfix requires read only access to the same tables. The password is the same one you entered when creating the user.
| File: /etc/postfix/mysql_virtual_alias_maps.cf |
user = mailauth password = password hosts = localhost dbname = postfixadmin query = SELECT goto FROM alias WHERE address='%s' AND active = '1' |
| File: /etc/postfix/mysql_virtual_domain_maps.cf |
user = mailauth password = password hosts = localhost dbname = postfixadmin query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1' |
| File: /etc/postfix/mysql_virtual_mailbox_maps.cf |
user = mailauth password = password hosts = localhost dbname = postfixadmin query = SELECT CONCAT(maildir, 'Maildir/') AS maildir FROM mailbox WHERE username='%s' AND active = '1' |
To tell Postfix about the maps that you've just set up, add the following to the bottom of /etc/postfix/main.cf:
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domain_maps.cf virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
[edit] Relay (Backup MX) Domains
If you don't want your server to relay mail for other domains, you can skip this section.
Create the MySQL map file:
| File: /etc/postfix/mysql_relay_domain_maps.cf |
user = mailauth password = password hosts = localhost dbname = postfixadmin query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '1' AND active = '1' |
And then add the following to the bottom of /etc/postfix/main.cf:
relay_domains = mysql:/etc/postfix/mysql_relay_domain_maps.cf
[edit] Other Settings
The following directory sets the mailbox base directory. This is prepended to all results returned by virtual_mailbox_maps.
virtual_mailbox_base = /var/mail
Add the following to set up the restrictions the Postfix will impose on mails:
smtpd_client_restrictions= permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated, permit smtpd_sender_restrictions= reject_non_fqdn_sender, permit smtpd_reject_unlisted_sender = yes smtpd_recipient_restrictions= permit_mynetworks, reject_non_fqdn_recipient permit_sasl_authenticated reject_unauth_destination permit
[edit] Checking Configuration
You can have Postfix perform a cursory check of your configuration by running postfix check. The only message you should expect to receive is the following one, which is regarding a file installed by portage:
postfix/postfix-script: warning: not owned by postfix: /var/lib/postfix/./.keep_mail-mta_postfix-0
[edit] Setting up Services
Start all of the services with: /etc/init.d/dovecot start; /etc/init.d/postfix start
And add them to the default run level so they start on boot: rc-update add dovecot default; rc-update add postfix default
[edit] Setting up Mailboxes
Go to the URL you set up PostfixAdmin at and enter the global admin username and password you created when setting up PostfixAdmin.
This article will show you how to set up a simple domain with a single mailbox and a catch-all alias (ie. anything@example.org will go to the same account).
[edit] Domain
First you want to set up the domain, so from the drop-down menus along the top of the page, select Domain List and then New Domain.
Fill out the form as follows:
- Domain: Enter the domain name (excluding the "www."). For example, "example.com"
- Description: This is just a description for your reference. Note that the Domain administrator will also be able to see this value.
- Aliases: The number of aliases that the domain is allowed to have.
- Mailboxes: The number of mailboxes that the domain is allowed to have.
- Max Quota: The maximum mail quota for the domain.
- Add default mail aliases: This adds the default mail aliases configured in the PostfixAdmin configuration file. Leave this disabled.
- Mail server is backup MX: Is this server the backup MX for this domain? (Generally you want to leave this disabled).
When you're done, click the Add Domain button.
You should now be able to see the domain in the "Domain List" and "Virtual List" screens.
[edit] Initial Mailbox
Now that you've created the domain, you want to create atleast one mailbox for it, called "postmaster" (since all domains should have atleast a postmaster mailbox).
Select Virtual List then, from the drop-down menu that appears, Add Mailbox.
To create the "postmaster" mailbox, fill out the form as follows:
- Username: "postmaster" (This is the part of the email address before the @)
- Password (and Password (again)): Enter a password for the account (Don't forget it!).
- Name: This is a name for the account. It's only visible in PostfixAdmin and has no real effect on the mailbox.
- Quota: Enter a quota for the mailbox in MB. For example, 1024 for 1GB.
- Active: Is the mailbox currently active (accepting mail)? You'll want to leave this checked.
- Send Welcome mail: This sends the welcome email with the text specified in the PostfixAdmin configuration file. Sending an email to the account causes the mailbox folder to get created on the hard disk, so unless you intend to immediately send your own welcome email, leave this checked.
When you're finished, click the Add Mailbox button.
[edit] Catch-all Alias
Now you have a domain with a mailbox, create an alias for it. In this case the alias will be a "catch all" alias the causes any email sent to an address for which there is not another alias or mailbox to be sent to the address specified in the catch all alias.
Select Virtual List then, from the drop-down menu that appears, Add Alias.
Fill out the form as follows:
- Alias: This is the address that emails are addressed to. Because you're creating a "catch all" alias, enter "*"
- To: This is the address that emails sent to the address specified above are forwarded to. In this case enter "postmaster@example.com"
- Active: Is this alias currently active? Leave this checked.
Click the Add Alias button to add the alias.
Congratulations. Your new mail server now has a single domain with a single catch-all mailbox.
[edit] Testing
Now that you've set up your server with a mailbox, you'll want to test that everything works as expected.
Set up and fetch the mail for the mailbox. Using the example values above, the details you need to enter into your client are as follows:
- Server (incoming and outgoing): Your servers address (for example: mail.example.com)
- Username: postmaster@example.com
- Password: The password you entered when creating the mailbox
First set up the account as an IMAP account. When you collect the mail, you should receive the "Welcome" message sent when you created the mailbox with PostfixAdmin.
Next, set up the account as a POP3 account. When you collect the mail, you should receive the "Welcome" message sent when you created the mailbox with PostfixAdmin.
Using an account hosted on another server (for example, a webmail account), send an email to your new mailbox (eg. postmaster@example.com). Wait a couple of minutes and collect mail for the account. You should receive the email you just sent yourself.
Using the account on your new server, send an email to your webmail account and send a cc to an address other than postmaster at your new server (eg. something@example.com). Wait a couple of minutes and collect email on both accounts. You should received the email you sent yourself on both accounts.
If all these tests passed, then your server is working as expected. If any of these tests fail, then check the mail logs on your server and any bounce messages you receive for information on what went wrong.
[edit] Troubleshooting
[edit] Postfix Process Logging
You can increase the amount of logging that postfix processes do by adding "-v" or "-v -v" (for more verbosity) to the last parameter of the appropriate line in /etc/postfix/master.cf
