Postscreen – Greylisting in Postfix

Greylisting is well known antispam technique. It’s idea is basing on fact, that spamming hosts (zombies) do not have time for re-transmission and are trying to send maximum amount of spam in shortest time period. This is achieved by connections to different mail servers and submission of message even without wait for server’s response. In opposition to that, legitimate mail servers presents themselves and waits for server’s response, and then beginning mail submission. If they receive temporary error code (4xx) from server, they will try to submit mail again after defined time period (e.g. 5 minutes)

Implementation of Greylisting brings tangible benefits for mail system. Greylisting is able to filter even above 90% incoming traffic to mail server, and it’s done on session level, which is huge benefit for system performance, because no resources are wasted for mail processing. General rule is to filter junk mail as soon as possible, so if we can filter this on session level we shouldn’t waste time and resources to antivirus and antispam. Cons of Greylisting is that incoming messages have few minutes of latency, because client’s server needs to repeat transmission. False positives are very rare and mostly comes from misconfiguration of sending server.
One of wide known and used solutions for Greylisting is Postgrey – Postfix Greylisting Policy Server written by David Schweikert. This is a Perl software, which we successfully used for few years. Actually we switched to Postscreen which is embedded in new version of Postfix.
Postscreen configuration is simple and well described in Postscreen HOWTO. To enable this mechanism and see how it works without enabling Greylisting you need only to add few lines to Postfix configuration (in main.cf) and modify master.cfsmtp service needs to be changed to be served by postscreen. See below:

#smtp      inet  n       -       -       -       -       smtpd
smtp      inet  n       -       -       -       1       postscreen
smtpd     pass  -       -       -       -       -       smtpd
dnsblog   unix  -       -       -       -       0       dnsblog
tlsproxy  unix  -       -       -       -       0       tlsproxy

Create postscreen_access.cidr file and add to main.cf:

postscreen_blacklist_action = ignore
postscreen_access_list =
        permit_mynetworks
        cidr:/etc/postfix/postscreen_access.cidr

postscreen_greet_action = ignore
postscreen_greet_banner = Spammers may talk now :)

For test purpose the action is set to ignore, so there is no impact on system, but if you do telnet mydomain.tld 25 you will see greeting like this:

Trying ...
Connected to mydomain.tld.
Escape character is '^]'.
220-Spammers may talk now :)

And after few seconds you will receive second line:

220 mydomain.tld ESMTP Postfix

Why after few seconds? That’s because legitimate server will wait for this line, but spammers in most cases will not wait for server’s answer but will start to submit messages. If you will change ignore to enforce or drop – Postscreen will start to drop these type of connections. The difference between enforce and drop is that enforce will wait until tests will be finished, logging helo/sender/recipient information and rejecting with 550 code, while drop rejects immediately with 521 code. I recommend to use enforce, especially on beginning, to have information about sender and recipient in logs to be able to check if there is no false positives.
In this stage you can also enable DNSBL, with settings are like below, client must be listed in zen.spamhause.org (factor 2) and in one of other DNSBL to reach threshold of 3 and be rejected. Of course factors and DNSBL servers you can set at your own.

postscreen_dnsbl_action = enforce
postscreen_dnsbl_threshold = 3
postscreen_dnsbl_sites =
        zen.spamhaus.org*2
        bl.spamcop.net*1
        b.barracudacentral.org*1

You should see similar entries in log after Postfix restart:

Aug 17 15:30:40 mydomain.tld postfix/postscreen[31984]: CONNECT from [41.205.39.169]:4308
Aug 17 15:30:40 mydomain.tld postfix/dnsblog[32089]: addr 41.205.39.169 listed by domain zen.spamhaus.org as 127.0.0.11
Aug 17 15:30:40 mydomain.tld postfix/dnsblog[32089]: addr 41.205.39.169 listed by domain zen.spamhaus.org as 127.0.0.4
Aug 17 15:30:40 mydomain.tld postfix/dnsblog[32088]: addr 41.205.39.169 listed by domain b.barracudacentral.org as 127.0.0.2
Aug 17 15:30:40 mydomain.tld postfix/dnsblog[32088]: addr 41.205.39.169 listed by domain bl.spamcop.net as 127.0.0.2
Aug 17 15:30:46 mydomain.tld postfix/postscreen[31984]: DNSBL rank 4 for [41.205.39.169]:4308
Aug 17 15:30:49 mydomain.tld postfix/postscreen[31984]: NOQUEUE: reject: RCPT from [41.205.39.169]:4308: 550 5.7.1 Service unavailable; client [41.205.39.169] blocked using zen.spamhaus.org; from=..., to=..., proto=ESMTP, helo=
Aug 17 15:30:49 mydomain.tld postfix/postscreen[31984]: HANGUP after 3.2 from [41.205.39.169]:4308 in tests after SMTP handshake
Aug 17 15:30:49 mydomain.tld postfix/postscreen[31984]: DISCONNECT [41.205.39.169]:4308

A client which will not reach a threshold defined in postscreen_dnsbl_threshold, will obtain a status PASS NEW:

Aug 17 16:12:43 mydomain.tld postfix/postscreen[2391]: CONNECT from [173.232.32.14]:45116
Aug 17 16:12:43 mydomain.tld postfix/dnsblog[2416]: addr 173.232.32.14 listed by domain b.barracudacentral.org as 127.0.0.2
Aug 17 16:12:49 mydomain.tld postfix/postscreen[2391]: PASS NEW [173.232.32.14]:45116
Aug 17 16:22:26 mydomain.tld postfix/smtpd[2919]: connect from unknown[173.232.29.251]
Aug 17 16:22:26 mydomain.tld postfix/smtpd[2919]: 69AD180A94: client=unknown[173.232.29.251]

A client which was already noticed as legitimate and wants to submit another message will pass with status PASS OLD:

Aug 17 16:51:53 mydomain.tld postfix/postscreen[4493]: CONNECT from [213.134.151.158]:45226
Aug 17 16:51:59 mydomain.tld postfix/postscreen[4493]: PASS OLD [213.134.151.158]:45226
Aug 17 16:52:00 mydomain.tld postfix/smtpd[4496]: connect from mail.silfarm.com.pl[213.134.151.158]
Aug 17 16:52:00 mydomain.tld postfix/smtpd[4496]: 41B1780295: client=mail.silfarm.com.pl[213.134.151.158]

Postscreen has also ability known as deep_protocol_test. Detailed description you can find in documentation. If client will pass these tests then it’s added to temporary whitelist, but this time is rejected with temporary failure error code 4XX. If client will connect once again then will be allowed to submission. Embedded in Postscreen SMTP engine doesn’t have AUTH, XCLIENT and XFORWARD implementation. Support for AUTH can be implemented in newer versions. In the meantime, when these services needs to be available on port 25, you shouldn’t enable deep protocol test. But good practice is to configure submission on port 587 (with TLS) or 465 with SSL, so deep_protocol_test can be enabled and should not have impact on mail system. To enable it you need to add some configuration directives to (main.cf):


postscreen_pipelining_action = enforce
postscreen_pipelining_enable = yes

postscreen_non_smtp_command_action = enforce
postscreen_non_smtp_command_enable = yes

postscreen_bare_newline_action = enforce
postscreen_bare_newline_enable = yes

After Postfix restart is worthwhile – as always – to check logs and observe if system is working as expected. Description of particular tests is in mentioned documentation.

You may also like...

Leave a Reply