Qmail Patch Explanations and Recommendations
|
Only patch if you really need to and only if you understand exactly what the patch does.
|
Contents
- Introduction
- How to apply
- Minimum Patches
- Small Site Patches
- Big Sites
Introduction
I'm a qmail enthusiast. I've even
written a book
about it. Qmail has a lot of available patches. There are good
reasons for using each patch, but in general you should try to use as
few as possible. It is the general consensus that the more patches you
use, the more likely there are to be bugs that crop up and conflicts
between patches. The general rule for patching qmail is highlighted
across the top of this page. Disobey it at your peril.
That said, I have found a collection of patches that work for me. I
have installed them for the reasons I explain, which are not
necessarily reasons that matter to everyone. This is a list of the
patches I use (and some others I have run across), with descriptions
and reasons for using them. Most of these patches were pulled from qmail.org , which has many many more and is
worth looking over if you're facing a situation you can't handle.
Some people feel that qmail has certain shortcomings (like
non-conformance to RFCs) and either like complaining or have found a
solution, or have developed patches to fix the problem. Trust me, the
issues have been hashed over again and again and again on the qmail
mailing list, and the current state of things seems to keep the most
people happy. In most cases, things are the way they are on purpose
(but feel free to search the qmail list archives for the reasons
why).
These patches all work on netqmail, which you should be using
anyway. While vanilla qmail is as cool and unbreachable as ever,
netqmail is a convenient packaging of some of the patches that have
cropped up as being very important. It is not officially the same thing
as qmail, but is a convenience packaging of qmail. For more
information, go here.
One final note, some of these patches conflict (or seem to), and
resolving them takes a little bit of knowledge of C. If and when I get
a chance, I'll put up an über patch collecting and reconciling the
patches that I use. For any others, you're at your own.
Apply these patches with the following commands:
cd /path/to/netqmail/
patch -p1 < /path/to/patch
Minimum Patches
(Recommended for: everybody who refuses to use netqmail)
These patches all fix known bugs in qmail. They are also almost all simple patches, and unlikely to conflict with other patches.
-
Phil Edwards wrote a patch to fix qmail for the changes in the new
glibc. This is only necessary for people using a version of glibc
2.3.1 or newer, but it's not a bad idea for everyone else.
(local copy)(news.gmane.org)
-
Erik Sjoelund found a bug (a logic error) in qmail-local. Everyone
should use this patch to fix it.
(local copy)
(ornl.gov)
-
Qmail ought to recognize 0.0.0.0 as a local IP address, but doesn't
by default. That may allow spammers to spoof you, and certainly
means that qmail is incorrect. No matter where or what you're doing
with qmail, this oversight should be corrected. Scott Gifford wrote
the patch.
(local copy)
(suspectclass.com)
-
David Phillips noticed that qmail's sendmail emulation doesn't
correctly support the -f flag as it should. Scripts may
rely on this flag (it sets the envelope sender address—the
address where delivery problems are sent to unless the message also
contains an Errors-To: message header). Everyone should
fix it.
(local copy)
(david.acz.org)
Small Site Patches
These are patches that I have installed on my small qmail installation
and I recommend them. They are not necessary, but they are quite
useful. In some cases, the feature the patch is for requires a little
bit more setup, and perhaps some more software. This is generally
minimal, but very worth it.
- RFC 2821
-
- Some broken email servers send a 5xx or 4xx response at
the beginning of an SMTP connection. This is incorrect
behavior and can throw default qmail for a loop in an
inconvenient way (i.e. messages won't get delivered to that
domain). Specifically, qmail *could* try the next-lower MX
record if it gets a 4xx greeting, and could quit trying if
it gets a 5xx greeting, and some broken email servers which
rely on a poor interpretation of the SMTP standards,
require this behavior. The patch to make qmail handle these
broken servers better is written by Matthias Andree.
(local copy)
(www-dt.e-technik.uni-dortmund.de)
- This patch modifies the behavior of qmail-smtpd so that
it responds with a 500 error code to unrecognized SMTP
commands instead of a 502 error code. It's a minor
distinction, but RFC2821 (published several years after the
current version of qmail) said that's the way it
should be done. Which, unless you have a good
reason, RFC SHOULD's mean just that. Since it's trivial,
here it is. This patch was written by Jonathan de Boyne
Pollard.
(local copy)
(tesco.net)
- DNS-related Patches
-
-
You can save yourself a lot of trouble, and you can
optimize qmail by trimming its DNS requests to only the
information it really needs. Jonathan de Boyne Pollard
wrote this one-liner. (more details at his qmail page,
and while you're at it, check out his djbdns page)
(local copy)
(homepages.tesco.net)
-
You should also install Christopher K. Davis's patch to get
qmail to handle large DNS packets. Sometimes (rarely) the
answer to a DNS query is larger than 512 bytes (the max
that qmail allows (which was based on the UDP DNS protocol
definition (RFC 1025,
section 4.2.1))). This is not a widespread occurrence, yet,
but can and does happen from time to time. This patch
allows DNS packets to be as big as the maximum DNS response
size, but does not waste memory if you never see one that's
that big.
(local copy)
(ckdhr.com)
- Common Spam Relay-attempt
Rejection
- Spammers frequently rely on bizarre manipulations of the
standard user@host.tld email address format in order to trick
mail servers into forwarding their spam. Tricks like
user@remoteaddress@thismailserver, for example, or
user%remoteaddress@thismailserver (aka "the
percent hack"). Unfortunately, qmail doesn't reject all of
these attempts out of hand, but instead accepts them and
generates a bounce message. This behavior is technically valid,
but some automated relay testing software assumes that if the
message is accepted then it will be delivered/relayed instead
of bounced. This means that the RELAY TESTERS are
broken. This means that you may get onto one or two
blacklists that are based on incorrect relay checks. To avoid
this hassle, use this patch, written by Russel Nelson, to
reject such relay attempts. This patch precludes using the
percent hack, but you shouldn't be allowing that anyway so its
no big loss.
(local copy)
(qmail.org)
- RFC 1870 (ESMTP SIZE)
- One useful extension people have made to the SMTP protocol
is defined in RFC 1870, which establishes the SIZE command.
This has two primary consequences. First, it announces (as a
response to the initial EHLO greeting) the maximum size of mail
that the server is willing to accept. Qmail's default behavior
without this patch is to accept any amount of data and if the
amount exceeds the maximum allowed, to reject it after it has
been received. This wastes bandwidth: smart ESMTP senders that
also support the SIZE command could have avoided wasting that
bandwidth. Second, as part of the MAIL FROM command, the sender
can specify the size of the mail it is going to send, allowing
the receiver (qmail) to reject it at that point for being too
big. (local copy)(will.harris.ch)
- SMTP AUTH
- If all you're doing is sending email from your own machine,
then you don't have to worry about who can relay email through
you — only your machine can, of course. But, if you may
want to send email from random locations (say, from your laptop
as you travel around the country), you don't want to have to
allow just any old computer to relay email through your server.
You need some way to identify and authenticate yourself to the
email server, so you can have it let you relay email through it
without opening it up to every spammer in the world. To do
this, you need support for SMTP AUTH. This patch is written by
Erwin Hoffmann, and requires a bit of extra configuration to
set up. Full documentation is here.
(local copy)
(fehcom.de)
Caveat: This patch defaults to enabling CRAM-MD5
authentication. If you really want/need CRAM-MD5 authentication
(that decision is up to you), you will need to use the cmd5checkpw
implementation of checkpassword (fehcom.de).
Otherwise, you'll want to disable CRAM-MD5 advertising, which has
to be done at compile-time (unfortunately).
- SSL (STARTTLS)
- SMTP transmits email unencrypted. Other than privacy
concerns, this is not typically a problem. However, if you use
SMTP AUTH, you are sending your username and password across
the network in plain text (which is easy for a hacker or
spammer to extract if they wanted to). The solution is to use
encryption in SMTP — in other words, make qmail support
the STARTTLS ESMTP extension. Frederik Vermeulen wrote a patch
to get it to work. It adds one minor step to the compilation of
qmail: you must create a server certificate (run
make
cert before running make setup check).
Also, you must create a cron job to rebuild the certs daily
(because otherwise, over time, an attacker could figure out
what they are). Commonly, when someone indicates that they want
qmail to support SSL/STARTTLS they will be referred to a
project like mailfront. While
mailfront is a worthy project, it doesn't always solve the
entire problem. Specifically, it doesn't enable qmail to use
SSL for sending mail to other servers that support
STARTTLS (this is a problem of privacy; but keep in mind that
if the email is being relayed, it may be transmitted via an
unencrypted communication later---if you're really worried, use
PGP). This patch, however, does enable qmail to do that.
(local copy)
(inoa.net)
- Executable Banning
- As anyone who has spent any time paying attention to
computer news in the last decade or so knows, computer viruses
are a problem — specifically, email viruses have become
more prevalent, and even more specifically, they are Microsoft
viruses (that is, most viruses are executable files that only
run under some form of Microsoft Windows, and not under any
other operating system). All Microsoft Windows programs begin
with information that tells Windows how to load the program.
This information is small and can easily be detected. This
information is the same in all Windows programs and is required
in order to run the file. It is not used in scripts (like
Visual Basic scripts (.vbs)), but most email viruses these days
aren't scripts anyway (nevertheless this patch is NOT a full
anti-virus solution, just a quick and fast help). An email
policy that may help prevent the spread of Windows viruses is
to say that you may not send Windows executables (if you must
send them, compress them first — that changes their
header information). A way to enforce a policy like this is to
look at all email attachments and see if they begin with
Windows executable header information, and reject them if they
do. Russell Nelson wrote a patch to do this.
(local copy)
(qmail.org)
- QMAILQUEUE
- The complete anti-virus solution for your email server is
to use something like qmail-scanner, simscan, or my
current favorite, qmail-qfilter,
in combination with a good antivirus program like clamav. These
programs sit in the middle of your qmail installation,
intercept emails, scan them with whatever scanners you specify,
and if the scanners approve, pass the messages along to the
usual queue of email (think of them as filters). In order for
these programs to sit in the middle of qmail like that, you
must use the QMAILQUEUE patch, written by Bruce Guenter. The
QMAILQUEUE patch has other uses, because it is used as a
generic way to insert another program into the qmail queueing
chain. This patch is part of netqmail.
(local copy)
(qmail.org)
- Recipient Verification
- One of the behaviors that many people dislike about qmail
is that it accepts email based only on the domain of the
recipient, rather than the full recipient address. The argument
is that this behavior causes qmail to generate spurious and
avoidable bounce messages. There are several ways to check
this, but perhaps the most flexible are the RCPTCHECK patch and
the CHECKENV patch. Both are functionally equivalent. They run
an admin-determined script to determine whether the recipient
is valid. Full details on the RCPTCHECK patch used to be
available here,
but Jay seems to have taken them down.
(local copy)
(soffian.org
(offline?)) Kelly French's CHECKENV patch can be obtained
here.
I personally use the RCPTCHECK patch, because that's the
first one I found, but they're both equally good (and
CHECKENV is older).
These patches are far more powerful and flexible than most
people give them credit for. For example, using such a patch,
it is trivial to implement things like three-tuple greylisting
(based on RECIPIENT, SENDER, and
TCPREMOTEIP). You can also, as Soffian suggests, use a
script that queries another server to see if the recipient is
valid. I like this script in part because I can use different
verification techniques depending on the domain (for example, I
can do one kind of check for lists.memoryhole.net, and another
for memoryhole.net itself). I often hear questions on the qmail
mailing list that could be solved simply and easily with this
(relatively trivial) patch, and every time, I am re-impressed
with the power and flexibility that this patch provides. It
doesn't get enough credit.
Since the original documentation of the RCPTCHECK patch seems
to be offline, here's how it works: when the environment
variable
RCPTCHECK is set, qmail-smtpd will execute
the program specified in that variable. Before the program is
executed, the recipient in question is stored in the
RECIPIENT environment variable, and the sender is
stored in the
SENDER environment variable. The exit
code of the specified program determines whether qmail views
the recipient as valid or not. Possible exit codes include:
- 100
- Means that the recipient is invalid. The client
receives a 553 error.
- 111
- Means that there was a temporary problem verifying the
recipient. The client recieves a 421 error code and the
connection is closed.
- 120
- Means that the recipient check program could not
execute correctly. The client recieves a 421 error code and
the connection is closed.
- anything else
- Means that the recipient is valid.
A trivial example script would be something like this:
#!/bin/sh
GoodRecipient=0
BadRecipient=100
Error=120
if grep "$RECIPIENT" /var/qmail/control/goodrcptto >/dev/null; then
exit $GoodRecipient
else
exit $BadRecipient
fi
Here's a slightly more complex example:
#!/bin/sh
GoodRecipient=0
BadRecipient=100
Error=120
User=$( echo "$RECIPIENT" | cut -d@ -f1 )
Domain=$( echo "$RECIPIENT" | cut -d@ -f2- )
if ! type id >/dev/null 2>&1 ; then
# id program not in PATH
exit $Error
fi
if id "$User" >/dev/null 2>&1 ; then
exit $GoodRecipient
else
exit $BadRecipient
fi
A basic example of how to do greylisting with this patch is
here (based on
Kelly French's
script). Note that you'd want to combine that script with some other
kind of recipient validation as well, and needs a cron job to clean up after
itself.
- Better Maildir
- Some operating systems quickly recycle PIDs, which can lead
to collisions between Maildir-style filenames, which must be
unique and non-repeatable within one second. This patch is a
means of updating qmail-local to use the format of the revised
Maildir protocol, available here. This
patch written by Toby Betts.
(local copy)
(vorlon.cwru.edu)
- Better qmail-smtpd Logging
- It is often convenient, for diagnosing problems and for
monitoring what your server is up to, to have it log it's
actions and decisions. The qmail-send-related programs
(qmail-remote and qmail-local) do this well,
but qmail-smtpd doesn't produce any logs at all. I
wrote a patch to add some basic logging to it, so that it
records its decisions in the log (i.e. prints them to stderr).
There are several similar patches out there, which one you use
depends largely on whose logging format you like best. My patch
is available here.
(Old versions are available here.)
- Outgoing IP Control
- For servers that host multiple domains or have multiple IP
addresses assigned to them, it is sometimes useful (or
important) to have qmail use a specific IP address for its
outgoing mail. By default, qmail uses whatever address the OS
chooses for all outbound connections. With this patch, you can
specify which address to use.
(local copy)
(fefe.de)
- DKIM Wrapper
- To sign all outbound messages with a DKIM and/or DomainKey,
there are several alternatives. One is Russ Nelson's qmail-dk.
While popular, it only handles DomainKeys, and doesn't sign all
outbound messages, merely all inbound messages (that may
then become outbound). Thus, things like bounce-messages cannot
be signed, because they don't go through the usual
qmail-smtpd/qmail-inject filters. A way
around this is to use a script wrapper around
qmail-remote, like this
(txt). All you need to do is
move the real qmail-remote to
qmail-remote.orig and put that script in as
qmail-remote (make sure it's readable and executable
by everyone). The script uses two programs to do its job: the
dktest program that comes with libdomainkeys and
dkimsign.pl that comes with Perl's Mail::DKIM
module. If you're interested in verifying DKIM and DomainKey
signatures, a similar script that can be used in much the same
way as Russ Nelson's program is here (txt). (That script expects
that dkimsign.pl accepts the --key argument;
if yours does not, you can use this
simple patch (txt)
to modify your dkimsign.pl so that it does accept the
--key argument.)
Patches for Big Sites
- External Todo (qmail-todo)
- When email comes into the server extremely quickly,
qmail can sometimes spend so much time pre-processing the email
that the email starts backing up and most of it is in an
undeliverable state in the
todo queue rather than
the real queue (note that this is only a problem when you get
massive amounts of email at the same time (several per
second)). This behavior is frequently referred to as "silly
qmail syndrome." André Opperman wrote a patch to solve
the problem. It makes qmail-todo a separate program,
allowing the pre-processing to happen asynchronously and thus
does not prevent deliveries from ocurring at the same time. The
solution is a bit complicated, and is not worth applying unless
you are experiencing "silly qmail syndrome." This patch is
referred to as the ext_todo patch.
(local copy)
(nrg4u.com)
- Big Todo
- Another issue that can come into play when email comes into
your server extremely quickly is that if several thousand email
messages accumulate in the
todo queue, an
inefficient filesystem that has trouble with large directories
may restrict the speed of todo processing significantly. The
best way to address this is to use a better filesystem,
but that's not always possible, depending on your situation. Of
course, qmail already worked around this kind of problem in the
rest of the queue by using a hash system to reduce the number
of message files per directory in the queue. For whatever
reason, this workaround wasn't applied to the todo queue. Russ
Nelson wrote a patch to make qmail use that hashing system in
the todo portion of the queue as well. This patch is referred
to as the "big-todo" patch. There's no reason to apply this
patch unless you really really need it, because getting
a better filesystem (or enabling the right features on the one
you're already using) is the best option; this patch can
require that your queue be rebuilt, and so applying it to a
running system can be a bit of a pain.
(local copy)
(qmail.org)