# $Id: README,v 1.69 2017/07/07 21:59:13 manu Exp $
###########################################################################

		     ======================================
		       milter-greylist installation notes 
		       $Date: 2017/07/07 21:59:13 $
		     ======================================

		       Emmanuel Dreyfus <manu@netbsd.org>

Table of contents:  
==================

 1 Building and installing milter-greylist 
 2 Configuring Sendmail with milter-greylist
 3 Configuring Postfix with milter-greylist
 4 Configuring milter-greylist 
 5 Trying it out for a few users 
 6 Running it for the whole site 
 7 Lists and per-ACL settings
 8 Dealing with mail farms
 9 Working with multiple MXs
 10 Using DNSRBL
 11 Building with SPF
 12 Using DRAC
 13 Using URL checks
 14 Using LDAP natively
 15 Using TLS
 16 Using tarpit
 17 Custom logs
 18 Packaging
 19 Things to look at if things get wrong
 20 Known problems
 21 License

Run this command to regenerate a table of contents:
 sed '/^.====/{g;p;};h;d' README

 1 Building and installing milter-greylist 
 =========================================

This section deals with installing milter-greylist from sources. If you
want to generate a RPM, see section 16 of this document.

First, download the sources. You can get a tarball from
http://ftp.espci.fr/pub/milter-greylist

or you can check out bleeding edge source from milter-greylist CVS:
cvs -danoncvs@anoncvs.fr.netbsd.org:/milter-greylist co -P milter-greylist
Don't forget to set CVS_RSH=ssh if this is not your system default.

Build dependencies: 
- flex (AT&T lex cannot build milter-greylist sources)
- yacc or bison (some older yacc will fail, use bison instead)
- libmilter (comes with Sendmail, or with the sendmail-devel
  package on RedHat, Fedora and SuSE. Debian and Ubuntu have it
  in libmilter-dev)
- Any POSIX threads library (Provided by libc on some systems)

Optional dependencies: 
- libspf2, libspf_alt or libspf, for SPF support
- libcurl, for URL checks support
- libGeoIP, for GeoIP support
- libbind from BIND 9, for DNSRBL support, except if your system has a 
  thread-safe DNS resolver built-in.

Before building milter-greylist, it might be wise to view the
configuration options by running:
./configure -help

To build milter-greylist, just do the usual 
./configure && make && make install

If libpthread and libmilter are not automatically located, use
--with-libpthread and --with-libmilter flags to the configure
script.

If you intend to run milter-greylist under an unprivileged
UID, use the --with-user flag.

A Makefile is supplied in the distribution in case you run into real 
trouble with configure and are unable to get it generating a Makefile
suited to your system. Of course this Makefile is not likely to work 
on your system (it is configured for NetBSD-3.0) and it will probably
need manual tweaks.

On the make install step, the Makefile will install a default config
file in /etc/mail/greylist.conf, except if there is already such
a file. In that case the original file is preserved. Great care is taken
to maintain milter-greylist backward compatibility, so no config file 
change should be nescessary when upgrading: Just replacing the 
milter-greylist binary and restarting the milter should be enough.

Some startup scripts are available: rc-redhat.sh, rc-debian, rc-gentoo.sh,
rc-suse.sh for Linux, rc-bsd.sh for NetBSD and FreeBSD, and rc-solaris.sh
for Solaris. They are not installed by default; you have to install the 
startup script manually if you want to use one.


 2 Configuring Sendmail with milter-greylist
 ===========================================

You need a few options in sendmail.cf to use milter-greylist:

O InputMailFilters=greylist 
Xgreylist, S=local:/var/milter-greylist/milter-greylist.sock 
O Milter.macros.connect=j,{if_addr}
O Milter.macros.envfrom=i

If you use SPF, DNSRBL or urlchecks, then milter-greylist can 
spend a lot of time waiting for DNS lookups to complete. This
may lead to sendmail reporting timeout errors. If you see such
messages, consider setting a timeout larger than the default (see 
Sendmail's milter documentation for more details on timeout settings):

Xgreylist, S=local:/var/milter-greylist/milter-greylist.sock, T=R:1m

Note that InputMailFilters and Milter.macros.* options are shared 
with other milters, and the other milters you have set up may 
require additionnal macros. Therefore you need to merge what
milter-greylist needs with what other milters need. If you just
copy the lines proposed in this file, this is likely to break 
other milters setup. In this section we simply list the macros 
milter-greylist require. Your default sendmail.cf is likely to already 
contain the proper Milter.macros.* setup.

If you want to bypass greylisting for users that succeeded SMTP AUTH, 
you also need {auth_authen} in Milter.macros.envfrom:
O Milter.macros.envfrom=i, {auth_authen}

If you want to bybass greylisting for users that use STARTTLS with 
a client certificate, you also need {verify} and {cert_subject}
in Milter.macros.helo: 
O Milter.macros.helo={verify},{cert_subject}

If you want to use Sendmail access DB as a whitelisting source, you
will need {greylist} too. milter-greylist will whitelist a message
when the {greylist} macro is defined and set as WHITE.
O Milter.macros.envrcpt={greylist}

When using access DB as a whitelisting source, you will also need some
rules for the ruleset "Local_check_rcpt" which assign a value to the
macro {greylist}.
Kstorage macro
SLocal_check_rcpt
R$+		$: $(storage {greylist} $) $&{client_addr}
R$+		$: $>A <$1> <?> <+Connect> <$1>
R<$+> <$*>	$: $(storage {greylist} $@ $1 $) $2

Alternatively, you can use the following m4 macro definitions 
if you build sendmail.cf with m4 (contributed by Hubert Ulliac).
Here again, confMILTER_MACROS_* are shared with other milters,
so you need to merge the definitions with what others milters 
require. Just copying the lines below is likely to cause other
milters to malfunction.

INPUT_MAIL_FILTER(`greylist',
`S=local:/var/milter-greylist/milter-greylist.sock')
define(`confMILTER_MACROS_CONNECT', `j, {if_addr}')
define(`confMILTER_MACROS_HELO', `{verify}, {cert_subject}')
define(`confMILTER_MACROS_ENVFROM', `i, {auth_authen}')
define(`confMILTER_MACROS_ENVRCPT', `{greylist}')

Ivan F. Martinez contributed the milter-greylist.m4 file that includes 
thoses definitions and will take care of adding the macros required by
milter-greylist instead of overwriting what has already been done. This 
should simplify an automatic generation of sendmail.cf.

To add the rules for defining the {greylist} macro via m4, add the following
lines to your m4 input file:

LOCAL_CONFIG
Kstorage macro
LOCAL_RULESETS
SLocal_check_rcpt
R$+		$: $(storage {greylist} $) $&{client_addr}
R$+		$: $>A <$1> <?> <+Connect> <$1>
+R<?> <$+>	$: <?> $&{client_name}
+R<?> $+	$: $>D <$1> <?> <+Connect> <$1>
+R<$+> <$*>	$: $(storage {greylist} $@ $1 $) $1

Note that there must be tabs and no spaces before the "$:"!

Some sample entries for /etc/mail/access:

Connect:1.2.3          OK
Connect:provider.net   OK

As RHS the keywords "WHITE", "RELAY" or "OK" are allowed. But to make sure
Sendmail keeps accepting mails from the given source "OK" is the usually
the best, except explicitly full relaying is desired where "RELAY" should
be given.

On the LHS the tag "connect:" is mandatory, followed by either an address
or a domain (both of them might be partial, covering a whole network or
any subdoman).

 3 Configuring Postfix with milter-greylist
 ==========================================

As Postfix currently does not provide milter library, you need to have
sendmail sources or development package installed. See
http://www.postfix.org/MILTER_README.html#limitations

Use --enable-postfix flag when configuring milter-greylist, or you
can build an rpm like this:
rpmbuild --define "build_postfix 1" -tb milter-greylist-3.1.4.tgz

Add the following to postfix main.cf (customize for your needs):
milter_default_action = accept
milter_connect_macros = j
milter_protocol = 3
smtpd_milters = unix:/var/milter-greylist/milter-greylist.sock

To include postfix queue IDs in the milter-greylist log, add the
following to postfix main.cf (this may impact performance of postfix;
see postconf(5) man page for details):
smtpd_delay_open_until_valid_rcpt = no


 4 Configuring milter-greylist 
 =============================

Edit /etc/mail/greylist.conf, and add addr lines for at least
localhost and all your local network addresses. Here is an example:

racl whitelist addr 127.0.0.0/8
racl whitelist addr 192.0.2.0/24 
racl whitelist addr 10.0.0.0/8

Then consider adding addresses of all the friendly networks you get
mail from. By friendly networks, we mean networks with no spammers:
Universities are usually friendly, some companies are friendly,
some others are not, and dial-up and ADSL ISPs are definitively not
friendly at all.

For the sake of completeness, "racl" stands for RCPT-stage ACL. This
rule is evaluated on each of the RCPT stages of the SMTP transaction. 
milter-greylist also supports "dacl", evaluated once after DATA stage.

 5 Trying it out for a few users 
 ===============================

Add some rcpt access-lists to /etc/mail/greylist.conf for the users 
that want to try milter-greylist filtering. Here is an example:

racl greylist rcpt John.Doe@example.net 
racl greylist rcpt webmaster@example.net 
racl greylist rcpt postmaster@example.net

Then finish your ACL with the default rule: here, anything that
is not for John.Doe@example.net, webmaster@example.net, or
postmaster@example.net will not get greylisted:

racl whitelist default

Now you can start milter-greylist:

milter-greylist -u smmsp -p /var/milter-greylist/milter-greylist.sock

If you have trouble with the socket file, check the permissions of
the directory where the socket is located. The default directory is
/var/milter-greylist and it should be chmod 0755 and owner smmsp, if 
you are running the milter as smmsp. If permissions are wrong, 
sendmail will complain to syslog, stating the directory is unsafe.

If sendmail complains it cannot connect to the milter because of a 
connection refused, that either means that the milter is not running, 
or that the socket location configured in sendmail.cf is not the same
as what was given to milter-greylist with the -p flag.

Sometimes, milter-greylist has trouble starting up because of a stale
socket file in /var/milter-greylist/milter-greylist.sock. Just removing
the socket and restarting milter-greylist should fix the problem.

You might want to add -v and -D to get more debugging output. The
-w flag is used to choose how long we will refuse a given message.
If you want to check that things work, try 10 seconds with -w10.

The -a option controls auto-whitelisting. Once a (sender IP, sender e-mail,
recipient e-mail) tuple has been accepted, it is marked autowhitelisted,
and similar tuples will be accepted with no retry for one day. Using -a0
disables this feature.


 6 Running it for the whole site 
 ===============================

Remove the "racl greylist rcpt ..." lines from /etc/mail/greylist.conf, 
and replace "racl whitelist default" by

racl greylist default

Now greylisting is enabled for every recipient. If some of your 
users don't want greylisting, add a "racl whitelist rcpt" line for them 
in /etc/mail/greylist.conf. Make sure you put it before 
"racl greylist default": ordering does matter, as the ACL rules are
evaluated on a first match wins basis.

If your mail server handles several domains and you want to enable
milter-greylist for a whole domain but not for everyone, this is 
possible, just use a regular expression:

racl greylist rcpt /@example\.net$/
racl whitelist default


 7 Lists and per-ACL settings
 ============================

It is possible to have per-ACL greylisting and autowhitelisting
settings:

racl greylist rcpt /@example\.net$/ delay 15m autowhite 3d
racl greylist default delay 30m autowhite 1d

Here, all messages to domain example.net will have a greylisting delay
of 15 minutes and will be autowhitelisted for 3 days, while messages
to other domains will be greylisted for 30 minutes and autowhitelisted
for one day.

milter-greylist is now also able to use lists, which is very useful for
factoring rules:

list "users" rcpt { user1@example.com user2@example.com user3@example.com }
racl greylist list "users"
racl whitelist default

Here message sent to members of the "users" list will be greylisted, while
other messages will not.

Theses two advanced features were added in release 2.1.7 and may not be
fully stable.


 8 Dealing with mail farms
 =========================

Some Internet service provider such as Hotmail feature mail farms,
where several different machines are able to resend an e-mail. The
message is likely to be resent from different IP addresses, and this
is likely to break with milter-greylist.

The -L option is an ad-hoc hack for this problem. It provides
milter-greylist a CIDR mask to use when comparing IPv4 addresses. 
With -L24, the match mask is 255.255.255.0, and any address in a 
class C network is considered the same.

There is also a real fix for the problem: SPF. SPF is a DNS based
mechanism that enables domains to publish the identity of machines
allowed to send mail on behalf of the domain. milter-greylist knows 
how to use SPF through libspf or libspf_alt. See section 8 of this
document: Building with SPF

Another workaround is simply to whitelist the netblocks allocated to 
mail farms. As any machine in theses IP address ranges are real SMTP 
servers that will always resend their messages, there is no point in 
greylisting them.


 9 Working with multiple MXs
 ===========================

When running several MXs, the client should try each server after
its message gets refused, thus causing greylist entries creation 
on each MX. Things should work, but with two minor problems:

* Some stupid clients don't try all the available MXs. In that 
  situation, it could take some time before the message gets in,
  as the client might try a different MX each time and wait for 
  several hours between the retries.

* After a messages is accepted, its entry is removed for one MX, 
  but not the others. Stale entries remain until being flushed
  because of a timeout. If a message with the same {IP, from, rcpt}
  gets in on an MX with a stale entry, it will be accepted 
  immediately, and the X-Greylist header will report it had been
  delayed for some time.

In order to address these issues, milter-greylist is now able to
sync the greylist among different MXs. This can be configured in
the greylist.conf file, by adding one line per peer MX,  
like this:
peer 192.0.2.17
peer 192.0.2.18

If you have firewalls between your MXs, you should enable TCP 
connections in both directions between random unprivileged 
source ports and destination port 5252.


 10 Using DNSRBL
 ===============

milter-greylist can use a DNSRBL to decide wether a host should be
greylisted or whitelisted. For instance, let us say that you want to
greylist any host appearing in the SORBS dynamic pool list (this include
DSL and cable pools). You would do this:

# if IP 192.0.2.18 is positive, then nslookup of 18.2.0.192.dnsbl.sorbs.net 
# returns 127.0.0.10
dnsrbl "SORBS DUN" dnsbl.sorbs.net 127.0.0.10
racl greylist dnsrbl "SORBS DUN"

You can combine it with variable greylisting delays so that dynamic hosts
get a greylisting delay of 12 hours while other hosts only get 15 minutes:

dnsrbl "SORBS DUN" dnsbl.sorbs.net 127.0.0.10
racl greylist dnsrbl "SORBS DUN" delay 12h
racl greylist default delay 15m

This feature was introduced in milter-greylist 2.1.7 and may not be
fully stable. You need the --enable-dnsrbl flag to configure to use 
it. You must link milter-greylist with a thread-safe resolver, else 
the milter will be unstable (see the explanation in the SPF section).

If your resolver is not thread safe, install BIND9, and use 
--with-libbind. If you know your resolver is thread-safe but 
configure tells otherwise (because you lack the res_ninit() function),
then use --with-thread-safe-resolver. 

If you install BIND9, make sure it includes libbind.a, since this is
what milter-greylist needs. libbind.a is not created in BIND9 default
build setup, so you might not have it in a precompiled package. If you 
cannot find a package that contains libbind.a, then you have to rebuild
BIND9 from sources, using the --enable-libbind 
flag to BIND9's configure.


 11 Building with SPF
 ====================

milter-greylist can use either libspf or libspf2 to perform SPF
checks. Use --with-libspf=DIR or --with-libspf2=DIR to enable this
feature. DIR must be the base directory where include and lib
directories containing the headers and library can be found.

If you want to link with an older version of libspf2, you will
need one of the following configure flags:
For older libspf_alt: --with-libspf_alt=DIR
For older libspf2 up to version 1.0: --with-libspf2_10=DIR
For newer libspf2: --with-libspf2=DIR

WARNING: milter-greylist is a multithreaded program. The external
functions it uses must be thread-safe. While libspf and libspf_alt
contain only thread-safe code, they use the DNS resolver. By default,
the DNS resolver from libc or libresolv is used. If this resolver
is not thread-safe, milter-greylist with SPF will quickly crash or
hang.

You need to make sure that libspf or libspf_alt are linked against
a thread-safe DNS resolver. For instance, NetBSD-1.6.2 libc-supplied
resolver is from BIND 4, and it is not thread safe. In order to get
a stable milter-greylist, you need to link with a BIND 8.2 or higher
resolver.

When building with libspf_alt-0.4, you might encounter problems if
libbind is only available as a static library. It seems to be the
default with BIND 8, which causes troubles. BIND 9 is fine.


 12 Using DRAC
 =============

milter-greylist can be built with DRAC (Dynamic Relay Authorization
Control) support, by giving the --enable-drac flag to configure.
Location of the DRAC DB file can be chosen at build time with
--with-dracdb=PATH, and at runtime with the drac db "PATH"
configuration file option.

If built-in, DRAC can be disabled by the nodrac configuration file
option.

More information on DRAC can be obtained at 
http://mail.cc.umanitoba.ca/drac/


 13 Using URL checks
 ===================

ACL can cause URL lookups:

urlcheck "mytest" "http://www.example.net/mgl.php?rcpt=%r+ip=%i" 10
racl greylist urlcheck "mytest"

For each ACL evaluation will spawn a request to
http://www.example.net/mgl.php?rcpt=%r+ip=%i, with
%r replaced by recipient e-mail
%i replaced by IP address
You can also substitute domain, sender address, and various other data,
including any sendmail macro. Check the greylist.conf(5) man page for
details. The trailing 10 is the maximum number of simultaneous
connections you want to have.

The mgl.php script is to answer if you get a match by sending back this:
milterGreylistStatus: Ok

Even better, you can send settings in the reply:
milterGreylistStatus: Ok
milterGreylistDelay: 1h

autowhite, code, ecode, flushaddr and msg can be overloaded. You can
even overload the ACL action (ie: turning a greylist ACL into a
blacklist action), see the man page for details.

Something to note: the reply format is LDIF-like. It was chosen so that
the URL could be a ldap:// query, though this has not been experimented 
yet. 


 14 Using LDAP natively
 ======================

It is possible to use URL checks against an LDAP URL, but that method
has some drawbacks:
- This uses CURL, which must be built with LDAP support
- There might be thread-safety problems. A workaround it to use the
  fork option of urlcheck statement, so that milter-greylist forks 
  a pool of instances to perform queries. This may not be very reliable
  on some setups.
- It is not possible to fallback to another server if the LDAP directory 
  goes down.

milter-greylist can also support LDAP natively, using OpenLDAP libraries,
if configure --with-openldap is used. 

Here is an example that pulls a per-user sender whitelist from the 
directory:

ldapconf "ldapi:// ldaps://ldap.example.net"
ldapcheck "mytest" "ldap://ldap.example.net/o=example?whitelist?sub?mail=%r"
racl whitelist ldapcheck "mytest" $whitelist "%f"
racl greylist default

The ldapconf statement is used to list LDAP servers. If one goes down, 
another will be contacted. For ldaps:// URLs, certificate information
is taken from system ldap.conf.

ldapcheck definition works like urlcheck with the getprop option (see 
the man page for details). Note that the scheme and host parts of the 
URL are just ignored: information from ldapconf is used instead.


 15 Using TLS
 ==============

Using the "tls" clause, an ACL could match any email that succeeded TLS
check in sendmail (STARTTLS giving "verify=OK"). This assumes you already
have TLS working in sendmail.

racl whitelist tls "DN1"
racl whitelist tls "DN2"

or

list "trusted" tls { "DN1" "DN2" }
racl whitelist list "trusted"

A DN has a special syntax.
If you used the 'update_tls' script provided with sendmail to generate
your certificates, your DN should look like this:

"/O=Sendmail/OU=Sendmail+20Client/CN=machine.example.net/emailAddress=admin@machine.example.net"

Note that it's the "client" certificate (of the remote server) that is used
as (the local) sendmail is acting as server during that transaction.

To find the DN of any certificate, you can use the openssl command:

$ openssl x509 -noout -issuer < some.crt | cut -d' ' -f2- | sed -e 's/ /+20/g'

 15 Using tarpit
 ===============

'tarpit' is an anti-spam technique by lazy response.

  racl whitelist tarpit 65s

This ACL means that clients that can wait a response in
65s are whitelisted. If the clients access again, they are
accepted without lazy response because they are in
auto-whitelist.

If clients that couldn't wait a lazy response access again,
the ACL doesn't match.

  racl whitelist tarpit 65s
  racl default greylist

Those ACLs means that clients that can wait a lazy
response or resend a message are acceptable.

  racl greylist tarpit 10s

This ACL means that clients should wait a response in 10s
then pass greylist.

If clients that couldn't wait a lazy response access again,
the ACL doesn't match.

  racl greylist tarpit 10s
  racl default blacklist

Those ACLs means that clients should wait a lazy response
and pass greylist. Otherwise they are rejected.

There is a 'tarpit_scope' configuration parameter. It
controls how to count tarpitted time. Available values are
'session' and 'command'. 'session' means that tarpitted time
is counted in a SMTP session scope.  'command' means that
tarpitted time is counted in an SMTP command (request/response)
scope. The default is 'session'.

  racl whitelist rcpt user1@example.com tarpit 10s
  racl whitelist rcpt user2@example.com tarpit 30s
  racl whitelist rcpt user3@example.com tarpit 15s

It assumes that a client sends a mail to user1@example.com,
user2@example.com and user3@example.com in a SMTP session
when those ACLs are used.

'session' case:
  milter-greylist waits to return a response in
  10s for user1@example.com. Then milter-greylist waits to
  return a response in 20s for user2@example.com. 20s is
  30s (tarpit time for user2@example.com) - 10s (tarpit time
  for user1@example.com). milter-greylist just wait 20s
  because milter-greylist had waited 10s. Then
  milter-greylist doesn't wait to return a response for
  user3@example.com because total 30s had waited in this
  SMTP session.

    user1@example.com: tarpit 10s
    user2@example.com: tarpit 20s
    user3@example.com: not tarpitted

'command' case:
  milter-greylist waits to return a response in 10s for
  user1@example.com. Then milter-greylist waits to return a
  response in 30s for user2@example.com. Waited time in the
  previous SMTP command is not counted. Then milter-greylist
  doesn't wait to return a response for user3@example.com
  because over 10s had waited in other SMTP command.

    user1@example.com: tarpit 10s
    user2@example.com: tarpit 30s
    user3@example.com: not tarpitted

 17 Custom logs
 ==============

It is possible to monitor milter-greylist activity with a custom log
format. You can choose where the output is sent (file or external
command), and the output format. If you have this in greylist.conf:
stat ">>/var/log/milter-greylist.log" "%T{%T}    %i:%f:%r:%S\n"

On each mail, this will give you a line like this in milter-greylist.log:
10:08:04    192.0.2.16:spammer@evil.com:postmaster@example.net:reject

Another example, to send the data to the local7 facility of syslog,
using the external command logger:
stat "|logger -p local7.info" "%i:%f:%r:%S\n" 

Substitutions are the same as in URL checks (%i becomes sender IP, %s
becomes sender e-mail, %r becomes recipient, and so on). A few nifty
additions:

%T{format} is substituted by strftime(3) time format. So %T{%F %T} gives
you a date/time in the following format: YYYY-MM-DD HH:MM:SS 
%S is substituted by the action milter-greylist chose: accept, tempfail
or reject
%A is substituted by the line number of the ACL that caused the decision


 18 Packaging
 ============

milter-greylist is available from NetBSD pkgsrc and FreeBSD ports.
A .spec file is included in the distribution to build an RPM for
RedHat Linux. This is achieved by running rpmbuild on milter-greylist
source tarball: rpmbuild -tb milter-greylist-3.1.4.tgz. You can define
build_user, build_postfix, build_dnsrbl, build_libbind - for example,
to build with DNSRBL support and choose smmsp as the user that will run
milter-greylist, use
rpmbuild --define "build_user smmsp" --define "build_dnsrbl 1" \
  -tb milter-greylist-3.1.4.tgz


 19 Things to look at if things get wrong
 ========================================

First, read the milter-greylist(8) and greylist.conf(5) man page! :-)

Second, reread the installation notes at the beginning this file! ;-)

Each message will get an X-Greylist header indicating either how long the
message has been delayed, or that it has been passed through because of
whitelisting. It looks something like this:

For messages which were delayed because of greylisting:
  X-Greylist: Delayed for 00:53:21 by milter-greylist-M.m
      (mail.example.net [192.0.2.16]); Wed, 3 Mar 2004 17:01:06 -0000

For messages which were not delayed because of whitelisting (e.g. they
are whitelisted in the configuration file):
  X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-M.m
      (mail.example.net [192.0.2.16]); Wed, 3 Mar 2004 17:01:06 -0000
  X-Greylist: Sender DNS name whitelisted, not delayed by milter-greylist-M.m
      (mail.example.net [192.0.2.16]); Wed, 3 Mar 2004 17:01:06 -0000

For messages which were not delayed because of auto-whitelisting from a
previously resent and accepted message:
  X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by
      milter-greylist-M.m (mail.example.net [192.0.2.16]); Wed, 3 Mar 2004
      17:01:06 -0000

where M.m is the major and minor version number of milter-greylist.

The file /var/milter-greylist/greylist.db is a dump of the greylist.
It is done periodically and is used to restore state after
milter-greylist has been restarted. The file contains an entry per
line, with four columns:  IP address, sender e-mail address,
recipient e-mail address, and time when the message will be accepted
(in seconds since 00:00:00 01-01-1970).  Here is an example:

10.0.23.1  <evilspammer@example.com>  <pooruser@example.net>  1078344409

Additionally, you can find a human-readable time in the comment at the
end of each line.

At the end of the file, you will find entries with the keyword AUTO
at the end of the line. Theses are auto-whitelisted tuples. The date
tells you when the entry will expire.

Examining the tail of this file may reveal problems with domains which
use multiple MX servers or whose mail is actually served by another site.


 20 Known problems
 =================

If milter-greylist terminates during its operation, first check your
system limits with ulimit (sh/ksh/bash) or limit (csh/tcsh). As it stores 
its complete database in memory, milter-greylist can eat a large amount of 
memory on a busy mail server. Each incoming connection uses a socket, so
file descriptors can easily be exhausted too. Any resource shortage will
cause milter-greylist to quit. This is not specific to milter-greylist; 
all milters do that.

When SPF support is compiled in, if milter-greylist hangs and/or crashes
regularly, check that you linked your SPF library with a thread-safe
resolver. This can be done by running nm(1) on milter-greylist: if
nres_init is referenced, you are fine.  If res_init is referenced, you 
are probably at risk.

When DNSRBL support is compiled in, you also need to make sure that
milter-greylist itself is linked with a thread-safe resolver.

On Solaris 2.8, milter-greylist may grow out of memory rather quickly 
due to some bugs in the pthread nsl and socket libraries. It is strongly 
recommended that you install the latest revision of patch 108993 (sparc) 
or 108994 (x86). Solaris 9 and later do not seem to be affected.
Solaris patches are available from <http://sunsolve.sun.com/>

On Solaris, and on some IRIX releases, the file descriptor field 
of <stdio.h>'s FILE structure is a char, and thus no more than 255 
streams can be open at once. This will cause failures in milter-greylist 
when handling a large number of connections. If you are not sure whether 
your system is affected or not, check your system headers for the FILE 
definition. On Solaris, the problem only exists with the 32 bit ABI, 
so rebuilding milter-greylist with a 64 bit compiler will fix the problem.
An alternative is to use the --enable-stdio-hack option to configure

On IRIX, milter-greylist has to be compiled with the same ABI as
libmilter. If libmilter was built with the MIPSpro compiler,
milter-greylist should be too, because of binary incompatibility
between gcc and the MIPSpro compilers. This can be achieved by invoking
configure with the CC environment variable set to cc. This
incompatibility may be fixed in gcc 3.4.


 21 License
 ==========

This software is available under a 3 clauses BSD license:
  Copyright (c) 2004-2007 Emmanuel Dreyfus
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
  3. All advertising materials mentioning features or use of this software
     must display the following acknowledgement:
         This product includes software developed by Emmanuel Dreyfus

  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  OF THE POSSIBILITY OF SUCH DAMAGE.


If you run on a non-BSD system, two files with different licenses might
be required for building or installing.

install-sh has a MIT BSD-like license:
  Copyright 1991 by the Massachusetts Institute of Technology
 
  Permission to use, copy, modify, distribute, and sell this software and its
  documentation for any purpose is hereby granted without fee, provided that
  the above copyright notice appear in all copies and that both that
  copyright notice and this permission notice appear in supporting
  documentation, and that the name of M.I.T. not be used in advertising or
  publicity pertaining to distribution of the software without specific,
  written prior permission.  M.I.T. makes no representations about the
  suitability of this software for any purpose.  It is provided "as is"
  without express or implied warranty.


queue.h has a 4 clause BSD license:
  Copyright (c) 1991, 1993
 	The Regents of the University of California.  All rights reserved.
 
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
  3. All advertising materials mentioning features or use of this software
     must display the following acknowledgement:
 	This product includes software developed by the University of
 	California, Berkeley and its contributors.
  4. Neither the name of the University nor the names of its contributors
     may be used to endorse or promote products derived from this software
     without specific prior written permission.
 
  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  SUCH DAMAGE.


The configure script has the following license:
  Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
  Free Software Foundation, Inc.
  This configure script is free software; the Free Software Foundation
  gives unlimited permission to copy, distribute and modify it.


If you use the 32 bit ABI on Solaris and have a large traffic, you will 
need the a workaround for stdio unability to use streams with associated
file dexriptor above 255. The files implementing the workaround are
fd_pool.c and fd_pool.h, and they have a 3 clause BSD license:
  Copyright (c) 2007 Johann Klasek
  All rights reserved.
 
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
  3. All advertising materials mentioning features or use of this software
     must display the following acknowledgement:
         This product includes software developed by Johann Klasek
 
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  OF THE POSSIBILITY OF SUCH DAMAGE.


SpamAssassin binding requires the spamd.c file, which has a 3-clauses
BSD licence:
  Copyright (c) 2008 Manuel Badzong, Emmanuel Dreyfus
  All rights reserved.
 
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
  3. All advertising materials mentioning features or use of this software
     must display the following acknowledgement:
         This product includes software developed by Manuel Badzong
 
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,  
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  OF THE POSSIBILITY OF SUCH DAMAGE.
