Source: http://www.postfix.org/POSTSCREEN_README.html
Not known by many people, Postfix (version 2.8 and higher) actually has a way of holding of spam and reducing mail-server load using the Postscreen Daemon.
Postscreen is able to filter out connections from zombies, spambot’s and other poorly written email spam services. Postscreen is a light-weighted extra layer of security and spam protection.
I you want to use postscreen, it is recommended to do this by using port TCP 25 for MTA traffic only, and use the submission port TCP 587 for the client connections. This way the postscreen functionality won’t affect client connections, but only server connections for delivering email between MTA’s.
If you plan using postscreen on a postfix mail-server with a high traffic load, it is good to know that many free services for blacklisting like spamhaus.org, have limits in how often the free services can be used.
But for most average load mail servers this shouldn’t be a big concern. There is also the possibility of using a local caching DNS server to solve this concern.
Because of the way postscreen works, email delivery can get delayed for some amount of time (see: Whitelisting). You should be aware of this change in email behavior before implementing the postscreen functionality.
The first step in the postscreen process is to do a locale black/white list test. This test speeds up the process of handling known clients. To configure this step we need to define an accept list.
First we create a file: /etc/postfix/postscreen_access.cidr and fill it with for example:
# Rules are evaluated in the order as specified.
# Blacklist 192.168.* except 192.168.0.1. and block all other rfc-1918 addresses
192.168.0.1 permit
192.168.0.0/16 reject
172.16.0.0/12 reject
10.0.0.0/8 reject
This example states that the source 192.168.0.1 is permitted, and that the source network 192.68.0.0/16 is rejected. If you have trusted sources that you want to bypass the postscreen process you can add them here and set the ‘permit’ parameter. Or if you have specific sources that you want to block up front, you can add them here and set the ‘reject’ parameter.
First we add a new section title to the bottom of our /etc/postfix/main.cf file: Below this section tile we will add all of our postscreen settings so they can be easily found and changed.
#### POSTSCREEN OPTIONS v2017-06-28 ####
Then we add this to our /etc/postfix/main.cf file (below the section tile):
postscreen_access_list = permit_mynetworks,
cidr:/etc/postfix/postscreen_access.cidr
To work with zombie/spam servers postscreen does a pregreet test by default. When a connection is made, the postscreen daemon reply’s with a pregreet banner to the connecting server and starts a wait timer. A normal SMTP server should wait for its turn to speak, where most zombie/spam servers are in a hurry sending spam, they will speak for their turn. Depending on the action parameter, postscreen will reply accordingly.
In our configuration we will set the parameter to: enforce in the /etc/postfix/main.cf file:
postscreen_greet_banner = $smtpd_banner
postscreen_greet_ttl = 1d
postscreen_greet_wait = ${stress?2}${stress:6}s
postscreen_greet_action = enforce
Make sure that the $smtpd_banner is set in the /etc/postfix/main.cf file (uncomment this parameter)
smtpd_banner = $myhostname ESMTP $mail_name
Or you can set the postscreen_greet_banner to whatever you like.
The postscreen_greet_wait is the amount of time the connecting server has to wait before it’s turn to speak.
The postscreen_greet_ttl is the amount of time that postscreen will use the result from a successful PREGREET test.
During this time, the client IP address is excluded from this test. This is set to 1 day as normal clients will easily pass this test.
During the greet_wait timer, postscreen does the DNS White/blacklist test. With this test postscreen can check external lists for a domain score of the connecting server. This list is set with the postscreen_dnsbl_sites parameter. You can set weights to the lists so you can influence the outcome.
There are to kinds of weight factors, positive weights for blacklisting and negative for whitelisting. The servers listed in the postscreen_dnsbl_sites parameter will be queried in parallel with the reverse client IP address.
In our configuration we will set the parameter to: enforce in the /etc/postfix/main.cf file:
postscreen_dnsbl_sites = zen.spamhaus.org*2
bl.spamcop.net*1
b.barracudacentral.org*1
list.dnswl.org=127.0.[0..255].0*-2
list.dnswl.org=127.0.[0..255].1*-3
list.dnswl.org=127.0.[0..255].[2..3]*-4
postscreen_dnsbl_threshold = 2
postscreen_dnsbl_action = enforce
postscreen_blacklist_action = drop
In the list above, we will block mail from domains on the spamhaus list, and we will block mail when spamcop and barracusa give the same result.
As there are many block-lists available, you can add them here as you like.
These tests are more in depth tests and are more intrusive as the pregreet tests. One of the biggest change in behavior is that connecting severs need to do a disconnect after passing these postgreet tests.
Then they need to reconnect from the same IP as the initial connection. This can cause serious mail delivery delay’s when the sending server is constantly connecting from a different source IP like for example gmail or office365 does.
luckily there are settings to work around these challenges which we will discuss later.
Pipelining will force a “one command & response” at a time communication. Many zombies, spambot’s and other poorly written email spam services will try to send multiple commands at a time. Therefor this functionality will filter these connections out.
postscreen_pipelining_enable = yes
postscreen_pipelining_ttl = 30d
postscreen_pipelining_action = enforce
The pipelining_ttl is for: The amount of time that postscreen will use the result from a successful “pipelining” SMTP protocol test.
During this time, the client IP address is excluded from this test. The default is long because a good client must disconnect after it passes the test, before it can talk to a real Postfix SMTP server.
Postscreen can block non SMTP commands comming in with the settings below. This is usefull when spambots are using proxy’s to connect. Than these kind of non SMTP commands can occur.
postscreen_non_smtp_command_enable = yes
postscreen_non_smtp_command_ttl = 30d
postscreen_non_smtp_command_action = enforce
SMTP is a line-oriented protocol: lines have a limited length, and are terminated with
postscreen_bare_newline_enable = yes
postscreen_bare_newline_ttl = 30d
postscreen_bare_newline_action = enforce
You will receive mails with a delay from a few minutes to a few hours depending on the client side behavior when using the postgreet tests.
Since postfix version 2.11 there is a parameter: postscreen_dnsbl_whitelist_threshold. This parameter allows a remote SMTP client to skip the pregreet and postgreet tests, based on its combined DNSBL score as defined with the postscreen_dnsbl_sites parameter.
Specify a negative value to enable this feature. When a client passes the postscreen_dnsbl_whitelist_threshold without having failed other tests, all pending or disabled tests are flagged as completed with a time-to-live value equal to postscreen_dnsbl_ttl. When a test was already completed, its time-to-live value is updated if it was less than postscreen_dnsbl_ttl.
This setting helps to prevent long delay’s for services like gmail or office365, since these email providers often use a large number of IP addresses to deliver email like explained earlier in this document.
postscreen_dnsbl_whitelist_threshold = -1
postscreen_cache_cleanup_interval = 12h
postscreen_cache_map = btree:$data_directory/postscreen_cache
postscreen_cache_retention_time = 7d
postscreen_client_connection_count_limit = $smtpd_client_connection_count_limit
postscreen_command_count_limit = 20
postscreen_command_filter =
postscreen_command_time_limit = ${stress?10}${stress:300}s
postscreen_disable_vrfy_command = $disable_vrfy_command
postscreen_discard_ehlo_keyword_address_maps = $smtpd_discard_ehlo_keyword_address_maps
postscreen_discard_ehlo_keywords = $smtpd_discard_ehlo_keywords
postscreen_enforce_tls = $smtpd_enforce_tls
postscreen_use_tls = $smtpd_use_tls
postscreen_tls_security_level = $smtpd_tls_security_level
postscreen_expansion_filter = $smtpd_expansion_filter
postscreen_forbidden_commands = $smtpd_forbidden_commands
postscreen_helo_required = $smtpd_helo_required
postscreen_post_queue_limit = $default_process_limit
postscreen_pre_queue_limit = $default_process_limit
postscreen_reject_footer = $smtpd_reject_footer
postscreen_watchdog_timeout = 10s
So here we are with our complete postscreen configuration. it should look like this:
#### POSTSCREEN OPTIONS v2017-06-28 ####
#### Quick Tests
postscreen_access_list = permit_mynetworks,
cidr:/etc/postfix/postscreen_access.cidr
#### Pregreet Test
postscreen_greet_banner = $smtpd_banner
postscreen_greet_ttl = 1d
postscreen_greet_wait = ${stress?2}${stress:6}s
postscreen_greet_action = enforce
### DNS White/blacklist test
postscreen_dnsbl_sites = zen.spamhaus.org*2
bl.spamcop.net*1
b.barracudacentral.org*1
list.dnswl.org=127.0.[0..255].0*-2
list.dnswl.org=127.0.[0..255].1*-3
list.dnswl.org=127.0.[0..255].[2..3]*-4
postscreen_dnsbl_threshold = 2
postscreen_dnsbl_action = enforce
postscreen_blacklist_action = drop
### Postgreet Test
postscreen_pipelining_enable = yes
postscreen_pipelining_ttl = 30d
postscreen_pipelining_action = enforce
postscreen_non_smtp_command_enable = yes
postscreen_non_smtp_command_ttl = 30d
postscreen_non_smtp_command_action = enforce
postscreen_bare_newline_enable = yes
postscreen_bare_newline_ttl = 30d
postscreen_bare_newline_action = enforce
### Whitelist Threshold
postscreen_dnsbl_whitelist_threshold = -1
### Optional Settings
postscreen_cache_cleanup_interval = 12h
postscreen_cache_map = btree:$data_directory/postscreen_cache
postscreen_cache_retention_time = 7d
postscreen_client_connection_count_limit = $smtpd_client_connection_count_limit
postscreen_command_count_limit = 20
postscreen_command_filter =
postscreen_command_time_limit = ${stress?10}${stress:300}s
postscreen_disable_vrfy_command = $disable_vrfy_command
postscreen_discard_ehlo_keyword_address_maps = $smtpd_discard_ehlo_keyword_address_maps
postscreen_discard_ehlo_keywords = $smtpd_discard_ehlo_keywords
postscreen_enforce_tls = $smtpd_enforce_tls
postscreen_use_tls = $smtpd_use_tls
postscreen_tls_security_level = $smtpd_tls_security_level
postscreen_expansion_filter = $smtpd_expansion_filter
postscreen_forbidden_commands = $smtpd_forbidden_commands
postscreen_helo_required = $smtpd_helo_required
postscreen_post_queue_limit = $default_process_limit
postscreen_pre_queue_limit = $default_process_limit
postscreen_reject_footer = $smtpd_reject_footer
postscreen_watchdog_timeout = 10s
Now to enable postcreen, change the /etc/postfix/master.cf file:
old:
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - n - - smtpd
#smtp inet n - n - 1 postscreen
#smtpd pass - - n - - smtpd
#dnsblog unix - - n - 0 dnsblog
#tlsproxy unix - - n - 0 tlsproxy
#submission inet n - n - - smtpd
new:
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
#smtp inet n - n - - smtpd
smtp inet n - n - 1 postscreen
smtpd pass - - n - - smtpd
dnsblog unix - - n - 0 dnsblog
tlsproxy unix - - n - 0 tlsproxy
#submission inet n - n - - smtpd
and restart postfix:
sudo systemclt restart postfix
Now Postscreen is enabled you should see postscreen log entries in your maillog file.
For example:
postfix/postscreen[932]: NOQUEUE: reject: RCPT from [xxx.xxx.xxx.xxx]:4938: 550 5.7.1 Service unavailable; client [xxx.xxx.xxx.xxx] blocked using zen.spamhaus.org; from=<misterx@xyz.com>, to=<test@example.com>,
proto=ESMTP, helo=<xxx.xxx.xxx.xxx>
After enabling postscreen it is a good practice to monitor the maillog files fore some time to see what effect postscreen has on your mailflow.
There is a tool for postscreen statistics: https://github.com/jvehent/Postscreen-Stats
But this uses the maillog file in /var/log. And as newer systems log to the systemd log system this script could use some changes to make it work with journalctl.
maybe someone in the community could write a nice webfrontend for these statistics.