% Greyfix
Copyright 2007, 2008, 2009, 2013 by
[Kim Minh Kaplan](mailto:kaplan+greyfix@kim-minh.com)

[Greyfix](http://www.kim-minh.com/pub/greyfix/) is the greylisting policy daemon for [Postfix](http://www.postfix.org/) written by
[Kim Minh Kaplan](http://www.kim-minh.com/).  [Greylisting](http://projects.puremagic.com/greylisting/) is an anti spam technique described by
Evan Harris.  Postfix is a popular mail transport agent developped by
[Wietse Zweitze Venema](http://www.porcupine.org/wietse/).  Greyfix uses Postfix policy mechanism to
enable greylisting with Postfix.

It is recommended that you use at least version 0.3.8.

## Latest version

### Stable version

[greyfix-0.4.0.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.4.0.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.4.0.tar.gz.asc))

The database format has changed. Greyfix will automatically upgrade
it's database. But you will *not* be able to downgrade it.

   - New option `--network6-prefix` for IPv6 address [[Ticket #13](http://trac.kim-minh.com/greyfix/ticket/13)],
   - Use Berkeley DB transaction system,
   - Automatic database recovery,
   - Fix signal handling.

## Features

   - Low and tunable resource usage and high efficiency.  The program
     is written in C and uses Berkeley DB to track mailers.  By itself it
     allocates memory only for a single request and the Berkeley DB library
     can be configured to use very few RAM.
   - Integrates with Postfix's master daemon.  Postfix will shutdown
     greyfix when it is not used completely freeing its runtime
     resources.
   - No administrative burden.  Everything happens "automagically".
   - No need for a database server.  Uses Berkeley DB which is already
     installed with most free Unix distributions.

## Requirements

   - [Postfix 2.1](http://www.postfix.org/) or later.  Greyfix is designed exclusively for it.
     It will *not* work with other mailers.
   - [Berkeley DB 4.0](http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html) or later.  Chances are you already have it.
     It is recommended that you use at least version 4.4.

## Quickstart

Greyfix uses GNU's build system.  To install the greyfix daemon just
type the following commands:

    $ gzip -cd greyfix-0.4.0.tar.gz | tar xf -
    $ cd greyfix-0.4.0
    $ ./configure
    $ make
    $ su -c 'make install'

Edit Postfix's master configuration file, `/etc/postfix/master.cf`, and
add the following (if you are running Solaris see below):

    greyfix    unix  -       n       n       -       -       spawn
      user=nobody argv=/usr/local/sbin/greyfix -/ 24 -6 56

Edit Postfix's main configuration file, `/etc/postfix/main.cf` and add
the following (not for Solaris):

    smtpd_recipient_restrictions = permit_mynetworks,
      reject_unauth_destination,
      check_policy_service unix:private/greyfix

If there is already a `smtpd_recipient_restrictions` configuration line
you should edit it rather than add a new one.  The important part for
Greyfix is that you should add `check_policy_service
unix:private/greyfix` to it.

Finally have postfix reload its configuration with `postfix reload`.

### Solaris

[http://www.postfix.org/SMTPD_POLICY_README.html](http://www.postfix.org/SMTPD_POLICY_README.html) has some important
note for Solaris.  The important thing to note is that Solaris
UNIX-domain sockets do not work reliably. Use TCP sockets instead.
Here is what you should add to your `/etc/postfix/master.cf`:

    127.0.0.1:9998  inet  n       n       n       -       9       spawn
      user=nobody argv=/usr/local/sbin/greyfix -/ 24 -6 56

and to your `/etc/postfix/main.cf`:

    smtpd_recipient_restrictions = permit_mynetworks,
      reject_unauth_destination,
      check_policy_service inet:127.0.0.1:9998
    127.0.0.1:9998_time_limit = 3600

## Usage

    greyfix [-V] [-v] [-d] [-h <Berkeley DB home directory>]
        [-g <greylist delay>]
        [-b <bloc maximum idle>] [-p <pass maximum idle>]
        [-r <reject action>] [-G <greylisted action>]
        [-/ <network bits>] [-6 <network bits]
        [--dump-triplets] [--help]

        -b <seconds>, --bloc-max-idle <seconds>

            This determines how many seconds of life are given to a record
            that is created from a new mail (ip, from, to) triplet.  Note
            that the window created by this setting for passing mails is
            reduced by the amount set for --greylist-delay.  NOTE: See
            also --pass-max-idle.  Defaults to 18000 (5 hours).

        -d, --debug

            Debug logging

        -g <seconds>, --greylist-delay <seconds>

            This determines how many seconds we will block inbound mail
            that is from a previously unknown (ip, from, to) triplet.  If
            it is set to zero, incoming mail association will be learned,
            but no deliveries will be tempfailed.  Use a setting of zero
            with caution, as it will learn spammers as well as legitimate
            senders.  Defaults to 3480 (58 minutes).

        -h <Berkeley DB home directory>, --home <Berkeley DB home directory>

            Location of the Berkeley DB environment home location (the
            default is autoconf's $localstatedir/greyfix
            i.e. /usr/local/var/lib/greyfix).

        --help

            Show usage information.

        -p <seconds>, --pass-max-idle <seconds>

            How much life (in secs) to give to a record we are updating
            from an allowed (passed) email.

            The default is 36 days, which should be enough to handle
            messages that may only be sent once a month, or on things like
            the first monday of the month (which sometimes means 5 weeks).
            Plus, we add a day for a delivery buffer.

        -r <reject action>, --reject-action <reject action>

            The reject action directive that will be used.  See access(5)
            for valid actions.  The string expands %d to the number of
            seconds, %p to the empty string if %d expands to 1 or "s"
            otherwise, %s to " " and %% to "%".

            The default is "DEFER_IF_PERMIT Greylisted by Greyfix X.Y.Z,
            try again in %d second%p.  See
            http://www.kim-minh.com/pub/greyfix/ for more information.".

        -G <greylisted action>, --greylisted-action <greylisted action>

            The action that will be used the first time a triplet passes
            greylisting.  Same expansion as for --reject-action.

            The default is "PREPEND X-Greyfix: Greylisted by Grefix X.Y.Z
            for %d second%p.  See http://www.kim-minh.com/pub/greyfix/ for
            more information."

        -v, --verbose

            Verbose logging

        -V, --version

            Show version information.

        -/ <nbits>, --network-prefix <nbits>

            Only consider the first <nbits> bits of an IPv4 address.
            Defaults to 32 i.e. the whole adresse is significant.

        -6 <nbits>, --network6-prefix <nbits>

            Only consider the first <nbits> bits of an IPv6 address.
            Defaults to 128 i.e. the whole adresse is significant.

        --dump-triplets

            Dump the triplets database to stdout.  Mostly for debugging
            purposes.

## Notes

### Database location

GNU Autoconf's default value for `$(localstatedir)` is
`/usr/local/var/lib` which is quite different from what most Unix
distribution use.  You'll probably want to invoke configure like this:

    $ ./configure --localstatedir=/var/lib

This makes Greyfix DB be located in `/var/lib/greyfix`.  Alternatively
you can use the `-h <DB home>` command line option but do not forget
to create the directory and give it correct permissions so that
Greyfix can access it.

### Logs

Greyfix uses syslog with facility `LOG_MAIL`.  As such the log messages
should appear along postfix's.

### Whitelisting

Should you need some sort of whitelisting for some servers you will
find this feature already built into Postfix.  Therefore refer to its
extensive documentation.  As a quick example to get you started create
a file called `/etc/postfix/whitelist_ip`, each line consisting of the
IP addresse or prefix you need whitelisted followed by the word `OK`
(see the manual for [`access(5)`](http://www.postfix.org/access.5.html) for more on the format of this file):

    # /etc/postfix/whitelist_ip
    127.0.0.1 OK
    192.168   OK
    10        OK

Turn this into a Postfix map file with:

    $ postmap /etc/postfix/whitelist_ip

Then add that as a `check_client_access` lookup *before* Greyfix therefore
bypassing greylisting:

    smtpd_recipient_restrictions = permit_mynetworks,
      reject_unauth_destination,
      check_client_access hash:/etc/postfix/whitelist_ip,
      check_policy_service unix:private/greyfix

A good starting list of hosts to whitelist is
[whitelist_ip.txt](http://projects.puremagic.com/web-svn/wsvn/greylisting/trunk/schema/whitelist_ip.txt).
If you have
[downloaded](http://projects.puremagic.com/web-svn/wsvn/greylisting/trunk/schema/whitelist_ip.txt?op=dl)
that file you can easily create your `whitelist_ip`
file:

    # sed -e '/^[0-9]/s/\([.0-9]*\).*/\1 OK/' whitelist_ip.txt >/etc/postfix/whitelist_ip

### Multiple mail exchangers (MX)

If you have multiple MX on your domain then greylisting has to be
enabled on all of them to be effective.  Otherwise a spamer will just
pass through the MX that has no greylisting enabled.  But if you
install Greyfix on each of your MX, mail can be very long to come
through as each of them is ignorant that a sender has already been
greylisted on one of the other MX.

In that case you have to use a single Greyfix server and have each
Postfix on your MX connect to that Greyfix instance.  Let's pretend we
handle mail for the domain `mydomain.example` using the MX
`mx1.mydomain.example`, `mx2.mydomain.example` and `mx3.mydomain.example`.
We decide to install Greyfix on `greyfix.mydomain.example` port `50804`.

#### Setting up the Greyfix server

Greyfix must be launched from a [super-server](http://en.wikipedia.org/wiki/Super-server) like `inetd`.  First you
should add a line to the `/etc/services` file of `greyfix.mydomain.example`:

    greyfix         50804/tcp       # Postfix greylisting daemon

The `inetd` configuration requires that you add a line to `/etc/inetd.conf`:

    greyfix stream tcp nowait nobody /usr/local/sbin/greyfix greyfix -/ 24 -6 56

Remember to have `inetd` reload its configuration file (`kill -1
$pid_of_inetd` should do the trick).

If you have experience using `xinetd` or other super-server examples are
welcome.

#### Configuring Postfix

Each MX must now be setup to query that particular Greyfix server.  On
`mx1.mydomain.example`, `mx2.mydomain.example` and `mx3.mydomain.example`
use a Postfix `/etc/postfix/main.cf` with something like:

    smtpd_recipient_restrictions = permit_mynetworks,
      reject_unauth_destination,
      check_policy_service inet:greyfix.mydomain.example:50804
    greyfix.mydomain.example:50804_time_limit = 3600

#### Caveats

When you do this the Greyfix server becomes a single point of failure
so you should carefully consider the pros and cons of such a setup.

You should protect the Greyfix service from access from unauthorized
parties either putting it behind a firewall or enabling [TCP Wrapper](http://en.wikipedia.org/wiki/TCP_Wrapper):
Greyfix itself does not provide any access control.

## TODO

   - Real documentation
   - Statistic collection
   - Distribute triplets to other MX.
   - Auto whitelisting of mail relays that pass greylisting repeatedly
   - SPF?  This could render `--network-prefix` unnecessary,
   - Use Milter protocol?

## BUGS

Bugs are filed on [Greyfix's ticket page](http://trac.kim-minh.com/greyfix/report).  To report a bug see first
check that it is not already present in the list.  Then you can create
a [New Ticket](http://trac.kim-minh.com/greyfix/newticket).

## Mailing list

The Greyfix mailing list is hosted at [Google
groups](http://groups.google.com/group/greyfix). You can subscribe by
sending an email to
[greyfix+subscribe@googlegroups.com](mailto:greyfix+subscribe@googlegroups.com). Currently
(year 2013) this is a very low volume mailing list.

## Older versions

Note that version 0.3.8 fixes important bugs.  Do *not* use earlier
versions.

   - [greyfix-0.3.9.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.9.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.9.tar.gz.asc))
      - BUGFIX: when greylisting by network prefix (option `-/`) Greyfix
	 would treat all IPv6 addresses as `""` (empty string) [[Ticket #9](http://trac.kim-minh.com/greyfix/ticket/9)].

   - [greyfix-0.3.8.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.8.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.8.tar.gz.asc))
      - BUGFIX: when there is an error let the email through and exit the process [[Ticket #5](http://trac.kim-minh.com/greyfix/ticket/5)].
      - BUGFIX: detect deadlocks and resolve them [[Ticket #8](http://trac.kim-minh.com/greyfix/ticket/8)].
      - Don't remove the DB environment.
      - Remove the unused stats.db database.
      - Minor install directories fix [[Ticket #7](http://trac.kim-minh.com/greyfix/ticket/7)].
   - [greyfix-0.3.7.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.7.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.7.tar.gz.asc))
      - Do not block emails if there is an error.  Previous versions would die.  This would cause Postfix's smtpd to reply with an error code 500 and the email would bounce.  Now Greyfix will log a warning and let the email continue.
      - BUGFIX: expire correctly IDLE triplets.
   - [greyfix-0.3.6.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.6.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.6.tar.gz.asc))
      - Backward compatibility fix for Berkeley DB 4.0.
   - [greyfix-0.3.5.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.5.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.5.tar.gz.asc))
      - Backward compatibility fix for Berkeley DB 4.2 and before.
      - Add `--help` and `--version` options, thanks to Stefan Siegel.
   - [greyfix-0.3.4.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.4.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.4.tar.gz.asc))
      - BUGFIX: include missing `policy.h` file.
   - [greyfix-0.3.3.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.3.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.3.tar.gz.asc))
      - BUGFIX expire correctly triplets
      - Add option `--dump-triplets`, `--reject-action` and `--greylisted-action`.
      - Really delete expired triplets from the DB.
      - Note that `451` reject code is probably better than `DEFER_IF_PERMIT`.
   - [greyfix-0.3.2.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.2.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.2.tar.gz.asc))
      - Runtime configurable delays.
      - Document command line arguments in README.
      - New option `--network-prefix`.
   - [greyfix-0.3.1.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.1.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.1.tar.gz.asc))
      - Syslog with `LOG_MAIL` facility.
      - Expire positive triplets.
      - Error on invalid command line arguments.
      - Add delay information in SMTP and header messages.
      - Cleanup on receipt of signal.
   - [greyfix-0.3.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.3.tar.gz.asc))
   - [greyfix-0.2.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.2.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.2.tar.gz.asc))
   - [greyfix-0.1.tar.gz](http://www.kim-minh.com/pub/greyfix/greyfix-0.1.tar.gz) ([signature](http://www.kim-minh.com/pub/greyfix/greyfix-0.1.tar.gz.asc))
