qmail-local, which make use of the users/assign file,
actually uses users/cdb. A change to users/assign will
have no effect until /var/qmail/bin/qmail-newu is run and creates
an uptodate cdb file.
- the control/virtualdomains file
Once qmail has accepted the email it needs to know what to do with it.
We've chosen the virtualdomains/users mechanism of qmail to sort things
For each of the domains you want to serve you have to add entries to
the control/virtualdomains file. This file is organized as
lines, containing a mapping from a domain to an id.
For an easier reading and assigning we've chosen to use the name of the
domain as the id.
Note: the id could be any identifier that is kind of unique in
identifying the domain it is mapped to. Choosing the domain name for the
id was our layout decision.
The same rules for domains and subdomains/hosts apply for
control/virtualdomains as they do for control/rcpthosts.
As we want domains and hosts/subdomains to be handled by the same
id the entries in control/virtualdomains look like:
There are cases, where you have various delivery strategies for emails
within one domain. In our example we want to have everything for
example.com to be delivered via POP boxes, except for host some.example.com,
to which email should be delivered via SMTP to a dialin account. So we add
one more line to control/virtualdomains:
In order to make qmail know about your changes to the
control/virtualdomains file you have to send a signal 1 to
the qmail-send process (or restart it).
- the users/assign file
The next step is to actually define where to deliver the email to. This
is done with the users/assign file. Qmail looks up this file
with the id defined above to find a matching entry.
We're using an unique handle for each of our customers and we've organized
the filesystem making use of it. Example Inc. would have been assigned
e.g. a handle of ex1.
All the POP Boxes would physically be found in a directory
and would be named ex1-0000, ex1-0001, ex1-0002, ...
The .qmail control files for example.com would be
located in the directory
Note: Be sure that the above directory and all the .qmail files in
there belong to the appropriate user (in our case popusr) and
that they are neither world nor group writeable
The SMTP deliveries are not organized within this structure, but are
Although it would be no problem to have them in e.g.
/home/popmail/e/ex1/SMTP/some.example.com or another place.
This leads to a users/assign file that looks like:
510 is the UID of the user popusr.
51 is the GID of the user popusr.
ex1 is used by us as an identifier for our customer id.
According to the qmail-users(5) man-page this should be popusr
- Don't forget to have a dot on a line by itself as the last line
in the file.
delivery to POP boxes
For POP users set up the boxes with
$ cd /home/popmail/e/ex1/POP
$ /var/qmail/bin/maildirmake ex1-0000
$ /var/qmail/bin/maildirmake ex1-0001
$ /var/qmail/bin/maildirmake ex1-0002
$ chown -R popusr ex1-0000 ex1-0001 ex1-0002
Then you have to create "mappings" to those Maildirs.
This is done by creating .qmail files. To make qmail deliver all
emails for email@example.com to the POP box ex1-0001 simply
$ cd /home/popmail/e/ex1/DOMAINS/example.com
$ echo "/home/popmail/e/ex1/POP/ex1-0001/" > .qmail-joe
$ chmod 644 .qmail-joe
$ chown popusr .qmail-joe
Be sure to have a trailing slash ("/") after the name of
the POP box directory (.../POP/ex1-0001) in the .qmail
file, to have qmail deliver to a Maildir not to a Mailbox.
As RFC ???? requires the existance of a postmaster address, you
should set up a .qmail-postmaster file for each domain. Either map it
to the appropriate mailbox in that domain or map it to yourself.
You may also want to set up a .qmail-default file for a domain, that
catches all unknown addresses, for which no .qmail file exists. A good
way is to map it to the postmaster address of that domain.
For SMTP deliveries you have some choices:
We've chosen the cron way. For that we've set up the
/home/serialmail/some.example.com/ directory (this is defined
in users/assign above) like the following:
- if you are only backup MX (i.e. it exists an host with a better
MX priority in DNS) then simply add the domain to the
control/rcpthosts file, all else will be handled by qmail
- if you are a relay for a customer (this might be useful if his
mailer is behind a firewall, you are the best MX and so you get
the mails and his mailer does only accept mails from your mailer)
then you additionally have to add entries to the
control/smtproutes file specifying the domain and the
hostname of his mailer:
Again, delivery will be handled by qmail automatically.
- if the customer is connected through a dialup connection (like
assumed for the above some.example.com) the quadratic
retry strategy of qmail is bad for you, because the customer
usually doesn't like to have to be online for a long period of time to
receive his email.
Dan Bernstein's serialmail package
will be your friend in this setup.
You could either have some mechanism to allow the customer
to trigger the delivery (see http://www.qmail.org/
or the qmail mailing list archive
or do it on a regular basis via a script called from cron.
The latter is, however, only usable, if your customers have
static IP addresses.
$ cd /home/serialmail/some.example.com
$ echo "some.example.com" > RELAYHOST
$ /var/qmail/bin/maildirmake ./Maildir
$ chown -R popusr ./Maildir
$ echo "./Maildir/" > .qmail-default
$ chmod 644 .qmail-default
$ chown popusr .qmail-default
For delivery we have a "master script" that starts a "delivery
script" for each directory within /home/serialmail/ with
a grace period of 1 second. The delivery script checks if the
RELAYHOST file is locked. If it is locked there is already a
transfer underway, which has not yet finished. If it is not locked, it
locks the file and checks whether Maildir/new/ contains any
files. If not, it unlocks the RELAYHOST file and exits. If
messages do exist, it starts serialmail, waits for it to complete and
then unlocks RELAYHOST and exits.
Starting the master script from cron every 2 minutes guarantees that
a delivery is attempted every two minutes.