Configuring and Monitoring Postfix DNSBL
Expanded from Zimbra MTA RBLs
Turning On or Off RBLs
RBL (Real time black-hole lists) can be turned on or off in SpamAssassin from the Zimbra CLI.
The three RBL’s that are enabled during installation
- reject_invalid_hostname
- reject_non_fqdn_hostname
- reject_non_fqdn_sender
Available DNSBLs
- reject_rbl_client dnsbl.njabl.org
- reject_rbl_client cbl.abuseat.org
- reject_rbl_client bl.spamcop.net
- reject_rbl_client dnsbl.sorbs.net
- reject_rbl_client sbl.spamhaus.org (use zen.spamhaus.org)
- reject_rbl_client relays.mail-abuse.org (no longer free)
To add more RBL's you can edit the /opt/zimbra/conf/postfix_recipient_restrictions.cf file by adding the exact details used with the zmprov command (see below). For instance, if you wanted to make the RBL zen.spamhaus.org, you would need to add the following line to /opt/zimbra/conf/postfix_recipient_restrictions.cf:
%%contains VAR:zimbraMtaRestriction reject_rbl_client zen.spamhaus.org%%
Then just add the RBL per the instructions below.
To turn RBL on
- Log on to the server and go to the Zimbra directory (su - zimbra)
- Enter zmprov gacf | grep zimbraMtaRestriction, to see what RBLs are set.
- To add any new RBL types, you must list the existing RBLs and the new RBLs all in one command as:
zmprov mcf zimbraMtaRestriction [RBL type]
To add all the possible restrictions
The command should be entered as follows (quotes required for rbl_clients):
zmprov mcf \ zimbraMtaRestriction reject_invalid_hostname \ zimbraMtaRestriction reject_non_fqdn_hostname \ zimbraMtaRestriction reject_non_fqdn_sender \ zimbraMtaRestriction "reject_rbl_client dnsbl.njabl.org" \ zimbraMtaRestriction "reject_rbl_client cbl.abuseat.org" \ zimbraMtaRestriction "reject_rbl_client bl.spamcop.net" \ zimbraMtaRestriction "reject_rbl_client dnsbl.sorbs.net" \ zimbraMtaRestriction "reject_rbl_client sbl.spamhaus.org" \ zimbraMtaRestriction "reject_rbl_client relays.mail-abuse.org"
or one at a time you can use +-
zmprov mcf +zimbraMtaRestriction "reject_rbl_client zen.spamhaus.org"
Monitoring Logs for DNSBL bounces
dnsblcount is a perl script that checks your Postfix mail log for for RBL rejections. It produces a report tallying rejections per RBL.
Note: You may decide against doing this if you have 1GB logfiles...
Install dnsblcount
Download and install dnsblcount to your /usr/local/bin folder.
Example Output
[zimbra@zimbra01 ~]$ /usr/local/bin/dnsblcount /var/log/zimbra.log bl.spamcop.net 233 dnsbl.sorbs.net 112 sbl.spamhaus.org 4 ================================= Total DNSBL rejections: 349
Configure logrotate to send daily results to postmaster
Modify your zimbra logrotate file (/etc/logrotate.d/zimbra) to add a prerotate rule as follows:
/var/log/zimbra.log { daily missingok notifempty create 0644 zimbra zimbra prerotate /usr/local/bin/dnsblcount /var/log/zimbra.log | mail -s "$HOSTNAME - DNSBL Count" postmaster@example.com # <-- Change to your domain endscript postrotate killall -HUP syslogd 2> /dev/null || true kill -HUP `cat /opt/zimbra/log/swatch.pid 2> /dev/null` 2> /dev/null || true kill -HUP `cat /opt/zimbra/log/logswatch.pid 2> /dev/null` 2> /dev/null || true endscript compress }
For Zimbra 7 on CentOS 5:
/etc/logrotate.d/zimbra
/var/log/zimbra.log { daily missingok notifempty create 0644 zimbra zimbra prerotate /usr/sbin/dnsblcount /var/log/zimbra.log | mail -s "$HOSTNAME - DNSBL Count" admin@ics-il.net # <-- Change to your domain endscript postrotate kill -HUP `cat /var/run/syslog*.pid 2> /dev/null` 2> /dev/null || true su - zimbra -c "/opt/zimbra/bin/zmswatchctl restart" > /dev/null 2>&1 || true endscript compress }
Don't forget to Setting_System_MTA_To_ZCS
The script
For posterity, the dnsblcount script as of 11/3/2007 (but do see if there's updates here http://www.joreybump.com/code/dnsblcount/index.html)
#!/usr/bin/perl # dnsblcount # version 20061111 # (c) 2004, 2005, 2006 Jorey Bump # URL # http://www.joreybump.com/code/dnsblcount/ # Description: # Counts DNSBL rejections in Postfix log # Usage: # dnsblcount /path/to/maillog # dnsblcount /path/to/maillog1 /path/to/maillog2 # dnsblcount /path/to/maillogs* # grep "search string" /path/to/maillog | dnsblcount # Sample crontab: # 30 5 * * * /usr/local/sbin/dnsblcount /var/log/maillog | mail -s "$HOSTNAME - DNSBL Count" postmaster # Sample Postfix 1.1 log lines: # Mar 6 06:52:03 mail postfix/smtpd[11873]: reject: RCPT from unknown[208.61.231.102]: 554 Service unavailable; [208.61.231.102] blocked using bl.spamcop.net, reason: Blocked - see http://www.spamcop.net/bl.shtml?208.61.231.102; from=<bob@example.net> to=<rob@example.com> # Mar 13 05:47:51 mail postfix/smtpd[28269]: reject: RCPT from mail68.example.info[66.63.191.68]: 554 Service unavailable; [66.63.191.68] blocked using sbl.spamhaus.org, reason: http://www.spamhaus.org/SBL/sbl.lasso?query=SBL12057; from=<bob@example.net> to=<rob@example.com> # Sample Postfix 2.1 log line: # Apr 17 13:49:07 mail postfix/smtpd[18143]: NOQUEUE: reject: RCPT from c-7209e055.1111-2-64736c10.cust.bredbandsbolaget.se[85.224.9.114]: 554 Service unavailable; Client host [85.224.9.114] blocked using bl.spamcop.net; Blocked - see http://www.spamcop.net/bl.shtml?85.224.9.114; from=<haqyhakox@example.com> to=<bob@example.net> proto=ESMTP helo=<c-7209e055.1111-2-64736c10.cust.example.com> # Sample postfix 2.3 log line: # Dec 25 05:41:28 mail postfix/smtpd[14586]: NOQUEUE: reject: RCPT from unknown[202.43.175.151]: 554 5.7.1 Service unavailable; Client host [202.43.175.151] blocked using bl.spamcop.net; Blocked - see http://www.spamcop.net/bl.shtml?202.43.175.151; from=<iglkjlpioed@example.com> to=<bob@example.net> proto=SMTP helo=<mail.example.com> # Begin: use strict; my ( $dnsbl, $dnsbltotal, $ip, $length, $line, $max, %dnsblcount ); my $rule = "="; my $totstr = "Total DNSBL rejections:"; $max = length($totstr); # read line from stdin while ($line = <>) { if ($line =~ /(\[.*\]) blocked using ([^\s]*)(,|;) /) { $ip = $1; $dnsbl = $2; $dnsblcount{$dnsbl} += 1; $dnsbltotal += 1; } } foreach $dnsbl (sort keys %dnsblcount) { $length = length($dnsbl); if ( $length > $max ) { $max = $length } } foreach $dnsbl (sort { $dnsblcount{$b} <=> $dnsblcount{$a} } keys(%dnsblcount)) { printf "%-${max}s %7s\n", $dnsbl, $dnsblcount{$dnsbl}; } foreach (1..($max + 10)) { printf "%s", $rule; } print "\n"; printf "%-${max}s %8s\n", $totstr, $dnsbltotal; 1;