John Levine's greydaemon
On this page: • Introduction • License • Status/Warranty • Documentation • Pre-requisites • Download • Installation • Setup / Configuration • Compatibility • Security • Programming Notes • Archives
Introduction
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.
License
The 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.
Documentation
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):
- greydaemon(8)
- qmail-smtpd(8) - see the 'Greylisting' section.
Pre-requisites
This package is for netqmail 1.06 patched with qmail-logmsg. Perl is required - that's what greydaemon
is written in.
Download
The current release, version 1.15, is available in plaintext or gzipped (.gz).
Installation
Proceed as follows:
- Unpack the patch if you've downloaded a compressed version.
- Patch your qmail source: Enter your
netqmail-1.06
source 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 check
in 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 yourqmail-smtpd
setup, 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 grey-compat@acrconsulting.co.uk with details of your system (esp. OS & CPU) - just
cat systype
from within your qmail source directory after compilation is enough if you're in a hurry.
Setup / Configuration
Summary:
- Setup a 'service' for
greydaemon
. - Enable greylisting in
qmail-smtpd
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...
In detail:
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
greydaemon
[/log
],mkdir -p /var/qmail/supervise/greydaemon/log
- Change into the
supervise/greydaemon
directory,cd /var/qmail/supervise/greydaemon
- Create the save directory you've just specified and set its ownership to that of the username
greydaemon
will run as,mkdir -p save
chown greyd save
- Create a whitelist if you are using one (called
greywhite
in this example). You may like to use this whitelist as a starting point (it includes some instructions). - Create the
run
file,#!/bin/sh
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
log/run
file,#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/greydaemon
- Make the
run
andlog/run
files executable,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
supervise/greydaemon
directory into/service
:ln -s /var/qmail/supervise/greydaemon /service
- Check
greydaemon
andgreydaemon/log
are running:svstat /service/greydaemon /service/greydaemon/log
which should give a result like,/service/greydaemon: up (pid 16646) 100 seconds
/service/greydaemon/log: up (pid 16831) 100 seconds
If 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 thereadproctitle
ps entry.
Enabling greylisting in qmail-smtpd
:
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 GREYIP=":"
causes 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 GREYIP="192.168.10.10:19191"
.
- Assuming you've setup your qmail-smtpd service with tcpserver and the
-x
option (as in LWQ), you just need to update the cdb file referenced by this-x
option. The source for this file is typically/etc/tcp.smtp
. For example,127.:allow,RELAYCLIENT=""
192.168.:allow,RELAYCLIENT=""
:allow,GREYIP=":"
which would perform greylisting on all addresses except the loopback address and 192.168.x.y addresses. - If you've setup
greydaemon
on a non-default address (perhaps you're runninggreydaemon
on a separate machine), you'll also need to specify the address it's listening on - adjust the above to includeGREYIP="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 cdb
otherwise (assuming/etc/tcp.smtp
,/etc/tcp.smtp.cdb
),tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
- Alternatively (and particularly if you're not using the
-x
option totcpserver
) you can enable greylisting for all SMTP connections by settingGREYIP
in the environment in whichqmail-smtpd
is started - for example your startup script might now contain the lineexec env GREYIP=":" /usr/local/bin/tcpserver ...
Compatibility
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:
Linux:
- Centos 5.3 / i386 (Systype: linux-2.6.18-128.1.10.el5pae-:i386-:-:ppro-:-)
- Fedora 8 / i386 (Systype: linux-2.6.26.8-57.fc8-:i386-:-:ppro-:-)
Unix:
- OpenBSD 4.0 / Sparc64 (Systype: openbsd-4.0-custom#1-:openbsd.sparc64-:-:sparc64-:-)
As discussed below under programming notes, the UDP/socket code is the same as that in qmail-verify which will make patching with it relatively straightforward.
Security
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, greydaemon
, with qmail-smtpd
using UDP to communicate with it. Changes to qmail-smtpd
are minimal and very similar to those used by qmail-verify.
Once greydaemon
has started listening it changes its effective UID/GID if the -u
option has been used.
Programming Notes
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 MAXGREYDATASIZE
below.
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 grey.h
:
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 greycheck()
in grey.c
to return 0.
Archives
The only other public releases were versions 1.12 and 1.14:
In v1.14 there was a memory leak with the declaration of chkpacket
in 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.