Lighttpdでプロセスを起動せずにスパムを撃退する方法
キャッシュを有効に活かすことはmod_rewriteでも処理可能ですから不要なモジュールを使用しないという意味においては積極的にmod_cmlを導入する理由もみつからなかったのですが、こんな使い方も考えてみました。
mod_cmlの目的はサーバ内で処理できるリクエストはサーバ内で処理しできるだけrubyなりphpなりのインタプリタを起動しないで負荷を減らし高速化しようというものです。それでちょっと前に悩まされていたトラックバックスパムの撃退に利用できないか思いついた訳なんです。現在、このブログでもdrupalのtrackback.moduleにスパム撃退のコードを埋め込んでいますが、結局phpは起動されているわけでこういう不毛な処理をサーバ側追い出すことができれば実にうれしい。早速トライしてみました。
当初、現在Drupalのtrackback.moduleに組み込んでいるのはまちゅダイアリー - コメント SPAM 対策 - 日本語を含まないコメントを禁止なのでこれをそのままpower-magnet.cmlに追い出すことを検討したのですがLuaが文字列のマルチバイトに対応していないため断念。(時間があればこの部分をカスタマイズして再チャレンジしたいですが)代わりにキーワードを指定してスパム判定するオーソドックスなやり方を実装してみました。
まず、最初はtrackbackモジュールへのURLかどうか調べます。例えば、トラックバックURLが”http://example.com/trckback/id”の場合、キーワードとしてtrackbackをチェックします。power_magnet.cmlはすべてのリクエストに先立って実行されるのでこの判定を誤ると痛いメにあうかも。
ur = request["REQUEST_URI"] if not string.find(ur,"trackback") then return CACHE_MISS end
トラックバックリクエストの判定をした後、trackbackのtitle/excerptに指定したキーワードが含まれていたらこれをスパムとみなします。その場合、あらかじめ作成しておくerror.xmlを返します。OKであればCACHE_MISSを返しアプリケーションに処理を委ねます。
is_spam = 0
title = get["title"]
excerpt = get["excerpt"]
-- NGワードを指定
evil_words = {}
evil_words[0] = 's*x'
evil_words[1] = 'po**o'
evil_words[2] = 'v**lence'
:
-- excerptにNGワードが含まれていればspam
if excerpt then
for key,value in pairs(evil_words) do
if string.find(excerpt,tostring(value)) then
is_spam = 1
break
end
end
end
-- titleにNGワードが含まれていればspam
if is_spam == 0 and title then
for key,value in pairs(evil_words) do
if string.find(title,tostring(value)) then
is_spam = 1
break
end
end
end
if is_spam == 1 then
dr = request["DOCUMENT_ROOT"]
output_include = { dr .. "/spam.xml" }
return CACHE_HIT
end
return CACHE_MISS
|
キーワードのメンテナンスが逐次必要となりますがphpモジュール側に組み込んでいるロジックと併せれば十分に負荷を減らすという目的は達成できると思います。
戻り値としてCACHE_HIT/CACHE_MISSを返すのはちょっと違和感があったのですが、mod_cml is dead, long live mod_cmlの記事を発見。たくさんのコメントがついていますが、僕的にはmod_logicが一番わかりやすいかな。










Comments