Patching QMAIL to avoid brute force SMTP deliveries

In our experience running a mail server, we're constantly wrestling with different hack approaches, spam situations, and just plain old general nasty emailers. One of the situations that we frequently encounter is brute force attempts to deliver email to a domain that we host. QMAIL is pretty good at rejecting invalid domains, but when the domain is valid, QMAIL allows bogus email to be at least received. This was causing our server bandwidth to be utilized in 2 ways, one during the receipt of the invalid email, and secondly when an undeliverable message was returned to the sender. These attempts often utilized lists containing several hundred email addresses, often containing 1 or 2 valid emails in the middle somewhere. In a couple of extreme cases, we had inbound SMTP sessions lasting a couple of hours, which is totally unacceptable. We decided that a more "aggressive" approach to dealing with this was required, so we embarked on a journey to solve this problem on our server.

One approach came to mind immediately, block this bogus inbound emails before they are accepted. In order to do this, we needed to modify the QMAIL components that manage this activity. This would happen to be the daemon qmail-smtpd. Since we are running the netqmail (v1.05) version of QMAIL, we downloaded the package ( available at ) and incorporated our logic into the source code. Basically what we've done is performed a "QMAIL user lookup" by examining the incoming email, extracting the username and domain, and then finally validating that against our QMAIL configuration. Unfortunately, 1 side effect of this was that we had to make several of the QMAIL installation directories readable to the qmail-smtpd process. Since we don't allow shell accounts on our server, we took the simple route and allowed all users read access to the QMAIL directories. You may want to explore a different, more secure route for this process depending upon you security requirements.

Note: If the permissions on your QMAIL directories are incorrect, ALL mail may end up being rejected. Make sure that you understand the requirements here!

Finally, in order to test our new QMAIL process, we instituted a configuration file and some logging. The configuration file is located (by default) in /var/qmail/control/trace.cfg, and contains a very simple format. Here is an example of our config file:

# This is the qmail trace configuration file
# Version 1.0

# Name of the trace file, if empty or invalid, logging is disabled

# Level of logging, if invalid or outside of the range 0-4, logging is disabled
We've found that a trace_level of 3 is suitable for our needs, however you may increase that value to increase the level of logging, or decrease the value to reduce the amount of logging. A value of 0 will disable logging and is fine once you know that the system is working properly. It is interesting to see just how many inbound deliveries are attempted and rejected, you might be surprised when you start monitoring the situation.

Note: Please make sure to backup all of your production QMAIL binaries and any sources that you patch BEFORE making any changes!

Unfortunately, the QMAIL license agreement does not allow us to distribute a modified version of qmail-smtpd.c, so we've created a source code patch file for you. You may download a gzipped tarball containing the patch for netqmail-1.05 version of qmail-smtpd.c and a sample configuration file here. After unpacking the tarball, move the configuration file trace.cfg to /var/qmail/control (seemed like a good place for it). Prior to making any patches, make sure that your QMAIL sources compile. Instructions are included with QMAIL for doing this. After a successful compilation, patch your qmail-smtpd.c file by issuing the following command:
patch -i qmail-smtpd-check.diff
Now rebuild qmail-smtpd by typing "make". If you see any errors from the build, either your patch command failed, you aren't using netqmail 1.05, or it never compiled prior to patching (okay, there are other reasons...but we're not going down that path).

Here is a simple way to test your new executable, create a file called smtp.txt containing the following (make sure to replace with a valid domain that QMAIL recognizes on your system):
Now, pipe this file to your new qmail-smtpd and check the logfile. The data in this file isn't exactly formatted properly, but it is sufficient for testing the new qmail-smtpd executable. The test command is as follows (you may need to specify the path for your new version of qmail-smtpd, depending on your system):
cat smtp.txt | qmail-smtpd
It will send some output to the screen, which you can safely ignore. Then take a peek at your logfile, you should see something that looks like this:
2005-02-17 15:41:40 (1) (25466) setup: remoteip: 111.222.333.444
2005-02-17 15:41:40 (2) (25466) smtp_rcpt: user[baduser] domain []
2005-02-17 15:41:40 (2) (25466) smtp_rcpt: invalid rcpt user, terminating connection
If your log exists and contains output similar to this, congratulations, it's working. You may want to change the input datafile to contain a valid email and perform the same test. You should NOT see the "terminating connection" message for valid data. If you do, something is still not quite right.

Being forever paranoid, I shy away from doing full installs on functioning systems. For our purposes, copying the new qmail-smtpd executable was what we wanted. Stop QMAIL, on our system this is done by typing /etc/init.d/qmail stop. Replace the qmail-smtpd file in /var/qmail/bin (it may be wise to "mv" the previous version to just in case). If you get a permission denied, you may have insufficient system privileges or qmail-smtpd may still be running and handling requests. Renaming this file usually resolves this issue if the latter is the case. If it's the former, now's a good time to talk to your system admin.

Don't forget to check the ownership and permissions on qmail-smtpd and set them appropriately.

Now, restart QMAIL and send yourself a test message (from outside of the server). You should see entries in your log that look something like the following:
2005-02-17 14:59:59 (2) (24730) smtp_rcpt: invalid rcpt user, terminating connection
2005-02-17 15:00:00 (1) (24732) setup: remoteip:
2005-02-17 15:00:01 (2) (24732) smtp_rcpt: user[angela] domain []
2005-02-17 15:00:01 (2) (24732) smtp_rcpt: invalid rcpt user, terminating connection
2005-02-17 15:00:02 (1) (24739) setup: remoteip:
2005-02-17 15:00:22 (1) (24741) setup: remoteip:
2005-02-17 15:00:24 (2) (24741) smtp_rcpt: user[burgess] domain []
2005-02-17 15:00:24 (2) (24741) smtp_rcpt: invalid rcpt user, terminating connection

If you do not receive your email, something may be broken and you may want to revert back to the previous executable while you investigate the situation.

We hope that this article has been of interest and help to you. We've found that the number of brute force attacks on our server has been reduced by about 90 percent (roughly guessing).
This article was designed, produced, and written by Bill Johnson exclusively for KATR Inc.
and is copyrighted 2005-2008, KATR Inc., all rights reserved.

About the writer:Bill Johnson
Having worked as a computer consultant, independent contractor, and an IT employee,
Bill has developed a strong background in many areas, including information
systems technologies, systems administration, application development, web development
and deployment, game research and development, and graphics manipulation.  Bill
operates as a full-time computer consultant, while at the same time maintains numerous servers,
web sites, and office networks for a variety of clients, both professional and personal.  Having previously 
served as an owner, partner, and director for a successful 80 employee computer consulting, he has unique insights
into the challenges of owning and operating a business with partners of diverse business backgrounds.

Bill graduated summa cum laude from Bemidji State University in 1989 with a bachelor's 
degree in computer science.  He has earned his private pilots license with an instrument rating and is a
certified SCUBA diver.  As well as serving on the local Community Education Advisory
board, he also enjoys coaching his two boys in various athletic programs, karate,
hiking, camping, fishing, rock climbing, and hunting.