Install Postgrey - Optional
Install policyd-weight - Optional
Install Botnet SA plugin - Optional
Install p0f - Optional
Use an RBL - Optional

Install Postgrey - Optional

Index
Of course Greylisting will reject a ton of spam - but at a cost. Some mail will be delayed. To help out I cut the retry time from 6 minutes to 29 seconds. We will use 'selective greylisting' with the idea being we will attempt to only target clients that appear to come from dial-up and dynamic IP addresses. If you decide to implement this I also recommend you whitelist clients you trust. The whitelists are located in the /etc/postgrey/ directory. We can also whitelist senders, clients or networks in Postfix by using the greylist_sender_exceptions or cidr_greylist_network_exceptions maps that we configure below.
apt-get install postgrey

sed -i 's/--inet=127.0.0.1:60000/--inet=127.0.0.1:60000 --delay=29/' /etc/default/postgrey
sed -i 's/--inet=10023/--inet=127.0.0.1:60000 --delay=29/' /etc/default/postgrey
/etc/init.d/postgrey restart
ps aux | grep postgrey | grep -v grep

cd /etc/postfix
wget http://verchick.com/mecham/public_html/spam/check_client_fqdn
cp -ip main.cf main.cf-before-grey

postconf -e "smtpd_restriction_classes = check_greylist"
postconf -e "check_greylist = check_policy_service inet:127.0.0.1:60000"
touch greylist_sender_exceptions
postmap greylist_sender_exceptions
touch cidr_greylist_network_exceptions


In main.cf, our smtpd_recipient_restrictions should already look pretty like the sample below. Read the beginning (half dozen lines or so) of http://www.postfix.org/postconf.5.html. Now we need to add greylisting and a sender whitelist for greylisting.
Either vi /etc/postfix/main.cf or use the WinSCP editor and edit smtpd_recipient_restrictions, adding the items in red as usual:
smtpd_recipient_restrictions =
    permit_mynetworks,
    reject_unauth_destination,
    reject_unlisted_recipient,
    check_recipient_access hash:/etc/postfix/greylist_sender_exceptions,
    check_client_access cidr:/etc/postfix/cidr_greylist_network_exceptions,
    check_client_access pcre:/etc/postfix/check_client_fqdn
Once the file is saved:
postfix reload
tail -f /var/log/mail.log


We add reject_unlisted_recipient so we do not waste time greylisting clients that are addressing mail to unknown recipients. Set your MUA to deliver normally to port 25 (no authentication) and then attempt to send a message through and see if your client gets greylisted like mine did. If I wait 30 seconds I should be able to send the message. Note that my client IP is not included in mynetworks in main.cf (if it were, everything in smtpd_recipient_restrictions would be bypassed):
Jun 15 21:12:19 sfa postfix/smtpd[10095]: NOQUEUE: reject: RCPT from
 unknown[192.168.1.41]: 450 4.7.1 <unknown[192.168.1.41]>: Client host rejected:
  Greylisted, see http://isg.ee.ethz.ch/tools/postgrey/help/example.com.html;
   from=<garyv@example.org> to=<garyv@example.com> proto=ESMTP helo=<nobody>


I am going to whitelist 192.168.1.0 so clients on my internal network are not subjected to greylisting. Note that typically you would simply add your internal network to the mynetworks setting in main.cf. Cidr type tables do not need to be postmapped. http://www.postfix.org/cidr_table.5.html. I will place the whitelist entry in
vi /etc/postfix/cidr_greylist_network_exceptions
192.168.0.0/16 OK

postfix reload

I am going to wipe out the entire Postgrey database in order to prove to myself that my change did in fact whitelist my network. You don't want to do this once the system is up and running (unless the database becomes corrupt). Then I am going to try to send another message.

ls -l /var/lib/postgrey/
/etc/init.d/postgrey stop
rm /var/lib/postgrey/*
/etc/init.d/postgrey start

ls -l /var/lib/postgrey/


tail -f /var/log/mail.log

And it worked:
Jun 15 21:36:51 sfa postfix/smtpd[10167]: connect from unknown[192.168.1.41]
Jun 15 21:36:52 sfa postfix/smtpd[10167]: 1EDD624218: client=unknown[192.168.1.41]



Install policyd-weight - Optional

Index
Policyd-weight is no longer maintained. One thing to consider when using this is that RBLs at www.spamhaus.org are queried. If spamhaus is blocking you, then this program looses some value http://www.spamhaus.org/organization/dnsblusage.html. Remember that how Bind9 is configured (forwarding - or no forwarding) may affect whether spamhaus allows you to use their free service or not. Policyd-weight will block a client if it hits a few RBLs or appears to be poorly configured (or not configured) as a mail server. The $REJECTLEVEL setting is what will make the biggest difference as far as how much mail is rejected. I set it to a conservative 4.8 in /etc/policyd-weight.conf in order to give idiots running real (but poorly configured) mail servers a fighting chance. The RBL checks in policyd-weight may cause a slight delay when a client connects.
apt-get install policyd-weight

cd /etc
wget http://verchick.com/mecham/public_html/policyd-weight.conf
sed -i "s/'IX_MANITU',/'IX_MANITU'/" /usr/sbin/policyd-weight
sed -i "s/ 'rbl.ipv6-world.net'/#'rbl.ipv6-world.net'/" /usr/sbin/policyd-weight
/etc/init.d/policyd-weight stop
/etc/init.d/policyd-weight start
cd /etc/postfix
cp -ip main.cf main.cf-before-policyd-weight
postconf -e "smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname"
test -e greylist_sender_exceptions || touch greylist_sender_exceptions
postmap greylist_sender_exceptions
touch cidr_greylist_network_exceptions


Now vi /etc/postfix/main.cf or use the WinSCP editor to edit main.cf. If you installed Postgrey, insert policyd-weight (check_policy_service) ahead of check_client_fqdn:
smtpd_recipient_restrictions =
    permit_mynetworks,
    reject_unauth_destination,
    reject_unlisted_recipient,
    check_recipient_access hash:/etc/postfix/greylist_sender_exceptions,
    check_client_access cidr:/etc/postfix/cidr_greylist_network_exceptions,
    check_policy_service inet:127.0.0.1:12525,
    check_client_access pcre:/etc/postfix/check_client_fqdn
otherwise, add a few lines to the end:
     [...]
    reject_unauth_destination,
    check_recipient_access hash:/etc/postfix/greylist_sender_exceptions,
    check_client_access cidr:/etc/postfix/cidr_greylist_network_exceptions,
    check_policy_service inet:127.0.0.1:12525
Then:
/etc/init.d/postfix restart
tail -f /var/log/mail.log


Make sure reject_unlisted_recipient, is set as shown above. Set your MUA to deliver normally to port 25 (no authentication) and then attempt to send a message through and see if you get a hit like mine did (you may have to temporarily remove your network from /etc/postfix/cidr_greylist_network_exceptions and reload postfix). Note that my client IP is not included in mynetworks in main.cf (if it were, everything in smtpd_recipient_restrictions would be bypassed). If you installed postgrey and entered your local network in cidr_greylist_network_exceptions you will have to remove it and reload postfix in order to test this. After doing so, I once got something similar to:
Apr  5 13:48:17 msa postfix/policyd-weight[19123]: decided action=550 
 Mail appeared to be SPAM or forged. Ask your Mail/DNS-Administrator to correct HELO and DNS MX
 settings or to get removed from DNSBLs; MTA helo: myclient, MTA hostname: unknown[192.168.1.41]
 (helo/hostname mismatch); in dsn.rfc-ignorant.org; in postmaster.rfc-ignorant.org;
 in abuse.rfc-ignorant.org; <client=192.168.1.41> <helo=myclient>
 <from=test@example.com> <to=garyv@example.com>; delay: 3s

Apr  5 13:48:17 msa postfix/smtpd[19117]: NOQUEUE: reject: RCPT from unknown[192.168.1.41]:
 550 5.7.1 <garyv@example.com>: Recipient address rejected: Mail appeared to be SPAM or
 forged. Ask your Mail/DNS-Administrator to correct HELO and DNS MX settings or to get removed
 from DNSBLs; MTA helo: myclient, MTA hostname: unknown[192.168.1.41] (helo/hostname mismatch);
 in dsn.rfc-ignorant.org; in postmaster.rfc-ignorant.org; in abuse.rfc-ignorant.org;
 from=<test@example.com> to=<garyv@example.com> proto=ESMTP helo=<myclient>
In order to prevent internal clients from getting scanned (and possibly rejected) by policyd-weight (and postgrey),
vi /etc/postfix/main.cf and place your internal network in mynetworks (and reload postfix) or whitelist the network by adding it to /etc/postfix/cidr_greylist_network_exceptions as mentioned above in the postgrey instructions.

Make a couple changes to logcheck (this is four lines)
echo "^\w{3} [ :0-9]{11} [._[:alnum:]-]+ postfix/policyd-weight\[[[:digit:]]+\]: decided action=" >>/etc/logcheck/ignore.d.server/postfix
echo "^\w{3} [ :0-9]{11} [._[:alnum:]-]+ postfix/policyd-weight\[[[:digit:]]+\]: weighted check:" >>/etc/logcheck/ignore.d.server/postfix
echo "^\w{3} [ :0-9]{11} [._[:alnum:]-]+ postfix/policyd-weight\[[[:digit:]]+\]: child: spawned" >>/etc/logcheck/ignore.d.server/postfix
tail -2 /etc/logcheck/ignore.d.server/postfix



Install Botnet SA plugin - Optional

Index
This plugin is designed to detect botnet (zombie) clients. It is outdated and no longer supported. I trim the score way down in case of false positives (which do happen). Running this check will increase scan times.
cd /usr/local/src
mkdir Botnet-0.8
cd Botnet-0.8
wget http://verchick.com/mecham/public_html/spam/Botnet-0.8.tar
tar -xf Botnet-0.8.tar
wget http://verchick.com/mecham/public_html/spam/botnet8patch2.txt
cp Botnet.pm Botnet.pm~
patch -p0 <botnet8patch2.txt
cp Botnet.pm /etc/spamassassin/
cp Botnet.cf /etc/spamassassin/
cd /etc/spamassassin/
sed -i 's/5.0/1.0/' Botnet.cf
/etc/init.d/amavis restart
spamassassin --lint


You will have to wait for some mail from distant servers to test this. Look for a hit to the BOTNET rule in the X-Spam-Status: header. This will only happen occasionally as much of this stuff may be blocked before SpamAssassin sees it.

Install p0f - Optional

Index
Passive OS Fingerprinting attempts to discover what type of system a message is sent from. This program is also somewhat outdated. If mail comes directly from a Windows XP machine (for example) one might assume the machine is a zombie. If this machine is behind a NAT or proxy server that proxies the TCP sessions, p0f may not work. Trusted clients are not checked (due to settings in our MYNETS and TRUSTED policy banks):
apt-get install p0f

cd /etc/init.d
wget http://verchick.com/mecham/public_html/spam/p0f2
mv p0f2 p0f
chmod +x p0f
update-rc.d p0f defaults
cd /etc/spamassassin
wget http://verchick.com/mecham/public_html/spam/p0f.cf
/etc/init.d/p0f start


vi /etc/amavis/amavisd.conf and add the lines shown in red at the location shown:
# $os_fingerprint_method = 'p0f:*:2345'; # to query p0f-analyzer.pl
# Use passive OS fingerprinting
$os_fingerprint_method = 'p0f:127.0.0.1:2345';


Once the edits are finished:
/etc/init.d/amavis restart

You will have to wait for some mail from distant servers to test this. Look for hits to P0F rules in the X-Spam-Status: header. Look for an X-Amavis-OS-Fingerprint: header. If you have both p0f and Botnet installed, you may find this post relevant http://marc.info/?l=spamassassin-users&m=118272807918926

Use an RBL - Optional

Index
I'm only going to illustrate one (fairly safe and reliable) RBL. One thing to consider when using this is that RBLs at www.spamhaus.org are queried. If spamhaus is blocking you, then this setting will not be beneficial http://www.spamhaus.org/organization/dnsblusage.html

cd /etc/postfix
cp -ip main.cf main.cf-before-rbls
touch rbl_sender_exceptions
postmap rbl_sender_exceptions
touch rbl_client_exceptions
postmap rbl_client_exceptions
touch rbl_recipient_exceptions
postmap rbl_recipient_exceptions


You can add senders, clients or recipients (respectively) to the maps above to have them bypass all the checks after reject_unlisted_recipient. See http://www.postfix.org/access.5.html. Now vi /etc/postfix/main.cf or use the WinSCP editor to edit main.cf and insert the access maps and single RBL as shown.
smtpd_recipient_restrictions =
    permit_mynetworks,
    reject_unauth_destination,
    reject_unlisted_recipient,
    check_sender_access hash:/etc/postfix/rbl_sender_exceptions,
    check_client_access hash:/etc/postfix/rbl_client_exceptions,
    check_recipient_access hash:/etc/postfix/rbl_recipient_exceptions,
    reject_rbl_client sbl-xbl.spamhaus.org,
    check_recipient_access hash:/etc/postfix/greylist_sender_exceptions,
    check_client_access cidr:/etc/postfix/cidr_greylist_network_exceptions,
    check_policy_service inet:127.0.0.1:12525,
    check_client_access pcre:/etc/postfix/check_client_fqdn
Then:
postfix reload
tail -f /var/log/mail.log



Gary V
mr88talent at yahoo dot com
JUN 5 2011