Paranoid Penguin - Secure Mail with LDAP and IMAP, Part I
In the September 2003 issue, I ended a series on building an OpenLDAP server. With this current column and the next, I discuss in-depth one of LDAP's most compelling applications: providing authentication and address book information for IMAP users. These aren't more LDAP articles, though. The focus is on IMAP itself (Cyrus) and how it can leverage LDAP and its own security features to provide secure remote mail services. In other words, assume you already have (or know how to get) an LDAP server running and populated with user accounts.
First, a little background on IMAP's role in the e-mail food chain. IMAP, the Internet Message Access Protocol (specified in RFC 3501), is a protocol for mail delivery agents (MDAs). Whereas mail transport agents (MTAs), such as Postfix and Sendmail, move mail between networks, MDAs move mail from MTAs to destination mailboxes. To use a simile from my book Building Secure Servers With Linux, if an MTA is like a mail truck that moves mail between post offices, an MDA is like a letter carrier who delivers mail from the local post office to your house.
An IMAP-based MDA system has two parts: an IMAP server, which houses user mailboxes and receives mail from some MTA, and a group of users running IMAP client software. The three most popular open-source IMAP servers are University of Washington IMAP (UW IMAP), Cyrus IMAP from Carnegie Mellon University and Courier IMAP from Inter7 Internet Technologies. Popular IMAP client applications include Netscape/Mozilla Communicator, Ximian Evolution, Microsoft Outlook Express, KMail, mutt, pine and Apple Mac OS X Mail. IMAP clients are beyond the scope of our purposes here, but they're relatively easy to configure and use. Furthermore, most IMAP clients interoperate with most IMAP servers, so there isn't much to explain anyhow.
When building an IMAP system, the first choice an e-mail administrator must make is which server to use. What are the major differences between UW IMAP, Courier IMAP and Cyrus IMAP? Because features are added to the latter two fairly frequently, I'm going to cop out of telling you the answer in much detail. What I can say is:
Of the three, UW IMAP is the least flexible, as it supports only local-user-account mail file delivery; each local user's inbox is stored as a single flat file, /var/mail/myusername. This has two disadvantages: each mail user also must be a system user, and only one process may write to any given user's inbox at any given time, potentially resulting in file-locking complications.
Courier IMAP, actually part of the Courier Mail Server, was designed to support qmail's maildir system. In it, users have their own mail directories that store messages as individual files, which is better both from a performance standpoint and for obviating file-locking problems. Courier also can store mail in databases (see point 3); recent versions of Courier IMAP also support LDAP authentication.
Cyrus IMAP can be more complicated to set up than UW IMAP or Courier IMAP, mainly due to the Cyrus SASL authentication libraries on which it depends. However, Cyrus IMAP uses its own user and mail databases, both completely separate from the underlying OS, which allows you to add mail users without adding system user accounts. Also, using databases rather than flat files to store messages has an obvious performance benefit.
Personally, I've used Cyrus IMAP the most, so it is the MDA this article discusses. Refer to the features lists on the respective home pages of UW IMAP, Courier IMAP and Cyrus IMAP (see Resources) to decide which is the best fit for your environment. If your choice is different from mine, I hope some of the concepts in the rest of this article still are helpful to you.
As you know, I'm a big fan of binary packages due to the version control and patch management features provided by a good package manager. To my thinking, the major distributions' package managers all are quite good. Accordingly, I recommend you install Cyrus IMAP from your distribution's update service or installation media if at all possible. You also need Cyrus SASL, an authentication back end Cyrus IMAP requires. SMTP AUTH also uses this, so you already may have it installed.
Thus, in SuSE 8.2 the RPMs you need are cyrus-imapd and cyrus-sasl2. In Debian 3.0, you need the deb packages cyrus-common, cyrus-imapd, libsasl2 and sasl2-bin. Both SuSE and Debian users should be aware that earlier versions of your respective distributions may have Cyrus SASL packages based on old (pre-v2.0) versions of Cyrus SASL. The method of authenticating Cyrus IMAP against LDAP that I'm about to describe depends on SASL v2.0 or later, however. If your distribution version has a pre-2.0 SASL package, you may need to obtain and compile Cyrus SASL source code (available at ftp.andrew.cmu.edu/pub/cyrus-mail).
For Red Hat 9.0, you have to do a little more work than you do for the latest versions of SuSE or Debian, because Red Hat hasn't provided Cyrus IMAP packages since Red Hat 7.1. You should install the RPMs cyrus-sasl, cyrus-sasl-plain and cyrus-sasl-md5, which are part of the standard Red Hat 9.0 distribution. But, you need to get Cyrus IMAP itself in the form of an SRPM from home.teleport.ch/simix (graciously maintained and provided by Simon Matter in Switzerland).
If you've never dealt with source RPM (SRPM) files before, don't worry: the command to build a binary RPM from an SRPM is simply rpm --rebuild [--target yourarch] srpm.name.src.rpm, where srpm.name.src.rpm is the name of your SRPM file, and yourarch is your machine's architecture (such as i386, i586, i686). For example, when I ran this command on my Pentium III server I used rpm --rebuild --target i686 cyrus-imapd-2.1.12-7.src.rpm. Although the --target setting is optional, if you're going to have a large IMAP user database, optimizing Cyrus IMAP for your CPU type reportedly yields noticeable speed improvements over the default i386 build.
rpm then automatically compiles several new binary RPMs, customized for your local system architecture. These RPMs are written into /usr/src/redhat/RPMS/ (the precise subdirectory being whatever you specified after --target or i386/ by default). These RPMs are cyrus-imapd, cyrus-imapd-utils, cyrus-imapd-devel and perl-Cyrus. Install them with the rpm -Uvh filenames command.