对 SPAM 的攻防,我之前在利用 Postfix 抵挡垃圾信 (new window) 就有简单的提过,基本上,使用 postfix 的内建 header_checks 和 body_checks 可以应付一些阳春的垃圾信,最多再使用一些进阶的选项来分析连线资讯。不过对于垃圾客的手法越来越新,使用这种手动更新 rule 的使法似乎成果有限而且非常累人,因此,在小弟饱受 SPAM 的威胁之下决定使用 Spamssassin 来抵制 SPAM。
安装
安装 HTML::Parser
其实 Spamssassin 是 Perl 的一个模组,当然我是使用 CPAN 这个好东西来安装我所需要的模组,而在安装 Spamssassin 之前,需要安装 Perl 的 HTML::Parser Module。
CODE:
root # cpan HTML::Parser
安装 SpamAssassin
当然 SpamAssassin 是主角啦!可以使用 Perl CPAN 来安装,或是到 这里 来下载安装。
CODE:
root # cpan Mail::SpamAssassin
如此就安装完毕。
安装 Mail::SPF::Query
嗯,还需要 Mail::SPF::Query 这个模组,所以就安装起来吧!
CODE:
root # cpan Mail::SPF::Query
设定
设定 SpamAssassin 设定档
SpamAssassin 的设定档是放在 /etc/mail/SpamAssassin/local.cf 里面,而且个档案里面定义了很多简查规则,以下,我把最简单的设定列出来。
CODE:
#多少分才判为 SPAM
required_hits 5
report_safe 1
#若为 SPAM,是否设修改主旨
rewrite_subject 1
#修改主旨为 (当 rewrite_subject 是 1 的时候才会有用)
rewrite_header Subject [SPAM]
# Encapsulate spam in an attachment
report_safe 1
# Use terse version of the spam report
use_terse_report 1
# Enable the Bayes system
use_bayes 1
# Enable Bayes auto-learning
auto_learn 1
# Enable or disable network checks
skip_rbl_checks 0
use_razor2 1
use_dcc 1
use_pyzor 1
# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
# - chinese english japanese
ok_languages zh en ja
# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales en ja zh
这样做,就可以把基本的 SpamAssassin 设定起来。
新增一个 spamfilter 使用者
这个 spamfilter 主要是 spamd 会使用的,所以请建立起来,当然这个帐号是不允许从外面登入的:
CODE:
root # useradd -s /bin/false spamfilter
编写 filter script
CODE:
root # touch /usr/local/sbin/filter.sh
CODE:
root # vi /usr/local/sbin/filter.sh
#!/bin/bash
exec /usr/bin/spamc -d 127.0.0.1 -f -p 783 -t 30 -e /usr/sbin/sendmail -i "$@"
exit $?
root # chmod 755 /usr/local/sbin/filter.sh
你可以 按这里 下载 filter.sh。
设定 postfix
再来,我们需要再设定 postfix 一下,让 postfix 在接收信件时,使用 SpamAssassin 来做信件过泸。其中会设定到最重要的 /etc/postfix/master.cf 档,所要请记得要特别小心!
CODE:
root # vi /etc/postfix/master.cf
~ 略 ~
#修改以下两个项目
CODE:
smtp inet n - n - - smtpd -o content_filter=postfixfilter
smtp unix - - n - - smtp -o content_filter=postfixfilter
~ 略 ~
# 在最后一行加入以下句子
CODE:
postfixfilter unix - n n - - pipe flags=Rq user=spamfilter
argv=/usr/local/sbin/filter.sh -f ${sender} -- ${recipient}
root #
设定了 master.cf 之后,如果你在 main.cf 有设定其它的垃圾邮件规则的话,像是 header_checks 和 body_checks 的话,就请关闭吧,这种全文分析的工作可以让 SpamAssassin 来做就可以了。
CODE:
root # vi /etc/postfix/master.cf
#把 header_checks 和 body_checks 注解起来
#header_checks = regexp:/etc/postfix/header_checks
#body_checks = regxp:/etc/postfix/body_checks
root #
重新启动 postfix 和 SpamAssassin
CODE:
root # postfix stop; sleep 3; postfix start
root # service spamassassin start
测试
当然要测试最直接的方法就是使用 telnet
CODE:
root # telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to mail-test.l-penguin.idv.tw (127.0.0.1).
Escape character is '^]'.
220 l-penguin.idv.tw ESMTP Postfix
MAIL FROM: [email]babiku007@yahoo.com.tw[/email]
250 Ok
RCPT TO: [email]someone@your.domain.name[/email]
250 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: Test SPAM mail
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
.
250 Ok: queued as 450BFC6249
quit
221 Bye
Connection closed by foreign host.
root #
上面是一封 SPAM body 的测试内容,现在请看一下你的 maillog,就会发现这是一封分数很高的 SPAM。
CODE:
root # cat /var/log/maillog
1 Dec 4 11:55:56 dns spamd[17862]: connection from mail-test.l-penguin.idv.tw [127.0.0.1] at port 39463
2 Dec 4 11:55:56 dns spamd[17862]: info: setuid to spamfilter succeeded
3 Dec 4 11:55:56 dns spamd[17862]: processing message <[email]20051204035518.450BFC6249@l-penguin.idv.tw[/email]> for spamfilter:86.
4 Dec 4 11:55:58 dns spamd[17862]: identified spam (999.6/5.0) for spamfilter:86 in 1.2 seconds, 487 bytes.
5 Dec 4 11:55:58 dns spamd[17862]: result: Y 999 - ALL_TRUSTED,DNS_FROM_RFC_ABUSE,FROM_ENDS_IN_NUMS,GTUBE,NO_REAL_NAME,UNDISC_RECIPS scantime=1.2,size=487,mid=<[email]20051204035518.450BFC6249@l-penguin.idv.tw[/email]>,autolearn=disabled
6 Dec 4 11:55:58 dns postfix/pickup[18137]: 251C8C625F: uid=86 from=<[email]babiku007@yahoo.com.tw[/email]>
7 Dec 4 11:55:58 dns postfix/cleanup[18169]: 251C8C625F: message-id=<[email]20051204035518.450BFC6249@l-penguin.idv.tw[/email]>
8 Dec 4 11:55:58 dns postfix/pipe[18170]: 450BFC6249: to=<[email]someone@your.domain.name[/email]>, relay=postfixfilter, delay=40, status=sent (l-penguin.idv.tw)
9 Dec 4 11:55:58 dns postfix/qmgr[18138]: 450BFC6249: removed
10 Dec 4 11:55:58 dns postfix/qmgr[18138]: 251C8C625F: from=<[email]babiku007@yahoo.com.tw[/email]>, size=3186, nrcpt=1 (queue active)
11 Dec 4 11:55:58 dns postfix/local[18174]: warning: dict_nis_init: NIS domain name not set - NIS lookups disabled
12 Dec 4 11:55:58 dns postfix/local[18174]: 251C8C625F: to=<[email]someone@your.domain.name[/email]>, relay=local, delay=0, status=sent (delivered to mailbox)
13 Dec 4 11:55:58 dns postfix/qmgr[18138]: 251C8C625F: removed
14 Dec 4 11:55:59 dns postfix/smtpd[18166]: disconnect from mail-test.l-penguin.idv.tw[127.0.0.1]
root #
当你有看到信被打分数,就表示新的垃圾分析有在运作了。
分析
在你的 maillog 里,会明显看到这是一封分数高达 999 的 SPAM,现在我们来看看被认定为 SPAM 的信会长什么样子,当然以下我以 Openwebmail 来开启我的信件。
若是为 SPAM,那么就会在主旨的最前面多出个 [SPAM] 字样,现在来看看表头部份。
CODE:
Return-Path: <[email]babiku007@yahoo.com.tw[/email]>
X-Original-To: [email]someone@your.domain.name[/email]
Delivered-To: [email]someone@your.domain.name[/email]
Received: by l-penguin.idv.tw (Postfix, from userid 86)
id 251C8C625F; Sun, 4 Dec 2005 11:55:58 +0800 (CST)
Received: from localhost by dns.l-penguin.idv.tw
with SpamAssassin (version 3.0.4);
Sun, 04 Dec 2005 11:55:58 +0800
From: [email]babiku007@yahoo.com.tw[/email]
To: undisclosed-recipients:;
Subject: [SPAM] Test SPAM mail
Date: Sun, 4 Dec 2005 11:55:18 +0800 (CST)
Message-Id: <[email]20051204035518.450BFC6249@l-penguin.idv.tw[/email]>
X-Spam-Flag: YES
X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on
dns.l-penguin.idv.tw
X-Spam-Level: **************************************************
X-Spam-Status: Yes, score=999.6 required=5.0 tests=ALL_TRUSTED,
DNS_FROM_RFC_ABUSE,FROM_ENDS_IN_NUMS,GTUBE,NO_REAL_NAME,UNDISC_RECIPS
autolearn=disabled version=3.0.4
X-Spam-Report:
* 0.2 NO_REAL_NAME From: does not include a real name
* 0.5 FROM_ENDS_IN_NUMS From: ends in numbers
* 1.4 UNDISC_RECIPS Valid-looking To "undisclosed-recipients"
* -2.8 ALL_TRUSTED Did not pass through any untrusted hosts
* 1000 GTUBE BODY: Generic Test for Unsolicited Bulk Email
* 0.4 DNS_FROM_RFC_ABUSE RBL: Envelope sender in abuse.rfc-ignorant.org
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----------=_439268CE.44AD695C"
Status: R
X-Spam-Level 后面接了个很多 "*",每个 * 都表示一个分数,而超过所设定的分数 (本例为 5),那么就会在 X-Spam-Status 记录为 Yes,判别为 SPAM。
应用
在使用过 SpamAssassin 之后,小弟本人是非常的建议使用,因为判别的精准度非常高,当然在 User 使用离线软体 (如 Outlook) 时,再配合其过滤功能 (把 [SPAM] 开头的信件直接删除) 就能让信件看起来更清爽。
后记
小弟在 12/04/2005 完成这篇文章之后,发现收到测试的 SPAM mail 越来越多了,这表示有很多网友观看小弟的文章,小弟非常高兴,但是也希望把 RCPT TO: 这个后面的 mail 改成您自己实际的测试帐号,不然小弟一开信就是一堆 Test SPAM Mail,开始有点吃不消了呢!