Since my previous blog post on this topic was so useful to me, but slightly obsolete, I’m posting updates. I recently had occasion to rebuild my mail server, and decided to bite the bullet and go with Mavericks plus the new Server.app
.
The new Server.app
thing is a pretty pathetic replacement for the classic OS X Server, but most of the same stuff can be found under the hood. Eventually.
The SpamAssassin implementation is buried in, and invoked by, amavisd
, which means that if you want to run spamc
directly, you have to do Something Else. The basic idea from before remains; create a launchd
job for the spamd
program.
But, there’s changes, because the new system puts server stuff inside Server.app, in Server.app/Contents/ServerRoot
. (If you are interested in this post, you probably already know that applications are just directories and can contain all sorts of things, like a partial root filesystem image in this case.) So my new org.spamassassin.spamd.plist
looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.spamassassin.spamd</string>
<key>OnDemand</key>
<false/>
<key>Program</key>
<string>/Applications/Server.app/Contents/ServerRoot/usr/bin/spamd</string>
<key>ProgramArguments</key>
<array>
<string>-D</string>
</array>
<key>RunOnLoad</key>
<true/>
</dict>
</plist>
But that turns out not to entirely solve my problem. What I’m trying to do is have a local IMAP server so that I can have fetchmail
grab mail from a couple of sources, accumulate it in a single place, and so on. And I want it to be subject to SpamAssassin rules. And because of reasons, I want to also hand it off to procmail
for some other filtering. And instead of having procmail
run everything through spamc
, I can just rely on the fact that local delivery goes through the mail server, and thus through amavisd
, right?
Almost right. There’s some configuration changes needed (in /Library/Server/Mail/Config/amavisd/amavisd.conf
, which is of course the first place you would look.) First, I wanted SpamAssassin tagging on everything, even boring stuff, so I changed the minimum score needed to produce tags:
$sa_tag_level_deflt = -999.0; # add spam info headers if at, or above that level
I would like to point out that “deflt”, here, is a really great example of an abbreviation which does not save enough space to help. I would have called this $sa_tag_minimum_score
maybe.
But amavisd
is also clever enough not to do tagging on anything that it isn’t delivering locally. Unfortunately, for historical reasons, I am receiving mail for more than one domain, so the To: lines in my email don’t always match. There’s lots of ways to set the list of domains you want, but what I want is to always match everything, because I don’t care what the address is, this mailer only does local delivery and thus everything is always local, period. Amusingly, “period” turns out to be the magic word:
@local_domains_maps = ['.'];
This tells amavisd
that everything is local delivery and should get properly processed.
And while I’m at it, the place for custom SpamAssassin rules is local.cf
, found in /Library/Server/Mail/Config/spamassassin
. Only it’s not there, just a local.cf.default
, but you can just create a local.cf
and stuff seems to work.
And, speaking of things that took me a while to find: The amavisd
job description lives in Server.app/Contents/ServerRoot/System/Library/LaunchDaemons
, which is a fascinating bit of history: Normally, /System/Library
is used only for the base operating system, while installed apps put their stuff in /Library
. But the parts of Server.app
which aren’t really intended to be tweaked or modified just live in the place under ServerRoot
that they would have been in an OS X Server filesystem. Interesting.
By the way, I’d also like to state for the record that mail server failures are a big hassle.