John Levine's greydaemon
This package extends netqmail with John Levine's greylisting daemon. Subject to the environment variable
GREYIP being set, greylist checks are made for incoming SMTP connections prior to accepting messages.
'Full' greylisting is implemented, meaning that the connecting IP address, envelope sender and envelope recipient form the triplet that is checked.
greydaemon is used by
qmail-smtpd to carry out these checks;
qmail-smtpd communicates with
greydaemon using UDP.
greydaemon itself is written in Perl.
qmail-logmsg is a pre-requisite of this package, along with Perl.
Also note that although this package comes with the 'glue' for it to be used with netqmail there is no reason why greydaemon couldn't be used with other MTAs, subject to appropriate 'glue' being added for the relevant MTA. Ask me or John about this if it's relevant to you.
greydaemon [Perl] program is subject to a 'BSD' style license: Please see the
greydaemon program itself - the text of the license is included there.
Status / Warranty
No warranty, express or implied is given - USE THIS SOFTWARE ENTIRELY AT YOUR OWN RISK. You will need to satisfy yourself as to the suitability of this software before deploying it in a production environment.
The documentation for this package consists of this web page and the included man pages (the
qmail-smtpd man page is an updated version of the original):
Proceed as follows:
- Unpack the patch if you've downloaded a compressed version.
- Patch your qmail source: Enter your
netqmail-1.06source directory (already patched with qmail-logmsg) and type,
patch < path_to_the_patch/nq106-grey-v1.15.patch
which should apply the patch. If this fails, you will need to patch the failed parts by hand. If you're basing your installation on a Life with qmail (LWQ) style setup, you'd apply the patch then continue with
make setup checkin section 2.5.5.
- You can now compile qmail and install as normal.
- You will need to setup a new 'service' to run
greydaemon, and adjust your
qmail-smtpdsetup, see the Setup/Configuration section below.
- I'd appreciate your report on whether you could compile qmail successfully with this patch so that I can update the Compatibility section below - please email email@example.com with details of your system (esp. OS & CPU) - just
cat systypefrom within your qmail source directory after compilation is enough if you're in a hurry.
Setup / Configuration
- Setup a 'service' for
- Enable greylisting in
If you're comfortable with qmail, daemontools etc. you can probably just skim-read this section; if you need a bit more detail, then this section should provide it...
Setting up greydaemon as a 'service':
- You need to run
greydaemon- it runs as a daemon. It listens for UDP requests.
- Assuming you have daemontools installed (as in LWQ), you can create a 'service' as follows (the example paths here follow those of LWQ esp. section 2.8.22, please adjust them for your own installation if necessary):
- Create a user
greyd(for example) for greydaemon to run as.
- Create supervise directories for
mkdir -p /var/qmail/supervise/greydaemon/log
- Change into the
- Create the save directory you've just specified and set its ownership to that of the username
greydaemonwill run as,
mkdir -p save
chown greyd save
- Create a whitelist if you are using one (called
greywhitein this example). You may like to use this whitelist as a starting point (it includes some instructions).
- Create the
exec /var/qmail/bin/greydaemon -m 2 -g 24 -t 30 -u greyd -w greywhite 127.0.0.1 save/savefile 2>&1
- Create the
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/greydaemon
- Make the
chmod +x run log/run
- Create the log directory you've just specified,
mkdir -p /var/log/greydaemon
chown qmaill /var/log/greydaemon
- Link the
ln -s /var/qmail/supervise/greydaemon /service
svstat /service/greydaemon /service/greydaemon/logwhich should give a result like,
/service/greydaemon: up (pid 16646) 100 seconds
/service/greydaemon/log: up (pid 16831) 100 secondsIf either service shows 'up' for only a second or two, you need to check that you've followed these instructions carefully, you can also get a clue looking at the
Enabling greylisting in
Greylisting is enabled using the
GREYIP environment variable. This specifies the IP address and/or port on which
greydaemon is listening. Specifying an empty string,
GREYIP="" disables greylisting; setting
qmail-smtpd to use the default IP address and port for greylisting; or you can specify the IP address where
greydaemon is listening before the
: and/or the port it's listening on after the
:, so for example
- Assuming you've setup your qmail-smtpd service with tcpserver and the
-xoption (as in LWQ), you just need to update the cdb file referenced by this
-xoption. The source for this file is typically
/etc/tcp.smtp. For example,
:allow,GREYIP=":"which would perform greylisting on all addresses except the loopback address and 192.168.x.y addresses.
- If you've setup
greydaemonon a non-default address (perhaps you're running
greydaemonon a separate machine), you'll also need to specify the address it's listening on - adjust the above to include
GREYIP="192.168.5.5:", for example.
- Finally, don't forget to update the cdb file corresponding to the source file you've just edited. If you have a LWQ setup that's,
qmailctl cdbotherwise (assuming
tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
- Alternatively (and particularly if you're not using the
tcpserver) you can enable greylisting for all SMTP connections by setting
GREYIPin the environment in which
qmail-smtpdis started - for example your startup script might now contain the line
exec env GREYIP=":" /usr/local/bin/tcpserver ...
Please let me know if you successfully install greydaemon on systems not listed below (see the end of the installation section on this page).
Compatibility with qmail, netqmail: The greydaemon patch should apply cleanly to the following:
- netqmail 1.05 patched with qmail-logmsg version 1.1, 1.2 or 1.3.
- netqmail 1.06 patched with qmail-logmsg version 1.1, 1.2 or 1.3.
Compatibility with Unix / Linux: Successful compilations have been reported on the following:
- Centos 5.3 / i386 (Systype: linux-2.6.18-128.1.10.el5pae-:i386-:-:ppro-:-)
- Fedora 8 / i386 (Systype: linux-126.96.36.199-57.fc8-:i386-:-:ppro-:-)
- OpenBSD 4.0 / Sparc64 (Systype: openbsd-4.0-custom#1-:openbsd.sparc64-:-:sparc64-:-)
Here are some notes relating to security with this package, these notes are unlikely to be exhaustive:
This package deliberately splits the greylisting functionality such that the actual greylisting part runs as a separate daemon,
qmail-smtpd using UDP to communicate with it. Changes to
qmail-smtpd are minimal and very similar to those used by qmail-verify.
greydaemon has started listening it changes its effective UID/GID if the
-u option has been used.
I've tried to ensure that the changes to
qmail-smtpd.c are minimal and have re-used code employed in qmail-verify to maximise commonality between these packages and make it relatively straightforward to patch both patches to an instance of netqmail.
The request to
greydaemon is sent when the connection gets to the
DATA stage, with the various recipients being included in the request packet. If there are very many recipients and/or these recipients have particularly long addresses, the maximum packet size may be exceeded, in which case the request is truncated. It should still however include some recipients. See the note on
Where greylisting occurs,
qmail-smtpd logs only the first recipient as greylisted - but all recipients will be logged by
greydaemon in this situation.
A few values are specified with
#define at the top of
MAXGREYDATASIZE specifies the largest amount of data to put in a UDP packet; the actual packet will be slightly larger. The default setup sends UDP queries to localhost, so packet fragmentation shouldn't be a problem. Alternatively, having a separate greylisting server may cause UDP fragmentation for larger queries. If you dislike this, you could convert the code to use TCP or lower the max. packet size; 1470 is likely to be fragmentation-safe, but this will reduce the amount of recipient addresses that can be checked.
DEFAULTGREYPORT specifies the default port that
greydaemon will listen on; this can be overridden by
GREYIP at run time.
DEFAULTGREYIP specifies the default IP address that
greydaemon will listen on; this can be overridden by
GREYIP at run time.
GREYTIMEOUT specifies the timeout within which a response would be expected from
greydaemon. In the case of a timeout connections are accepted. To change this behaviour alter the
if (r == 0) line in
grey.c to return 0.
The only other public releases were versions 1.12 and 1.14:
In v1.14 there was a memory leak with the declaration of
grey.c missing a
static prefix (thank you to Manvendra Bhangui).
In v1.12 the code parsing the
GREYIP value only worked by accident(!) - scan_ip_port() and grey_init() were faulty (thank you to Manvendra Bhangui).
This page last updated: AR, 1st July 2013.