Dovecot is an open source IMAP and POP3 server for Linux systems, written with security primarily in mind. Although it's written in C, it uses several coding techniques to avoid most of the common pitfalls.
For more information see: http://www.dovecot.org/
Compiling and Building from Source
Prerequisite:
yum -y install gcc gettext-devel
Next Download the latest source code from: http://dovecot.org/download.html. Then run:
./configure --with-mysql --enable-header-install --with-db && make
echo $?
(disable Monit if it's running with below)
monit unmonitor Dovecot && monit summary |grep Dovecot
/sbin/service dovecot stop && make uninstall && make install && /sbin/service dovecot start
echo $?
Link config files if there they get lost
ln -s /etc/dovecot.conf /usr/local/etc/dovecot.conf
ln -s /etc/dovecot-mysql.conf /usr/local/etc/dovecot-mysql.conf
Initial Setup of Dovecot When Compiled from Source
Using the below init file, create a new file named /etc/init.d/dovecot, then run the following:
chmod 755 /etc/init.d/dovecot
/sbin/chkconfig --add dovecot
/sbin/chkconfig dovecot on
/sbin/chkconfig --list dovecot
And to keep everything simple and in your /etc/ directory run:
mv /usr/local/etc/dovecot.conf /etc/dovecot.conf
ln -s /etc/dovecot.conf /usr/local/etc/dovecot.conf
Also make sure that the correct user and groups exist in /etc/passwd and /etc/group.
echo "virtualmail:x:1000:1000:virtualmail:/var/spool/virtualmailboxes:/sbin/nologin" >> /etc/passwd
echo "virtualmail:x:1000:" >> /etc/group
Dovecot INIT File
#!/bin/bash
#
# /etc/rc.d/init.d/dovecot
#
# Starts the dovecot daemon
#
# chkconfig: - 65 35
# description: Dovecot Imap Server
# processname: dovecot
# Source function library.
. /etc/init.d/functions
test -x /usr/local/sbin/dovecot || exit 0
RETVAL=0
prog="Dovecot Imap"
start() {
echo -n $"Starting $prog: "
daemon /usr/local/sbin/dovecot
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/dovecot
echo
}
stop() {
echo -n $"Stopping $prog: "
killproc /usr/local/sbin/dovecot
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/dovecot
echo
}
case "$1" in
start)
start
;;
stop)
stop
;;
reload|restart)
stop
start
RETVAL=$?
;;
condrestart)
if [ -f /var/lock/subsys/dovecot ]; then
stop
start
fi
;;
status)
status /usr/local/sbin/dovecot
RETVAL=$?
;;
*)
echo $"Usage: $0 {condrestart|start|stop|restart|reload|status}"
exit 1
esac
exit $RETVAL
Installing Dovecot (from prebuilt binaries)
With Fedora the easiest way to install Dovecot is via yum.
yum -y install dovecot dovecot-mysql
/sbin/service dovecot start
/sbin/chkconfig dovecot on
Configuring A Dovecot Server with MySQL, Postfix, Sieve, & Quota support
This is a pretty basic set-up using MySQL. We are also using the database for Quota information.
- /etc/dovecot.conf
## Dovecot configuration file
#protocols = imap imaps pop3 pop3s
protocols = imap imaps
login_user = postfix
listen =
ssl_listen =
ssl_disable = no
ssl_cert_file = /etc/pki/dovecot/certs/dovecot.pem
ssl_key_file = /etc/pki/dovecot/private/dovecot.pem
auth_cache_size = 128
auth_cache_ttl = 600
mail_location = maildir:/var/spool/virtualmailboxes/%d/%u/imap/:INBOX=/var/spool/virtualmailboxes/%d/%u/:INDEX=/var/spool/virtualmailboxes/%d/%u/imap/index/
protocol imap {
mail_plugins = quota imap_quota
}
protocol pop3 {
mail_plugins = quota
}
protocol lda {
postmaster_address = postmaster@example.com
hostname = mail.example.com
mail_plugins = cmusieve
mail_plugins = quota
sieve_global_path = /var/spool/sieve/dovecot.sieve
mail_plugin_dir = /usr/lib/dovecot/lda
auth_socket_path = /var/run/dovecot/auth-master
}
auth default {
mechanisms = plain digest-md5 cram-md5
userdb sql {
args = /etc/dovecot-mysql.conf
}
passdb sql {
args = /etc/dovecot-mysql.conf
}
user = root
count = 2
}
dict {
}
plugin sql {
quota = maildir:storage=1048576
quota = maildir:ignore=Trash
}
Configuring A Dovecot Server with MySQL, Postfix, Sieve, SMTP Authentication, & Quota support
- /etc/dovecot.conf
## Dovecot configuration file
protocols = imap imaps
login_user = postfix
listen = 143
ssl_listen = 993
ssl_disable = no
ssl_cert_file = /etc/postfix/smtpd.pem
ssl_key_file = /etc/postfix/smtpd.pem
auth_cache_size = 128
auth_cache_ttl = 600
mail_debug = no
mail_location = maildir:/var/spool/virtualmailboxes/%d/%u/imap/:INBOX=/var/spool/virtualmailboxes/%d/%u/:INDEX=/var/spool/virtualmailboxes/%d/%u/imap/index/
protocol imap {
listen = *:143
ssl_listen = *:993
mail_plugins = quota imap_quota zlib
ssl_cert_file = /etc/postfix/smtpd.pem
ssl_key_file = /etc/postfix/smtpd.pem
}
protocol pop3 {
mail_plugins = quota
}
protocol lda {
postmaster_address = postmaster@example.com
hostname = mail.example.com
mail_plugins = cmusieve quota
sieve_global_path = /var/spool/sieve/dovecot.sieve
mail_plugin_dir = /usr/local/lib/dovecot/lda
auth_socket_path = /var/run/dovecot/auth-master
}
auth default {
mechanisms = plain login
userdb sql {
args = /etc/dovecot-mysql.conf
}
passdb sql {
args = /etc/dovecot-mysql.conf
}
socket listen {
master {
path = /var/run/dovecot/auth-master
user = virtualmail
group = virtualmail
}
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
dict {
}
plugin {
sieve = /var/spool/virtualmailboxes/%d/%u/dovecot.sieve
}
plugin sql {
# 10 MB Default Mailbox Size Limit
quota = maildir:
quota_rule = *:storage=10M
quota = maildir:ignore=Trash
quota = maildir:ignore=Junk
}
- /etc/dovecot-mysql.conf
driver = mysql
connect = dbname=postfix user=postfix host=localhost password=postfix
default_pass_scheme = md5sum
password_query = SELECT password FROM mailbox WHERE username = '%u'
user_query = SELECT maildir, 1000 AS uid, 1000 AS gid, CONCAT('maildir:storage=', ROUND( mailbox.quota / 1024 ) ) AS quota FROM mailbox WHERE username = '%u' AND active = '1'
Dovecot SSL/TLS
Self-signed SSL Certificates
Self-signed SSL certificates are the easiest way to get your SSL server working. However unless you take some action to prevent it, this is at the cost of security:
- The first time the client connects to the server, it sees the certificate and asks the user whether to trust it. The user of course doesn't really bother verifying the certificate's fingerprint, so a man-in-the-middle attack can easily bypass all the SSL security, steal the user's password and so on.
- If the client was lucky enough not to get attacked the first time it connected, the following connections will be secure as long as the client had permanently saved the certificate. Some clients do this, while others have to be manually configured to accept the certificate.
The only way to be fully secure is to import the SSL certificate to client's (or operating system's) list of trusted CA certificates prior to first connection. See SSL/CertificateClientImporting how to do it for different clients.
Building Dovcot's Self-Signed Certificates
Dovecot includes a script to build self-signed SSL certificates using OpenSSL. First you need to find the dovecot-openssl.cnf file.
- Configuring the Certificate Config File
The best way on Fedora to do this is via the locate command.
locate dovecot-openssl.cnf
Mine was located at /etc/pki/dovecot/dovecot-openssl.cnf. Now that you have found the file you need to add your server information to it, like this.
[ 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=MN
# Locality Name (eg. city)
L=SaintPaul
# Organization (eg. company)
O=mattrude.com
# Organizational Unit Name (eg. section)
OU=IMAP server
# Common Name (*.example.com is also possible)
CN=*.mattrude.com
# E-mail contact
emailAddress=post@mattrude.com
[ cert_type ]
nsCertType = server
- Build the Certificates
/usr/libexec/dovecot/mkcert.sh
And now restart Dovecot
/sbin/service dovecot restart
Testing your SSL Certificates
openssl s_client -ssl2 -connect mail.mattrude.com:993
Other Dovecot How-TO's
Dovecot Plugins
Dovecot's Quota Plugin
printf "1 getquotaroot Inbox
" | dovecot --exec-mail imap |grep "STORAGE " |awk '{ print $6 }'
Dovecot's Trash Plugin
Dovecot's Virtual Mailboxes Plugin
Dovecot's Zlib Plugin
Troubleshooting Dovecot
See: http://bobpeers.com/technical/telnet_imap.php
- Connectiong into Dovecot with telnet
telnet mail.example.com 143
- Connecting into Dovecot using a SSL connection
openssl s_client -connect mail.example.com:993
- Logging In
. login
- Listing Imap Directories
. list "" "*"
- Selecting an Imap Directory
. select Save
Dovecot Notes
Delete messages in Trash and Junk folders, older then so many days
- For version 1.1 and older use
find /var/spool/virtualmailboxes/*/*/imap/ -regex '.*/\.\(Trash\|Junk\)\(/.*\)?\/\(cur\|new\)/.*' -type f -ctime +60 -delete
- In version 1.2 and higher, you can do this via imap
export USER=username@example.com
printf "1 select Trash
2 search return (save) before 01-jan-2009
3 store $ +flags.silent \deleted
4 expunge
5 select Junk
6 search return (save) before 01-jan-2009
7 store $ +flags.silent \deleted
8 expunge
9 logout
" | dovecot --exec-mail imap
Or for just the Trash folder
export USER=username@example.com
printf "1 select Trash
2 search return (save) before 01-jan-2009
3 store $ +flags.silent \deleted
4 expunge
5 logout
" | dovecot --exec-mail imap
Or as a script
# This will use the expire plug-in settings from the config file.
export USER=
for a in `echo "SELECT username FROM mailbox;" |mysql postfix -N`
do
USER=$a
dovecot --exec-mail ext /usr/local/libexec/dovecot/expire-tool
done
Or as an all in one script:
# Delete all messages in Trash and Junk, over 30 days old
export IMAPEXPIREDATE=`date +%d-%b-%Y -d "30 days ago"`
export USER=
for a in `echo "SELECT username FROM mailbox;" |mysql postfix -N`
do
USER=$a
echo "********* Working on user $USER *********"
echo
printf "1 select Trash
2 search return (save) before $IMAPEXPIREDATE
3 store $ +flags.silent \deleted
4 expunge
5 select Junk
6 search return (save) before $IMAPEXPIREDATE
7 store $ +flags.silent \deleted
8 expunge
9 logout
" | dovecot --exec-mail imap; done
To tell you what users expired mail:
export IMAPEXPIREDATE=`date +%d-%b-%Y -d "30 days ago"`
export USER=
for a in `echo "SELECT username FROM mailbox;" |mysql postfix -N`; do USER=$a; echo -n "Expiring messages for $USER: "; printf "1 select Trash
2 search return (save) before $IMAPEXPIREDATE
3 store $ +flags.silent \deleted
4 expunge
5 select Junk
6 search return (save) before $IMAPEXPIREDATE
7 store $ +flags.silent \deleted
8 expunge
9 logout
" | dovecot --exec-mail imap |grep "EXPUNGE" |wc -l; done