Greylisting to avoid spam

Greylisting is a method to fight spam. Senders who send a mail for the first time will be rejected with a temporary error message and stored in the greylist. Regular mailservers will attempt to deliver the mail a second time after a while, as it is not unusual that mails can not be delivered immediately. At this second delivery attempt the sender is known and the mail will be delivered. Further mails from the same sender will be delivered without any delay for a certain time span.

Spammers will send mails only once as they often use just a simple SMTP client without any error handling. Even if some spammers use regular mailservers there is a good chance that the spammer is already known at the second delivery attempt and will be recognized by RBLs and spam filters.

Installation of Postgrey for Postfix

If your server uses Postfix as mailserver, you can add greylisting additionally very easy using Postgrey.

Step 1: Install the package

apt-get install postgrey

Step 2: Check that the Postgrey daemon is running

ps aux | grep postgrey

You should see a line like this:

postgrey 31898 ?        Ss     0:00 /usr/sbin/postgrey --pidfile=/var/run/postgrey.pid --daemonize --inet=10023

The important thing is the output –inet=10023 – that is the port where Postgrey accepts connections.

If needed you can modify the options in the file /etc/default/postgrey – e.g. the delay after the second attempt of a sender is accepted (the standard is 300 seconds – reducing this to 50 seconds makes sense since some servers try a second delivery already after one minute):

POSTGREY_OPTS="--inet=10023 --delay=50"

Wenn you change any of the defaults for Postgrey you have to restart the Daemon with

/etc/init.d/postgrey restart

Step 3: Extend the Postfix configuration to use Postgrey

For this the file /etc/postfix/main.cf has to be extended as follows:

For smtpd_recipient_restrictions =  an additional entry check_policy_service inet:127.0.0.1:10023 has to be added (if Postgrey uses another port than 10023, the entry has to be changed accordingly). Either add an additional line or add the entry separated by a comma at the end of the line.

smtpd_recipient_restrictions =
  permit_mynetworks
  permit_sasl_authenticated
  reject_invalid_hostname
[...]
  check_policy_service inet:127.0.0.1:10023

Afterwards reload the Postfix configuration:

postfix reload

Step 4: Verify that greylisting works

For this you have to send a test mail – from a different address – and check, if the file /var/log/mail.info (or /var/log/mail.log) contains entries, which look similar to the following (some parts where made anonymous with xxx – of course you should find the real data there):

Sep 11 07:52:43 xxx postgrey[31898]: action=greylist, reason=new, client_name=xxx, client_address=xxx, sender=xxx, recipient=xxx
Sep 11 07:52:43 xxx postfix/smtpd[31972]: NOQUEUE: reject: RCPT from unknown[xxx]: 450 4.2.0 <xxx>: Recipient address rejected: Greylisted, see http://postgrey.schweikert.ch/help/xxx; from=<xxx> to=<xxx> proto=SMTP helo=<xxx>

When the sending mailserver tries the delivery again, the mail should be accepted then, which you can recognize by an according message in the log:

Sep 11 08:01:05 xxx postgrey[31898]: action=pass, reason=triplet found, delay=508, client_name=xxx, client_address=xxx, sender=xxx, recipient=xxx

The triplet of ip address, sender and receiver will now be stored to the database of postgrey as “known sender” and further mails from the same address should by delivered immediately without any delay.

Since the most spammers don’t to this – try the delivery a second time – most spam mails will just be ignored :-).

Possible problems

/etc/init.d/postgrey script does not work properly

In some distributions (e.g. newer version of Debian or Ubuntu) there is a problem with the distributed start script (/etc/init.d/postgrey). It will start Postgrey, but not stop it. The reason for this is the way the script tries to stop the running Postgrey daemon.

A fix for this is described in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=670681. This also applies to Ubuntu 12.04 (and maybe newer versions as well).

Postgrey does not accept connections

In some cases it may happen that Postgrey does not accept connections from Postfix on the configured port, which you can see by accordingly error messages in /var/log/mail.log:

Nov 17 13:35:54 root postfix/smtpd[16821]: warning: connect to 127.0.0.1:10023: Connection refused
Nov 17 13:35:54 root postfix/smtpd[16821]: warning: problem talking to server 127.0.0.1:10023: Connection refused

In this case it helps to add the IP address 127.0.0.1 in the start options in /default/postgrey:

POSTGREY_OPTS="--inet=127.0.0.1:10023 --delay=50"

Don’t forget to restart Postgrey afterwards.

Extending with selective greylisting

One issue with greylisting is the deferred delivery of messages. Even though e-mail is not a “realtime media” users expect e-mails to be delivered “instantly”. A solution for this is “selective greylisting”.

Selective greylisting means that not every delivery attempt will be checked by greylisting but only those which look “suspicous” (servers without names, dial-up addresses, web servers etc.). This is done by using the “SMTP restriction classes” of Postfix.

The procedure:

First create a file in /etc/postfix named check_client_greylist with the following content, which checks the IP address of the sender using regular expressions. If a condition applies the address will be classified as “check with greylisting” otherwise not:

# regex to check clients which seem to be dynamic
# only those will be greylisted
#
# regex type, no postmap needed

/^unknown$/                                   check_greylist
/([0-9]{1,3}[.-]){3,4}[^0-9.]+/               check_greylist
/^(dhcp|dialup|ppp|adsl|host|static|www|server|client)[^.]*[0-9]/     check_greylist
/^[^.]*[0-9]{5}/                              check_greylist

To activate this check modify the file /etc/postfix/main.cf as follows:

smtpd_restriction_classes = check_greylist
check_greylist = check_policy_service inet:127.0.0.1:10023

Additionally the entry check_policy_service inet:127.0.0.1:10023 in smtpd_recipient_restrictions =  will be replaced by check_client_access regexp:/etc/postfix/check_client_greylist:

smtpd_recipient_restrictions =
  permit_mynetworks
  permit_sasl_authenticated
  reject_invalid_hostname
[...]
  check_client_access regexp:/etc/postfix/check_client_greylist

Remember to use the right port if postfix does not use 10023. After this modification the configuration of Postfix has to be reloaded using postfix reload as well.

Leave a public comment

Your email address will not be published. This is not a contact form! If you want to send me a personal message, use my e-mail address in the imprint.