このブログも一日数百件のトラックバックスパムと数十件のコメントスパムを受けていて、MovableTypeのスパムフィルタが強力なおかげでほとんどがJunkに放り込まれているのですが、処理に結構負荷を食っているのと、スロットリングされてまともなトラックバックも受けれないようなので、やはりなんとか対策せねばと思い調べてみました。
スパムブロックの強力な順に上げると、ぱっと思いつくのは
- ルータで弾く
- サーバのファイアウォールで弾く
- apacheで弾く
- cgiで弾く
このうち4はMovableTypeが実装していて十二分に役に立ってくれています。しかし残念ながら受け取ってしまうと負荷とスロットリングの問題がでます。1のルータで弾く方法はいいルータとルータへのアクセス権が必要ですが、うちのは無理です。(あと、レンタルサーバなどではファイアウォールの設定も変更できないかもしれません)
ということでまずは3を、そして2でやってみます。
まずサーバのログをチェック。MT-comment.cgi, MT-tb.cgiにやってきているもののうちほとんどがスパムと思われます。件数を数えるとtbが6000以上来ています。で、単純にUserAgentを見てみると、なんともわかりやすいことに特定のいくつかのUserAgentから半数以上が来ていることが判明。特にlibghttpは1/3近く。また同一IPから複数のUAを使ってスパムしているものもあります。
というわけでまずはトラックバックスパムを以下のようにしてはじいて見ました。
.htaccessで弾く方法
.htaccessでスパムをブロックするには以下の方法が考えられます。
- UserAgentで弾く
- IPアドレスで弾く
ということで
1. UserAgentで弾く
怪しげなUAをリストアップしてみます。
これらを弾けば計算上90%以上のトラックバックスパムがapacheに弾かれるはずです。
#怪しげなのを見かけたら順次追加予定。イタチゴッコですな。
#MozillaとかOperaとかからも実用上問題ないはずなので追加。
#07/5/31 NP_Trackback追加 (8/4 NucleusCMSのTB機能のようなので文字列限定で拒否)
#07/6/6 USERAGENT追加
#07/6/17 tb_send/1.0追加
#07/6/20 Nutscrape/1.0追加
#07/6/23 Tackback追加。 MovableType/3.151-jaなるものも見つけたが。
#07/11/7 MovableType/3.14を追加。結構古いバージョンを騙るようです。
2. IPアドレスで弾く
2-1)AutoIPBanをありがたく導入してIPBanListを使ってIPを禁止にしてみます。インデックステンプレートで新規テンプレートを作成し、出力ファイル名でMTのCGIディレクトリ内の.htaccessを指定。この方法の問題は自動でBANになったものはいいのですが、残りは手動でBanしないといけない点です。
またIPBanのリストでtb-commentもはじくようにしました。FastCGIを使っている場合も考えて<Files>で指定している拡張子を.*cgiにしました。
SetEnvIf User-Agent "^.$" trackbackSpammer
SetEnvIf User-Agent "^libghttp/1.0" trackbackSpammer
SetEnvIf User-Agent "^TrackBack/1.02" trackbackSpammer
SetEnvIf User-Agent "^TrackBack/1.6" trackbackSpammer
SetEnvIf User-Agent "^TrackBack$" trackbackSpammer
SetEnvIf User-Agent "^NP_Trackback/2.0.3$" trackbackSpammer
SetEnvIf User-Agent "^User-Agent" trackbackSpammer
SetEnvIf User-Agent "^Opera/" trackbackSpammer
SetEnvIf User-Agent "^Mozilla/" trackbackSpammer
SetEnvIf User-Agent "^tb_send/1.0" trackbackSpammer
SetEnvIf User-Agent "^MovableType/3.14" trackbackSpammer
<Limit POST>
Order Allow,Deny
allow from all
deny from env=TrackbackSpammer
deny from <$MTIPBanListIP$>
</MTIPBanList>
<Files "mt-comments.*cgi">
<Limit POST>
Order Allow,Deny
allow from all
deny from <$MTIPBanListIP$>
</MTIPBanList>
2-2) サーバログからスパムを送ってきたIPのうち頻度の高いものを弾いてしまいましょう。
簡単なスクリプトですが、以下のスクリプトで上のテンプレートの#IPBanList部分にサーバログから取得した怪しいIPのリストを埋め込むようにします。
インデックスを再構築したらこのスクリプトも走らせないといけませんが、rootのcronで走らせておけば自動化出来ると思います。サーバログの位置、オーナー、MTのパスをセットしてcronで定期的に走らせます。rankで上位どれくらいを弾くかを指定します。
少し手抜きなので不審なUAとかぶるタイトルのエントリーが存在するとまずいです。
mt-spamipban.sh
tmpfile=`mktemp`
tmpfile2=`mktemp`
rank=-50
owner=apache.apache
logfiles="/var/log/httpd/SERVERLOG-access_log*"
fwpattern='s/^\(.*\)/deny from \1/'
fwfile=$MTDIR/.htaccess
(echo '#IPBanStart';grep -h mt-tb $logfiles| grep "$pattern" |awk '{print $1}'| sort | uniq -c | sort -r |head $rank|awk '{print $2}' |sed -e "$fwpattern";echo '#IPBanEnd') > $tmpfile
sed -e /#IPBanStart/,/#IPBanEnd/d -e /#IPBanList/r$tmpfile < $fwfile > $tmpfile2
cp $tmpfile2 $fwfile
chown $owner $fwfile
cat $tmpfile2
rm -f $tmpfile $tmpfile2
サーバログの取得できない環境であっても、mt-trb.cgiで自前のログを出力すればサーバログと似たようなログは取得できるはずです。
IPBanのリストと重複するはずなのでマジメにスクリプトを作ることにしました。後日。
Firewallでも弾いてみる
同じIPのリストを使ってFirewallでそもそものアクセスごと禁止してしまいます。これは強力で、apacheに優しくなります。リストが多すぎると今度はカーネルが負荷を食ってしまうと思いますが、どちらも一長一短なので。
FWで弾いてしまう方法の欠点としては
- apacheのログに残らなくなる
- 無関係なパケットでもkernelに負荷が(若干)かかる
利点としては
- そのIPからの全てがapacheにたどり着かないため気持ちいい
- httpが起動されるより負荷が低い
そこで上記の不審なUAのうちスレッショルドを超えたものだけを永久にiptablesで弾くように以下のようにしてみました。
RedHat系(RHEL,Fedora Core, CentOS)用になりますが、/etc/sysconfig/iptablesのport 80を許可する前に結果をペーストすればOKです。
tmpfile=`mktemp`
threshold=100
logfiles="/var/log/httpd/SERVER-access_log*"
pattern='\(libghttp\|Trackback/1.02\|Trackback/1.6\|"-" "-"\|User-Agent:\)'
fwpattern='s/^\(.*\)/-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 80 --src \1 -j REJECT/'
#
grep -h mt-tb $logfiles| grep "$pattern" |awk '{print $1}'| sort | uniq -c | sort -r |awk "\$1 >= $threshold { print \$2}" |sed -e "$fwpattern"
これも同じく不審なUAとかぶるタイトルのエントリーが存在すると引っかかってしまいます。iptablesの更新も完全自動化したいところですが、状態を残さないといけないので面倒です。
こういうブラックリスト方式のスパム対策はイタチごっごではあるのですが、何もしないよりずっとましです。
問題:IPベースのフィルタリングはレンタルの共用サーバからのまともなトラックバックもはじいてしまう可能性があります。
まずはここまで。
コメント (1)
コメントのテスト!
投稿者: yamap | 2007年04月29日 17:53
日時: 2007年04月29日 17:53