articles
index
spamassassin
>> config
>> faq
patches
pmmail
Hetzner RAID1
feedback
tell me
Copyright © Per Jessen, 2003-2006.
per@computer.org
Unless otherwise indicated, verbatim
copying and distribution of this entire
article is permitted in any medium,
provided this notice is preserved.

apache Apache/2.2.17 (Linux/SUSE)

Spamassassin & Postfix - configuration

.

Software versions

spamassassin: All of the below is based on my experiences with version 2.60. I suspect you should be fine with any post-2.60 release, but your milage may vary.

postfix: I'm now using 2.0.16, but I sincerely doubt if the version matters an awful lot, as long as it is fairly recent.

Spamassassin setup

There is really nothing much to say about the spamassassin setup/installation, except the next brief section on the setting up of spamd.

At this point it should be noted that spamassassin in this configuration only acts as a site-wide filter. I.e. it does not take any personal spamassassin configuration into account.

Starting spamd

There are probably at least a dozen miscellaneous options for starting the spamd daemon, but the two most obvious are:

  • via init-script
  • spawned by Postfix

I find option 2 interesting, but decided using an init-script would be more transparent. Also, spamd comes with a collection of init-scripts for a number of Linux distributions.

Postfix configuration

Of course, the two files we will be looking at are main.cf and master.cf.

smtpd daemons

As you will notice from the schematic, I use multiple smtpd daemons. The "standard" smtpd daemon:

from master.cf:
smtp      inet  n       -       n       -       -       smtpd
        -o smtpd_recipient_restrictions=permit_mynetworks,check_relay_domains
        -o content_filter=

has no content filter and will listen on the interfaces specified by the inet_interfaces configuration parameter:

from main.cf:
inet_interfaces = $myhostname, localhost

The second smtpd daemon is set up slightly different:

from master.cf:
external-mail:smtp   inet    n       -       n       -       -       smtpd
        -o smtpd_helo_restrictions=reject_unknown_hostname,permit
        -o content_filter=spamassassin

Important to note is that this daemon will:

  • listen on the interface specified by the "external-mail" name.
  • and pass all mail through the spamassassin content-filter

If you don't have a local DNS or just prefer using an IP-address:

from master.cf:
192.168.2.233:smtp   inet    n       -       n       -       -       smtpd
        -o smtpd_helo_restrictions=reject_unknown_hostname,permit
        -o content_filter=spamassassin

Network interfaces

For the "external-mail" interface-address above, I decided to simply setup a virtual interface rather than actually add a 2nd physical card to the server.

ifconfig eth0:0 a.b.c.d:

eth0      Link encap:Ethernet  HWaddr 00:20:ED:25:E4:68
          inet addr:192.168.2.104  Bcast:192.168.2.255  Mask:255.255.255.0
          UP BROADCAST NOTRAILERS RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5269641 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2578520 errors:1 dropped:0 overruns:0 carrier:1
          collisions:1641369 txqueuelen:100
          RX bytes:2943098845 (2806.7 Mb)  TX bytes:435405486 (415.2 Mb)
          Interrupt:20 Base address:0x9000 Memory:e8006000-e8006038

eth0:0    Link encap:Ethernet  HWaddr 00:20:ED:25:E4:68
          inet addr:192.168.2.233  Bcast:192.168.2.255  Mask:255.255.255.0
          UP BROADCAST NOTRAILERS RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:20 Base address:0x9000 Memory:e8006000-e8006038

In the example above, the physical interface has address 192.168.2.104, whereas the virtual is 192.168.2.233.

content_filter

To configure the content_filter, master.cf needs just a couple of lines added.

spamassassin unix -     n       n       -       -       pipe
        user=nobody argv=/usr/bin/spamc -f -e
        /usr/sbin/sendmail -oi -f ${sender} ${recipient}

This is where it gets interesting - essentially this statement establishes a content filter - spamc. To filter, Postfix will pipe an email (header and body) to spamc. Which is exactly what we need, except, after having called spamd, spamc would normally just write the email to stdout. However, by using the '-e' option we tell spamc to pipe the output to another program. In this case, we want to re-inject the mail, so we simply call sendmail.

One more thing

The one thing that is left now is to make sure that your external mail is delivered to the address that is filtered (external-mail/192.168.2.233). This will obviously depend on your local setup. Perhaps you need to change an MX record in your DNS.

Our internet connection is SDSL, going through a Zyxel SDSL router. We have simply configured the Zyxel routers server mapping set to forward all port 25 traffic to our internal server at 192.168.2.233.

Summary

To sum it up -

  • postfix - if you've ever wondered whether to stick to sendmail or go with Postfix, Postfix is the answer. It really is a lot easier to configure.
  • spamassassin - excellent tool. My only complaint is that it is written in Perl. But easy to install & configure.

Overall

Using spamassassin with postfix is fairly straight forward. My initial setup did take a while to get to work, but I learnt a lot about postfix. I feel this 3rd revised setup is now about as optimal as it can get, especially after I eliminated smtpclient.

I suspect the fact that SpamAssassin is using Perl is likely to cause someone performance-problems, but for the time being, we're quite happy with it. For the Postfix and/or SMTP novice, getting the overall setup to work is a very useful educational exercise.

Performance

I'm maintaining some statistics for our spamassassin processing, mostly to try to gauge spamassassins performance impact, but also because the data produced made a good sample for my Timian project.

See the spamassassin performance report. This is work in progress. I do intend to write up a summary of what we've seen regarding spamassassin performance, (a subject I gather is of interest to a lot of people), but it's not on the top-10 of priorities for now.

Some frequently asked questions

See the FAQ document.

td#changed2 { font-size: 80%; font-style: italic; border-style: solid none none none; border-width: 1px; vertical-align: top; } table#changed1 { clear: both; width: 100%; }