Installing
Dovecot: A Secure IMAP Server
Lawrence Teo
Last year, I began looking around for an IMAP server to replace
my aging UW IMAP server. Although UW IMAP has served me well, I
wanted something newer that was designed with security in mind and
was easier to configure. I found Dovecot, an open source IMAP server
that advertises itself as "an IMAP and POP3 server for Linux/UNIX-like
systems, written primarily with security in mind." I liked
what I read, so I tried it. I have been running Dovecot for close
to a year now, and it has served hundreds of thousands of email
messages without a hitch.
Apart from its security-focused design, Dovecot is also packed
with nifty features, despite its work-in-progress status. It's
IPv6 ready. It's fast -- very fast. I don't have specific
measures, but Dovecot's author Timo Sirainen mentions on the
Web site that he has successfully tested it up to 367,000 emails.
Dovecot runs on a wide range of operating systems, from the usual
open source suspects (Linux and *BSD) to the big Unix varieties.
It has complete support for the IMAP4rev1 standard, plus extensions
for Web mail clients. When I looked at the source code, I was impressed
by the quality of C code under the hood; the author definitely knows
what he's doing. I'm confident that I've finally
found an IMAP server that'll help me sleep better at night.
While I really like Dovecot, I found its documentation to be somewhat
sketchy. This is the key reason why I decided to write this article
-- I want to share what I've learned about installing Dovecot
with you.
I installed Dovecot on an OpenBSD system; both Dovecot and OpenBSD
have similar goals in security, which is extremely important for
security-conscious administrators. In this article, I'll describe
how to install Dovecot on a vanilla OpenBSD 3.3 system. Given the
myriad of ways in which an IMAP server can be configured, I won't
provide a complete HOWTO article; instead, I'll present a "how-I-did-it"
approach, with pointers along the way so you'll know where
to go if you need more information. My own IMAP needs are rather
simple, so I'll show a somewhat minimal installation and configuration
of Dovecot. This leaves a lot of room to play with more advanced
configuration options.
Decisions
Before you install Dovecot, you'll need to make a few key
decisions. For example, do you want to serve IMAPS in addition to
IMAP? Where are the users' mailbox locations? Which mailbox
format do you want to use: mbox or maildir? In my environment, I
made the following decisions, which I'll describe along with
my reasons:
- IMAPS only -- Dovecot will serve IMAPS (IMAP over SSL)
only, and not regular IMAP. This is because regular IMAP runs
over plaintext, and I don't want my messages to be intercepted
in transit.
- OpenSSL only -- By default, Dovecot uses GNUTLS if it's
found. Since OpenSSL comes stock with OpenBSD, I'll use OpenSSL
instead.
- No POP -- Although Dovecot supports POP, I won't be
serving it, because I'm primarily interested in IMAP.
- Non-standard IMAPS port -- The regular IMAPS port is 993.
However, as an extra precaution, I'll use port 779, just
to make things a little harder for portscanner-wielding attackers.
- Mailbox locations -- A user's main inbox will be in
$HOME/Mailbox, while the IMAP folders will be in the $HOME/mail/
directory. These locations could be elsewhere; this is just my
preference. You'll need to make sure that your MTA delivers
mail to your inbox location though, if the location is non-standard.
- mbox format -- I chose mbox over maildir. Although maildir
is much faster when additions and deletions are involved, I prefer
having my mail in a small collection of folders, as opposed to
an entire directory full of thousands of files (which would be
the case if you use maildir). Plus, my server isn't a terribly
busy mail server, so performance isn't too critical.
At the time of writing, the latest version of Dovecot is Dovecot
0.99.10, and the latest stable version of OpenBSD is OpenBSD 3.3.
I will use these versions for this article; however, I should point
out a few things that might have changed by the time you read this
article.
OpenBSD 3.4 is in the works and not released yet, but it does
contain a port for Dovecot. To make things more complicated, the
Dovecot port in 3.4 has a number of patches that address a few bugs
when running Dovecot in OpenBSD. These factors made it rather challenging
to write this article.
Therefore, to make this article accessible to non-OpenBSD users,
I will describe the generic way of compiling and installing it,
which was how I did it, but I will leave notes here and there for
future OpenBSD 3.4 administrators as well. Also, Dovecot is now
available for the other BSD variants (FreeBSD and NetBSD) as well
as Linux distributions like Debian and Red Hat. If you use their
specific installation methods, bear in mind that the file locations
(such as the configuration file and SSL certificate locations) may
be different from those described here.
Installation
To begin, you'll need to download the source tarball from
the Dovecot Web site:
http://dovecot.procontrol.fi/
At the time of writing, the source tarball's filename is dovecot-0.99.10.tar.gz.
On the same download page, you'll find a PGP signature for the
file. If you're truly security-conscious, you can verify the
signature using PGP or an open source alternative like GnuPG.
Extract the tarball:
lteo:~$ tar zxvf http://dovecot.procontrol.fi/dovecot-0.99.10.tar.gz
lteo:~$ cd dovecot-0.99.10
Next, you must decide what the relevant configure options should be.
Invoking ./configure --help provides a useful help screen.
If you want more details on each option, check the INSTALL file in
the source distribution. For my environment, I used the following
configure options:
./configure --without-pam --without-shadow \
--without-vpopmail --localstatedir=/var \
--with-ssldir=/etc/ssl --with-ssl=openssl \
--sysconfdir=/etc
This will build Dovecot without Pluggable Authentication Modules (PAM)
(which OpenBSD does not support), Shadow password, and Vpopmail support.
Next, it'll put local state information (such as SSL parameters
and Dovecot's Unix socket file) in /var and specify that the
SSL certificates live in /etc/ssl. The --with-ssl=openssl option
makes Dovecot use OpenSSL instead of GnuTLS. Then, --sysconfdir=/etc
will install the Dovecot example configuration file in /etc.
After configure finishes, you should see the following output:
Install prefix ...................... : /usr/local
File offsets ........................ : 64bit
Building with SSL support ........... : yes (OpenSSL)
Building with IPv6 support .......... : yes
Building with pop3 server ........... : yes
Building with user database modules . : static passwd passwd-file (modules)
Building with password lookup modules : passwd passwd-file (modules)
Next, compile and install Dovecot using the standard make and make
install routine:
lteo:~/dovecot-0.99.10$ make
lteo:~/dovecot-0.99.10$ su
root# make install
Configuration
After compilation is done, it's time to edit the Dovecot
configuration file to fit our requirements. A sample configuration
file is given in /etc/dovecot-example.conf. Make a copy of it called
/etc/dovecot.conf, which is the filename that Dovecot expects:
root:/# cd /etc
root:/etc# cp dovecot-example.conf dovecot.conf
We're now ready to edit dovecot.conf. Since we want to serve
just IMAPS, we remove the "imap" keyword and leave "imaps"
in the protocols line as follows:
protocols = imaps
Next, we want Dovecot to listen on port 779, and not the default IMAPS
port of 993:
imaps_listen = *:779
The asterisk makes Dovecot listen on all IPv4 interfaces, which
is what we want in most circumstances.
You may also want to consider increasing the login process count,
especially for busy servers. This is the number of login processes
that will wait for users to log in. The default number is 3, so
we can increase it to 5:
login_processes_count = 5
In terms of the default mail environment, we use the mbox format with
the IMAP folders in $HOME/mail/, and the inbox will be $HOME/Mailbox.
You can specify these locations as follows:
default_mail_env = mbox:~/mail/:INBOX=/home/%u/Mailbox
If you want to use the maildir format instead, read the doc/configuration.txt
file in the Dovecot source distribution. doc/mail-storages.txt also
has more information on how both mbox and maildir are stored internally.
Because I'm on OpenBSD, I won't be using PAM (which
is the default Dovecot authentication method), so I will change
the password database location to use the standard passwd file:
auth_passdb = passwd
Generating SSL Certificates
Since we're running IMAPS, we have to generate SSL certificates
first. There are two ways to do this. The first is to use Dovecot's
SSL certificate generation script (doc/mkcert.sh), and the second
is to generate them using OpenSSL.
Using Dovecot's script is more convenient -- however,
there are two caveats. The default filename generated by the script
is imapd.pem, while the filename actually used by Dovecot is dovecot.pem.
This is just a minor inconvenience; you can always rename the files
or change the filenames in /etc/dovecot.conf. The second caveat
is that the script does not specify the expiration period for the
certificates, so the generated certificates will have an expiration
period of 30 days (which I think is the OpenSSL default).
Now, we don't want to re-generate SSL certificates every
single month, so I recommend manually generating them with a longer
expiration period, say 365 days, using OpenSSL (the second method).
To begin, edit the Dovecot-supplied OpenSSL configuration file called
doc/dovecot-openssl.cnf. The fields in the file are fairly self-explanatory,
so I won't go into details. If you're unfamiliar with
X.509 certificates, the most "important" field is the
CN field. Make sure that the CN value matches the DNS name of your
mail server. For example, if your mail server's DNS name is
imapserver.example.com, make sure that the CN field reflects that
name. The contents of a sample doc/dovecot-openssl.cnf file are
shown here:
[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no
[ req_dn ]
# country (2 letter code)
C=US
# State or Province Name (full name)
ST=North Carolina
# Locality Name (eg. city)
L=Charlotte
# Organization (eg. company)
O=Example Corporation
# Organizational Unit Name (eg. section)
OU=IMAP server
# Common Name (*.example.com is also possible)
CN=imapserver.example.com
# E-mail contact
emailAddress=mailadmin@example.com
[ cert_type ]
nsCertType = server
OpenSSL will generate two certificates: a public certificate and a
private certificate. By default, Dovecot looks for the public certificate
in /etc/ssl/certs/dovecot.pem and expects the private certificate
to be in /etc/ssl/private/dovecot.pem. On a vanilla OpenBSD system,
the directory /etc/ssl/certs may not exist yet. If it does not exist,
you'll need to create it first.
In the next step, we generate the SSL certificates and install
them into their expected locations as follows:
root:/usr/src/dovecot-0.99.10# openssl req -new -x509 -nodes \
-config dovecot-openssl.cnf -days 365 \
-out /etc/ssl/certs/dovecot.pem \
-keyout /etc/ssl/private/dovecot.pem
Note to OpenBSD 3.4 administrators: If you installed from ports, the
caveats mentioned above do not apply to you. Your public X.509 certificate
will be called /etc/ssl/dovecotcert.pem. You can run the mkcert script
directly by invoking /usr/local/sbin/dovecot-mkcert.sh. The configuration
file is /etc/ssl/dovecot-openssl.cnf.
Adding the Dovecot User Account
Dovecot runs using a few separate processes and exercises the
principle of least privilege by running the login processes as a
non-root user called "dovecot". In this step, I'll
create the user account "dovecot" for this purpose. Most
readers are likely familiar with this, so I'll just describe
it briefly.
OpenBSD 3.4 administrators can skip this step if Dovecot was installed
from ports. If you used ports or a distribution-specific installation,
it is likely that the user account would have been created for you.
root:/# adduser
Use option ''-silent'' if you don't want to see all warnings and questions.
Reading /etc/shells
Check /etc/master.passwd
Check /etc/group
Ok, let's go.
Don't worry about mistakes. I will give you the chance later to correct any input.
Enter username [a-z0-9_-]: dovecot
Enter full name []: Dovecot
Enter shell bash csh ksh nologin sh [bash]: nologin
Uid [1002]: <enter>
Login group dovecot [dovecot]: <enter>
Login group is ''dovecot''. Invite dovecot into other groups: guest no
[no]: <enter>
Enter password []:
Enter password again []:
Name: dovecot
Password: ****
Fullname: Dovecot
Uid: 1002
Gid: 1002 (dovecot)
Groups: dovecot
HOME: /home/dovecot
Shell: /sbin/nologin
OK? (y/n) [y]: y
Added user ''dovecot''
Copy files from /etc/skel to /home/dovecot
Add another user? (y/n) [y]: n
Goodbye!
Migrating Mailboxes
You might have existing mail from another server that you would
like to move to your new Dovecot IMAP server. Say your old mail
is in mbox format and the messages are stored in a server called
oldmail.example.com, organized in the exact directory structure
and using the same filenames.
Earlier, we set our inbox to be $HOME/Mailbox and IMAP folders
to be in $HOME/mail/, so we can just migrate the inbox and IMAP
folders with the secure copy command (scp) as follows:
lteo:~$ scp lteo@oldmail.example.com:~/Mailbox .
lteo:~$ mkdir mail
lteo:~$ cd mail
lteo:~/mail$ scp -pr lteo@oldmail.example.com:~/mail/* .
Dovecot manages IMAP folder subscriptions in a dotfile called .subscriptions
in the IMAP folder directory. The .subscriptions file contains the
filenames of IMAP folders to which you are subscribed. You can use
the following one-liner to easily subscribe to all current folders:
lteo:~/mail$ find . -type f | sed 's/^\.\///' >.subscriptions
To keep things simple, I have just described a method to migrate mail
for one user. If you have multiple users, mail migration can be done
using a few shell scripts.
If you would like to filter your messages, you can use procmail
to filter messages, or just let your users use their mail client
to handle it. Filtering messages is another subject altogether,
so I won't discuss it in this article.
Starting Dovecot at Boot
If you want to have Dovecot started automatically at boot time,
simply add the following lines to /etc/rc.local (on OpenBSD):
if [ -x /usr/local/sbin/dovecot ]; then
echo -n ' dovecot'; /usr/local/sbin/dovecot
fi
For other systems, just add the equivalent lines to your system's
respective startup script(s).
Let's Run It!
Now that everything is set up, you can run Dovecot to test whether
it actually works:
root:/# /usr/local/sbin/dovecot
If all goes well, netstat should show you that it's listening
on the non-standard port 779 as it was configured to do earlier:
root:/# netstat -an | grep LISTEN
tcp 0 0 *.779 *.* LISTEN
tcp 0 0 *.22 *.* LISTEN
tcp 0 0 127.0.0.1.587 *.* LISTEN
tcp 0 0 127.0.0.1.25 *.* LISTEN
tcp 0 0 *.113 *.* LISTEN
tcp6 0 0 *.22 *.* LISTEN
tcp6 0 0 ::1.587 *.* LISTEN
tcp6 0 0 ::1.25 *.* LISTEN
tcp6 0 0 *.113 *.* LISTEN
When you check the processes associated with Dovecot, you'll
see that the main Dovecot process and the authentication processes
run as root. The five login processes (set earlier in the Configuration
section) run using the non-root "dovecot" account:
lteo:~$ ps uaxwww | grep dovecot
root 6830 0.0 0.2 180 612 ?? Ss 1:53AM 0:00.03 /usr/local/sbin/dovecot
root 23920 0.0 0.1 268 536 ?? S 1:53AM 0:00.01 dovecot-auth
dovecot 30444 0.0 0.3 204 1148 ?? S 1:53AM 0:00.05 imap-login
dovecot 20264 0.0 0.3 204 1152 ?? S 1:53AM 0:00.05 imap-login
dovecot 17184 0.0 0.3 204 1152 ?? S 1:53AM 0:00.05 imap-login
dovecot 27273 0.0 0.3 204 1152 ?? S 1:53AM 0:00.05 imap-login
dovecot 11414 0.0 0.3 204 1152 ?? S 1:53AM 0:00.05 imap-login
For more information on what each process does, check out the file
doc/design.txt, which documents Dovecot's security design.
At this point, you might want to fire up a mail client and check
your mail from your brand-new Dovecot IMAP server to see whether
it works. Remember to allow your mail client to accept the self-signed
SSL certificate. Also, your mail client should be configured to
use IMAPS on the non-standard port 779 (if you selected that port
number).
To terminate Dovecot, send a SIGTERM signal to the main Dovecot
process (in this case, the Dovecot process running with PID 6830):
root:/# kill -TERM 6830
Optimizing Dovecot's Performance
Dovecot is already pretty fast, so it's probably not necessary
to make it even faster in most circumstances. However, if you operate
a busy mail server or if you have a need to push performance to
the limit (e.g., if you're running on older hardware), you
can tune your operating system to help Dovecot a little bit. I'll
provide some basic guidelines.
A typical mail server involves a lot of network and file accesses,
so choosing to optimize the network and filesystem settings is a
good idea. We'll follow the recommendations from the OpenBSD
FAQ to tune network and filesystem performance.
If you're operating a busy mail server, you can increase
the size of the kernel mbuf cluster map. Assuming you're running
an i386-based machine with a 100-Mbps Ethernet interface, a good
value would be 8192. Do this by adding the following line to your
kernel configuration file (which should be a copy of /usr/src/sys/arch/i386/conf/GENERIC
if you're using the generic kernel as a reference):
option NMBCLUSTERS=8192
If your mail server has enough RAM to spare, you can also use a larger
percentage of it as your filesystem buffer. By default, only 5% of
RAM is used. To increase the filesystem buffer to 30%, add the following
line to the kernel configuration file:
option BUFCACHEPERCENT=30
The soft updates feature, which was added in OpenBSD 2.9, significantly
speeds up filesystem performance. This, in turn, should increase
the speed of your mail server. Soft updates is already enabled by
default in the generic OpenBSD kernel; however, if it's not
turned on, you can do that by including the following line in the
kernel configuration file:
opton FFS_SOFTUPDATES
You'll also need to change /etc/fstab to enable the softdep option
so that soft updates will be used. The following shows how soft updates
is enabled for the /dev/wd0a partition:
/dev/wd0a / ffs rw,softdep 1 1
You can do the same for the other partitions.
Remember to reboot after recompiling your kernel. The afterboot(8)
man page and OpenBSD's online FAQ has detailed information
about recompiling an OpenBSD kernel.
Concluding Remarks
I have described a basic installation of Dovecot on OpenBSD. I
have tried to keep the steps as generic as possible, so that you
can use them on different platforms as well. As mentioned earlier,
this is a somewhat minimal installation of Dovecot, so there's
still plenty of room left for you to experiment with more advanced
IMAP server configurations. The documentation in the doc/ directory
of Dovecot's source distribution should give you some ideas,
and the Web site has more information as well.
Note that a few features of Dovecot aren't quite there yet,
such as support for Maildir++ quota and filesystem quota. If your
environment requires these features, you may want to defer setting
up Dovecot in a production environment. However, from my experience,
Dovecot is ready as it is, and I use it for my own daily work and
personal mail. For more critical environments, I recommend checking
Dovecot's mailing list (instructions are on Dovecot's
Web site) if there are particular issues you're not sure about.
It's pretty active so you should be able to obtain help. If
you do choose to try out Dovecot, I hope the instructions in this
article would be helpful to you.
References
Dovecot Web Site -- http://dovecot.procontrol.fi/
OpenBSD FAQ -- http://www.openbsd.org/faq/
Lawrence Teo is vice president and co-founder of Calyptix Security
Corporation (www.calyptix.com), a provider of Internet security
solutions based on emerging technologies from scientific research.
Prior to this, he held software engineering and research positions
in Singapore and Australia. He has been administering Linux and
*BSD systems for 7 years. Lawrence holds a Bachelor of Computing
degree with First Class Honors from Monash University, Australia,
and is currently working on his Ph.D. in security at the University
of North Carolina at Charlotte.
|