SpamAssassin

最後更新: 2019-04-23

目錄

 

 

介紹

SpamAssassin (content-based spam scanning)

spamassassin 會在 E-Mail 的 Header 加入以下內容:

X-Spam-Flag: NO
X-Spam-Score: 4.879
X-Spam-Level: ****
X-Spam-Status: No, score=4.879 tagged_above=-100 required=6.2
tests=[BAYES_50=0.8, HTML_MESSAGE=0.001, HTML_TAG_BALANCE_BODY=1.157,
MIME_HTML_MOSTLY=0.428, RDNS_NONE=0.793, URIBL_DBL_SPAM=1.7]

 


Install

 

Centos 6

yum install spamassassin

chkconfig spamassassin on

service spamassassin start

Basic Setting

/etc/mail/spamassassin/local.cf

required_score          5.0

# mx server ip
trusted_networks        R.R.R.R

Postfix Configure

Old method (original)

  • after-queue inspection
  • 缺點: backscatter email

master.cf

smtp      inet  n       -       -       -       -       smtpd
 -o content_filter=spamassassin

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

service postfix restart

Remark

[1]

-e command [args], --pipe-to command [args]

Instead of writing to stdout, pipe the output to command’s

[2]

/usr/sbin/sendmail -> /etc/alternatives/mta

update-alternatives --config mta

/usr/sbin/sendmail.postfix

Checking

eml header

...
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.datahunter.org
X-Spam-Level: **
X-Spam-Status: No, score=2.7 required=6.0 tests=HTML_FONT_FACE_BAD,
    HTML_MESSAGE,MIME_HTML_ONLY,RDNS_NONE shortcircuit=no autolearn=no
    version=3.3.1

 


Install by Source

 

useradd -s /bin/false spamd -m

cd /usr/src

wget https://apache.website-solution.net/spamassassin/source/Mail-SpamAssassi...

tar -zxf Mail-SpamAssassin-3.4.4.tar.gz

cd Mail-SpamAssassin-3.4.4

perl Makefile.PL

...
checking module dependencies and their versions...
...
dependency check complete...

optional module missing: GeoIP2::Database::Reader
optional module missing: IP::Country::DB_File
optional module missing: IO::Socket::IP
optional module out of date: IO::Socket::SSL
optional module missing: Net::Patricia
optional module missing: Net::DNS::Nameserver
optional module missing: BSD::Resource
optional module missing: IO::String
optional binary missing or nonfunctional: fetch
...

yum install perl-IO-String perl-BSD-Resource

make

make install     # 會安裝在 /usr/local

Checking

spamd -V

SpamAssassin Server version 3.4.4

spamc -V

SpamAssassin Client version 3.4.4

sa-update -v

Update finished, no fresh updates were available

Start Script

start_spamd.sh

#!/bin/bash

SPAMD=/usr/local/bin/spamd
USR=spamd
SPAMD_PID=/var/run/spamd.pid
SPAMDOPTIONS="-d -c -m5 -H -4"

# stop
killall spamd && sleep 3

# start
$SPAMD -u $USR -g $USR $SPAMDOPTIONS -r $SPAMD_PID

Opts

-d, --daemonize                   Daemonize

-c, --create-prefs                Create user preferences files

-m num, --max-children=num

-H [dir], --helper-home-dir[=dir] Specify a different HOME directory

Specify that external programs such as Razor, DCC, and Pyzor

should have a HOME environment variable set to a specific directory.

no argument => spamd will use the spamc caller’s home directory instead

-u username, --username=username              # Run as username

-g groupname, --groupname=groupname        # Run as groupname

IPv4

  • -4, --ipv4-only, --ipv4           Use IPv4 where applicable, disables IPv6
  • spamd -4
  • spamc -4

Start Service

start_spamd.sh

Setting File

/home/spamd/.spamassassin/user_prefs

 


sa-update

 

  • -V, --version
  • -v, --verbose
  • -h, --help

sa-update -V

sa-update version svn607589
  running on Perl version 5.8.8
  • --updatedir <path>         // default: /var/lib/spamassassin/
  • --channel <channel>       // default: updates.spamassassin.org (--channel .... --channel ....)
  • --channelfile <file>          // 一行一個 channel
  • --checkonly                    // Check for update availability, do not install (要用 echo $? 或加 -D 去 check 有無 update)

Debug:

sa-update -D

Sep 26 17:39:22.740 [7308] dbg: logger: adding facilities: all
Sep 26 17:39:22.740 [7308] dbg: logger: logging level is DBG
Sep 26 17:39:22.741 [7308] dbg: generic: SpamAssassin version 3.3.1
Sep 26 17:39:22.741 [7308] dbg: generic: Perl 5.010001, PREFIX=/usr, DEF_RULES_DIR=/usr/share/spamassassin, 
                                LOCAL_RULES_DIR=/etc/spamassassin, LOCAL_STATE_DIR=/var/lib/spamassassin
Sep 26 17:39:22.741 [7308] dbg: config: timing enabled
Sep 26 17:39:22.742 [7308] dbg: config: score set 0 chosen.
Sep 26 17:39:22.749 [7308] dbg: dns: is Net::DNS::Resolver available? yes
Sep 26 17:39:22.749 [7308] dbg: dns: Net::DNS version: 0.66
Sep 26 17:39:22.750 [7308] dbg: generic: sa-update version svn917659
Sep 26 17:39:22.750 [7308] dbg: generic: using update directory: /var/lib/spamassassin/3.003001
Sep 26 17:39:22.818 [7308] dbg: diag: perl platform: 5.010001 linux
Sep 26 17:39:22.818 [7308] dbg: diag: [...] module installed: Digest::SHA1, version 2.13
Sep 26 17:39:22.819 [7308] dbg: diag: [...] module installed: HTML::Parser, version 3.66
Sep 26 17:39:22.819 [7308] dbg: diag: [...] module installed: Net::DNS, version 0.66
..................................
Sep 26 17:39:22.824 [7308] dbg: diag: [...] module not installed: Encode::Detect ('require' failed)
Sep 26 17:39:22.825 [7308] dbg: gpg: Searching for 'gpg'
Sep 26 17:39:22.825 [7308] dbg: util: current PATH is:
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Sep 26 17:39:22.825 [7308] dbg: util: executable for gpg was found at /usr/bin/gpg
Sep 26 17:39:22.826 [7308] dbg: gpg: found /usr/bin/gpg
Sep 26 17:39:22.826 [7308] dbg: gpg: release trusted key id list: ? ? ?
Sep 26 17:39:22.829 [7308] dbg: channel: attempting channel updates.spamassassin.org
Sep 26 17:39:22.829 [7308] dbg: channel:
 update directory /var/lib/spamassassin/3.003001/updates_spamassassin_org
Sep 26 17:39:22.829 [7308] dbg: channel:
 channel cf file /var/lib/spamassassin/3.003001/updates_spamassassin_org.cf
Sep 26 17:39:22.830 [7308] dbg: channel:
 channel pre file /var/lib/spamassassin/3.003001/updates_spamassassin_org.pre
Sep 26 17:39:22.830 [7308] dbg: channel: metadata version = 1526135
Sep 26 17:39:22.888 [7308] dbg: dns: 1.3.3.updates.spamassassin.org => 1526135, parsed as 1526135
Sep 26 17:39:22.889 [7308] dbg: channel:
 current version is 1526135, new version is 1526135, skipping channel
Sep 26 17:39:22.889 [7308] dbg: diag: updates complete, exiting with code 1

http://wiki.apache.org/spamassassin/RuleUpdates

Cron Jobs

Debian:

10 4 * * *      root    /usr/bin/sa-update

Centos:

10 4 * * * root /usr/share/spamassassin/sa-update.cron 2>&1 | tee -a /var/log/sa-update.log

DB:

位置:

tree -d /var/lib/spamassassin

/var/lib/spamassassin
└── 3.004000
    ├── sought_rules_yerp_org
    └── updates_spamassassin_org

只要 keep 最大數字那個 folder 就可以, 舊果 D 可以 Delete

 


測試

 

清除 spamassassin 加入的 header

spamassassin -d spam.eml > mail.eml

Debug 一個 eml

spamassassin -t -D < /tmp/spam > out.eml

-t, --test-mode                   Pipe message through and add extra report to the bottom

-D, --debug

Debug spf

spamassassin -t -D spf < /tmp/spam > out.eml

Other opts

  • -r, --report                      Report message as spam
  • -L, --local                       Local tests only (no online tests)

 


Setting

 

 

*.pre

# new plugins will be added to new files (v310.pre, v312.pre, v320.pre ...)

local.cf

# These values can be overridden by editing ~/.spamassassin/user_prefs.cf

# Disable the DNSEval plugin (Default: 0)

  • skip_rbl_checks          1

OR

  • score RCVD_IN_RFCI  0
  • score RCVD_IN_ORBS 0
  • score RCVD_IN_DSBL  0

i.e.

/etc/mail/spamassassin/local.cf

skip_rbl_checks 1

locales

# "locales" are considered OK for incoming mail

ok_locales

Example:

# allow English, Japanese, and Chinese
ok_locales en ja zh    

whitelist

whitelist_from

whitelist_from_spf

 



Spamassassin Daemon

 

/etc/default/spamassassin

# enable spamd
ENABLED=1

# Set nice level of spamd
NICE="--nicelevel 15"

# cron job to automatically update
CRON=1

/etc/init.d/spamassassin status

Network

netstat -tnlp | grep spamd

tcp        0      0 127.0.0.1:783           0.0.0.0:*               LISTEN      13973/spamd.pid -d

 



Spamassassin Rule

 

Doc:

 

Header rules

 

# Subject

# a comment
header LOCAL_WL_SUBJECT      Subject =~ /\btestmsg\b/i

# score SYMBOLIC_TEST_NAME n.nn
score  LOCAL_WL_SUBJECT      -5
  • "header name" itself is always case-insensitive (i.e. Subject)
  • "=~"  =>  containing
  • "\b" => word-break, 令到只中
  • "i" =>  case-insensitive

# From

header LOCAL_WL_DOMAIN From =~ /test\.com/i

# All the headers

header LOCAL_DEMONSTRATION_ALL  ALL =~ /test\.com/i

# Use the '^' character here, you must put an m at the end of your line, "m" which will look at the header one line at a time (在 ALL 的 case 才用 m)

header LOCAL_DEMONSTRATION_WEIRD_FROM  ALL =~ /^FrOM\:/m

# Header Content Score

 0.5 MISSING_MID            Missing Message-Id: header
 1.4 MISSING_DATE           Missing Date: header

 

 

Body rules

 

[1]

body       LOCAL_DEMONSTRATION_RULE       /test/
score      LOCAL_DEMONSTRATION_RULE       0.1
describe   LOCAL_DEMONSTRATION_RULE       This is a simple test rule

 * case-sensitive

[2]

body LOCAL_DEMONSTRATION_RULE   /\btest\b/i

 * case-insensitive

[3]

body LOCAL_DEMONSTRATION_RULE   /\btest\b/

 * \b can be used to indicate where a word-break (anything that isn't an alphanumeric character or underscore)

 * not match "testing" or "attest" like

[4]

# My body rule
# R1
body            LOCAL_block_by_keyword_RULE_1   /Bitcoin\s+Address/i
score           LOCAL_block_by_keyword_RULE_1   10
describe        LOCAL_block_by_keyword_RULE_1   "Bitcoin Address"

P.S.

多空格的 perl regexp 有機會無效

# \s: matches any whitespace character (space, tab, newline)
\s+

原因

Nonbreaking space is 0xA0 in ISO-8859-1, and when it comes up in UTF-8 it is 0xC2A0. This will look like "Â ".

1空格    " "
2空格    "Â  "
3空格    "Â Â  "
4空格    "Â Â Â  "

 

Rule Default Score

* rules with a score set to 0 are not evaluated at all

* rules with no score statement will be scored at 1.0

header BIG5_SUBJECT_1    Subject =~ /代開*发票/
score BIG5_SUBJECT_1       5.460

 

特別的 score

any rule starting with T_ will be treated as a "test" rule and will be run with a score of 0.01

rules starting with a __ (double underscore) are evaluated with no score, and are intended for use in meta rules

 

External Image

 3.0 T_REMOTE_IMAGE         Message contains an external image

 

Rule check

# Lint the rule set: report syntax errors

spamassassin --lint

如果 syntax 沒有問題的話, 那沒有 output 及 echo $? output 是 0

# debug

spamassassin --lint -D

 

URI rules

match text in the URI's contained in plain text and HTML sections of mail.

link match "www.example.com/OrderViagra/"

uri LOCAL_URI_EXAMPLE   /www\.example\.com\/OrderViagra\//
score LOCAL_URI_EXAMPLE 0.1

 

Meta rules

Meta rules are rules that are boolean(true/false) or arithmetic combinations(1/0) of other rules

Note

  • \ placed before the @ sign
  • __ treated as having no score

Boolean

header __LOCAL_FROM_NEWS        From =~ /news\@example\.com/i
body   __LOCAL_SALES_FIGURES    /\bMonthly Sales Figures\b/
meta LOCAL_NEWS_SALES_FIGURES   (__LOCAL_FROM_NEWS && __LOCAL_SALES_FIGURES)
score  LOCAL_NEWS_SALES_FIGURES -1.0

Arithmetic

body __LOCAL_TEST1          /\btest1\b/
body __LOCAL_TEST2          /\btest2\b/
body __LOCAL_TEST3          /\btest3\b/
meta LOCAL_MULTIPLE_TESTS   (( __LOCAL_TEST1 + __LOCAL_TEST2 + __LOCAL_TEST3) > 1)
score LOCAL_MULTIPLE_TESTS  0.1

Weight your sub rules

meta LOCAL_MULTIPLE_TESTS (((0.8 * __LOCAL_TEST1) + (0.5 * __LOCAL_TEST2)) > 1)

Example

header __LOCAL_MyFrom From        =~ /\@datahunter\.org/i
header __LOCAL_MyRP   Return-Path =~ /\@datahunter\.org/i
meta   LOCAL_FAKE_MYDOMAIN        __LOCAL_MyFrom && !__LOCAL_MyRP
score  LOCAL_FAKE_MYDOMAIN        10

 


HEADER_FROM_DIFFERENT_DOMAINS

 

From and EnvelopeFrom 2nd level mail domains are different

即是 Return path != From

V 3.4 才有此功能

# This Rule Requires check_equal_from_domains() in HeaderEval.pm

header HEADER_FROM_DIFFERENT_DOMAINS eval:check_equal_from_domains()
describe HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different
score HEADER_FROM_DIFFERENT_DOMAINS 0.25

 



自定 Score

 

自定設定檔

/etc/mail/spamassassin/local.cf

ie.

score SPF_FAIL     5

P.S.

如果係用 amavisd call spamassin, 那更改完 rule 後要 reload 它(amavisd)

 

MySetting

# SPF
score   SPF_FAIL                7
score   SPF_PASS                -3
score   SPF_SOFTFAIL            1

# BL
score   URIBL_ABUSE_SURBL       3
score   URIBL_BLACK             3

# BAYES
score   BAYES_99                4

# DKIM (無咩用, 基本上 spammer 都會 sign DKIM )
score   DKIM_VALID              0
score   DKIM_VALID_AU           0


# How many seconds to wait for an SPF query to complete,
# before scanning continues without the SPF result.
spf_timeout                     5

 


URIDNSBL

 

Program: SpamAssassin 3 includes a plugin with SURBL support enabled by default: URIDNSBL

URIDNSBL - look up URLs against DNS blocklists

Centos6 Setting:

/etc/mail/spamassassin/init.pre

loadplugin Mail::SpamAssassin::Plugin::URIDNSBL

/usr/share/spamassassin/25_uribl.cf

ifplugin Mail::SpamAssassin::Plugin::URIDNSBL
## Spamhaus
## SURBL
## URIBL
## DOMAINS TO SKIP
endif   # Mail::SpamAssassin::Plugin::URIDNSBL

uridnsbl NAME_OF_RULE dnsbl_zone lookuptype

Specify a lookup. NAME_OF_RULE is the name of the rule to be used, dnsbl_zone is the zone to look up IPs in, and lookuptype is the type of lookup (TXT or A). Note that you must also define a body-eval rule calling check_uridnsbl() to use this.

SETTINGS

uridnssub       URIBL_SBL        zen.spamhaus.org.       A   127.0.0.2
body            URIBL_SBL        eval:check_uridnsbl('URIBL_SBL')
describe        URIBL_SBL        Contains an URL listed in the SBL blocklist
tflags          URIBL_SBL        net
reuse           URIBL_SBL

if can(Mail::SpamAssassin::Plugin::URIDNSBL::has_tflags_domains_only)
urirhssub       URIBL_DBL_SPAM   dbl.spamhaus.org.       A   127.0.1.2
body            URIBL_DBL_SPAM   eval:check_uridnsbl('URIBL_DBL_SPAM')
describe        URIBL_DBL_SPAM   Contains an URL listed in the DBL blocklist
tflags          URIBL_DBL_SPAM   net domains_only

# this indicates that IP-address queries were sent to DBL, and should
# never appear; if it does, something is wrong with SpamAssassin
urirhssub       URIBL_DBL_ERROR  dbl.spamhaus.org.       A   127.0.1.255
body            URIBL_DBL_ERROR  eval:check_uridnsbl('URIBL_DBL_ERROR')
describe        URIBL_DBL_ERROR  Error: queried the DBL blocklist for an IP
tflags          URIBL_DBL_ERROR  net domains_only
endif

skip_uribl_checks ( 0 | 1 ) (default: 0)

# DOMAINS TO SKIP (KNOWN GOOD)

uridnsbl_skip_domain domain1 domain2 ...

uridnsbl_max_domains

# The maximum number of domains to look up. (default: 20)

uridnsbl_max_domains N

tflags

tflags SYMBOLIC_TEST_NAME [ {net|nice|learn|userconf|noautolearn} ]

Used to set flags on a test

These flags are used in the score-determination backend system for details of the test's behaviour

(bayes_auto_learn and use_auto_whitelist)

Provider:

realtime database of domains

http://www.spamhaus.org/dbl/

sbl-multi.rbl.spamrl.com

*message bodies (message text and HTML for URLs)
-> IP addresses of these hosts
-> their nameservers
-> domain names of these hosts

Score

# Contains an URL listed in the URIBL blacklist

# Contains an URL listed in the URIBL blacklist
score   URIBL_BLACK           5

# Contains an URL listed in the ABUSE SURBL blocklist
score   URIBL_ABUSE_SURBL     5 

DOC

http://spamassassin.apache.org/full/3.4.x/doc/Mail_SpamAssassin_Plugin_URIDNSBL.html

 


spamc

 

介紹

client for spamd. It has extremely low overhead in loading (對比起 spamassassin)

Check Version

spamc -V

SpamAssassin Client version 3.4.0

Usage

spamc [options] < message

  compiled with SSL support (OpenSSL 1.0.1e-fips 11 Feb 2013)

Options:

  • -c, --check          # Just check if the message is spam or not.  Set process exitcode to 1 if message is spam
  • -r, --full-spam      # Just output the SpamAssassin report text to stdout, if the message is spam
  • -R, --full              # Just output the SpamAssassin report text to stdout

Example:

spamc -c < msg.eml

0/0

0/0

0/0 => That indicates an error.

[1]

log (Troubleshoot)

Mar 19 16:15:09 sf3 spamc[7007]: skipped message, greater than max message size (512000 bytes)

設定掃 mail 的 size 到 10 MB

spamc -s 10485760 -c <  test.eml

Change spamc Default Setting

"spamc" will attempt to load /etc/mail/spamassassin/spamc.conf

-s 10485760

[2]

... spamc[20557]: connect to spamd on 127.0.0.1 failed, retrying (#1 of 3): Connection refused

 


log

/etc/sysconfig/spamassassin

SPAMDOPTIONS="-d -c -m5 -H -s mail"

service spamassassin restart

Remark

-s mail                            # use syslog, facility mail (default)

-s stderr 2>/dev/null        # log to stderr, throw messages away

-s /var/log/spamd.log       # log to file /var/log/spamd.log

ps aux | grep spamd

/usr/bin/spamd --pidfile /var/run/spamd.pid -d -c -m5 -H -s mail

 

 


ok_locales

 

# default: all
ok_locales xx [ yy zz ... ] (default: all)

  • ok_locales all            (allow all locales)
  • ok_locales en           (only allow English)
  • ok_locales en ja zh   (allow English, Japanese, and Chinese)

zh - Chinese (both simplified and traditional) character sets

 


Whitelist & Blacklist

 

The headers checked for whitelist addresses are as follows:

  • Resent-From
  • Envelope-Sender
  • Resent-Sender
  • X-Envelope-From
  • From

Whitelist

Example:

# 支援多行及用"*"
whitelist_from a@b
whitelist_from *@example.com
whitelist_from [email protected] [email protected]

 * Defalt USER_IN_WHITELIST=-100
 * WHITELIST 後仍會 check SPF

進階 whitelist (_auth 及 _from_rcvd)

  • whitelist_auth
  • whitelist_from_rcvd

whitelist_from 係直接信 mail 內的資料, _auth 及 _from_rcvd 會查證來源

# The first parameter is a sender's e-mail address to whitelist,
# and the second is a string to match the relay's rDNS, or its IP address.
# Matching is case-insensitive.
# The reverse DNS lookup is done by a MTA, not by SpamAssassin.
# Subnet: [10.1.2.3], [10.1.2], [10.1], [10]

whitelist_from_rcvd [email protected] sourceforge.net
whitelist_from_rcvd *@axkit.org      [192.168.0]

# Authorization is performed using one of the installed sender-authorization schemes: SPF or DKIM
# 要有用此 plugin: Mail::SpamAssassin::Plugin::SPF, Mail::SpamAssassin::Plugin::DKIM

whitelist_auth [email protected]

Blacklist

blacklist_from [email protected]

 


Other Setting

 

use_learner ( 0 | 1 ) (default: 1)
use_bayes ( 0 | 1 ) (default: 1)
use_bayes_rules ( 0 | 1 ) (default: 1)
bayes_auto_learn ( 0 | 1 ) (default: 1)

# allows users to create rules (and only rules) in their user_prefs
allow_user_rules ( 0 | 1 ) (default: 0)

 


IP, DNS

 

NO_DNS_FOR_FROM

# Envelope sender has no MX or A DNS records

RDNS_NONE

# Delivered to trusted network by a host with no rDNS

This test checks to see if there is a PTR record (reverse DNS) for the last untrusted relay, which points to a domain with a matching A record.

The name is a little confusing, because it's Forward Confirmed reverse DNS that we're looking for, not just any PTR record.

Note that this may be done by interpreting information in the relevant Received header - if reverse DNS checks are not performed by the first trusted relay,

or if they are not recorded in the Received header, this test will be triggered (regardless of the actual rDNS status).

# 對方沒有 RDNS 都不加分

score   RDNS_NONE               0

ALL_TRUSTED

Passed through trusted hosts only via SMTP

it means that ALL of the "Received:" headers in the message were inserted by SMTP relays you have indicated are "TrustedRelays"

and the "from" part of the Received: header is also from one of your "TrustedRelays";

SPF

init.pre

Disable SPF Check

#loadplugin Mail::SpamAssassin::Plugin::SPF

score

# SPF_PASS: sender matches SPF record
# SPF_FAIL: sender does not match SPF record (fail)

score   SPF_FAIL                5
score   SPF_SOFTFAIL            1
score   SPF_PASS                -3

RBL

3.6 RCVD_IN_PBL            RBL: Received via a relay in Spamhaus PBL
                            [n.n.n.nlisted in zen.spamhaus.org]
0.0 RCVD_IN_SORBS_DUL      RBL: SORBS: sent directly from dynamic IP address
                            [n.n.n.nlisted in dnsbl.sorbs.net]

3.6 RCVD_IN_SORBS_WEB      RBL: SORBS: sender is an abusable web server
                            [n.n.n.n listed in dnsbl.sorbs.net]
          
1.6 RCVD_IN_BRBL_LASTEXT   RBL: No description available.
                           [n.n.n.n listed in bb.barracudacentral.org]

DNSWL

-5.0 RCVD_IN_DNSWL_HI       RBL: Sender listed at http://www.dnswl.org/, high trust
                            [x.x.x.x listed in list.dnswl.org]

DKIM

DKIM_VALID_AU            # Message has a valid DKIM or DK signature from author's domain
DKIM_VALID               # Message has at least one valid DKIM or DK signature
DKIM_SIGNED              # Message has a DKIM or DK signature, not necessarily valid

 


My Setting

 

/etc/mail/spamassassin/local.cf

# If the resulting score is high enough,
# the email is declared to be spam.
# 5.0 is the default setting, and is quite aggressive;
# if you're an ISP installing SpamAssassin, you should probably set 8.0
required_hits 5.0

# 0, incoming spam is only modified by adding some X-Spam- headers and
#    no changes will be made to the body.
# 1, SpamAssassin will create a new report message and
#    attach the original message as a message/rfc822 MIME part
report_safe 0

rewrite_header Subject [SPAM]

# Bayes
use_bayes        1
use_learner      1
bayes_auto_learn 1

# pyzor
use_pyzor              0

# Razor2
razor_config /etc/mail/spamassassin/razor/razor-agent.conf

################# Override Default Score #################

# Test Mail Score
header  LOCAL_WL_SUBJECT       Subject =~ /^testmsg\b/i
score   LOCAL_WL_SUBJECT       -10

header  LOCAL_BL_SUBJECT       Subject =~ /^banmsg\b/i
score   LOCAL_BL_SUBJECT       10

# SPF
score   SPF_FAIL                8
score   SPF_PASS                -3

# DKIM
score   DKIM_VALID              -3
score   DKIM_VALID_AU           -5

# DNS
score   RDNS_NONE               0.1
score   URIBL_BLACK             3
score   NO_DNS_FOR_FROM         3
score   RCVD_IN_RP_SAFE         0.1

# IP
score   RCVD_DOUBLE_IP_SPAM     0.1

# Whitelist
score   USER_IN_WHITELIST      -10
whitelist_from [email protected]

# Score domain
header  LOCAL_SCORE_DOMAIN     From =~ /x\.com\.hk/i
score   LOCAL_SCORE_DOMAIN     -5

# Header
score HEADER_FROM_DIFFERENT_DOMAINS     2
score MISSING_MID                       1
score MSGID_FROM_MTA_HEADER             0.1
score FROM_STARTS_WITH_NUMS             0.1

# Body
score   SUBJ_ALL_CAPS                   0.1
score   HEADER_FROM_DIFFERENT_DOMAINS   1
score   LOTS_OF_MONEY                   1
score   MPART_ALT_DIFF_COUNT            1
score   DEAR_NOBODY                     0.1
score   TVD_SPACE_ENCODED               0.1

# BAYES
score   BAYES_00        0.1
score   BAYES_05        1
score   BAYES_20        1
score   BAYES_40        2
score   BAYES_50        2
score   BAYES_60        2
score   BAYES_80        3
score   BAYES_95        5
score   BAYES_99        7
score   BAYES_999       10

 

必須更改 score 的 Setting

TVD_SPACE_ENCODED - Space ratio & encoded subject

"it's the ratio of spaces to non-spaces in each paragraph. apparently messages where generally there are lots of spaces mean the message is spam."

Extra space in HTML messages will be ignored in mail clients, but may not be ignored in pattern-matching filters.

RCVD_DOUBLE_IP_SPAM

# two reliable signatures
header __DOUBLE_IP_SPAM_1    Received =~ /from \[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\] by \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} with/
header __DOUBLE_IP_SPAM_2    Received =~ /from\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+by\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3};/
# loose match
header __DOUBLE_IP_LOOSE    Received =~ /(?:\b(?:from|by)\b.{1,4}\b\d{1,3}[._-]\d{1,3}[._-]\d{1,3}[._-]\d{1,3}(?<!127\.0\.0\.1)\b.{0,4}){2}/i
# spam signature
meta RCVD_DOUBLE_IP_SPAM    (__DOUBLE_IP_SPAM_1 || __DOUBLE_IP_SPAM_2)
describe RCVD_DOUBLE_IP_SPAM    Bulk email fingerprint (double IP) found
# other matches
meta RCVD_DOUBLE_IP_LOOSE    (__DOUBLE_IP_LOOSE && !RCVD_DOUBLE_IP_SPAM)
describe RCVD_DOUBLE_IP_LOOSE   Received: by and from look like IP addresses

MSGID_FROM_MTA_HEADER

The Message-Id header appears above at least one Received header in the message.

( indication that the Message-Id was generated by a relay, rather than by the user agent )

FROM_STARTS_WITH_NUMS

[email protected]

 


dcc fuz1 fuz2

 

The Fuz1 and Fuz2 checksums cannot be computed for messages that are too small,

and so will be missing for them. A checksum will also be missing if the DCC server is configured to not count it.

 


Change the SpamAssassin template for messages recognized as spam (-r / -R)

 

/etc/mail/spamassassin/local.cf

###################### report
clear_report_template
report Content analysis details:   (_SCORE_ points, _REQD_ required)
report
report " pts rule name              description"
report  ---- ---------------------- --------------------------------------------------
report _SUMMARY_

There is an example one at /usr/share/spamassassin/10_default_prefs.cf

 


Rule2XSBody

 

Version: 3.4.2

# Rule2XSBody - speedup by compilation of ruleset to native code
# This requires re2c (see http://re2c.org/), and the C compiler used to build Perl XS modules, be installed.
# re2c can match strings much faster than perl code, by constructing a DFA to match many simple strings in parallel,
# and compiling that to native object code. Not all SpamAssassin rules are amenable to this conversion, however.

yum install re2c -y

/etc/mail/spamassassin/v320.pre

loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody

spamassassin --lint

# compile SpamAssassin ruleset into native code

sa-compile

Feb  4 15:47:02.149 [6522] info: generic: base extraction starting. this can take a while...
Feb  4 15:47:02.149 [6522] info: generic: extracting from rules of type body_0
100% [===============================================================] 3812.09 rules/sec 00m00s DONE
...
cp /tmp/.spamassassin6522FCXH2xtmp/bases_body_0.pl /var/lib/spamassassin/compiled/5.010/3.004002/bases_body_0.pl
cd /
rm -rf /tmp/.spamassassin6522FCXH2xtmp

# "sa-compile" will not restart "spamd" or otherwise cause a scanner to reload the now-compiled ruleset automatically.

沒 compile 而 enable plugin 會見到

Feb  4 15:41:49 mail spamd[5854]: Can't locate Mail/SpamAssassin/CompiledRegexps/body_0.pm in @INC

service spamassassin restart

# Checking

# restart 後會見到 log

tail -f /var/log/maillog | grep spamd

Feb  4 15:43:58 mail spamd[6505]: zoom: able to use 348/348 'body_0' compiled rules (100%)

 


有用 Setting

 

INVALID_MSGID

RCVD_IN_BL_SPAMCOP_NET

A relay in the message's Received headers was listed in the Spamcop DNSBL;

RCVD_IN_RP_RNBL

The last external relay in the Received chain was listed in the DNSBL -RNBL(Return Path Reputation Network Blacklist).

FROM_STARTS_WITH_NUMS

0.7 FROM_STARTS_WITH_NUMS  From: starts with several numbers

 


backscatter mail

 

When a spammer or worm sends mail with forged sender addresses,

innocent sites are flooded with undeliverable mail notifications.

 


Score

 

HTML_OBFUSCATE_20_30 = Message is 20% to 30% HTML obfuscation

Explanation

The message includes HTML with obfuscated text, such as unnecessary hex-encoding of ASCII characters.

This is probably an attempt to avoid text-based filters

 


Doc

 

 


 

 

Creative Commons license icon Creative Commons license icon Creative Commons license icon