Courier-IMAP + Maildrop + QMail + Userdb + Virtual Domains HOWTO
Alex Porras ( alex ( at ) skander.net )
A comprehensive guide to installing, configuring, and running courier-imap with maildrop and qmail, using the courier-imap ``large server farm'' approach.
This document attempts to outline in detail the steps to configure a large scale email service using courier-imap, maildrop, and qmail. While the documentation for setting up courier-imap is sufficient for standard setups, IMHO, it does not go into enough detail as to how to implement the ``large server farm'' setup. I also had a pretty hard time finding documentation for getting the other components work with it.
courier-imap's authuserdb authentication module will be used for the management of virtual users, and courier-imap's authshadow authentication method will also be used so that real users can still receive email.
The sections detailing actual installation instructions are based on (verbatim at times) from documentation from the 3 packages, as well as from ``Life With Qmail'' ( http://www.lifewithqmail.org ), all which provided excellent documentation for installation, thus I did not see the need to reinvent the wheel there. My main goal was to provide additional documentation to help configure the three packages together.
This HOWTO was intended to be read chronologically. I tried not to be too lazy and made attempts to make it so you could read sections on their own, but I know that I'm still lazy nevertheless.
This document assumes that your system is using shadow passwords for real users. If that's not the case, then real users will not be able to use IMAP (which may or may not be what you desire). This should not have any effects on virtual user management described in this document.
This document is also pretty biased for Linux users, specifically the Red Hat distribution. If you're using something else, I'm going to assume you know how to execute the proper commands if they differ from what's in this document.
I'm still learning quite a bit about each individual package, so I can't say this is the best way to do this out there; it is only the best way I've found myself through lots of research and painful testing. I assume no risk or liability from any loss/damage caused to your system.
This document is copyrighted (c) 2001 Alex Porras and is distributed under the terms of the Linux Documentation Project (LDP) license, stated below.
Unless otherwise stated, Linux HOWTO documents are copyrighted by their respective authors. Linux HOWTO documents may be reproduced and distributed in whole or in part, in any medium physical or electronic, as long as this copyright notice is retained on all copies. Commercial redistribution is allowed and encouraged; however, the author would like to be notified of any such distributions.
All translations, derivative works, or aggregate works incorporating any Linux HOWTO documents must be covered under this copyright notice. That is, you may not produce a derivative work from a HOWTO and impose additional restrictions on its distribution. Exceptions to these rules may be granted under certain conditions; please contact the Linux HOWTO coordinator at the address given below.
In short, we wish to promote dissemination of this information through as many channels as possible. However, we do wish to retain copyright on the HOWTO documents, and would like to be notified of any plans to redistribute the HOWTOs.
If you have any questions, please contact linux-howto@metalab.unc.edu
Version info: '$Id: courier_imap_maildrop_qmail_virtualdomains_howto.pod,v 1.28 2004/09/11 22:13:06 alex Exp $'
The latest version number of this document can be found at http://www.skander.net/docs/email
You can see the changelog from CVS here: http://www.skander.net/docs/email/CHANGELOG
In this version I have the pleasure of acknowledging:
I would really really really like to hear your comments on this document. I've learned quite a lot from my own research, but I've also learned some good things from those of you who have written. Please send your additions, corrections, comments and criticisms to my address (found in the AUTHOR section).
If you used this HOWTO to set up a server in a commercial environment (i.e. you made money with it), maybe you could give me a little 'thanks' by sending me something from my Amazon wish list:
http://www.amazon.com/o/registry/132WQY7VWQ5O3
If anyone's up to this task, please let me know!
In this document, I'll refer to UNIX users of a machine as real users (the kind that you create with the adduser or useradd commands). I'll use the term virtual users for those whose purpose is for email functionality only.
I'll also include references by using the [n] convention. For example, if you see something like this following a word[12], it means that there is a matching item in the REFERENCES section with pointers for additional information.
This part took the longest for me read and learn about, so I hope this
will help others understand what the heck happens with qmail when an email
comes in. Here is the single most important fact that helped me
understand this: there is a difference between the user that will
*HANDLE* delivery of an email and the user who will actually *RECEIVE*
it. Qmail will perform several steps to figure out what real user is
supposed to handle delivery of an email. After that, file(s) in that
user's home directory will specify how (and/or to whom) to deliver the
email message.
Let's say my local machine's hostname is ``mybox.example.com''. In qmail, this means that there needs to be an entry in /var/qmail/control/locals for that domain so qmail will treat it as such. Now, on this box, there is a real user called ``betty''. Let's say that an email comes in for ``betty@mybox.example.com''. Qmail now needs to figure out who is going to handle delivery of the email. Here's what happens in a nutshell[10]: since it's a local domain, qmail will search for users using the local part of that address, i.e. ``betty''. Qmail first checks the /var/qmail/users/assign file for any entries that match ``betty'' (in one of several ways)[12]. I don't want to go into the details of that file here because we won't be using it, so let's assume that I didn't create a /var/qmail/users/assign file. If qmail doesn't find any matches in that file, it then checks the /etc/passwd file [14] for a user ``betty''. If none is found there, then qmail goes to its last resort and will let the real user ``alias'' handle it. The ``alias'' user should have been created when qmail was installed, so it should always be present for qmail to use as a last resort.
All that work was done simply to figure out what real user will handle delivery of the email. Now that qmail has figured that out, the question is, how is this email to be delivered? The answer is via a .qmail file located in that user's home directory[16]. In our example, let's say that ``betty'' was not found in the /var/qmail/users/assign or /etc/passwd file, so the ``alias'' user will handle delivery. Qmail will search for a file in alias's home directory called .qmail-betty for delivery instructions. If that doesn't exist, it will try a few default variations, including (and most notably) .qmail-default. If that doesn't exist either, qmail will deliver using its default delivery instructions. These are specified in /var/qmail/rc when qmail is first installed.
Whatever is specified in those .qmail files (or in the default delivery if no .qmail files exist) determines what happens to the email. They're pretty flexible--you can specify a forward address, run programs, deliver to mailboxes or maildirs, etc. It's perfectly OK to not have any .qmail files if the default delivery for that user is what's wanted. In many cases, you want the default delivery to be the norm, and .qmail files to be the exception. Here are some examples of .qmail files from the dot-qmail man page:
# forward my email &me@new.job.com
# deliver to a maildir in my home directory # (the slash at the end is required) ./Maildir/
# deliver to a mbox (do not put a slash at the end) ./mbox
Now, even though there are times that the user who is responsible for handling email delivery is the same as the user who will receive it, as I mentioned before, this is not always the case--especially when talking about virtual domains/users.
I'm still learning a bit about how this works, but I think I mostly got this down, so I'll include it now.
Qmail handles virtual domains through the /var/qmail/control/virtualdomains file. Let's say again that my local machine's hostname is ``mybox.example.com'', and I want to host a virtual domain called ``virtual.example.com'', which means that I must add that domain to qmail's /var/qmail/control/virtualdomains file. Here's what that entry looks like:
virtual.example.com:virtual-example-com
(Note: ``virtual-example-com'' is just something I picked because that's a convention I follow; you can write whatever you want to the right of the colon.)
Now, I know that entry looks funny, but just bear with me here. An email comes in for ``flo@virtual.example.com''. Here's what happens in a nutshell: qmail notices that virtual.example.com is in its /var/qmail/control/virtualdomains file, so it rewrites ``flo@virtual.example.com'' to ``virtual-example-com-flo@virtual.example.com''. Boy, does that look silly. Now, qmail needs to figure out what real user will handle delivery of this email. From this point on, qmail goes through the same logic as it does for local user deliveries, except this time, the local part of the address is now ``virtual-example-com-flo'', instead of just ``flo''. If qmail finds no matches in either /var/qmail/users/assign and /etc/passwd, it will resort to letting the real user ``alias'' handle it. Now, instead of looking for .qmail-flo, qmail will look for .qmail-virtual-example-com-flo for delivery instructions. If the .qmail-virtual-example-com-flo does not, exist, qmail then looks for .qmail-virtual-example-com-default, then .qmail-default, and finally resort to the default delivery for instructions.
In other words, the entry in the /var/qmail/control/virtualdomains file has changed the local part of the email, so now the mapping to .qmail files is different than it would have been had this been a local domain instead of a virtual domain.
Once it finds the real user to handle delivery, the same syntax for .qmail files apply as described in the LOCAL USER DELIVERIES section.
Now that you (hopefully) understand the delivery process, let's put our knowledge to the test and install the packages.
The following environment and tarballs were used for installation when writing this document.
Do not do any of the installation steps in this section as root unless specified. If a step needs to be done as root, it will be specified in that step.
First, download the courier-imap package from:
http://ftp1.sourceforge.net/courier/courier-imap-1.4.3.tar.gz
As an FYI, the homepage for courier-imap is:
http://www.courier-mta.org/imap/
Before installing the courier-imap package, a real user needs to be created. This is the user that I decided would take care of delivering email for virtual users, thus the home directory of this user will be the base directory where all the virtual user's mail will be kept.
As root:
useradd courier -d /home/courier
Unpack the source tarball:
tar -xvzf courier-imap-1.4.1.tar.gz cd courier-imap-1.4.1
Run the configure script. Since I only want to use the authuserdb and authshadow authentication modules, I opted to NOT include the others.
./configure \
--without-certdb \
--without-authpam \
--without-authldap \
--without-authpwd \
--without-authmysql \
--without-authpgsql \
--without-authvchkpw \
--without-authcram \
--without-authdaemon \
--without-authcustom
Compile sources:
make make check
If make check fails, you must fix the problem before continuing. Otherwise, install sources (as root):
umask 022 make install-strip make install-configure
If make install-strip fails, use make install instead.
Now we want to install the startup script (as root):
cp /usr/lib/courier-imap/libexec/imapd.rc /etc/rc.d/init.d/courier-imap
For Red Hat systems, you can add some stuff to that rc script to make it work with chkconfig.
# courier-imap This shell script takes care of starting and stopping # courier-imap. # # chkconfig: 2345 80 30 # description: courier-imap is an email server that supports imap. # processname: couriertcpd
You can download an already modified version of this file at:
http://www.skander.net/docs/email/config/etc/rc.d/init.d/courier-imap
Save it as /etc/rc.d/init.d/courier-imap
Set up the right ownership and permissions for it:
chown root.root /etc/rc.d/init.d/courier-imap chmod 755 /etc/rc.d/init.d/courier-imap
Now we can use chkconfig to make this rc script start courier-imap at boot time (as root):
/sbin/chkconfig courier-imap on
Start the server (as root):
/sbin/service courier-imap start
Let's test connecting to the server. This requires telnet to be installed:
telnet localhost 143
You should see something alongs the lines of:
Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. * OK Courier-IMAP ready. Copyright 1998-2002 Double Precision, Inc. See COPYING for distribution information.
If do see a message like above, then you are good to go. You can type this to log out:
1 logout
You should even be able to set up an IMAP client to connect to your server as a real user.
Finally, we need to set/modify some environment variables: PATH and MANPATH. For Red Hat distributions (and possibly others), edit /etc/man.config (as root) and add the following line under the other entries that start with MANPATH:
MANPATH /usr/lib/courier-imap/man
Next, add the following under the entries that start with MANPATH_MAP:
MANPATH_MAP /usr/lib/courier-imap/bin /usr/lib/courier-imap/man MANPATH_MAP /usr/lib/courier-imap/sbin /usr/lib/courier-imap/man
We can implement the PATH changes to all users by adding two scripts to /etc/profile.d (one for bash users and one for (t)csh users):
http://www.skander.net/docs/email/config/etc/profile.d/courier-imap.sh
Save it as /etc/profile.d/courier-imap.sh.
http://www.skander.net/docs/email/config/etc/profile.d/courier-imap.csh
Save it as /etc/profile.d/courier-imap.csh.
I'm not sure if this is necessary, but I did it anyway to match the rest of the files that were there:
chmod 755 /etc/profile.d/courier-imap.csh /etc/profile.d/courier-imap.sh chown root.root /etc/profile.d/courier-imap.csh /etc/profile.d/courier-imap.sh
Installation of courier-imap is complete.
First, download the maildrop package from:
http://ftp1.sourceforge.net/courier/maildrop-1.3.7.tar.gz
As an FYI, the homepage for maildrop is:
http://www.flounder.net/~mrsam/maildrop/
Unpack the source tarball:
tar -xvzf maildrop-1.3.7.tar.gz cd maildrop-1.3.7
Run the configure script:
./configure --enable-userdb --enable-syslog=1
Edit maildrop/config.h, and make the following changes:
Compile sources:
make
Install sources (as root):
make install-strip make install-man
If make install-strip fails, use make install instead.
Finally, despite the fact that the documentation states that maildrop is installed suid and sgid, such was not the case when I installed it. Check yours by getting a listing of maildrop:
ls -l /usr/local/bin/maildrop
-rwxr-xr-x 1 root mail 139604 Jan 4 15:57 /usr/local/bin/maildrop
The line above is what I saw on my installation. If it's the same way on yours, type the following (as root) to make it suid and sgid:
chmod +s /usr/local/bin/maildrop
It should now look like this:
-rwsr-sr-x 1 root mail 139604 Jan 4 15:57 /usr/local/bin/maildrop
Installation of maildrop is now complete.
Note: It is strongly recommended that you stop and uninstall sendmail before installing qmail. I know some of the qmail docs say it's ok to keep sendmail, but if you don't need it, save yourself some trouble later and uninstall it now.
Installation of qmail requires a few other packages as well. Download the qmail and related packages from:
http://cr.yp.to/software/qmail-1.03.tar.gz
http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
If above links are bad, it most likely means that the version have been updated. In that case, go to this link to find new versions:
As an FYI, the homepage (or at least one of the homepages) for qmail is:
The ucspi-tcp and daemontools packages are written by the same author, so you can also find information about them on the qmail website.
Create the qmail home directory (as root):
mkdir /var/qmail
Add real users and groups that will be used by qmail (as root):
groupadd nofiles useradd -g nofiles -s /bin/true -d /var/qmail/alias alias useradd -g nofiles -s /bin/true -d /var/qmail qmaild useradd -g nofiles -s /bin/true -d /var/qmail qmaill useradd -g nofiles -s /bin/true -d /var/qmail qmailp groupadd qmail useradd -g qmail -s /bin/true -d /var/qmail qmailq useradd -g qmail -s /bin/true -d /var/qmail qmailr useradd -g qmail -s /bin/true -d /var/qmail qmails
Install sources:
qmail:
tar -xvzf qmail-1.03.tar.gz cd qmail-1.03
as root:
umask 022 make setup check ./config
If ./config above fails, use ./config-fast the.full.hostname (of
course, replace the.full.hostname with your hostname).
ucspi-tcp:
tar -xvzf ucspi-tcp-0.88.tar.gz /usr/src/ucspi-tcp-0.88 make
as root:
make setup check
daemontools:
tar -xvzf daemontools-0.76.tar.gz cd admin/daemontools-0.76
as root:
./package/install
Now we need to set up a lot of config files.
Download http://www.skander.net/docs/email/config/var/qmail/bin/qmailctl
Save it as /var/qmail/bin/qmailctl. This is the qmail start/stop script (among other things).
Type the following commands to finish setting up the above files:
chmod 755 /var/qmail/bin/qmailctl ln -s /var/qmail/bin/qmailctl /usr/bin ln -s /var/qmail/bin/qmailctl /etc/rc.d/init.d/qmail /sbin/chkconfig qmail on
Now were going to set up the file that tells qmail what its default delivery is (read OVERVIEW OF HOW QMAIL HANDLES INCOMING EMAILS). This can be done by creating a file called /var/qmail/rc with instructions. Qmail comes with some different scripts in /var/qmail/boot that you can choose from (unless you want to make your own) and copy to /var/qmail/rc. We want the default delivery to be procmail, so we're going to use /var/qmail/boot/proc. I'm just going to make a symlink to that script:
ln -s /var/qmail/boot/proc /var/qmail/rc chown root.qmail /var/qmail/rc
Now let's create some more directories for some other config files:
mkdir -p /var/qmail/supervise/qmail-send/log mkdir -p /var/qmail/supervise/qmail-smtpd/log
Now let's download more config files:
The next two files have instructions for telling daemontools how to run qmail-send and qmail-smtpd:
Download http://www.skander.net/docs/email/config/var/qmail/supervise/qmail-send/run
Save it as /var/qmail/supervise/qmail-send/run.
Download http://www.skander.net/docs/email/config/var/qmail/supervise/qmail-smtpd/run
Save it as /var/qmail/supervise/qmail-smtpd/run.
The next two files have instructions for telling daemontools how to log output of qmail-send and qmail-smtpd:
Download http://www.skander.net/docs/email/config/var/qmail/supervise/qmail-send/log/run
Save it as /var/qmail/supervise/qmail-send/log/run.
Download http://www.skander.net/docs/email/config/var/qmail/supervise/qmail-smtpd/log/run
Save it as /var/qmail/supervise/qmail-smtpd/log/run.
This next file is used by /var/qmail/supervise/qmail-smtpd/run. I believe this file tells qmail-smtpd how many concurrent incoming connections it can have.
Download http://www.skander.net/docs/email/config/var/qmail/control/concurrencyincoming
Save it as /var/qmail/control/concurrencyincoming.
Type the following commands to finish setting up the above config files:
chmod 755 /var/qmail/supervise/qmail-send/run chmod 755 /var/qmail/supervise/qmail-send/log/run chmod 755 /var/qmail/supervise/qmail-smtpd/run chmod 755 /var/qmail/supervise/qmail-smtpd/log/run
Set up the log directories:
mkdir -p /var/log/qmail/smtpd chown qmaill /var/log/qmail /var/log/qmail/smtpd
Now we need to tell daemontools to run qmail-send and qmail-smtpd. daemontools constantly checks the /service directory for scripts to run. So we want to link the scripts we downloaded into that directory:
ln -s /var/qmail/supervise/qmail-send /var/qmail/supervise/qmail-smtpd /service
After doing this, you should be able to check the process list and see qmail-send and qmail-smtp running! Actually, you should see a few more things running. Here's a chunk of my process list, to give you and idea:
UID PID PPID C STIME TTY TIME CMD
root 32738 32481 0 14:46 ? 00:00:00 supervise qmail-send root 32739 32481 0 14:46 ? 00:00:00 supervise log root 32740 32481 0 14:46 ? 00:00:00 supervise qmail-smtpd root 32741 32481 0 14:46 ? 00:00:00 supervise log qmails 32742 32738 1 14:46 ? 00:00:00 qmail-send qmaill 32743 32739 0 14:46 ? 00:00:00 /usr/local/bin/multilog t /var/log/qmail qmaill 32744 32742 0 14:46 ? 00:00:00 splogger qmail root 32745 32742 0 14:46 ? 00:00:00 qmail-lspawn |preline procmail qmaill 32746 32741 0 14:46 ? 00:00:00 /usr/local/bin/multilog t /var/log/qmail/smtpd qmaild 32747 32740 0 14:46 ? 00:00:00 /usr/local/bin/tcpserver -v -R -l 0 -x /etc/tcp.smtp.cdb -c 20 -u 1004 -g 1003 0 smt qmailr 32750 32742 0 14:46 ? 00:00:00 qmail-rspawn qmailq 32751 32742 0 14:46 ? 00:00:00 qmail-clean
Now we need to tell qmail-smtp who can send mail (a.k.a. relay) through it [50]. This is specified in the /etc/tcp.smtp file. Entries look like this:
127.:allow,RELAYCLIENT=""
That tells qmail-smtp to allow clients in the 127. network range to send mail through it. Chances are you also have a private network you want to allow to send mail through qmail-smtp. For example, if your network is 192.168.123.xxx, your tcp.smtp file could look like this:
127.:allow,RELAYCLIENT="" 192.168.123.:allow,RELAYCLIENT=""
Once you make changes to the tcp.smtp file, you need to let qmail-smtp know by typing this command:
qmailctl cdb
There are three aliases that need to be created for our email system (if not most email systems) that are pretty much mandatory: the ``postmaster'', ``mailer-daemon'', and ``root'' aliases. The first two are where emails go when they bounce and such, and the ``root'' alias because the assumption is that you' re not always using your computer as root, but you should still get system related emails. The contents of these alias files will most likely need to be a valid local account (i.e. ``betty'') or a valid email address (i.e. ``betty@someotherbox.bar''). Using ``betty'' as an example:
echo betty > /var/qmail/alias/.qmail-postmaster chmod 600 /var/qmail/alias/.qmail-postmaster ln -s /var/qmail/alias/.qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon ln -s /var/qmail/alias/.qmail-postmaster /var/qmail/alias/.qmail-root chown alias.nofiles /var/qmail/alias/.qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon
Note that since I wanted ``betty'' to get emails for ``postmaster'', ``mailer-daemon'', and ``root'', I just made a symlinks to .qmail-mailer-daemon.
Lastly, replace any existing sendmail with the qmail version (note that the first line is not necessary if you uninstalled sendmail when instructed earlier):
mv /usr/sbin/sendmail /usr/sbin/sendmail.old ln -s /var/qmail/bin/sendmail /usr/sbin
Installation of qmail is just about complete. Actually, qmail should at this point be able to receive email to real users and deliver it using procmail. Let's test that real quick. This is assuming that the program mail is installed. Let's send an email to the real user ``betty'':
echo "hello betty!" | mail betty
tail'ing the /var/log/maillog as root, I see the following:
Mar 26 14:54:45 mybox qmail: 1017176085.243683 new msg 36331 Mar 26 14:54:45 mybox qmail: 1017176085.243793 info msg 36331: bytes 227 from <alex@mybox.example.com> qp 426 uid 0 Mar 26 14:54:45 mybox qmail: 1017176085.252370 starting delivery 5: msg 36331 to local betty@mybox.example.com Mar 26 14:54:45 mybox qmail: 1017176085.252475 status: local 1/10 remote 0/20 Mar 26 14:54:45 mybox qmail: 1017176085.275343 delivery 5: success: did_0+0+1/ Mar 26 14:54:45 mybox qmail: 1017176085.275450 status: local 0/10 remote 0/20 Mar 26 14:54:45 mybox qmail: 1017176085.275475 end msg 36331
I can then log in as betty and check my mail:
[betty@mybox ~]$ mail Mail version 8.1 6/6/93. Type ? for help. "/var/mail/betty": 1 message 1 new >U 1 alex@mybox.exam Tue Mar 26 20:53 12/366
There it is!
Now we are ready to set up virtual domains/users.
When using courier-imap's authuserdb authentication method, the virtual user account info is kept in a different place than their mailstore. According to the ``large server farm'' method in the courier-imap INSTALL doc, the virtual user account information is stored in a file called the userdb file. There is one userdb file for each virtual domain you wish to host that contains all the virtual user account entries for that domain. The userdb files are normally named after the domain they are for, and they are all kept in the /etc/userdb directory. Let's set up that directory now (as root):
mkdir /etc/userdb chmod 700 /etc/userdb chown root.mail /etc/userdb
The virtual users' mail can be placed anywhere on the file system you like (and since we're using courier-imap, that directory can be mounted over nfs). For this document, I chose /home/courier/domains.
Let's set that up now (as root):
mkdir /home/courier/domains chmod 700 /home/courier/domains chown courier.mail /home/courier/domains
Under this directory, there will be other directories, one for each domain, in which the users' mailstore for that domain will reside. Now let's download the .qmail file that we'll use to tell qmail to pass email on to maildrop:
Download http://www.skander.net/docs/email/config/var/qmail/alias/.qmail-maildrop-virtual
Save it as /var/qmail/alias/.qmail-maildrop-virtual.
Next type these commands to set up the correct permissions and ownership:
chmod 600 /var/qmail/alias/.qmail-maildrop-virtual chown alias.nofiles /var/qmail/alias/.qmail-maildrop-virtual
Note that any future .qmail files that are added in this directory will also need to have the same permissions and ownership!
Also note that the steps we just performed in this section only need to be done once, not for each virtual domain you add!
Now we're ready to add virtual domains.
Read VIRTUAL DOMAIN/USER DELIVERIES if you haven't already. This section also assumes that you have DNS set up properly for your virtual domain(s).
Domain management involves making changes to courier-imap and qmail's configurations.
For courier-imap, create a domain directory in the real user's mailstore directory:
mkdir /home/courier/domains/virtual.example.com chmod 770 /home/courier/domains/virtual.example.com chown courier.mail /home/courier/domains/virtual.example.com
Virtual users' mail for the virtual.example.com domain will reside in this directory (each user in his/her own directory).
For qmail, we need to add the domain to /var/qmail/control/rcpthosts, verbatim:
virtual.example.com
This tells qmail-smtpd that it's OK to accept emails for that domain.
Next, we need to add an entry to /var/qmail/control/virtualdomains, which has a special syntax that's explained in the VIRTUAL DOMAIN/USER DELIVERIES section. This file may not exist yet, so you may need to create it. For the entries, I like to follow the convention of changing dots in domains to dashes when adding entries, like this:
virtual.example.com:virtual-example-com
So, for our setup, incoming email for that domain will cause qmail to try and search for .qmail-virtual-example-com-xyz files in /var/qmail/alias. Since this is a virtual domain, we want to pass it on to maildrop, which will be responsible for delivery to the virtual user. The file /var/qmail/alias/.qmail-maildrop-virtual, which you downloaded earlier, has those instructions. So to make this work, we just create a symlink from .qmail-virtual-example-com-default to .qmail-maildrop-virtual:
ln -s /var/qmail/alias/.qmail-maildrop-virtual /var/qmail/alias/.qmail-virtual-example-com-default
Give it the right ownership:
chown alias.nofiles /var/qmail/alias/.qmail-virtual-example-com-default
Now let's look at the .qmail-maildrop-virtual file:
|/usr/local/bin/maildrop -d "${LOCAL}" || exit 77
Not much to it. This basically runs maildrop and passes the username to deliver the email to (the email itself is passed in via STDIN I believe). Anyway, the one thing I want you to note is the use of the LOCAL variable. This is one of the default variables passed into .qmail files [60]. The LOCAL variable contains the part of the email before the '@', so for ``betty@virtual.example.com'', LOCAL would contain ``betty''. However, we're dealing with virtual domains, so ``betty@virtual.example.com'' gets rewritten to ``virtual-example-com-betty@virtual.example.com'' at some point, so the value of LOCAL will actually be ``virtual-example-com-betty'' (phew!). We'll need to remember that when we add virtual users, because those are the values that will be used for virtual account usernames!
To outline the process of adding a user, I'll walk through an example. Note that these steps need to be done as root. I'll use ``betty'' as the login and ``virtual.example.com'' as the domain.
As mentioned before, the virtual user account information and the user mail are kept in separate places.
Let's set up the mail store first:
mkdir /home/courier/domains/virtual.example.com/betty maildirmake /home/courier/domains/virtual.example.com/betty/Maildir chown -R courier.mail /home/courier/domains/virtual.example.com/betty
Next, let's set up the virtual user account information.
If you recall from the OVERVIEW OF HOW QMAIL HANDLES INCOMING EMAILS section, the user that handles delivery of an email can be different than the user that receives the email. In this situation, that will always be the case because the user that the receives the email is a virtual user.
For my setup, I had decided to have the real user ``courier'' handle delivery for all my virtual users, which is why I put the mailstore in /home/courier/domains. So I need to find out what the userid and groupid for the real user ``courier'' are before I can add virtual users (you'll see why later).
One way to do this is to look at the /etc/password file (as root). You can try the command below to just show the line for courier:
grep courier /etc/passwd
And you should get something like this:
courier:x:123:456::/home/courier:/bin/bash
So, for my scenario, the userid is 123 and the groupid is 456. You'll need to know the numbers in your scenario whenever you add virtual users.
Now that we have the userid and groupid, we can add a virtual user. Virtual account information is kept in a file called a userdb file, and each virtual user entry contains at least the following information:
Notice the last two entries in the list above. Those are the two numbers we looked up for the real user ``courier''.
The userdb program is used to add virtual users. Here's the syntax
for the command:
userdb -f /path/to/userdbfile \ virtual-users-login \ set uid=123 gid=456 \ home=/home/courier/domains/virtual-domain/virtual-users-login \ mail=/home/courier/domains/virtual-domain/virtual-users-login/Maildir
So for our example with ``betty'', the command should look like this:
userdb -f /etc/userdb/virtual.example.com \ virtual-example-com-betty \ set uid=123 gid=456 \ home=/home/courier/domains/virtual.example.com/betty \ mail=/home/courier/domains/virtual.example.com/betty/Maildir
Remember, the login is ``virtual-example-com-betty'' instead of just ``betty'' because that is what the local part gets rewritten to.
Now set the password for the user. Here we use another command, userdbpw, for encrypting the password before passing it to the userdb program:
userdbpw -md5 | userdb -f /etc/userdb/virtual.example.com \ virtual-example-com-betty \ set imappw
This will prompt you to enter the password for that user twice.
You can combine both steps above into one command:
userdbpw -md5 | userdb -f /etc/userdb/virtual.example.com \ virtual-example-com-betty \ set uid=123 gid=456 \ home=/home/courier/domains/virtual.example.com/betty \ mail=/home/courier/domains/virtual.example.com/betty/Maildir imappw
Finally, run makeuserdb. This creates a file called userdb.dat, which is what is actually read by courier-imap:
makeuserdb
You should now be ready to test logging in as that user with an IMAP email client!
The client settings for the example above would be:
You probably need to read the OVERVIEW OF HOW QMAIL HANDLES INCOMING EMAILS section before doing this.
As a quick recap, if I have a virtual domain ``virtual.example.com'' and I have an entry in /var/qmail/control/virtualdomains like this:
virtual.example.com:virtual-example-com
Then an email coming in for ``betty@virtual.example.com'' will eventually cause qmail to look in the ``alias'' user's home directory for a file called .qmail-virtual-example-com-betty before looking for any other .qmail files. So creating an alias is just a matter of creating that file with the following contents:
&my@forwardaddress.bar
Qmail will find the file and forward the email to that address, instead of taking the next step of looking for .qmail-virtual-example-com-default, which, in our example elsewhere in this document, passed the email on to maildrop.
When we compiled courier-imap, we included the authshadow authentication module so that real users can also use courier-imap. However, real users' mail is being delivered by procmail, and NOT in maildir format, which is OK if you want real users' mail to behave in the traditional sense (i.e. such as the way it behaves in a default Red Hat installation).
Well, let's say ``betty'', who's a real user, decides she wants to receive mail to Maildir format so she can use an IMAP client. It's a simple two step process:
First, she needs to create a file called .qmail in their home directory with the following contents:
./Maildir/
Next, she needs to create a maildir. Assuming she's in her home directory, the command is:
maildirmake Maildir
She should now be able to use her favorite IMAP client to check her email (hopefully her favorite client is not Lookout..errr..Outlook).
As a system administrator, you could create that .qmail file in /etc/skel and then create a maildir there as well and all new real users will be set up for IMAP by default.
Here I have included resources contributed by other helpful folks:
Matthew Farrellee sent me some scripts for userdb management:
10 - qmail-lspawn(8) man page
12 - qmail-users(5) man page
14 - qmail-getpw(8) man page
16 - dot-qmail(5) man page
50 - http://www.palomine.net/qmail/relaying.html
60 - qmail-command(8) man page