Setting up an email server in CentOS
From (mt) Wiki
WARNING: This page is a work in progress. The steps here should work, but they have not been extensively tested.
Contents[hide] |
Introduction
I am working on setting up a functional email server on my (ve) using CentOS. The online documentation for this seems to be rather scattered, so I am going to document my work here. I am not an expert at email server configuration, so please do not take anything here as gospel. There are references to more authoritative sources at the bottom of this page.
There are many different tools that you can use for this job on Linux. I am going to be using Postfix as the MTA and Dovecot as the IMAP/POP server to let users retrieve their email. Postfix and Dovecot are both standard components of CentOS/RedHat Linux, which means that they are easily available in the CentOS software repositories, and they will be well-supported with long term security updates. Additionally, the two integrate well with each other, so I will let Dovecot handle the authentication for Postfix SMTP AUTH and also have Dovecot's LDA (local delivery agent) take over responsibility from Postfix's MDA component. The Dovecot LDA offers some extra functionality, such as enforcing disk space quotas, and has a reputation for being very efficient.
The simplest way to set up an email server is to have all the email users be UNIX user accounts (appearing in /etc/passwd) with a Maildir folder in their home directory. However, if you're hosting multiple domains and many email addresses on your server, that setup can quickly become unwieldy. For this reason, I am going to configure the server with "virtual" domains and "virtual" users. These will be specified in a MySQL database, which should be easier to maintain. To further ease administration, I'll be installing a PHP frontend, Postfixadmin which helps you to manage the database, as well as letting users change their own email passwords and some other nice perks.
Overview:
Preliminaries
Install Postfix and Dovecot
postfix - Postfix is a Mail Transport Agent (MTA), supporting LDAP, SMTP AUTH (SASL), TLS
dovecot - Dovecot is an IMAP server for Linux/UNIX-like systems, written with security primarily in mind. It also contains a small POP3 server. It supports mail in either of maildir or mbox formats.
For some reason, the default Postfix package in CentOS is not compiled with database support. There are many guides online that show you how to patch the source .rpm and recompile it, but I think an easier option is to get the version you need from the CentOS-plus repository. Here's how:
Open the yum repository file for the basic CentOS packages:
# vim /etc/yum.repos.d/CentOS-Base.repo
and add the line exclude=postfix
to the end of the [base] and [updates] section.
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
exclude=postfix
#released updates
[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
exclude=postfix
Then, go to the [centosplus] section and enable it:
enabled=1
and add includepkgs=postfix
[centosplus]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus
#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
includepkgs=postfix
These changes ensure that yum will install the version of Postfix from centosplus, instead of from the base
Save that file, and then do:
# yum install postfix dovecot
If you have correctly excluded the standard Postfix version, you should get the package: postfix.x86_64 2:2.3.3-2.1.centos.mysql_pgsql
You can verify that your Postfix has the capabilities we need by entering:
# postconf -m
and making sure that the output includes "mysql".
You can also check that Postfix supports authentication through Dovecot by entering:
postconf -a
and verifying that 'dovecot' is one of the options.
(Optional) Upgrade Dovecot
If you want to enforce disk space quotas for your email users, you may want to upgrade Dovecot. The version 1.0.7 that comes from the CentOS 5.5 repository includes a minor, but irritating bug when storing quota values in a MySQL database. You can download the source for the newest version of Dovecot here, but if you'd rather not compile it, it's also possible to get a newer version of Dovecot compiled for RHEL/CentOS 5 from the ATrpms repository.
You can upgrade to Dovecot 1.2.11 with this command: # rpm -Uvh http://dl.atrpms.net/all/dovecot-1.2.11-3_108.el5.x86_64.rpm
Install Apache/PHP/MySQL
If you're running a web server on your (ve), you may already have some or all of these packages installed. The php-mbstring and php-imap packages are required for functionality in postfix admin.
# yum install httpd mysql-server php php-mbstring php-imap php-mysql
Configure MySQL
Initial setup
If you are installing the MySQL server for the first time, you will want to enter
# service mysqld start
to start the server, and then run
# /usr/bin/mysql_secure_installation
to set the MySQL root user password, remove sample data, and some other steps to secure the MySQL server.
For added security, you might want to edit /etc/my.cnf and add:
bind-address=127.0.0.1
which will tell the MySQL daemon to only accept connections from the local host.
Enter # /etc/init.d/mysqld restart
to restart MySQL and pick up the configuration changes.
If you want mysqld to start automatically when your (ve) boots, enter:
# chkconfig mysqld on
Setup for mail database
Once you have a running MySQL server, you need to create a database to hold your email configuration, and a database user that Postfix and Dovecot can use to access it.
Log into the MySQL shell as the MySQL root user: # mysql -u root -p
Create a database called 'mail' (or whatever name you choose): mysql> CREATE DATABASE mail;
Create a database user named 'mail_admin' and grant it SELECT, INSERT, UPDATE and DELETE privileges on the mail database. Be sure to replace
mysql> GRANT ALL ON mail.* TO 'mail_admin'@'localhost' IDENTIFIED BY '';
mysql> FLUSH PRIVILEGES;
Setup Postfix Admin
Download files and configure Apache
Download Postfixadmin from the project site: http://sourceforge.net/projects/postfixadmin/
Watch out for the version numbers in the next few commands, in case postfixadmin has been updated since I wrote this.
# wget http://sourceforge.net/projects/postfixadmin/files/postfixadmin/postfixadmin_2.3.tar.gz/download
You can install it anywhere you want. I think this is a reasonable place:
# tar xzf postfixadmin_2.3.tar.gz
# mv postfixadmin-2.3/ /usr/share/postfixadmin
Then, configure Apache to know where to find it by opening a file in the conf.d directory: # vim /etc/httpd/conf.d/postfixadmin.conf
And inserting the following lines:
#
# Web application to manage Postfix email server
#
Order Allow,Deny
Allow from all
Alias /postfixadmin /usr/share/postfixadmin
Alias /PostFixAdmin /usr/share/postfixadmin
Alias /PostfixAdmin /usr/share/postfixadmin
Then, restart Apache to make sure the configuration is active: # service httpd restart
By adding this section to the Apache configuration, you should be able to reach Postfix Admin from any domain on your server by going to http://example.com/postfixadmin
Configure Postfix Admin
If you go to http://example.com/postfixadmin/ you should see a Postfix Admin welcome page, with links to some documentation, including the INSTALL.TXT. It's worth reading, but I'll summarize what I did here.
Open the config file for editing:
# vim /usr/share/postfixadmin/config.inc.php
Change $CONF['configured'] = false;
to
$CONF['configured'] = true;
Fill out the database configuration section:
// Database Config
// mysql = MySQL 3.23 and 4.0, 4.1 or 5
// mysqli = MySQL 4.1+
// pgsql = PostgreSQL
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'mail_admin';
$CONF['database_password'] = '';
$CONF['database_name'] = 'mail';
$CONF['database_prefix'] = '';
If you're using CentOS 5.5 that comes on the (ve), you should have MySQL version 5, so you'll want to set the database type to 'mysqli' for better performance.
You can set the address that welcome emails come from: $CONF['admin_email'] = 'postmaster@example.com';
I set up Postfixadmin to use Dovecot to encrypt the email passwords using the CRAM-MD5 scheme. This will allow you to offer CRAM-MD5 authentication, which is more secure in some situations. $CONF['encrypt'] = 'dovecot:CRAM-MD5';
There are some other settings in config.inc.php that are worth taking a look at, but they mostly seem to be personal preferences about the way you'd like Postfix Admin to look and behave.
One section I modified had to do with mailbox locations. This is a preference, but it will affect the structure of the MySQL queries we'll set up Postfix to do in the next section. I'm going to keep my mailboxes at /var/mail/vhosts/example.com/user/ and these settings reflect that.
// Mailboxes
// If you want to store the mailboxes per domain set this to 'YES'.
// Examples:
// YES: /usr/local/virtual/domain.tld/username@domain.tld
// NO: /usr/local/virtual/username@domain.tld
$CONF['domain_path'] = 'YES';
// If you don't want to have the domain in your mailbox set this to 'NO'.
// Examples:
// YES: /usr/local/virtual/domain.tld/username@domain.tld
// NO: /usr/local/virtual/domain.tld/username
// Note: If $CONF['domain_path'] is set to NO, this setting will be forced to YES.
$CONF['domain_in_mailbox'] = 'NO';
I also adjusted these settings which set the default limits for a domain. By default, when you create a domain, the domain administrator will be restricted to these limits. The best values for you are going to depend on how many domains you want to host email for, and how much disk space you have available. Note that 'maxquota' is specified in MB and only enforced if you enable quota support.
$CONF['aliases'] = '100';
$CONF['mailboxes'] = '100';
$CONF['maxquota'] = '100';
Postfix Admin has support for reading mail directly in the web interface using a retrieval script called Fetchmail. I haven't installed Fetchmail, and there are other, better, webmail options out there, so I don't have any need for this feature. This setting just hides that tab.
$CONF['fetchmail'] = 'NO';
The following parameters have to do with disk space quotas. If you aren't enforcing quotas, you can skip them.
Enforce quotas: $CONF['quota'] = 'YES';
Display the amount of quota used up in the Postfix Admin interface: $CONF['used_quotas'] = 'YES';
If you took my advice above and upgraded to Dovecot 1.2.X, you will need to use the newer style of quota table: $CONF['new_quota_table'] = 'YES';
Install Postfix Admin
Save that file, and then go to http://example.com/postfixadmin/setup.php
It will run some tests to verify that requirements are met. In my case, I had to go back and install some PHP packages, but you should already have those installed from the instructions above.
Now Postfix Admin will create the database schema that Postfix and Dovecot are going to read.
Next, it prompts you to enter a 'setup password'. You enter a password twice, and it will give you a hash (a long string of gibberish) to enter in /usr/shared/postfixadmin/config.inc.php
Find this line,
$CONF['setup_password'] = 'changeme'
and replace 'changeme' with the hashed password. I believe this measure prevents anyone else from re-installing Postfix Admin and wiping out your configuration. You could open up the Apache configuration now.
Finally, it will ask you to create a super-administrator account. I named mine admin@example.com, but you can name it whatever you want. The name does have to be in the format of an email address, even though it's not an account that receives mail.
Configure Postfix
Basic configuration
Postfix keeps most of its configuration settings in the file /etc/postfix/main.cf
You can find more details in the Postfix Basic Configuration README.
Uncomment and modify the following lines to reflect the details of your server:#myhostname = host.domain.tld
#mydomain = domain.tld
I set mine both to be the same thing, the primary domain/hostname of my (ve). But you could probably do:myhostname = mail.example.com
mydomain = example.com
Uncomment this line, but you can probably leave it set to $mydomainmyorigin = $mydomain
According to the Postfix documentation, this setting specifies, "the domain name that locally-posted mail appears to come from, and that locally posted mail is delivered to"
Set Postfix to listen on all interfaces:inet_interfaces = all
I changed the line:mydestination = $myhostname, localhost.$mydomain, localhost
To to be:mydestination = localhost
Because I intend to manage everything as virtual domains and virtual users.
You probably also want to uncomment this line, mynetworks_style = host
This will make postfix consider only the localhost part of the trusted "mynetwork". By default, it considers all other machines on the same subnet as part of your network, but that's probably not the setup you want if your server is in a data center with many other servers belonging to different customers.
Virtual Domains Setup
For more details, see Postfix Virtual Domain Hosting Howto. There is also good information in the Postfix Admin documentation at /usr/share/postfixadmin/DOCUMENTS/POSTFIX_CONF.txt (assuming you installed to the same path as I did above)
I created a 'vmail' user account that will have ownership of all the mail folders. I believe that strictly speaking you could have those folders belong to the postfix or dovecot user, but this way is perhaps a bit cleaner.
# useradd -u 5000 -d /var/mail/vhosts/ -m -s /sbin/nologin vmail
This sets the home directory for the vmail user to be /var/mail/vhosts/ and this is where I will be keeping my mail folders. I prefer that location because of the parallel with Apache's /var/www/vhosts/ folder, for its own virtual hosted domains. Obviously, you can keep your mail wherever you like.
In order for Postfix to communicate with with the MySQL database, you have to create several special files that contain database queries to return the information about your email users. First, we need to tell Postfix to look for those files. Open main.cf to edit again, # vim /etc/postfix/main.cf
Look for the section that deals with virtual domains, and make it look like this:
# ADDRESS REDIRECTION (VIRTUAL DOMAIN)
#
# The VIRTUAL_README document gives information about the many forms
# of domain hosting that Postfix supports.
# See: http://www.howtoforge.com/virtual-users-domains-postfix-courier-mysql-squirrelmail-ubuntu8.04-p2
# The follwing lines connect Postfix with the MySQL database that contains information about
# the virtual users/accounts hosted. See proxymap(8) virtual(5) and mysql_table(5)
#
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
#
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
#
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
#
# Additional for quota support
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, this user has exceeded their disk space quota, please try again later.
virtual_overquota_bounce = yes
#
#Specify the user/group that owns the mail folders. I'm not sure if this is strictly necessary when using Dovecot's LDA.
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
#
#Specifies which tables proxymap can read: http://www.postfix.org/postconf.5.html#proxy_read_maps
proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps
We've told Postfix to find information about the virtual addresses by making MySQL queries specified in the files named above (mysql_virtual_domains_maps.cf, etc.) but we need to create those files to tell it what queries to make.
Create the first file, # vim /etc/postfix/mysql_virtual_domains_maps.cf
And insert these lines:
user = mail_admin
password =
hosts = localhost
dbname = mail
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
#optional query to use when relaying for backup MX
#query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
Create the next file, # vim /etc/postfix/mysql_virtual_alias_maps.cf
user = mail_admin
password =
hosts = localhost
dbname = mail
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
Create the third file, # vim /etc/postfix/mysql_virtual_mailbox_maps.cf
user = mail_admin
password =
hosts = localhost
dbname = mail
query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = 1
If you included support for email quotas, create this file, # vim /etc/postfix/mysql_virtual_mailbox_limit_maps.cf
user = mail_admin
password =
hosts = localhost
dbname = mail
query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'
SMTP AUTH settings
Add the following section:
#SASL SUPPORT FOR CLIENTS
#
# The following options set parameters needed by Postfix to enable
# SMTP AUTH support using Dovecot's SASL component for authentication of mail clients.
# See: /usr/share/doc/postfix-2.3.3/README_FILES/SASL_README - http://www.postfix.org/SASL_README.html
# And /usr/share/doc/dovecot-1.0.7/wiki/HowTo.PostfixAndDovecotSASL.txt - http://wiki.dovecot.org/HowTo/PostfixAndDovecotSASL
#
# Turns on sasl authorization
smtpd_sasl_auth_enable = yes
#
#Use dovecot for authentication
smtpd_sasl_type = dovecot
#
# Path to UNIX socket for SASL
smtpd_sasl_path = /var/run/dovecot/auth-client
#
#Disable anonymous login. We don't want to run an open relay for spammers.
smtpd_sasl_security_options = noanonymous
#
#Adds support for email software that doesn't follow RFC 4954.
#This includes most versions of Microsoft Outlook before 2007.
broken_sasl_auth_clients = yes
#
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
Set Postfix to use Dovecot's LDA for delivery
A Local Delivery Agent (LDA) is the program that finally places the messages in a user's inbox. Postfix has its own component that can do this, but using Dovecot's LDA has some advantages. It offers some extra features such as quota enforcement, and autoresponders. Furthermore, it does indexing-on-delivery that reportedly makes it faster to access email with IMAP.
You'll need to add the following two lines to /etc/postfix/main.cf
# TRANSPORT MAP
#
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
As you can see, I put them in the TRANSPORT MAP section, but they can really go wherever.
Next, you'll have to edit Postfix's other important configuration file (I did say most of the settings were in main.cf) # vim /etc/postfix/master.cf
Add these lines to the end of the file, in the "Interfaces to non-Postfix software" section:
# Dovecot LDA, as explained here: http://wiki.dovecot.org/LDA/Postfix
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}
(Optional) Enable port 587
If you would like your email server to also be able to accept SMTP connections on port 587 (some ISPs block the default port 25), then edit master.cf and uncomment this line:
#submission inet n - n - - smtpd
Configure Dovecot
So far, we've set up Postfix to ask certain things of Dovecot: SASL authentication and mail delivery. However, the other side of that equation is we have to configure Dovecot to be willing to provide those services for Postfix.
For more details, there's a good readme included with Postfix Admin; you can find it at /usr/share/postfixadmin/DOCUMENTS/DOVECOT.TXT
Dovecot's main configuration file can be found at /etc/dovecot.conf
Note: When editing the Dovecot configuration, you may notice that the files are formatted a bit differently than the Postfix files. Dovecot is a newer piece of software and keeps its configuration options grouped together in stanzas, marked with curly braces {e.g. these things} —this is great for organization, but it means you have to be a bit more careful when editing. Watch out that you're un/commenting the closing brace, too. Otherwise, you'll learn like I did when Dovecot complains about all kinds of syntax errors. Vim and other modern text editors will probably give you some color highlighting that can make this easier.
Basic Settings
# vim /etc/dovecot.conf
I uncommented these two lines, to remind myself that they're things I (and perhaps you) might care about in the future, but I didn't change their defaults:
# Protocols we want to be serving: imap imaps pop3 pop3s
# If you only want to use dovecot-auth, you can set this to "none".
protocols = imap imaps pop3 pop3s
# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
disable_plaintext_auth = no
Pay attention to the double-negative here. By leaving the setting at 'no' you're not-disabling (i.e. enabling) plaintext authentication. This shouldn't be a security risk for your server, but it could potentially be for your users, if they were connecting from a hostile network.
Set the mail_location variable, which specifies where Dovecot should look for email. The %h will be replaced with the 'home' directory as specified in the MySQL database, and that already includes the trailing slash. So the mail location for a user will look like /var/mail/vhosts/example.com/user/Maildir
mail_location = maildir:%hMaildir
Namespace
The namespace feature of Dovecot lets you manually specify some parameters to help IMAP clients find the Inbox and other folders. It's probably a good idea to include this information, given that email software seems to do a pretty mediocre job supporting IMAP. Apple Mail in particular does a poor job with IMAP path prefixes when left to its own devices.
These settings are based on this guide, and should be backward-compatible with Courier-IMAP which is another very popular IMAP server in use today.
namespace private {
# Hierarchy separator to use. You should use the same separator for all
# namespaces or some clients get confused. '/' is usually a good one.
# The default however depends on the underlying mail storage format.
separator = .
# Prefix required to access this namespace. This needs to be different for
# all namespaces. For example "Public/".
prefix = INBOX.
# Physical location of the mailbox. This is in same format as
# mail_location, which is also the default for it.
#location =
# There can be only one INBOX, and this setting defines which namespace
# has it.
inbox = yes
# If namespace is hidden, it's not advertised to clients via NAMESPACE
# extension or shown in LIST replies. This is mostly useful when converting
# from another server with different namespaces which you want to depricate
# but still keep working. For example you can create hidden namespaces with
# prefixes "~/mail/", "~%u/mail/" and "mail/".
#hidden = yes
}
Protocol-specific settings
IMAP
If you want quota support, find the stanza that begins with protocol imap {
and set this line:
mail_plugins = quota imap_quota
POP3
Find the stanza that begins with protocol pop3 {
and uncomment this line:
pop3_uidl_format = %08Xu%08Xv
This will be the default in future versions of Dovecot, and makes some clients, such as Outlook 2003 work better with POP3.
If you want support for disk space quotas, also set this line:
mail_plugins = quota
LDA
The stanza beginning with protocol lda {
sets parameters relevant for Dovecot's LDA that will be delivering the messages. Here's what mine looks like, note that you may want to change the postmaster address and the hostname to suit your own preferences, and again, if you want quota enforcement, add the quota plugin.
protocol lda {
# Address to use when sending rejection mails.
postmaster_address = postmaster@example.com
# Hostname to use in various parts of sent mails, eg. in Message-Id.
# Default is the system's real hostname.
#hostname =
# Support for dynamically loadable plugins. mail_plugins is a space separated
# list of plugins to load.
mail_plugins = quota
#
#mail_plugin_dir = /usr/lib/dovecot/lda
# Binary to use for sending mails.
#sendmail_path = /usr/lib/sendmail
# UNIX socket path to master authentication server to find users.
#auth_socket_path = /var/run/dovecot/auth-master
}
Authentication
Mechanisms
Find the stanza that starts with auth default {
Edit the line: mechanisms = plain
You will probably at least want to add "login", which is a different style of plaintext authentication used by some email programs, including certain versions of Outlook. I also added support for CRAM-MD5, which is not really necessary, but supported by some email programs (for instance, if you check "use secure authentication" in Thunderbird)
mechanisms = plain login cram-md5
Note: If you set up your server and email software to use TLS/SSL, as explained later in this guide, then it doesn't really matter which authentication mechanism you use. The entire session will be encrypted by TLS, so even plaintext authentication will be protected. The only time CRAM-MD5 would really matter is if you needed to authenticate securely in a non-TLS session. For details, see here.
Next, we need to tell Dovecot where it's going to look to check those passwords.
Method
Find the the stanza passdb pam {
and comment it out:
# passdb pam {
(Don't forget the closing bracket!)
PAM stands for "pluggable authentication modules," which is a commonly-used authentication standard on Linux/UNIX systems. I think theoretically, it would be possible to set Dovecot to ask PAM, and then have PAM query our MySQL database for the users/passwords. However, that's a more complex setup, and I'm not sure what advantages you would gain.
Find the stanza passdb sql {
and un-comment it to make it active.
To tell it where to find the database information, set the line:
args = /etc/dovecot-sql.conf
Then, un-comment the stanza, userdb prefetch {
to make it active.
Further down, comment out the stanza userdb passwd {
to disable it.
Then, after the userdb prefetch stanza, set the userdb sql stanza:
# SQL database
userdb sql {
# Path for SQL configuration file, see doc/dovecot-sql-example.conf
args = /etc/dovecot-sql.conf
}
There may already be a commented-out userdb sql stanza before the userdb prefetch. You can leave it there, or delete it to not confuse yourself later. This may seem silly, but the order matters.
Here's what's going on: The passdb and userdb settings tell Dovecot where to check to verify passwords and look up other user information, respectively. In our case, that information all stored in the same place--the 'mailbox' table in our MySQL database. So, rather than having Dovecot make two separate MySQL queries any time a user connects with POP or IMAP, you can have it 'prefetch' the user's information at the same time it validates the password. That's what the 'prefetch' is about. However, because we want Dovecot's LDA to be responsible for delivering mail to user's folders, it has to have a way of looking up that user information even when there isn't anyone logging in with a password to validate. That's why we still need the 'userdb sql' stanza AFTER the prefetch stanza. For all the details about prefetching, you can refer to the Dovecot wiki'
Set the user account that's Dovecot's authentication process will run as. I'm using the 'vmail' user we created earlier.
# User to use for the process. This user needs access to only user and
# password databases, nothing else. Only shadow and pam authentication
# requires roots, so use something else if possible. Note that passwd
# authentication with BSDs internally accesses shadow files, which also
# requires roots. Note that this user is NOT used to access mails.
# That user is specified by userdb above.
#user = root
user = vmail
Sockets
The are two different UNIX sockets that dovecot-auth will listen for authentication requests on, one 'master' used by Dovecot itself, and a 'client' socket used by other software that wants to use Dovecot for authentication--in our case, this is Postfix.
Here's what my version of this looks like. Watch out for all the nested brackets here.
This works just fine in the default CentOS install. If you're running Postfix 'chrooted' for security reasons (on some other distributions this is the default setting) you would need to change the location of the client socket to put it within Postfix's chroot directory.
# It's possible to export the authentication interface to other programs:
socket listen {
master {
# Master socket provides access to userdb information. It's typically
# used to give Dovecot's local delivery agent access to userdb so it
# can find mailbox locations.
path = /var/run/dovecot/auth-master
mode = 0600
# Default user/group is the one who started dovecot-auth (root)
user = vmail
#group =
}
client {
# The client socket is generally safe to export to everyone. Typical use
# is to export it to your SMTP server so it can do SMTP AUTH lookups
# using it.
path = /var/run/dovecot/auth-client
mode = 0660
user = postfix
group = postfix
}
}
Database connections
As with Postfix, we need to create another file containing the database settings. There's a sample of this file in the documentation that comes with Dovecot, so you can copy that to the /etc/ folder.
# cp /usr/share/doc/dovecot-`dovecot --version`/examples/dovecot-sql-example.conf /etc/dovecot-sql.conf
Now, you need to edit that file and configure the database settings for Dovecot.
# vim /etc/dovecot-sql.conf
Specify that this is a MySQL database: driver = mysql
Provide the credentials to access the database: connect = host=localhost dbname=mail user=mail_admin password=YOUR_PASSWORD
Because we told Postfix Admin to store the passwords encrypted with cram-md5, you should set: default_pass_scheme = CRAM-MD5
Your exact settings for the next lines are going to depend on the choices you made earlier about where to store the mail, and the user account to own the mail.
My user query line is: user_query = SELECT CONCAT('/var/mail/vhosts/', maildir) AS home, 5000 AS uid, 5000 AS gid, CONCAT('*:bytes=', quota) as quota_rule FROM mailbox WHERE username = '%u' AND active='1'
If you're not using quotas, yours could look like: user_query = SELECT CONCAT('/var/mail/vhosts/', maildir) AS home, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username = '%u' AND active='1'
My password_query line is: password_query = SELECT username AS user, password, CONCAT('/var/mail/vhosts/', maildir) AS userdb_home, 5000 AS userdb_uid, 5000 AS userdb_gid, CONCAT('*:bytes=', quota) as userdb_quota_rule FROM mailbox WHERE username = '%u' AND active='1'
Again, if you don't care about quotas, password_query = SELECT username AS user, password, CONCAT('/var/mail/vhosts/', maildir) AS userdb_home, 5000 AS userdb_uid, 5000 AS userdb_gid FROM mailbox WHERE username = '%u' AND active='1'
Note that the password_query line actually returns all the same information included in the user_query as fields prefixed with userdb_--this is how the prefetch system works.
(Optional) Quota Table
So far you've told Dovecot how to check what the quota limits are supposed to be for a given user. Now, you also need to tell it where to keep information about how much mail the user already has.
Edit dovecot.conf # vim /etc/dovecot.conf
Find the dict { stanza, and set it
dict {
quotadict = mysql:/etc/dovecot-dict-quota.conf
}
Next, find the plugin { stanza and you can add these lines:
# Quota setting per /usr/share/postfixadmin/DOCUMENTS/DOVECOT.txt
# http://wiki.dovecot.org/Quota/Dict
quota = dict:user::proxy::quotadict
Save dovecot.conf, and then open the file: # vim /etc/dovecot-dict-quota.conf
And enter this:
connect = host=localhost dbname=mail user=mail_admin password=
map {
pattern = priv/quota/storage
table = quota2
username_field = username
value_field = bytes
}
map {
pattern = priv/quota/messages
table = quota2
username_field = username
value_field = messages
}
The preceding assumes that you've upgraded to Dovecot 1.2.X as I recommended at the start. Earlier versions of Dovecot have a different format for this file. You can find detailed information here.
Start and Test
Startup
Now for the moment of truth, you should be ready to start up your email server.
Start up Dovecot:
# service dovecot start
If you get errors like this, "Starting Dovecot Imap: Error: Error in configuration file /etc/dovecot.conf line 1109: Unknown setting" it's likely that you forgot to comment or uncomment all the curly brackets properly.
Next, start Postfix: # service postfix start
You'll probably want both of these components to start any time your server boots up, so you can use chkconfig to set that up:
# chkconfig dovecot on
# chkconfig postfix on
Assuming you don't get any error messages when you first start these programs, you may still want to check the mail logs to make sure there's no major warnings or errors recorded there.
# tail /var/log/maillog
A successful startup will probably look similar to this:
Jun 22 23:39:52 ve dovecot: Dovecot v1.2.11 starting up (core dumps disabled)
Jun 22 23:39:52 ve dovecot: Generating Diffie-Hellman parameters for the first time. This may take a while..
Jun 22 23:40:17 ve dovecot: auth-worker(default): mysql: Connected to localhost (mail)
Jun 22 23:40:17 ve dovecot: dict: mysql: Connected to localhost (mail)
Jun 22 23:40:48 ve postfix/postfix-script: starting the Postfix mail system
Jun 22 23:40:48 ve postfix/master[10208]: daemon started -- version 2.3.3, configuration /etc/postfix
Testing with telnet
Before you start setting up email accounts and testing with email clients, it's a good idea to make sure the daemons are at least listening correctly. Telnet is a good way to test this. To test SMTP, you can enter:
# telnet localhost 25
You should get a reply like:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 example.com ESMTP Postfix
Next, if you enter: EHLO example.com
You will get a listing of the features your Postfix server is offering:
250-example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
Especially make sure your output includes the line that reads "250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5" because this means that Postfix is advertising it can understand SMTP AUTH, which requires it to authenticate against Dovecot.
You can type "quit" to close the SMTP session.
You can test that Dovecot is listening for POP connections with: # telnet localhost 110
Which should give output like:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK Dovecot ready.
And to check IMAP connectivity, enter: # telnet localhost 143
A successful result will include Dovecot advertising its IMAP capabilities:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE STARTTLS AUTH=PLAIN AUTH=LOGIN AUTH=DIGEST-MD5 AUTH=CRAM-MD5] Dovecot ready.
TLS (SSL) Encryption
TLS is the successor to SSL. Confusingly, the two terms are used somewhat interchangeably in many contexts. Most of the information in this section is from the CentOS wiki.
In order to enable TLS encryption, you will need an SSL certificate/key pair. There are several commercial vendors you can buy them from, and also some free non-profit sources. However, I'm going to be generating my own self-signed certificate. If you're using a commercial certificate, you may also need to install their root CA certificate, and so your steps for this section would vary slightly.
There are other ways to generate an SSL certificate, but there's a nice RedHat utility included as part of the crypto-utils package that helps automate the process. Install it: # yum install crypto-utils
Then, run the genkey tool and follow the relevant prompts to fill in details for your server: # genkey --days 365 mail.example.com
When asked, Would you like to send a Certificate Request (CSR) to a Certificate Authority (CA)? select "No" unless you are going to be ordering a certificate from a 3rd party. Do not check the box for Encrypt the private key. While Dovecot does support encrypted, password-protected keys, Postfix does not, as of version 2.3.
The certificate and key, respectively will be saved to:
/etc/pki/tls/certs/mail.example.com.cert
/etc/pki/tls/private/mail.example.com.key
Next, tell Postfix to use your certificate and key: # vim /etc/postfix/main.cf
Add the following section:
#TLS CERTIFICATE SETTINGS
#See CentOS wiki at http://wiki.centos.org/HowTos/postfix_sasl
#Enables, but does not require use of TLS
smtpd_tls_security_level = may
#Location of private key
smtpd_tls_key_file = /etc/pki/tls/private/mail.example.com.key
#Public certificate
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.example.com.cert
#Certificate atuhority certificate, if you need this for a commercial certificate.
# smtpd_tls_CAfile = /etc/pki/tls/root.crt
#Log TLS sessions
smtpd_tls_loglevel = 1
#Cache TLS sessions for 1 hour to reduce CPU load
smtpd_tls_session_cache_timeout = 3600s
#Location to store cache
smtpd_tls_session_cache_database = btree:/var/spool/postfix/smtpd_tls_cache
#Raondom data source
tls_random_source = dev:/dev/urandom
#Require TLS security before allowing plaintext authentication
#smtpd_tls_auth_only = no
Save that file, and open Dovecot's configuration for editing: # vim /etc/dovecot.conf
Set the paths for the certificate and key:
ssl_cert_file = /etc/pki/tls/certs/craxz.com.cert
ssl_key_file = /etc/pki/tls/private/craxz.com.key
If necessary, you can set the CA root certificate as well, #ssl_ca_file =
Uncomment this line to disable some weak ciphers: ssl_cipher_list = ALL:!LOW:!SSLv2
After you're done with the configuration, restart Dovecot and Postfix to make it active:
# service dovecot restart
# service postfix restart
References
ISP-style Email Server with Debian-Etch - This page is slightly outdated, and written for Debian, but it's the most accessible and broadly informative article I've found. If you're just starting out, and you want to actually understand what you're doing before blindly entering commands, I would begin here.
Mail server with Postfix and Dovecot - From the Gentoo wiki, but uses all the same components covered in this guide. Well-written and through.
Postfix Official Documentation - Comprehensive, but could be better organized and more accessible.
The Dovecot Wiki - Dovecot has a great deal of excellent, well-written documentation on its wiki.
CentOS Wiki - Contains several useful guides related to email. They are mostly geared toward a more basic setup than the one outlined in this guide.
CentOS Postfix-Dovecot Howto - Blog post covering a very similar setup to the one I've outlined. Considerably more terse than this guide; you might look here if you're already an expert or would like some other examples of the configuration files.
REFERENCES
http://wiki.mediatemple.net/w/Setting_up_an_email_server_in_CentOS