SpamAssassin
スパムメールがひどい状況(1日100通以上)になってきたのでアンチスパムソフトであるSpamAssassinを導入する。
SpamAssassinはベイジアンフィルタ型のアンチスパムソフトなのでメールを受信するたびに学習して賢くなっていくのが特徴。
もちろんホワイトリストやブラックリストを使うことも可能。
SpamAssassinはPerlでかかれており、動作させるためにはいくつかのPerlモジュールが必要。
make時にインストールされていない旨表示されたら個別にインストールしておく。
・Digest::SHA1
・HTML::Parser
・Net::DNS
・Mail::SPF::Query
・IP::Country
・Razor2
・Net::Ident
・IO::Socket::INET6
・IO::Socket::SSL
・Time::HiRes
・DBI
・LWP::UserAgent
・HTTP::Date
・Archive::Tar
・IO::Zlib
# /usr/sbin/groupadd -g 206 spamd # /usr/sbin/useradd -u 206 -g 206 -s /sbin/nologin -d /etc/mail/spamassassin spamdSpamAssassinの公式サイトよりソースファイルを入手しインストールする。
$ wget http://ftp.kddilabs.jp/infosystems/apache/spamassassin/source/Mail-SpamAssassin-3.1.7.tar.bz2 $ tar xvjf Mail-SpamAssassin-3.1.7.tar.bz2 $ cd Mail-SpamAssassin-3.1.7 $ perl Makefile.PL PREFIX=/usr/local $ make # make install # chown -R spamd:spamd /etc/mail/spamassassin/ソースに含まれているサンプルのスパムメールを使って動作確認をしておく。
# /usr/local/spamassassin/bin/spamassassin -t < sample-spam.txt (省略) Content analysis details: (1000.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 NO_RELAYS Informational: message was not relayed via SMTP 1000 GTUBE BODY: Generic Test for Unsolicited Bulk Email -0.0 NO_RECEIVED Informational: message has no Received headersSpamAssassinの設定ファイルを編集する。
TLECというところで設定ファイルのサンプルを公開しているので使用させて頂く。
# cd /etc/mail/spamassassin # wget -O local.cf http://tlec.linux.or.jp/docs/user_prefs # echo "report_safe 0" >> local.cf起動スクリプトを作成する。
/etc/rc.d/init.d/spamd
#!/bin/bash
#
# spamassassin This script starts and stops the spamd daemon
#
# chkconfig: 345 70 30
# processname: spamd
# description: spamd is a daemon process which uses SpamAssassin to check \
# email messages for SPAM. It is normally called by spamc \
# from a MDA.
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
[ -r /etc/sysconfig/network ] && . /etc/sysconfig/network
RETVAL=0
prog="spamd"
# Set default spamd configuration.
SPAMDOPTIONS="-d -c -m5 -H"
SPAMD_PID=/var/run/spamd.pid
# Tack on path to spamd if not already in PATH
SPAMD_PATH=":/usr/local/bin/"
PATH=$PATH$SPAMD_PATH
export PATH
# See how we were called.
start() {
# Start daemon.
echo -n $"Starting $prog: "
daemon $NICELEVEL spamd $SPAMDOPTIONS -r $SPAMD_PID
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/spamd
return $RETVAL
}
stop() {
# Stop daemons.
echo -n $"Stopping $prog: "
killproc spamd
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/spamd
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
condrestart)
[ -e /var/lock/subsys/spamd ] && restart
;;
status)
status spamd
RETVAL=$?
;;
*)
echo "Usage: $0 {start|stop|status|restart|condrestart}"
exit 1
esac
exit $?
起動スクリプトを登録する。
# vi /etc/service spamd 783/tcp # SpamAssassin # chmod 755 /etc/rc.d/init.d/spamd # /sbin/chkconfig --add spamd # /sbin/chkconfig --list |grep spamd spamd 0:off 1:off 2:on 3:on 4:on 5:on 6:offSpamAssassinを起動する。
# /sbin/service spamd start spamd を起動中: [ OK ] # ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 13005 23.8 12.9 39548 33140 ? Ss 13:23 0:09 /usr/local/spamassassin/bin/spamd -d -c -m5 -H -r /var/run/spamd.pid root 13008 0.0 12.3 39548 31492 ? S 13:23 0:00 spamd child root 13009 0.0 12.2 39548 31372 ? S 13:23 0:00 spamd child # netstat -an Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:783 0.0.0.0:* LISTENサーバ稼働時のログ
# tail /vr/log/maillog Jan 31 20:19:35 bruna spamd[26479]: logger: removing stderr method Jan 31 20:19:38 bruna spamd[26481]: config: failed to parse, now a plugin, skipping: ok_languages ja en Jan 31 20:19:43 bruna spamd[26481]: rules: meta test DIGEST_MULTIPLE has undefined dependency 'DCC_CHECK' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test CURRWROTE has undefined dependency 'RCVD_FORGED_WROTE' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test KEITAIFROMISP has undefined dependency 'INFOSPHERE' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test ___TVD has undefined dependency 'TVD_FW_GRAPHIC_ID1' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test ___TVD has undefined dependency 'TVD_FW_GRAPHIC_ID2' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test ___TVD has undefined dependency 'TVD_FW_GRAPHIC_ID3' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test ___TVD has undefined dependency 'TVD_FW_GRAPHIC_NAME_LONG' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test SPANFLOAT has dependency 'FORGED_RCVD_HELO' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test UKGEOFORMAT2 has dependency 'FORGED_RCVD_HELO' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test SUBJ_SPACES_UNIQID has dependency 'SUBJ_HAS_UNIQ_ID' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test SORBSDUL00 has dependency 'BAYES_00' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test FRGDHLDIRECT has dependency 'FORGED_RCVD_HELO' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test ___DCN has undefined dependency 'DCC_CHECK' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test URIBLSBL00 has dependency 'BAYES_00' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test SPAMCOP00 has dependency 'BAYES_00' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test CORE_B64 has dependency 'MIME_BASE64_NO_NAME' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test CORE_B64 has dependency 'MIME_BASE64_BLANKS' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test BASE64TXT60 has dependency 'MIME_BASE64_NO_NAME' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test BASE64TXT60 has dependency 'MIME_BASE64_BLANKS' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test FRGDMTAWROTE has undefined dependency 'RCVD_FORGED_WROTE' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test HTMLIMG_FRGDHELO has dependency 'FORGED_RCVD_HELO' with a zero score Jan 31 20:19:43 bruna spamd[26481]: rules: meta test STILL_TVDFUZREF has undefined dependency 'TVD_FUZZY_FINANCE' Jan 31 20:19:43 bruna spamd[26481]: rules: meta test RCVDSBLBLACK has undefined dependency 'URIBL_BLACK' Jan 31 20:19:44 bruna spamd[26481]: spamd: server started on port 783/tcp (running version 3.1.7) Jan 31 20:19:44 bruna spamd[26481]: spamd: server pid: 26481 Jan 31 20:19:44 bruna spamd[26481]: spamd: server successfully spawned child process, pid 26485 Jan 31 20:19:44 bruna spamd[26481]: spamd: server successfully spawned child process, pid 26486 Jan 31 20:19:44 bruna spamd[26481]: prefork: child states: II # tail /var/log/boot.log Jan 31 20:19:35 bruna spamd: spamd 起動 succeededMTAであるPostfixと連携する。
イメージ的には「外部MTA」→「Postfix」→「SpamAssassin」→「メールスプール」→「MailDrop」となる。
ここを参考にPostfixの設定ファイルを編集する。
/etc/postfix/master.cf
smtp inet n - n - - smtpd
-o content_filter=spamassassin
(省略)
spamassassin unix - n n - - pipe
user=spamd argv=/usr/local/bin/spamc -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}
外部からメールを受信したときのログで正常に動作しているか確認する。
Jan 29 14:09:50 bruna postfix/smtpd[14997]: connect from nz-out-0506.google.com[64.233.162.229] Jan 29 14:09:51 bruna postfix/smtpd[14997]: 64D7A5B46C: client=nz-out-0506.google.com[64.233.162.229] Jan 29 14:09:51 bruna postfix/cleanup[15000]: 64D7A5B46C: message-id=<4c1f7c180701282109w791906a2nc5f54d72a740602c@mail.gmail.com> Jan 29 14:09:51 bruna postfix/qmgr[14926]: 64D7A5B46C: from=<example@gmail.com>, size=1312, nrcpt=1 (queue active) Jan 29 14:09:51 bruna spamd[14976]: spamd: connection from bruna [127.0.0.1] at port 33012 Jan 29 14:09:51 bruna spamd[14976]: spamd: setuid to spamd succeeded Jan 29 14:09:51 bruna spamd[14976]: spamd: creating default_prefs: /etc/mail/spamassassin/.spamassassin/user_prefs Jan 29 14:09:51 bruna spamd[14976]: config: created user preferences file: /etc/mail/spamassassin/.spamassassin/user_prefs Jan 29 14:09:51 bruna spamd[14976]: spamd: processing message <4c1f7c180701282109w791906a2nc5f54d72a740602c@mail.gmail.com> for spamd:206 Jan 29 14:09:52 bruna spamd[14976]: spamd: clean message (-1.5/13.0) for spamd:206 in 0.5 seconds, 1288 bytes. Jan 29 14:09:52 bruna spamd[14976]: spamd: result: . -1 - ALL_TRUSTED,CONTENT_TYPE_PRESENT,ISO2022JP_BODY,ISO2022JP_CHARSET,QENCPTR2 scantime=0.5,size=1288,user=spamd,uid=206,required_score=13.0,rhost=bruna,raddr=127.0.0.1,rport=33012,mid=<4c1f7c180701282109w791906a2nc5f54d72a740602c@mail.gmail.com>,autolearn=ham Jan 29 14:09:52 bruna postfix/pickup[14925]: 624865B46F: uid=206 from=<example@gmail.com> Jan 29 14:09:52 bruna postfix/cleanup[15000]: 624865B46F: message-id=<4c1f7c180701282109w791906a2nc5f54d72a740602c@mail.gmail.com> Jan 29 14:09:52 bruna postfix/pipe[15001]: 64D7A5B46C: to=<testuser@kajukaju.net>, relay=spamassassin, delay=1.2, delays=0.56/0.02/0/0.62, dsn=2.0.0, status=sent (delivered via spamassassin service) Jan 29 14:09:52 bruna postfix/qmgr[14926]: 64D7A5B46C: removed Jan 29 14:09:52 bruna postfix/qmgr[14926]: 624865B46F: from=<example@gmail.com>, size=1671, nrcpt=1 (queue active) Jan 29 14:09:52 bruna spamd[14972]: prefork: child states: IISpamAssassinのデーモンであるspamdがrootで動いている。
セキュリティを確保するために専用ユーザ(spamd)で動くようにする。
起動スクリプトを一部修正する。
/etc/rc.d/init.d/spamd
SPAMDOPTIONS="-d -c -m5 -H" ↓ SPAMDOPTIONS="-d -c -m5 -H -u spamd"spamdユーザで起動していることを確認する。
# ps auxww root 2215 0.0 7.6 47056 39368 ? Ss Apr04 3:35 /usr/local/bin/spamd -d -m 5 -H -u spamd -r /var/run/spamd.pid spamd 16945 0.1 8.6 52400 44548 ? S Apr06 5:06 spamd child spamd 17775 0.0 7.3 47056 37716 ? S Apr08 0:00 spamd child
