http:// / upgrade-qmr.shtml

Upgrading from qmailrocks 2.2.0

A lot of people seem to be interested in "upgrading" from qmailrocks version 2.2.0 to the current version of my combined patch file. Since qmailrocks is based on an earlier version of my combined patch (a MUCH earlier version,) you might think the process would be fairly easy... not so.

There were a lot of differences between how qmailrocks installs things and how my own scripts set things up. I've had people ask me why qmailrocks did things the way they did when my scripts are so much different- my only response is to remind people that the only thing of mine that qmailrocks actually copied was the qmail combined patch itself- the scripting and the configuration of the other packages all came from other sources.

This page will try to list the differences and explain how to deal with each one.

AUTH Security

The first thing which needs to be explained is that, even though my patch is part of the qmailrocks-2.2.0 package, the final result does not work the way I designed it. This is because qmailrocks installs another patch after mine- the so-called "forcetls" patch. I remember talking to Eric (the maintainer of qmailrocks) on the phone about it, and after examining the patch in detail to see what it actually did, my recommendation was that he not include it when creating a qmailrocks package. Apparently that recommendation was not followed.

The problem is that the AUTH command allows a client to send their userid and password across the internet in what amounts to plain text, and anybody with a packet sniffer in the right place can literally harvest your users' passwords, and then use one or all of them to use your server as an open relay (for spamming.)

I wrote the combined patch to enforce a security policy where the AUTH command would not be advertised (in response to an EHLO command) or accepted from a client unless the connection was secure. It determines the security of the connection using one of two methods- either an internal ssl context exists because the STARTTLS command has been sent and accepted, or en environment variable SSL=1 exists (which should only be set by an SSL-enabled SMTP service.)

I went through the so-called "forcetls" patch, line by line. From the name you would think it had something to do with forcing the client to do STARTTLS... but what it actually does is bypass the lines of code where it looks to see if the connection is secure before including AUTH in the EHLO response, or when handling an AUTH command from the client. The patch has nothing to do with TLS, I don't know why it has the name it does... but it makes your server less secure than it could/should be.

Since that time I have added a way to allow the AUTH command to be used on a non-secured connection, by setting an environment variable. This was meant for people with "internal only" SMTP services, where the SMTP traffic never crosses any un-trusted network segments... or for people who have PHB issues (PHB meaning "pointy haired boss", from the Dilbert cartoons... basically people who are stuck working for clueless managers who don't understand, or care about, security.)

Of course this is not the only difference in the patches, but it seems to be the biggest stumbling block that people run into. If you are using the AUTH command on your server, you should make sure your clients are all using some kind of secure connection (either SSL or STARTTLS) when they send their AUTH command, or the server will not allow it. Again, there is an option to bypass this check, but you should have a very good reason for allowing your users to send their passwords across the net in plain text before you turn it on. Educating your users, or at least changing their options for them, is a better option than "just let them use AUTH without security".

Hopefully you understand this point and don't have to learn it the hard way, like one of my clients did. Somehow, a spammer found out the password for one of his users' mailboxes, and spent four days using his server as a relay before their ISP shut them down to stop the spam. I suspect that the owner of the mailbox was using the same password on everything, and the spammer got their password through some other method, but the user claims that they had a different password for this mailbox- which means the only way the spammer could have gotten it was to somehow sniff the traffic when she checked her mail or used AUTH to send mail. I don't know how likely this is, but I believe in "better safe than sorry."

The other thing that I've seen confuse people is the various interactions between the TLS options, whether or not AUTH is accepted, and whether AUTH is accepted with or without TLS. I have written this page which shows the various combinations of options. The one that seems to confuse people the most is the REQUIRE_AUTH variable- REQUIRE_AUTH=1 means that AUTH will be required to accept ANY incoming mail. If you turn this on, you will not be able to receive normal incoming mail from other servers on the internet. Caveat administrator.

Permissions on vchkpw

qmail was designed as a collection of little tiny programs, each of which does one specific part of the overall "mail server" job, and does it well. The qmail big picture shows how these programs interact with each other. If you haven't seen it yet, you should take a few minutes and go look at it now- it's probably the one thing that helped me to understand qmail as well as I do now. I used to have a printout of all four pages hanging on the wall in my office.

Each of these programs was designed to run as a specific userid, the idea being that each program only had access to those files it actually needed and therefore a bug in any one program couldn't cause damage outside of what that program would normally be involved with.

The qmail-smtpd program handles the server end of an SMTP connection. It was originally designed to run as the userid qmaild. However, the /service/qmail-smtp/run script that qmailrocks installs sets things up so that qmail-smtpd runs as the vpopmail user, which means that a bug in qmail-smtpd (or in any of the programs that it calls, such as qmail-scanner, clamav, or spamassassin) could possibly erase all of your users' mailboxes. Not cool.

My scripts set things up so that qmail-smtpd runs as the qmaild user, as djb originally designed it.

Why did qmailrocks change from djb's standard? qmailrocks sets things up to use vpopmail's vchkpw program to validate any AUTH commands. And in order for vchkpw to read the files which actually contain the passwords (or the MD5 hashes of the passwords, or the file containing login information to a mysql server with that information) it needs to run as the vpopmail user.

At some point in the past, somebody decided that the best way to allow vchkpw to access these files was to run qmail-smtpd as the vpopmail user, and apparently qmailrocks blindly copied that person's "run" script when putting the qmailrocks package together.

There are two alternatives to this, both of which are more secure:

Either option is preferable to making qmail-smtpd, plus all of the child processes it runs, run as the vpopmail user.

tcpserver access control files

Most qmail walk-through documents, qmailrocks included, will have you set up the access control files used by tcpserver with names like /etc/tcp.smtp, and run a tcprules command (if you're using that "qmailctl" script, read it sometime- you will find that it runs the tcprules command for you) to build the /etc/tcp.smtp.cdb file which tcpserver actually uses.

If you are using the "qmailctl" script that qmailrocks gives you, do yourself a favour and learn how to use the underlying commands that it calls for you. At some point in the future you may need to work on a qmail machine which doesn't have "qmailctl" available, but you will always have "svc", "tcprules", "qmail-qread", "qmail-qstat", and the other real commands, because they are part of the daemontools, ucspi-tcp, qmail, and other packages which are installed as part of setting up any qmail server.

Rather than using these names, I keep all of these files in a single /etc/tcp directory. This lets me to keep them all together where I can find them, and also allows me to write a single Makefile and then just type make to rebuild any .cdb files which may need to be rebuilt.

I started doing this because I use tcpserver for several other things which have nothing to do with qmail, and because some of my access control files are built from multiple input files rather than from just a single file.

My scripts are written to assume that the files are all inside this directory. You could change the scripts to look for wherever you keep the files, but you may also want to try it this way- it has ended up being a major time-saver for me. I've at least tried to make it easy to change this for people who are more comfortable keeping the files where they are now- in the service-qmail-smtpd-run script, for example, you only need to change the line which says SMTP_CDB= so that it points to your cdb file.

Permissions on SSL .pem files

The qmailrocks install script creates /var/qmail/control/clientcert.pem as a symbolic link to servercert.pem. I'll be honest, I don't know whether or not this even works under the qmailrocks install, but I do know that if I were to do this on my own server, it would not work- and the only way to make it work would be to make the file world-readable, which opens up a potential security hole on the machine. (Maybe qmailrocks also makes the file world-readable?)

These two files are used by different programs. The servercert.pem file is used by qmail-smtpd when processing the STARTTLS command, and under my service-qmail-smtpd-run script the file is also used by sslserver. The clientcert.pem file is used by qmail-remote if the remote server includes STARTTLS in the list of capabilities it sends in response to the EHLO command.

These two programs run as different users. qmail-smtpd runs as the qmaild user, while qmail-remote runs as the qmailr user. In order to minimize the damage due to an as-yet unknown security hole in one or the other, each file should be readable to the userid which needs it, but not writable (which means it should not be owned by that userid.) This means that the files should be owned by root and readable to the group which each userid belongs to.

The problem is that with a symbolic link, there is really only one file, which has one owner, one group ID, and one set of permissions. Unfortunately, the userids which the two programs run as, are members of different groups- which means that no one group ID could make the file readable to both programs.

At first glance it would seem that the solution is to make the file world-readable. However, the file contains the secret key used to encrypt all of your incoming and outgoing email- not something you want people to get their hands on. If your system allows any kind of filesystem access to people who are not trusted administrators, there is nothing to stop them from reading that file and using it to decrypt your SMTP traffic.

The solution is this- instead of making one file a symlink of the other, create two physical files, each with its own ownership and permissions. The fact that they happen to contain the same data is meaningless- and in fact if you wanted to use different keys for incoming and outgoing connections, you could easily do this.

The ownership and permissions of these files should look like this (from my own server)...

# cd /var/qmail/control
# ls -laF *.pem
-rw-r----- 1 root qmail 2142 Jun 24 2004 clientcert.pem
-rw-r----- 1 root nofiles 2142 Jun 24 2004 servercert.pem

Added enviornment variables

Many of the features offered by the newer combined patch files are configured using environment variables. Rather than list them all here, I recommend you look at the combined patch page, where you will find a list of the environment variables used by each version of the combined patch. The variables are also documented on the page which talks about the service-qmail-smtpd-run script as well.

Problem with the "locals" file

This one isn't so much a difference as it is an outright incorrect step in the qmailrocks documents. On this page in the qmailrocks setup instructions you will find an instruction which tells you to run the command

# ./config-fast your_fqdn_hostname (ex: ./config-fast

The config-fast script that you're running is not designed to be used on a pure-virtual system (like what qmailrocks builds.) The name you enter as your_fqdn_hostname above will end up being placed in the /var/qmail/control/locals file. However, if that name will later be used as the name of a domain in vpopmail, it should not be listed in the locals file.

The problem develops later on. If a given domain name is listed in both locals and virtualdomains (where it must be listed in order for vpopmail to use it) then the listing in locals takes precedence, and mail sent to that domain will try to be delivered to system userid's which have the same names as the mailboxes.

The solution is to remove the domain name from the locals file. In fact, if all of your mailboxes are managed through vpopmail, the locals file should be empty.

Note, however, that even if the locals file is empty, it must still exist. Otherwise, the contents of the /var/qmail/control/me file will be treated as if the locals file contained it.

courier-imap and courier-authlib

This section applies more to Debian users than anybody else, but it may prove useful for others so please read it, even if you know you don't need it.

The qmailrocks instructions for Debian tell you to install courier-imap using the binary packages from the Debian package repository. It is easy, but you will find that their binary packages don't work with vpopmail, which makes me wonder why qmailrocks tells people to do this. If you're going to run courier-imap on a Debian system, you should compile the courier-imap and courier-authlib packages from source, using the directions you will find in the documentation included with the packages themselves.

Once you have finished compiling the packages, you may want to run courier-imap and courier-authlib under daemontools. (This is how I run my own server.) This is nice, not only because daemontools will make sure they automatically start back up if they happen to die, but because it follows the same daemontools mechanisms that qmail itself uses, and the directions will work no matter what system you're running- Linux, BSD, Solaris, OSX, whatever... if you have daemontools working, these directions will work on your system.

If your system is like most qmailrocks systems (and other multi-domain qmail systems in general) with all mailboxes managed by vpopmail, configuring courier-authlib to work with vpopmail couldn't be easier. Part of configuring courier-authlib is editing the /etc/authlib/authdaemonrc file, and changing the authmodulelist= line. For a system where all mailboxes are managed by vpopmail, this line should say:


After changing the file, stop and restart the courier-authlib service (using svc -t /service/courier-authlib if you're using the daemontools directions linked above, or whatever the appropriate commands may be for your system- you need to stop, and then restart, the authdaemond process.)


Some people are reporting issues with SquirrelMail not being able to send mail, with an error message saying 503 auth not available. This is because squirrelmail sends the AUTH command without checking to see if the server supports the command or not. The 503 auth not available message you are seeing is the server's response to an AUTH command when the command is not available (i.e. when the connection is not secure.)

Squirrelmail is actually "broken" in this regard. According to the SMTP standard, any capabilities which were not part of RFC 821 (the original SMTP specification) should not be relied upon unless the server advertises their availability in response to an EHLO command. Squirrelmail is supposed to send an EHLO command and examine the results to see if AUTH is listed before it tries to send an AUTH command.

In 99% of the cases, squirrelmail is running on the same machine as the SMTP server, and using as the SMTP server address... and the SMTP server has,RELAYCLIENT="" in the SMTP server's tcpserver access control file. Basically, the SMTP server will allow relaying from anyway, so why does squirrelmail even need to send an AUTH command in the first place?

The solution is to configure squirrelmail to not use AUTH. You may want to go one step further and configure squirrelmail to not use SMTP at all (which is what I've done on my own server.)

The cause of the error message is, again, that squirrelmail is sending an AUTH command when the server does not support the AUTH command. As you know (because you read the beginning of this page), AUTH is not supported unless the connection is known to be secure. A non-SSL connection, with no STARTTLS command, is not considered secure.