Top/PukiWiki/1.4/ちょっと便利に/連続アクセスを回避する

連続アクセスを回避する by Cue

ノーウェイトでwgetできなくなる等々副作用も多いので必要とされる方・解説無しで動作が理解できる方の参考程度にお願いします。

  1. ストレステストはやってません
  2. 瞬間最大風速を抑制する効果しかありません
  3. 制限の処理で少し変なところがあります
  4. Googleのクローラーは通ります
  5. 本当に困った時は .htaccess なり別の手段をお勧めします

メッセージ


追加ファイル

/lib/pukiwiki.phpでDATA_HOME、LIB_DIRを設定した直後にrequireするのが効果的です。

access_check.php

<?php
// PukiWiki - Yet another WikiWikiWeb clone.
//
//	access_check.php		Copyright Cue 2005
//
//	2005/09/18	v0.01
//		とりあえず作る(PHP4.3.5以降でflock可能な環境専用)
//
//	2006/03/26	v0.02
//		flockに第三引数を与えないよう変更(与えるとPHP4と5で戻り値が異なる)
//
//
//	あるリモートアドレスから1秒間に受け付けるリクエストの最大値
//	※リダイレクトすると強制的に連続アクセスになるので2以上を設定すること
define('ACCESS_CHECK_MAX_EXEC_PER_SEC',	4);
//
//	アクセス拒否を解除するまでに最低限必要な秒数
define('ACCESS_CHECK_DENY_TIME_LIMIT',	5 * 60);
//
//	アクセス記録するディレクトリ(counter/に置くとファイル名が困ったことになる)
define('ACCESS_LOG_DIR',	DATA_HOME . 'access_log/');


$time = time();
if(!access_check_set_ip_log($_SERVER['REMOTE_ADDR'], $time)){
	header('Status: 403 Forbidden');
	exit;
}
$_plugin_online2_ip_count = access_check_get_online_ip($time);
unset($time);

function access_check_set_ip_log($ip, $time)
{
	$logfile = ACCESS_LOG_DIR . $ip . '.log';
	$retcode = FALSE;
	$fp = fopen($logfile, 'a+b');
	if(flock($fp, LOCK_EX | LOCK_NB)){
		rewind($fp);
		$data = explode("\n", fread($fp, 4096));
		if(count($data) > ACCESS_CHECK_MAX_EXEC_PER_SEC){
			if((int)$data[0] != $time)
				ftruncate($fp, 0);
			fputs($fp, $time . "\n");
			$retcode = TRUE;
		}
	}
	fclose($fp);
	return $retcode;
}

function access_check_get_online_ip($time)
{
	$lists = array();
	if(($dh = @opendir(ACCESS_LOG_DIR)) !== FALSE){
		while(($lists[] = readdir($dh)) !== FALSE);
		closedir($dh);
	}
	$count = 0;
	$time -= ACCESS_CHECK_DENY_TIME_LIMIT;
	foreach($lists as $key=>$file){
		if(preg_match('/^(?:\d+\.){4}log$/', $file)){
			if(@filemtime(ACCESS_LOG_DIR . $file) <= $time){
				@unlink(ACCESS_LOG_DIR . $file);
			}else{
				$count++;
			}
		}
	}
	return $count;
}
?>

このログを利用するとonlineプラグインを下のように変えることもできます。

<?php
// PukiWiki - Yet another WikiWikiWeb clone.
//
//	online2.inc.php		Copyright Cue 2005
//
//	2005/09/18	v0.01
//		とりあえず作る

function plugin_online2_convert()
{
	return plugin_online2_itself(TRUE);
}

function plugin_online2_inline()
{
	return plugin_online2_itself(FALSE);
}

function plugin_online2_itself($convert)
{
	global $_plugin_online2_ip_count;

	if(isset($_plugin_online2_ip_count)){
		$retval = $_plugin_online2_ip_count;
	}else{
		$retval = 'access_check.php required';
	}
	return $retval . ($convert ? '<br />' : '');
}
?>

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2006-03-26 (日) 20:54:26
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.446 sec.

SourceForge