DNS ブラックリストによる SPAM フィルタリング (2)
2005-10-03
PukiWikiの荒らし対策として、以前試したDNSブラックリストを使ったフィルタリングに再挑戦する。 元ネタは、otsuneさんのtDiaryやwikiへのスパム書き込みにniku.2ch.netのDNSブラックリストを使うアイデア。
niku.2ch.net にて、BBQ という DNS ブラックリストが提供されているので、それを使わせてもらう。 PukiWiki への編集が発生するタイミングで、書込み元のIPアドレスがブラックリストに登録されているかどうかを、この DNS へ問い合わせる。
PukiWiki のソースを以下のように修正する。
plugin/edit.inc.php
function plugin_edit_action()
{
global $vars, $_title_edit, $load_template_func;
if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
$page = isset($vars['page']) ? $vars['page'] : '';
check_editable($page, true, true);
+ check_blackList($page);
plugin/comment.inc.php
function plugin_comment_action()
{
global $script, $vars, $now, $_title_updated, $_no_name;
global $_msg_comment_collided, $_title_comment_collided;
if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
+ check_blackList($vars['page']);
plugin/pcomment.inc.php
function plugin_pcomment_action()
{
global $vars;
if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
+ check_blackList($vars['page']);
pukiwiki.ini.php
check_blackList の実体は、とりあえず安易に pukiwiki.ini.php で定義した。 以前は Net_DNSBL という PEAR のモジュールを使ったけど、依存モジュールが多くインストールが面倒なので今回は1から作成する。
define('WHITELIST', "/(\.jp)$/");
function check_blackList($page)
{
if(!$_SERVER['REMOTE_HOST']) {
$_SERVER['REMOTE_HOST'] = gethostbyaddr($_SERVER['REMOTE_ADDR']);
}
if(preg_match(WHITELIST, $_SERVER['REMOTE_HOST'])) {
return false;
}
$rev_ip = implode('.', array_reverse(explode('.', $_SERVER['REMOTE_ADDR'])));
$blacklists = array(
'list.dsbl.org',
'niku.2ch.net'
);
foreach ($blacklists as $blacklist) {
$host = $rev_ip . '.' . $blacklist;
if(gethostbyname($host) != $host) {
$log = strftime('%y/%m/%d %H:%M:%S') . "\t" . $_SERVER['REMOTE_ADDR'] . "\t" . $_SERVER['REMOTE_HOST'] . "\t" . $page . "\n";
$fp = fopen(DATA_HOME . 'log/' . strftime('%y%m%d') . '.ignore.log', 'a');
fwrite($fp, $log);
fclose($fp);
die_message('Proxy規制のため書き込みできません。');
}
}
return false;
}
ブラックリストに載っていたら一律で拒否するのではなく、別にホワイトリスト(WHITELIST)を定義できるようにして、少し緩めのポリシーとしている。 このサンプルでは、 jp ドメインからの接続は全て許可し、それ以外の接続のみブラックリストでチェックするようにしている。