The Perfect SpamSnake - Ubuntu 8.04 LTS - Page 4

6.3 Postfix Anti-Spam Settings

6.3.1 smtpd_helo_required

Make any connecting mail server do a proper smtp "handshake" and announce its name. Internet RFCs require this, so we do too.

postconf -e "smtpd_helo_required = yes"

I also changed the smtpd_banner to "$myhostname ESMTP $mail_name SpamSnake".

Preface: Postfix' restriction stages are as follows, and are processed in the following order:


We are only going to place entries in the last three restriction stages. Restriction stages are processed in this order regardless of the order listed in


6.3.2 smtpd_sender_restrictions

This restriction stage restricts what sender addresses this system accepts in MAIL FROM: commands (the envelope sender). We will place three tests (restrictions) in this restriction stage.


6.3.4 check_sender_access (Optional)

Here we ask Postfix to compare the envelope sender to entries in an /etc/postfix/sender_access database and act upon those entries if a match is found. We also define what action is taken there (OK, DUNNO, REJECT etc.) on a sender by sender basis. If the sender is not listed in the file, the test evaluates to DUNNO, and the next test is performed.


6.3.5 reject_non_fqdn_sender

Reject when the envelope sender mail address is not in the proper format.


6.3.6 reject_unknown_sender_domain

Reject when the envelope sender's domain part of the mail address has no DNS "A" or "MX" record at all. On occasion, you will see in a report that someone you wish to receive mail from has been rejected by this setting. One possible cause of this is when legitimate senders deliberately use bogus domain names so you will not reply to them. This is where the sender access list comes in handy. You can give them an OK there, and this test will be bypassed.

Now to implement these three restrictions:

postconf -e "smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_access, reject_non_fqdn_sender, reject_unknown_sender_domain"


6.3.7 smtpd_recipient_restrictions

The access restrictions that the Postfix SMTP server applies in the context of the RCPT TO: command. This refers to the "envelope recipient" which is what the client gave in the "RCPT TO:" line during the SMTP session, not the header "To:" line. Let's look at those specific restrictions (tests) we place in smtpd_recipient_restrictions:


6.3.8 permit_mynetworks

Allows machines listed in "mynetworks" to skip the rest of the tests in this restriction stage (permit = OK). In other words, it exits this stage and is tested in the next stage (smtpd_data_restrictions). Because permit_mynetworks is placed in front of reject_unauth_destination, this means machines in $mynetworks are allowed to relay mail to any domain. Without this, we would only be able to send mail to our own domain(s). If the IP address of the sender is not listed in $mynetworks, the test evaluates to "DUNNO" and continues on to the next test (reject_unauth_destination).


6.3.9 reject_unauth_destination & reject_unknown_recipient_domain

This, along with permit_mynetworks is used for relay control. This setting, in essence, means that mail bound for any domain that we have not configured our machine to accept mail for will be rejected. In our case Postfix will use the relay_domains setting (or table) that we configured earlier to determine what domains those are. If the domain is listed in relay_domains, this test evaluates to "DUNNO" and the session is allowed to go on to the next test (if any).


6.3.10 reject_unauth_pipelining

Rejects bulk mailers that attempt to use pipelining to speed delivery, without checking if it is supported first (non-RFC, common among spammers).

Now to implement these three restrictions:

postconf -e "smtpd_recipient_restrictions = reject_non_fqdn_sender, reject_unknown_sender_domain, reject_non_fqdn_recipient, reject_unknown_recipient_domain, permit_mynetworks, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_rbl_client"


6.3.11 smtpd_data_restrictions

Optional access restrictions that the Postfix SMTP server applies in the context of the SMTP DATA: command. Like smtpd_recipient_restrictions, this is a restriction stage.


6.3.12 reject_unauth_pipelining

I repeat this setting in smtpd_data_restrictions as it is not always effective when placed in smtpd_recipient_restrictions. I include it in smtpd_recipient_restrictions as I like to place it prior to any policy servers. Note that there are only a couple of restrictions that make good use of smtpd_data_restrictions.

postconf -e "smtpd_data_restrictions = reject_unauth_pipelining"


6.3.13 /etc/postfix/sender_access

We referenced this file in smtpd_sender_restrictions. We use this file to check the sender right at the front door. In this file, we'll list certain senders/domains/IPaddress ranges for special handling. Below are bogus examples, create your own as you see fit. Please read /etc/postfix/sender_access for more information. Although you could use this file for various purposes, considering the way we have set this up in smtpd_sender_restrictions, I suggest using it to either blacklist senders, or allow certain senders to bypass the remaining tests in smtpd_sender_restrictions.

vi /etc/postfix/sender_access

#Example sender access map file
[email protected] 550 No MLM thanks
allspam.tld 550 Spam is not accepted here REJECT
[email protected] REJECT OK OK

Since this is a hash table, you need to postmap it as usual:

postmap /etc/postfix/sender_access


6.3.14 Final Look at the Postfix Install

Review changes:

less /etc/postfix/

Check the contents of the file for errors and repair if needed. Fire up Postfix:

postfix start

Check that Postfix responds:

telnet 25

You should see:

220 [yourFQDNhere] ESMTP Postfix (Ubuntu)

Hit [enter] a few times; then type quit to exit.

If it does not reply in this manner, open another terminal window and stop Postfix:

postfix stop

Make sure you ran newaliases and all the postmap commands above. Check all the settings in and Any time you make changes to or or to data tables, most (not all) of the time, it is required that you to reload Postfix with:

postfix reload


7 Pyzor, Razor, DCC, SpamAssassin and MailScanner Configuration

7.1 Install MailScanner

Install MailScanner Dependencies by doing the following:

apt-get install libconvert-tnef-perl libdbd-sqlite3-perl libfilesys-df-perl libmailtools-perl libmime-tools-perl libmime-perl libnet-cidr-perl libsys-syslog-perl libio-stringy-perl libfile-temp-perl

Install MailScanner from the Debian .deb Source:

dpkg -i mailscanner_4.68.8-1_all.deb


7.2 Pyzor Configuration

We need to change some permissions on pyzor first:

chmod -R a+rX /usr/share/doc/pyzor /usr/bin/pyzor /usr/bin/pyzord
chmod -R a+rxX /usr/share/python-support/pyzor

Here we supply the IP address of the Pyzor server to Pyzor. This will create the server's IP address in a servers file therein. Then it will test the connection. If you are behind a firewall, open port 24441/udp in and out to your server. While you're at it also open up 6277/udp for DCC, 2703/tcp for Razor and 783/tcp for SpamAssassin:

pyzor --homedir /var/lib/MailScanner discover
pyzor ping


7.3 Razor Configuration

Create the .razor configuration:

rm /etc/razor/razor-agent.conf
mkdir /var/lib/MailScanner/.razor
razor-admin -home=/var/lib/MailScanner/.razor -create
razor-admin -home=/var/lib/MailScanner/.razor -discover
razor-admin -home=/var/lib/MailScanner/.razor -register
chown -R postfix:www-data /var/lib/MailScanner
chmod -R ug+rwx /var/lib/MailScanner

Make the following changes to /var/lib/MailScanner/.razor/razor-agent.conf:

vi /var/lib/MailScanner/.razor/razor-agent.conf

Change debuglevel = 3 to debuglevel = 0 (yes zero not "o"). This will prevent Razor from filling up your drive with debug information. Those two lines should look like this when done:

debuglevel = 0
razorhome = /var/lib/MailScanner/.razor/


7.4 DCC Setup and Configuration

Install DCC from .deb source:

dpkg -i dcc-common_1.3.42-5_i386.deb
dpkg -i dcc-server_1.3.42-5_i386.deb

We are not running a DCC server, so we don't need to waste time checking ourselves.
Once the installation is done run:

cdcc "delete"
cdcc "delete Greylist"

Test our installation with:

cdcc info

You should get 'requests ok' from the servers.

7.4.1 64-bit DCC Installation

dpkg -i dcc-common_1.3.42-5_amd64.deb
dpkg -i dcc-server_1.3.42-5_amd64.deb

cdcc "delete"
cdcc "delete Greylist"

Test our installation with:

cdcc info

You should get 'requests ok' from the servers.


8 Configuring MailScanner and ClamAV

8.1 Stop Postfix:

postfix stop

Install the packages:

apt-get install clamav clamav-daemon

Update ClamAV virus defenitions:


Once that is done, we need to make a directory for SpamAssassin in the spool and give postfix permissions to it, if you run sa-learn --force as root, bayes databese that is stored in these directories will change to root:root and spamassassin will error looking at the db. Just keep an eye on the mail.log and you'll remember to change the permissions back. Also disable the MailScanner default configs:

mkdir /var/spool/MailScanner/spamassassin

Backup your MailScanner.conf file:

cp /etc/MailScanner/MailScanner.conf /etc/MailScanner/MailScanner.conf.back

Edit MailScanner.conf:

vi /etc/MailScanner/MailScanner.conf

Change the following parameters in MailScanner.conf:

%org-name% = ORGNAME
%org-long-name% = ORGFULLNAME
%web-site% = ORGWEBSITE
Run As User = postfix
Run As Group = www-data
Incoming Queue Dir = /var/spool/postfix/hold
Outgoing Queue Dir = /var/spool/postfix/incoming
MTA = postfix
Virus Scanners = clamav
Spam Subject Text = ***SPAM***
Send Notices = no
Spam List = SBL+XBL
Required SpamAssassin Score = 6
High SpamAssassin Score = 10
Spam Actions = deliver
High Scoring Spam Actions = delete
Rebuild Bayes Every = 0
Wait During Bayes Rebuild = no
SpamAssassin User State Dir = /var/spool/MailScanner/spamassassin

The first 9 lines are basically required in order for everything to work, the rest are recommended.


8.2 header_checks & body_checks

Let's go ahead and put this in header_checks is required because it allows us to hold all incoming email in order for MailScanner to do its thing:

postconf -e "header_checks = regexp:/etc/postfix/header_checks"

Edit header_checks:

vi /etc/postfix/header_checks

Add this line to the header_checks file, without it MailScanner will not work:

/^Received:/ HOLD


8.3 Fix to Disable Permission Checks on MailScanner Directories

Edit /etc/rc2.d/S20mailscanner to look like:

check_dir /var/spool/MailScanner       ${user:-postfix} ${group:-www-data}
#check_dir /var/lib/MailScanner         ${user:-mail} ${group:-mail}
#check_dir /var/run/MailScanner         ${user:-mail} ${group:-mail}
check_dir /var/lock/subsys/MailScanner       ${user:-postfix} ${group:-www-data}

In the file /etc/default/mailscanner, make sure this parameter is at 1:

vi /etc/default/mailscanner



8.4 MailScanner Webmin Plugin (Optional)

Login to Webmin, https://localhost:10000, and install the MailScanner module for webmin found at After this is done, you'll have to enter the following into your mailscanner module to get it to work:

Full path to MailScanner program /etc/init.d/mailscanner
Full path and filename of MailScanner config file /etc/MailScanner/MailScanner.conf
Full path to the MailScanner bin directory /usr/sbin
Full path and filename for the MailScanner pid file /var/run/MailScanner/
Command to start MailScanner /etc/init.d/mailscanner start
Command to stop MailScanner /etc/init.d/mailscanner stop


8.5 You can now start the system

/etc/init.d/mailscanner start
/etc/init.d/postfix start

Check your logs for errors:

tail -f /var/log/mail.log



Share this page:

3 Comment(s)