Complete Virtual Mail Server/Courier-IMAP to Database

From Gentoo Wiki
Jump to:navigation Jump to:search
Outdated translations are marked like this.

Introduction

Courier-IMAP will be used to provide both IMAP and POP3 services. Many will be interested in IMAP as POP3 is not being used as much anymore. This is quite understandable as IMAP has many advantages.

The major difference between POP3 and IMAP would be that IMAP keeps messages on the server whereas with POP3, the client retrieves the messages and are then gone from the server. Having the messages kept on server allows for several clients to actively work with the same mailbox from different locations. The most basic example would be webmail and a desktop client, both accessing the same mailbox at the same time. Also in general, webmail clients strongly favor IMAP. The price this comes with of course, is primarily disk space and processing power on the mail server. With disk space being as cheap as it is these days, 32Gb set aside pure for e-mail offers a lot of space for mails, at hardly any cost. And if processing power is an issue, server-side based searches can be disabled to reduce the stress on the machine.

This chapter will mainly focus on IMAP, but will include POP3 for completeness sake. Some research into the two protocols may be required if the choice is not so certain.

Installing Courier-IMAP

net-mail/courier-imap has a few USE flags that need to be examined. net-libs/courier-authlib is an important dependency as it is responsible for how users authenticate, so it's USE flags are examined as well.

USE flags for net-libs/courier-authlib Courier authentication library

berkdb Add support for sys-libs/db (Berkeley DB for MySQL)
debug Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces
gdbm Add support for sys-libs/gdbm (GNU database libraries)
ldap Add LDAP support (Lightweight Directory Access Protocol)
mysql Add mySQL Database support
pam Add support for PAM (Pluggable Authentication Modules) - DANGEROUS to arbitrarily flip
postgres Add support for the postgresql database
sqlite Add support for sqlite - embedded sql database
static-libs Build static versions of dynamic libraries as well

Only choose the desired database backends.

Warning
libauth*sql.so may only be built if -vpopmail is set as USE flag and the system does not have vpopmail installed. Vpopmail and libauth*sql.so do not mix.
Note
The fam USE flag is required for the IDLE (e.g. 'push') function to work.

If the proper USE flags are set, emerging courier-imap should pull in courier-authlib:

root #emerge --ask net-mail/courier-imap

Configuring courier-authlib

Postgres

Courier-authlib runs as root, so access to the socket will be permitted by default.

Note
Only fields that should be changed are listed here. There are two commented options. PGSQL_HOST obviously as mentioned before, unix sockets will be used. PGSQL_QUOTA_FIELD is commented for now, as quotas will be enabled at a later stage. The PGSQL-UID_FIELD, PGSQL-GID_FIELD and PGSQL_HOME_FIELD (Note the trailing slash!) are set to static values, noticeable as they are quoted. Thus static values, and not values from a database are used.
FILE /etc/courier/authlib/authpgsqlrcObtain access to the database
##NAME: LOCATION:0
# PGSQL_HOST		pgsql.example.com
PGSQL_PORT		5432
PGSQL_USERNAME		postfix
PGSQL_PASSWORD		$password
 
##NAME: PGSQL_DATABASE:0
PGSQL_DATABASE		postfix
 
##NAME: PGSQL_USER_TABLE:0
PGSQL_USER_TABLE	mailbox
 
##NAME: PGSQL_CRYPT_PWFIELD:0
PGSQL_CRYPT_PWFIELD	password
 
##NAME: PGSQL_UID_FIELD:0
PGSQL_UID_FIELD		'5000'
 
##NAME: PGSQL_GID_FIELD:0
PGSQL_GID_FIELD		'5000'
 
##NAME: PGSQL_LOGIN_FIELD:0
PGSQL_LOGIN_FIELD	local_part
 
##NAME: PGSQL_HOME_FIELD:0
PGSQL_HOME_FIELD	'/var/vmail/'
 
##NAME: PGSQL_NAME_FIELD:0
PGSQL_NAME_FIELD	name
 
##NAME: PGSQL_MAILDIR_FIELD:0
PGSQL_MAILDIR_FIELD	maildir
 
##NAME: PGSQL_QUOTA_FIELD:0
# PGSQL_QUOTA_FIELD	quota
 
##NAME: PGSQL_WHERE_CLAUSE:0
# Deal only with active mail accounts.
PGSQL_WHERE_CLAUSE      active='1'

If logins are used in the syntax of user@domain.com instead of username, the value of PGSQL_LOGIN_FIELD needs to be changed from local_part to username.

To use more advanced authentication SQL statements the PGSQL_SELECT_CLAUSE can be used. Courier-authlib will ignore any of the previous set parameters for SELECT statements, but will use them for counting the number of accounts or for changing the password and thus when changing the password the username field is still used. If authentication is done against username remember that usernames need to be unique.

FILE /etc/courier/authlib/authpgsqlrcObtain custom access to the database
PGSQL_SELECT_CLAUSE	SELECT local_part, password, '', '5000', '5000',	\
			'/var/vmail/', maildir, quota, name, ''		 	\
			FROM mailbox WHERE local_part='$(local_part)'	 	\
			AND active='1'

MySQL

Next reconfigure the authentication to use the mailsql database in courier-imap and postfix. In all of the following examples, replace $password with the password set for the mailsql mysql user.

FILE /etc/courier/authlib/authmysqlrcConfiguring authentication
MYSQL_SERVER            localhost
MYSQL_USERNAME       mailsql
MYSQL_PASSWORD      $password
MYSQL_DATABASE          mailsql
MYSQL_USER_TABLE        users
## (Make sure the following line is commented out since we're storing plaintext.)
#MYSQL_CRYPT_PWFIELD    crypt
MYSQL_CLEAR_PWFIELD     clear
MYSQL_UID_FIELD         uid
MYSQL_GID_FIELD         gid
MYSQL_LOGIN_FIELD       email
MYSQL_HOME_FIELD        homedir
MYSQL_NAME_FIELD        name
MYSQL_MAILDIR_FIELD     maildir

Reload the necessary services:

root #rc-service courier-authlib restart
root #rc-service saslauthd restart

Configuring authdaemon

Authdaemon is actually responsible for doing the authentication. Here authdaemon is configured to use the right database backend. Portage actually does set the authmodulelist variable properly. Verify this in the configuration file. Also enable debugging here as this will help with any potential issues later.

PostgreSQL

FILE /etc/courier/authlib/authdaemonrcVerify authentication modules
##NAME: authmodulelist:2
authmodulelist="authpgsql "
 
##NAME: DEBUG_LOGIN:0
DEBUG_LOGIN=1
Note
Obviously if more or others authmodules are desired, these should be listed here as well.

MySQL

FILE /etc/courier/authlib/authdaemonrcVerify authentication modules
##NAME: authmodulelist:2
authmodulelist="authmysql authpam"
 
##NAME: DEBUG_LOGIN:0
DEBUG_LOGIN=1

Access permissions

Permissions must be set correctly, as the files can contain sensitive password information.

root #chmod 660 /etc/courier/authlib/auth*rc
root #chown mail:mail /etc/courier/authlib/auth*rc

Testing courier-authlib

Courier-authlib includes a simple testing utility. It requires a valid username as parameter. Don't hesitate to check out the authtest manual page for more information. It is short but concise.

To perform some basic tests start the authlib daemon:

root #/etc/init.d/courier-authlib start

Run authtest with the testuser:

root #authtest testuser
Authentication succeeded.
 
     Authenticated: testuser  (uid 5000, gid 5000)
    Home Directory: /var/vmail
           Maildir: example.com/testuser/
             Quota: (none)
Encrypted Password: $1$16117118$ajxN3QRilmP5zLVHjTkE31
Cleartext Password: (none)
           Options: (none)

Configuring POP3/IMAP

POP3

POP3 requires little configuring to get working. It is however recommended to skip this section and not enable/use pop3 and thus leave this setting at NO. A user may be able to remove all messages that were supposed to be stored on the server for imap usage, then incorrectly configure his mail client and purge the server of his mailbox this way.

FILE /etc/courier-imap/pop3dEnable pop3
##NAME: POP3DSTART:0
POP3DSTART=YES

IMAP

IMAP has a few capabilities that can be enabled.

  • SORT to allow server side searching through messages.
  • IDLE to allow 'push' like connections.
FILE /etc/courier-imap/imapdEnable imapd and some options
##NAME: IMAP_CAPABILITY:1
IMAP_CAPABILITY="IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE"
 
##NAME: IMAP_CHECK_ALL_FOLDERS:0
IMAP_CHECK_ALL_FOLDERS=1
 
##NAME: IMAP_ENHANCEDIDLE:0
IMAP_ENHANCEDIDLE=1
 
##NAME: IMAP_EMPTYTRASH:0
IMAP_EMPTYTRASH=Trash:40,Junk:7
 
##NAME: IMAPDSTART:0
IMAPDSTART=YES
 
##NAME: MAILDIRPATH:0
MAILDIR=.maildir
MAILDIRPATH=.maildir
Note
The MAILDIRPATH section contains some dupes, make sure it is properly set and cleaned up.

Some clients need a minimum DH parameter length of 2048 bits (such as those using >=dev-libs/nss-3.19.1). Generate one with:

root #DH_BITS=2048 mkdhparams

Next ensure Courier is using it:

FILE /etc/courier-imap/imapd-sslEnsure Courier is using our dhparams.pem
TLS_DHPARAMS=/usr/share/dhparams.pem

Testing IMAP/POP3

POP3

Courier-pop3d should be started:

root #/etc/init.d/courier-pop3d start

Once started, telnet could be used to identify initial problems. Once logging in with telnet works, a mail client can be used:

user $telnet foo.example.com 110
+OK Hello there.
user testuser
+OK Password required
Pass secret
+OK logged in
Note
This is the first time the password is used in plain text. It was previously only known as $1$16117118$ajxN3QRilmP5zLVHjTkE31.
Warning
Remember to prepare the user maildir with the courier-maildirmake tool.

If testing works properly, add courier-pop3d to the default runlevel:

root #rc-update add courier-pop3d default

IMAP

Courier-imapd should be started:

root #/etc/init.d/courier-imapd start

Once started, telnet could be used to identify initial problems. Once logging in with telnet works, a mail client can be used:

user $telnet foo.example.com 143
Trying 127.0.0.1...
Connected to foo.example.com.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998-2008 Double Precision, Inc.  See COPYING for distribution information.
1 LOGIN testuser secret 
1 OK LOGIN Ok.
1 LOGOUT
* BYE Courier-IMAP server shutting down
1 OK LOGOUT completed
Connection closed by foreign host.

If testing works properly, add courier-imap to the default runlevel:

root #rc-update add courier-imapd default

Wrapping things up

Turn off debugging if this stage works properly.

FILE /etc/courier/authlib/authdaemonrcDisable debugging
##NAME: DEBUG_LOGIN:0
DEBUG_LOGIN=0