Greylisting HOWTO

1. Introduction

NOTE: This guide was originally written to compliment the basic postfix guide and postfix restrictions guide, but has since been expanded for use with other MTA's.

Postgrey is a policy server implementing greylisting to filter spam on Postfix mail servers. The principle of greylisting works on the basis that much spam is sent by spambots and other non RFC compliant MTAs. Postgrey will temporarily reject new mail with error 450 "try again later" for a set period of time and will log the triplet CLIENT_IP / SENDER / RECIPIENT in it's database. If the sending server is RFC compliant, then it should resend the message at which point Postgrey will check it's database for a match and accept the message. The delay is configurable and Postgrey maintains a database of known triplets, so mail from a given sender should only be delayed the first time.

However, a typical spambot mailer is likely to receive a huge number of bounced or rejected mail so spammers typically do not resend messages when they are temporarily rejected. Thus, any mail received from such sources is simply dropped by the mail server. This has the added advantage of reducing the filtering and processing overhead on the mail server as a large percentage of messages will simply be dropped before entering the MTA and will not need to be otherwise filtered or processed.

2. Configuration

Greylisting may be configured to work with a number of different MTS's. Please refer to the appropriate section below for the MTA you are using.

2.1. Postfix

Postgrey was installed from RPMForge on CentOS 5.1 fully updated, although it should apply equally on other versions. To enable the RPMForge repository, please see the RPMForge instructions. First, install postgrey:

# yum install postgrey

Postgrey is written in Perl, so Perl is required along with some additional Perl modules. Yum should automatically resolve any missing dependencies for you and you can check the requirements at the Postgrey website.

First we need to configure Postfix to use Postgrey. Edit /etc/postfix/main.cf to include the following check_policy_service line within the smtpd_recipient_restrictions section as shown below (if you don't have a smtpd_recipient_restrictions section, then the following example will work fine):

smtpd_recipient_restrictions =
   permit_mynetworks,
   reject_unauth_destination,
   check_policy_service unix:postgrey/socket,
   permit

By default, the amount of time by which Postgrey will reject new messages is set to 5 minutes but we can change this using the --delay switch. There is a trade off in that the longer the time the more chance of rejecting spam but also the longer legitimate mail will be delayed for the first time. It might be worth initially setting this value to 1 minute (60 seconds) and subsequently increasing the value once Postgrey has built a database of regular mail contacts for your server. Setting your delay to values larger than 300 Seconds ( 5 Minutes ) is really not recommended. To manually set the delay (in seconds), we need to create the Postgrey configuration file at /etc/sysconfig/postgrey and append the --delay switch as shown below (see 'man postgrey' for a full list of options):

OPTIONS="--unix=/var/spool/postfix/postgrey/socket --delay=60"

Finally, we need to start the Postgrey service and reload Postfix settings:

# /sbin/service postgrey start
# /sbin/service postfix reload

Ensure postgrey automatically starts when the machine is booted:

# /sbin/chkconfig --levels 345 postgrey on 

Now we can check our mail logs and see postgrey in action. Here's an (obfuscated) excerpt from my /var/log/maillog:

#
# postgrey loads:
#
Dec 17 21:44:58 jessie postgrey[6844]: Process Backgrounded
Dec 17 21:44:58 jessie postgrey[6844]: 2007/12/17-21:44:58 postgrey (type Net::Server::Multiplex) starting! pid(6844)
Dec 17 21:44:58 jessie postgrey[6844]: Binding to UNIX socket file /var/spool/postfix/postgrey/socket using SOCK_STREAM
Dec 17 21:44:58 jessie postgrey[6844]: Setting gid to "101 101"
Dec 17 21:44:58 jessie postgrey[6844]: Setting uid to "100"
#
# postgrey greylisting a message:
#
Dec 17 21:23:49 jessie postfix/smtpd[6714]: connect from mk-outboundfilter-4-a-1.mail.uk.tiscali.com[212.74.114.8]
Dec 17 21:23:49 jessie postfix/smtpd[6714]: NOQUEUE: reject: RCPT from mk-outboundfilter-4-a-1.mail.uk.tiscali.com[212.74.114.8]:
        450 4.2.0 <ned@example.com>: Recipient address rejected: Greylisted, see http://postgrey.schweikert.ch/help/example.com.html;
        from=<bob@example.com> to=<ned@example.com> proto=ESMTP helo=<mk-outboundfilter-4-a-1.mail.uk.tiscali.com>
Dec 17 21:23:54 jessie postfix/smtpd[6714]: disconnect from mk-outboundfilter-4-a-1.mail.uk.tiscali.com[212.74.114.8]
#
# postgrey accepting a message:
#
Dec 17 22:23:45 jessie postgrey[2218]: action=pass, reason=triplet found, client_name=mk-outboundfilter-3-a-1.mail.uk.tiscali.com,
        client_address=212.74.114.7, sender=bob@example.com, recipient=ned@example.com

If you see a message like the following:

Nov 18 09:39:03 jessie postfix/smtpd[26006]: warning: connect to postgrey/socket: Permission denied

don't be frustrated, that is a SELinux issue and the solution is discussed in the following wiki page: HowTos/SELinux#head-faa96b3fdd922004cdb988c1989e56191c257c01.

2.2. Greylisting in Sendmail

Sendmail uses milter-greylist, which is available from RPMForge. To enable the RPMForge repository, please see the RPMForge instructions. First, install milter-greylist:

# yum install milter-greylist

Milter-greylist is written in C, so there are few, if any, dependancies. Yum should automatically resolve any missing dependencies for you and you can check the requirements at the milter-greylist website.

Add the following to the bottom of your sendmail.mc script:

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

You can also specify timeouts if you like, the following example has a one minute timeout when sending information to the milter and the same waiting for a reply, the defaults are just 10 seconds each and may not be enough when using DNSRBL and/or SPF. Read more at Sendmail milter installation instructions.

INPUT_MAIL_FILTER(`greylist',`S=local:/var/milter-greylist/milter-greylist.sock, F=, T=S:1m;R:1m')dnl

Make the sendmail.cf file from the m4-file. Many systems have a Makefile that will do this automagically.

/usr/bin/m4 /usr/share/sendmail/cf/m4/cf.m4 sendmail.mc > sendmail

and restart sendmail

service sendmail restart

2.3. Exim

Exim configuration to go here. Please feel free to volunteer if you use greylisting with exim (or any other MTA)

3. Reporting

Postgrey includes a reporting tool call postgreyreport. Its installed by default when you install the postgrey rpm. Postgreyreport will parse a maillog ( read from STDIN ), compare it with the postgrey db and output details on all 'fatal' greylist entries. A host is considered to be 'fatally' greylisted when it does not retry within 300 seconds from its first attempt at email delivery for a specific destination. Postgreyreport uses the complete triple as a candidate. You can tune this delay of 300 seconds using the command line option --delay, however 300 is a good benchmark. Most mail servers will retry within 300 seconds.

Basic usage :

cat /var/log/maillog | /usr/sbin/postgreyreport --delay=300

Depending on how busy your server is, the report can get quite large. To get only the top 20 sources getting greylisted out - you can use something like this :

cat /var/log/maillog | postgreyreport | awk '{print $1}' | sort | uniq -c | sort -nr | head -n20

To get a list of the top 20 email address that the greylisted sources are sending email to :

cat /var/log/maillog | postgreyreport | awk '{print $4}'  | sort  | uniq -c | sort -nr | head -n20

To get a list of all options that postgreyreport supports and their functions:

postgreyreport -h

4. Multiple MX considerations

If your domain has more than one mail server (MX), make sure you enable greylisting on all the servers or the spammers will target your backup MX machines and route email in from there. And it might be worth whitelisting the machines amongst each other. Check the next section on how to do whitelisting in postgrey.

For greylisting to work on backup MX machines, its important that the greylist check happens before the mail accept! While this sounds like common sense, its the one issue that causes most people a lot of confusion when they setup greylisting on backup MX machines. As an example if you are using permit_mx_backup in postfix your smtpd_recipient_restrictions on the backup MX should look like this :

smtpd_recipient_restrictions =
    reject_unauth_destination,
    check_policy_service unix:/var/spool/postfix/postgrey/socket,
    permit_mx_backup,
    permit

5. Whitelisting

In postgrey its possible to whitelist senders as well as recipients. All that needs doing in order to whitelist a host is to add its fully qualified domain name or its ip address to the /etc/postfix/postgrey_whitelist_clients.local file. eg:

192.168.1.10
mydesktop.office.mydomain.com

Now all email recieved from either 192.168.1.10 or mydesktop.office.mydomain.com will not be greylisted, it will be accepted immediately ( as long as its valid, and passes all postfix rules ). On the other hand if you want to whitelist a recipient you can add their username part of the email address to the /etc/postfix/postgrey_whitelist_recipients file. eg:

postmaster@
abuse@
theboss@

Now all emails being received for any of these email address' wont be greylisted, and all email will be accepted right away. Note that postgrey already comes with whitelist setup for postmaster and abuse.

6. Summary

Greylisting is a highly effective way of combating spam sent from non RFC compliant spambots. Postgrey is an easy to implement greylisting policy server that may be installed and configured in a matter of minutes on an operational mail server in CentOS.

7. Links

http://www.greylisting.org/

http://postgrey.schweikert.ch/

http://milter-greylist.wikidot.com/sendmail

HowTos/postgrey (last edited 2009-02-08 14:39:12 by AlanBartlett)