SpamAssassin - Creating your own rules

First, read http://wiki.apache.org/spamassassin/WritingRules, it's a good introduction.

Why should I write rules myself?

Normally this isn't necessary. But I got some german/french "wrist watch" SPAM which SpamAssassin just couldn't score high enough, not even after feeding dozens of e-mails to sa-learn. So take this as an extendable example.

Collect several SPAM messages

Scan your Inbox for more samples of that bothersome spam message. In my case, there were multiple variations of "wrist watch" SPAM:

Subject: Wir Liefern Die Uhren Ganz Schnell Nach Hause
Subject: Bekommen Sie Die Marken Uhren Jetzt Und Hier
Subject: Reiche Uhren Jetzt Ganz Billig - Top Tip

And so on. Copy all the full e-mails (plain-text, with headers) into a file.

Finding similarities

You don't want rules for one single SPAM message. What you will try to implement, is a rule (or ruleset) which matches similar components of that SPAM "category".

In my case, I analyzed the headers and found out, that all (certainly faked) MUAs had a similar name:

X-Mailer: blablah.94
X-Mailer: bxyz.34
X-Mailer: blkdfie.21

Therefore, our first rule will be a header check (take care, this rule also matches "Microsoft Outlook Express"):

header LOCAL_WRISTWATCH_MAILER X-Mailer =~ /\.[0-9][0-9]/
score LOCAL_WRISTWATCH_MAILER 0.5

Let's move on to the mail body: I've detected that most SPAMs link to URLs via the bit.ly URL-shortener:

uri LOCAL_WRISTWATCH_BITLY_URL /bit.ly/
score LOCAL_WRISTWATCH_BITLY_URL 0.5

You can parse raw HTML with rawbody. We need it for this string here:

rawbody LOCAL_WRISTWATCH_HTML /<a href=3D"http://bit.ly/
score LOCAL_WRISTWATCH_HTML 0.5

Now combine these checks to a meta-rule which will trigger (=score) if all elements match:

meta UHRENSPAM_META (UHRENSPAM_MAILER && UHRENSPAM_BITLY_URL)
score UHRENSPAM_META 2.0