greylisting-spp - A qmail-spp plugin implementing greylisting

    Copyright (C) 2004-2007,2011 Peter Conrad <conrad@tivano.de>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License (version 2) as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

qmail-spp (http://qmail-spp.sf.net/) is a patch for D. J. Bernstein's 
"qmail" MTA package. The patch enables "plugin" programs to be run at various
stages during an SMTP protocol exchange.

"greylisting" (http://greylisting.org/ , 
http://projects.puremagic.com/greylisting/) is the concept of temporarily
rejecting an incoming email, unless delivery of the same email has been tried
before. The idea of greylisting is that typical malware like spam senders or
email worms / virii typically do not implement a proper mailqueue and will
therefore not try delivery again if the first attempt failed. Thus, 
greylisting can stop SPAM and/or malware at the earliest possible time, i. e.
before the actual content is being received by the target MTA.

Guess what - this package combines both by implementing a qmail-spp-style
plugin providing greylisting functionality.


How it works
============

The operation of the plugin is (almost) completely driven by environment
variables. It is invoked by qmail-smtpd after each "RCPT TO:" SMTP command.
At that time, all three values required for the greylisting decision are
set:

 - the sending MTA's IP address in the environment variable TCPREMOTEIP,
   e. g. set by tcpserver (both IPv4 and IPv6 are supported)
 - the envelope sender (as set by qmail-spp for the "MAIL FROM:" command)
 - the envelope receipient (set by qmail-spp for the "RECIPIENT TO:" command)

This plugin requires the environment variable GL_DATABASE to contain the full
path to a readable and writeable (for qmail-smtpd) file that will be used
as the greylisting database. Set this variable e. g. before invoking 
tcpserver for qmail-smtpd.

In addition, if one of the env variables RELAYCLIENT or GL_WHITELISTED is set,
the plugin exits immediately (see the page on whitelisting at
http://greylisting.org/whitelisting.shtml). If you run your qmail-smtpd via
tcpserver, you can whitelist specific IP numbers using tcprules (1). A file
containing a list of IP numbers that should be whitelisted can be found at
http://cvs.puremagic.com/viewcvs/greylisting/schema/whitelist_ip.txt
(a copy of revision 1.16 is available in the file "whitelist_ip.txt").

Three more environment variables are available to (optionally) tweak certain
timeout values used by this plugin:

 - GL_MIN_REJECT	How many seconds to wait after the first delivery
			attempt, before another delivery attempt will be
			accepted (default: 300 = 5 minutes)
 - GL_MAX_WAIT		How many seconds to wait after the first delivery
			attempt, after which a second delivery attempt will
			no longer be accepted (default: 86400 = 1 day)
 - GL_ACCEPT_GOOD	How many seconds after a successful delivery to
			accept mail with the same IP/sender/recipient
			combination (default: 259200 = 3 days)

Another two environment variables can be used to configure the amount of
logging output:

 - GL_DEBUG	If set (to any value), the plugin will write lots of debugging
		output to wherever your qmail-smtpd's log output ends up.
 - GL_VERBOSE	If set (to any value), the plugin will log rejected triples
		of (IP, sender, recipient) to wherever your qmail-smtpd's log
		output ends up. The output of GL_DEBUG includes that of
		GL_VERBOSE.


Status
======

The current implementation has been in productive use at several low-volume
sites for more than two years now. This applies to the plain-text as well
as the SQLite backends. So far, no unexpected problems have occurred.
In any case you should be aware that you use this software at your own risk!

Care has been taken to make the plugin fail in a safe way: in case of an
error, an incoming email will most likely be accepted (although an error
message may be logged by qmail-smtpd). So in case of a severe problem,
SPAM would get through, but no important mail would be lost.

The (default) flat-file database format was chosen for its straightforward and
lean implementation. It is anything but efficient, so don't use it for medium-
or even high-volume sites.

In version 0.2 I have added two more database implementations based on
Berkeley DB version 4.0 (see http://sleepycat.com/ ) and
SQLite version 2 (see http://sqlite.org/ ). I've also improved support for
EZMLM-style VERPs (i. e. per-message unique sender address on a mailing list,
like securityfocus.com).

In version 0.3 I have added some improvements / optimizations regarding
servers that implement "callback" checks for the envelope sender address.
ATTENTION: This requires version 0.40 (or later) of the qmail-spp patch!

Version 1.0 is identical to 0.3

Version 1.0.1 fixes a bug when GL_DEBUG and RELAYCLIENT are both set.
Thanks to Jacek Trzcinski for the patch!

Version 1.1 adds an sqlite3 backend, and contains minor code cleanups.


Downloading
===========

This package should be available at 

http://www.unix-ag.uni-kl.de/~conrad/greylisting/

The sources are managed using the GNU Arch revision control system. You can
check out a copy using

tla register-archive conrad@tivano.de--2004 \
	http://www.unix-ag.uni-kl.de/~conrad/Archives/conrad@tivano.de--2004
tla grab http://www.unix-ag.uni-kl.de/~conrad/greylisting/releases--1.1


Building
========

Simply unpack the sources and type "make" in the top-level directory of the
distribution. This will create a subdirectory ",,build", in which the build
will take place.

Hint: apparently you need "GNU make", which may be installed under a different
name on your platform. Or not at all.

By default, the flat-file database implementation will be used. If you want
to use one of the other implementations, specify the "DB_IMPL" parameter
to the make command, i. e. "make DB_IMPL=bdb" for Berkeley DB or
"make DB_IMPL=sqlite" for the SQLite interface. Needless to say, the respective
libraries and header files must be present on your system. See

README.db-file, 
README.db-bdb or
README.db-sqlite
README.db-sqlite3

for more info on these implementations.

In any case, the resulting executable will reside in
",,build/src/greylisting-spp".


Installing
==========

A "make install" target is *not* provided, because the installation process
requires some manual intervention as well as some decisions you'll have to
make yourself. Basically, you'll have to perform the steps enumerated below.
For RPM-based systems, a .spec file is provided (assuming a qmail installation
under /var/qmail). The RPM-based installation requires some manual work as
well.

0. Be sure to read the whitepaper on greylisting
   (http://projects.puremagic.com/greylisting/whitepaper.html). You should
   have a general understanding of how greylisting works and about the
   risks involved (mail can get delayed or lost).
   If you're providing SMTP service for others, check the legal situation in
   your country. It should be safe to inform your users about it and have
   them agree, e. g. by including it in your terms of service.

1. As has been said above, this program is a *plugin* for a Qmail installation
   that was built with the qmail-spp patch. So, as the first step, you'll
   have to build and install Qmail with that patch (version 0.40 or later!).
   In the following, we'll assume that the patched Qmail is installed in
   "/var/qmail" (the default location).

2. If you don't have a directory where your plugins reside, create it. It must
   be situated somewhere within the Qmail installation dir.
   In the following, we'll assume that the plugin dir is "/var/qmail/plugins".

3. After building this plugin with "make", copy the resulting executable
   to the plugin directory "/var/qmail/plugins".

4. Choose and prepare a location for the greylisting database file.
   If the file does not exist, the plugin will try to create it. In that case,
   appropriate directory write permissions are required. Otherwise, read/write
   permission for the database file itself are sufficient (directory seeks,
   too, of course).

   You can create an empty database file with "touch". Then, assign ownership
   to the user under which qmail-smtpd runs, usually qmaild/qmail. Make the
   permissions 0600.

5. Modify whatever process you use for running qmail-smtpd to set the
   environment variable GL_DATABASE to the full path of the greylisting
   database file.

   For example:
     GL_DATABASE=/var/qmail/greylisting/db-file
     export GL_DATABASE
     tcpserver -R -v -x /etc/tcprules.smtpd.cdb -c 20 0 smtp qmail-smtpd 2>&1

   Don't forget to restart the service if required!

   Optionally, set GL_VERBOSE or GL_DEBUG so you can monitor how / if
   the plugin works.

6. Think about whitelisting some IP addresses, e. g. your own backup MX's or
   your customers' mailservers. Also, certain misbehaving mailservers need
   whitelisting (see http://greylisting.org/whitelisting.shtml for an
   explanation).
   If you use tcpserver for starting qmail-smtpd like in the example above,
   you'll want to include ",,build/doc/whitelist.tcpserver" in your
   "/etc/tcprules.smtpd".

   The provided list of addresses requiring whitelisting is incomplete,
   therefore please pay attention to step 8.

7. Enable the plugin by adding the path (relative to the qmail installation
   dir) to the "[rcpt]" section of the qmail-spp configuration file
   "/var/qmail/control/smtpplugins".
   Minimal example:

[auth]

[helo]

[mail]

[rcpt]
plugins/greylisting-spp

8. Keep an eye on the database file. 
   The provided list of adresses requiring whitelisting is incomplete.
   If legitimate email never gets through you'll most likely have to whitelist
   the sending IP number.


Extending it
============

If you want to create your own database interface, take a look at
README.dbapi and "src/db-api.h". Please let me know if you're successful.

