2chBBSでのスパムフィルタリング

当然ですが、掲示板の数が増えるに従ってスパムの数は多くなり、輪をかけて管理がやりづらくなってしまいます。そこで、2chBBSを使った掲示板に対するレスの投稿に、akismet.inc.phpを使って、スパムフィルタリングをかける方法を紹介します。(他の掲示板プラグインにも応用できると思います)前提として、AkismetreCAPTCHAへの登録が済んでいることとします。(akimet.inc.phpの導入方法はこちらのページなどを参照)

Table of Contents

plugin/akismet.inc.phpの編集

プラグインとして、スパムフィルタリングを行う主体となるのがakismet.inc.phpの中で定義されている関数spamfilter()です。そのままの状態では、cmd=readを変数として渡された場合にはフィルタリングをしないように設定されており、その変数を渡してしまう掲示板への書き込みに対して有効になっていません。そこで、オリジナルでは以下のようになっている部分(300行目前後)を書き換えます。

function spamfilter($comment = NULL)
{
	global $vars, $defaultpage;
	// Through if GET (Check only POST)
	if ($_SERVER['REQUEST_METHOD'] === 'GET') return;
	// Through if POST is from akismet plugin (submitHam)
	if (isset($vars['cmd']) && $vars['cmd'] == 'akismet') return;
	// Through if in IGNORE list
	$cmd = isset($vars['cmd']) ? $vars['cmd'] : (isset($vars['plugin']) ? $vars['plugin'] : 'read');
	if (defined('PLUGIN_AKISMET_IGNORE_PLUGINS')) {
		if (in_array($cmd, explode(',', PLUGIN_AKISMET_IGNORE_PLUGINS))) return;
	}

上の最後の if (defined('PLUGIN_AKISMET_IGNORE_PLUGINS')) { ... という記述を下のように書き換えると、掲示板が投げる固有の変数(sub)を拾って、cmd=readが渡されたとしてもスルーしなくなります。

	// Modified for BBS -- Identify by the posted variable (sub)
	if (defined('PLUGIN_AKISMET_IGNORE_PLUGINS') && !isset($vars['sub'])) {
		if (in_array($cmd, explode(',', PLUGIN_AKISMET_IGNORE_PLUGINS))) return;
	}

ここでついでに、特定のコマンドが投げられた時にフィルタリングをさせないための記述(60行目前後)を以下の様な記述に変更しておくと、bbsadmin.inc.phpがポスト変数を投げてもフィルタリングしないようになります。ちなみに、cmdではなくpluginで呼び出す場合にはcmdの部分をpluginに変更します。(実験では動作速度が改善しました)

	// Do not spam filter POST via these plugins (SPAM filter works only for POST, not GET)
	if (! defined('PLUGIN_AKISMET_IGNORE_PLUGINS')) {
		define('PLUGIN_AKISMET_IGNORE_PLUGINS', 'read,vote,vote2,bbsadmin');
	}

plugin/bbs.inc.phpの編集

次に、bbs.inc.phpはpost()という関数でコメントを投稿するようになっているので、この関数が宣言されている部分(恐らく60行目前後)を見つけ出し、akismet.inc.phpで定義されている関数spamfiter()を呼び出すように、以下の様な感じで書き直します。

function post($sub, $name, $com, $email, $kdate){
	global $script, $vars;
	global $script, $vars;
	global $notify, $notify_diff_only, $notify_to, $notify_subject, $notify_header;
	global $smtp_server, $smtp_auth;
	
	// Akismet SPAM Filtering 開始
	$comment = array(
		'author'       => $post['name'],
		'email'        => $post['email'],
		'website'      => '',
		'body'         => $post['com'],
		'permalink'    => '',
		'user_ip'      => $_SERVER["REMOTE_ADDR"],
		'user_agent'   => $_SERVER["HTTP_USER_AGENT"],
	);
	if(exist_plugin('akismet')) PluginAkismet::spamfilter( $comment, 1 );
	// Akismet SPAM Filtering 終了

lib/pukiwiki.phpの編集

こちらのページで紹介されている方法に従えば、恐らく70〜90行目あたりlib/pukiwiki.phpは以下のように書き換えられているはずです。

	/////////////////////////////////////////////////
	// Main
	
	$retvars = array();
	$is_cmd = FALSE;
	if (isset($vars['cmd'])) {
		$is_cmd  = TRUE;
		$plugin = & $vars['cmd'];
	} else if (isset($vars['plugin'])) {
		$plugin = & $vars['plugin'];
	} else {
		$plugin = '';
	}
	// Akismet SPAM Filtering 開始
	if(exist_plugin('akismet')) PluginAkismet::spamfilter();
	// Akismet SPAM Filtering 終了

この場合、akismet.inc.phpの設定でcmd=readでかつ掲示板が投げる固有の変数がある場合にはスルーしないように設定しているので、コメントの投稿の場合に重複してspamfiter()が呼び出されてしまいます。それは動作速度上マズいので、以下のように書き換えて、掲示板固有の変数(BBS_NAME)が設定されている場合にはpukiwiki.phpを通してspamfiter()を呼び出さないようにします。(この場合、掲示板がおかれているページは凍結しておいて下さい)

	// Akismet SPAM Filtering 開始
	if(!defined('BBS_NAME')) if(exist_plugin('akismet')) PluginAkismet::spamfilter();
	// Akismet SPAM Filtering 終了

動作確認

spam.png

以上でスパムフィルタリングの設定は完了です。スパムっぽい書き込みではじかれるかどうか試してみて下さい。akismetがスパムと判断すると、右の様な認証画面が表示され、キーワードを入れると投稿できるようになっています。もしこれが表示されない場合は、変数の設定など、変更したプログラムのどこかに問題があるか、スパムがフィルターをすり抜けることができたということです。

Free Web Hosting with Website Builder