Installing Courier IMAP On Westhost VPS

WARNING: Use at your own risk. Following any of these procedures could cause problems with your VPS account. I don’t claim to be an expert on this, I just kept working at it (ugh, like for a whole weekend) until I got it to work. I have only been using this setup for a couple of days, but so far so good. There may be better ways of installing an IMAP server, and there may be better IMAP servers. This just happens to be the one I found. Please email me if you find any errors in this document, or have any suggestions.

-webmaster at mountcrosby dot org-

It’s actually not all that difficult to install courier-imap, all told. However, there are some things that threw me for a loop. I’m not an expert at compiling and installing Linux applications. I am quite familiar with Linux/Unix in general, however. This document should start you in the right direction toward getting IMAP working on Westhost (maybe other VPSs too). One thing you have to know, is that although VPS users have “root equivalent” permissions (although, it’s really not EQUIVALENT to root, is it?), there are directories we cannot muck with, like /usr/local. I install everything into something like /usr/mylocal. Everything in this document will be installed there, or a subdirectory.

I found the installation documents from courier to be a bit lacking in description. They are OK for reference. To use courier-imap, you have to first compile/install courier-authlib, which does the authentication. According to the documentation, these used to be a single app, but are now split up (maybe that adds to the confusion). Most of the documentation I found here:

You can get the latest sources here:

After you have downloaded the sources uncompress them and untar them:

$ bunzip2 courierauthlib-0.55.20050407.tar.bz2
$ bunzip2 courier-authlib-0.55.20050407.tar.bz2
$ bunzip2 courier-imap-4.0.2.tar.bz2
$ tar -xvf courier-authlib-0.55.20050407.tar
$ tar -xvf courier-imap-4.0.2.tar

1.1 Compiling courier-authlib

See quotes from install document below:

VARIABLE=value

Environment variables may be set either before running the configure script, or by providing the environment variables as parameters to the configure script. Example: ./configure --with-mailuser=mail --with-mailgroup=mail CC=/opt/fsf/bin/gcc LDFLAGS=-L/opt/fsf/lib MAKE=gmake

http://www.courier-mta.org/authlib/?INSTALL.html

This configure script descends from the old authentication library that was included in the older Courier, Courier-IMAP, and SqWebMail packages. As such, it also has many other undocumented options that manually disable specific authentication modules. These options are no longer officially documented. Individual modules can be disabled after installation, by editing the authdaemonrc configuration file.

http://www.courier-mta.org/authlib/?INSTALL.html The first time I tried to compile authlib, I found that I needed the two packages listed in the sources above (PostgreSQL and gdbm). Those were easy to compile to /usr/mylocal (just a matter of --prefix). After those were installed, compiling courier-authlib was relatively easy. I need to specify extra include paths to the compiler, because my includes aren’t in /usr/local/include.

$ cd courier-authlib-0.55.20050407
$ ./configure --prefix=/usr/mylocal/courier-authlib CPPFLAGS=-I/usr/mylocal/include --with-authshadow
$ make
$ make install
$ make install-configure
$ emacs /usr/mylocal/courier-authlib/etc/authlib/authdaemonrc

I found through trial and error, that although the install document seems to hint that individual modules do not need to be en/disabled at compile time, it is necessary to use –with-authshadow to get shadow password authentication compiled in. It may also be possible with options to remove the requirement for PostgreSQL and gdb.

Editing authdaemonrc

I replaced the original with mine, in order to only use authshadow.

##NAME: authmodulelist:2
# The authentication modules that are linked into authdaemond. The
# default list is installed. You may selectively disable modules   simply
# by removing them from the following list. The available modules you
# can use are: authuserdb authshadow authpgsql authldap authcustom authpipe
#authmodulelist="authshadow authpgsql authldap authcustom authpipe" #original
authmodulelist="authshadow" #mine

Next I started and tested the daemon likey so:

$ /usr/mylocal/courier-authlib/sbin/authdaemond start
$ /usr/mylocal/courier-authlib/sbin/authtest <username>

Authentication succeeded.
     Authenticated: <username>  (system username: <username>)
    Home Directory: /
           Maildir: (none)
             Quota: (none)
Encrypted Password: blahblahblah
Cleartext Password: (none)
           Options: (none)
$

1.2 Compiling courier-imap

There are a couple tricks to compiling courier-imap. Two libraries must be included in CPPFLAGS. The COURIERAUTHCONFIG variable must be set, because courier-authlib is not in the normal place. –disable-root-check is also needed. I have to admit I am not sure what the consequences of compiling as root are. ./configure fails if you try to run it without --disable-root-check. The only check I saw ./configure doing was checking to see if /etc/ was writable to the current user. It is for the VPS user, so ./configure seems to assume you are root. I ignored this warning/error, after I found the disable switch.

$ ./configure --prefix=/usr/mylocal/courier-imap COURIERAUTHCONFIG=/usr/mylocal/courier-authlib/bin/courierauthconfig CPPFLAGS="-I/usr/mylocal/courier-authlib/include -I/usr/mylocal/include" --disable-root-check
$ make
$ make install-strip
$ make check
$ make install-configure
$ emacs /usr/mylocal/courier-imap/libexec/imapd.rc

make check actually should pass!

If you run /usr/mylocal/courier-imap/libexec/imapd.rc start without any modification, it will not do anything but spit out the environment variables. I’m guessing it has something to do with a difference between /bin/bash and /bin/sh. imapd.rc expects to be running under sh, but on Westhost, sh is actually bash. This is just my guess, but the solution is to get rid of the /bin/env -i command in the script. I am not familiar with /bin/env, but according to the man pages, it will either print the environment, or if used with -i, it will execute a given command with no environment. Getting rid of it here seems to work OK. imapd doesn’t seem to be confused by the extra environment variables it is getting. Make this change in /usr/mylocal/courier-imap/libexec/imapd.rc:

#/bin/env -i /bin/sh -c " set -a ; #original
/bin/sh -c " set -a ; #mine

You will need to make a Maildir/ directory for whatever users will be using IMAP. I’m not sure, but you may even need to have some real mail in it for the following test to work. I think there are utilities to create Maildirs, but basically it is just a directory which stores each mail as a file, and uses subdirectories for different mailboxes. See the procmail section below for more details (you may need to complete that section before the following test works fully).

No if you want, you can run:

$ /usr/mylocal/courier-imap/libexec/imapd.rc start
[/etc/rc.d/rc0.d]$ telnet yourdomain.tld 143
Trying x.x.x.x...
Connected to yourdomain.tld.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION STARTTLS] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc.  See COPYING for distribution information.
a login <username> <password>
a OK LOGIN Ok.

1.3 Starting IMAP Automatically

I believe I did this correctly, but I don’t know anything about the rc directory. I just linked the imap and authlib startups into the rc0.d directory. Everything seems to restart when I restart the VPS.

/etc/rc.d/rc0.d:
lrwxrwxrwx  K100courier-authlib -> S100courier-authlib
lrwxrwxrwx  K110courier-imapd -> S110courier-imapd
lrwxrwxrwx  K20httpd -> ../init.d/httpd
lrwxrwxrwx  S100courier-authlib -> /usr/mylocal/courier-authlib/sbin/authdaemond
lrwxrwxrwx  S110courier-imapd -> /usr/mylocal/courier-imap/libexec/imapd.rc
lrwxrwxrwx  S80httpd -> ../init.d/httpd

1.4 Modifying etc/procmailrc for Maildirs

Procmail is pretty arcane, and difficult to get started with. Here are some good sites for reference:

Procmail on westhost dumps user mail into /var/mail/<username> in mbox format. courier-imap uses Maildirs format. Luckily procmail is capable of delivering mail in Maildirs format simply by putting a trailing “/” on the end of the directory name you want to use.

You will want to create a Maildir/ ($HOME/Maildir/) directory for all of your users. There is a (many, more too, probably) utility to convert mbox-style mail to Maildirs/ (Converting Mbox mailboxes to Maildir format). As stated above, I think there are utilities to generate Maildirs/ too. But, if you create the $HOME/Maildir/ directory in the appropriate home directory (/ftp/pub/<username>, or / for the ssh user), procmail will fill it in correctly when mail comes in. IMPORTANT NOTE: the ssh user (the one you log in via ssh with) will not be able to use courier-imap, at least not the way courier-imap is configured by default. The home directory of that user is /, and the “sticky bit” is set in that directory. courier-imap will not work in that users Maildir/ directory. I don’t use that user for mail, so I don’t care.

Your /ect/procmailrc probably looks something like this:

# Added By HostDir
VERBOSE = "no"
LOGABSTRACT = "no"
SHELL = "/bin/sh"

RESIDUE = `/bin/procmail_checker  $DEFAULT $LOGNAME 2>/dev/null`
:0
* ? test $RESIDUE != "unlimited"
{
 :0
 * > $RESIDUE
 {
    LOGFILE=/proc/self/fd/2
    LOG="554 - Mailbox quota exceeded by $LOGNAME
  "
    EXITCODE=69
    :0
    /dev/null
 }
}

I modified my /etc/procmailrc file as follows:

# Added By HostDir
VERBOSE = "on"
SHELL = "/bin/sh"
LOGABSTRACT = "all"
LOGFILE = "/var/log/procmail.log"

:0 c:
* ? test ! -r $HOME/.procmailrc
$HOME/Maildir/

RESIDUE = `/bin/procmail_checker  $DEFAULT $LOGNAME 2>/dev/null`
:0
* ? test $RESIDUE != "unlimited"
{
 :0
 * > $RESIDUE
 {
    LOGFILE=/proc/self/fd/2
    LOG="554 - Mailbox quota exceeded by $LOGNAME
  "
    EXITCODE=69
    :0
    /dev/null
 }
}

The first 3 changes simply log verbosely into the file specified. I found this very helpful in debugging procmail changes. I just hacked my way through the procmail configuration, so I’ll do the best I can at explaining it. The second change is a procmail test which will deliver mail to $HOME/Maildir/ (the default Maildir for a user) in the Maildir format. :0 starts the test. c: tells procmail to continue, even if this test matches. :c here will cause mail to be delivered to the default Westhost mailboxes(/var/mail/<username>), even if the procmail test passes, and mail is delivered also in $HOME/Maildir/. The actual conditional is whether $HOME/.procmailrc exists. If the local user does not have a .procmailrc, this global /etc/procmailrc will deliver a copy of the mail to their Maildir.

This /etc/procmailrc delivers mail to both places, so the old pop3 access will work, and the new IMAP access will work. BUT, there will be copies of every mail in each place. I just did this for testing purposes to make sure IMAP works, before making the switch (by gettng rid of the c: in the test for instance).

1.5 A local .procmailrc

I have different aliases pointing to one of my email accounts so I can easily shut off an address if spam starts to show up on it. I like to have these aliases filtered into different mailboxes. This is even “easier” than it used to be now with Maildirs, procmail and courier-imap. Here is a sample .procmailrc. Because of the test above, this .procmailrc, overrides the default Maildirs delivery I added in /etc/procmailrc.

:0 c
{
:0
* ^TO_/(alias1|alias2|alias3)
#* MATCH ?? ()/[^@]+
{
  BOX = `echo "$MATCH" | tr [A-Z] [a-z]`

  :0
   /ftp/pub/<username>/Maildir/.$BOX/
}

:0
/ftp/pub/<username>/Maildir/

This .procmailrc separates mail to different “To:” addresses (my aliases) to different Maildirs mailboxes ($HOME/Maildir/alias1, $HOME/Maildir/alias1, etc…). The last test delivers the mail to the default inbox if it does was not sent to a known alias.

Leave a Reply